Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Table of Contents

Requirements

  • many-to-one assignment (one assignment group can have many email addresses)
  • should not have to edit code to add/update/delete queue mail aliases
  • should ignore Cc: address list

Proposal

  • create a related table under Assignment Groups for Mail Aliases
  • modify the Create Incident inbound action script to use the new table to match To: address to Assignment Group

Steps

  • create/populate table 'u_group_mail_aliases':
    • u_email (string)
    • u_group (reference to sys_user_group)
  • update the Create Incident inbound action with something like this:
    Code Block
    // bw -- expose headers and text in description (just for PoC)
    // current.description = email.headers + email.body_text;
    
    // bw -- find assigment group by doing a lookup in u_group_mail_aliases
    // loop through email.direct 
    var addresses = email.direct.split(",");
    for (var i=0; i < addresses.length; i++) {
        var alias = new GlideRecord('u_group_mail_aliases');
        alias.addQuery('u_email', '=', addresses[i]);
        alias.query();
        if (alias.getRowCount() > 0) {
            break;
        }
    }
    // if there was an alias match, use it to assign group
    if (alias.getRowCount() > 0) {
    // first match wins!
        alias.next();
        current.assignment_group = alias.u_group;
    }
    

...

Service Now isn't all that fantastic at handling mail, and incidents created from inbound mail are missing many properties that must be fixed before the recipient can handle the created incident. We also have spammable mail aliases, which then create bogus incident tickets we have to clean up. Eventually it would be nice to turn off inbound mail, or restrict it to a limited set of senders.

Debugging

We've had some issues which require us to correlate inbox contents with emails received by ServiceNow. Below is a utility script for diffing the two sets using message ID. Set the usernames, passwords accordingly.

Code Block

#!/usr/bin/env python
# 
# connect to an imap mail account, pull the message ids after a certain date, 
# store in a set
#
# connect to a SNow instance, pull the message ids after a certain date,
# store in another set
#
# perform the symmetric difference on the two sets, and return the count 
# (and perhaps the message ids) from the resulting set
#
import imaplib;
import datetime;
import urllib2;
import base64;
import re;

mailuser = 'servicenow@yale.edu'
mailpass = 'XXXX'
mailhost = 'imap.googlemail.com'
mailsslport = 993

snowuser = 's_unixsys'
snowpass = 'XXXX'
snowhost = 'yale.service-now.com'

def getMailSet():
    global mailuser, mailpass, mailhost, mailsslport
    M = imaplib.IMAP4_SSL(mailhost, mailsslport);
    M.login(mailuser, mailpass)
    M.select()

    set = []
    today = datetime.date.today()
    yesterday = today - datetime.timedelta(days=1)
    today = str(today.strftime("%d-%b-%Y"))
    yesterday = str(yesterday.strftime("%d-%b-%Y"))

    #typ, data = M.search(None, '(SINCE "' + today + '")')
    typ, data = M.search(None, '(SINCE "' + yesterday + '" BEFORE "' + today + '")')
    rcount = 0
    for num in data[0].split():
        typ, data = M.fetch(num, '(BODY[HEADER.FIELDS (MESSAGE-ID)])')
        raw = data[0][1]
        msgid = raw[raw.find("<")+1:raw.find(">")]
        set.append(msgid)
        rcount += 1
        print str(rcount) + ':' + msgid
    M.close()
    M.logout()
    
    set = frozenset(set)
    return set
## end getMailSet()

def getSNowSet():
    global snowuser, snowpass, snowhost
  
    set = []

    today = datetime.date.today()
    yesterday = today - datetime.timedelta(days=1)
    today = str(today.strftime("%Y-%m-%d"))
    yesterday = str(yesterday.strftime("%Y-%m-%d"))

    query = "sys_email_list.do?sysparm_query=sys_created_on%3Ejavascript%3Ags.dateGenerate('" + yesterday + "'%2C'00%3A00%3A00')%5Esys_created_on%3Cjavascript%3Ags.dateGenerate('" + today + "'%2C'00%3A00%3A00')%5Emailbox%3Dreceived%5EORmailbox%3Djunk&XML"

    url = 'https://' + snowhost + '/' + query

    cred = base64.encodestring('%s:%s' % (snowuser, snowpass)).replace('\n', '')
    
    req = urllib2.request = urllib2.Request(url)
    req.add_header('Authorization', "Basic %s" % cred)

    res = urllib2.urlopen(req)
    rcount = 0
    for line in res.readlines():
        if re.match("^(.*)message_id(.*)$", line):
            raw = line
            msgid = raw[raw.find(";")+1:raw.rfind(";")-3]
            set.append(msgid)
            rcount += 1
            print str(rcount) + ':' + msgid

    return frozenset(set)
    
## end getSNowSet()

mailset = getMailSet()
snowset = getSNowSet()

diffset = snowset ^ mailset
print diffset