示例#1
0
    def Authenticate(self):

        botlog.LogConsoleInfo('Authenticating...')
        self.SessionToken = callout.GetSessionToken()

        if self.SessionToken != '':
            botlog.LogSymphonyInfo('Success! Session token obtained.')

            self.KeyAuthToken = callout.GetKeyManagerToken()

            if self.KeyAuthToken != '':
                botlog.LogSymphonyInfo('Success! Key Manager token obtained.')

                self.SessionExpirationDate = datetime.date.today() + datetime.timedelta(days=7)
                # self.RESTHeaders = {"sessionToken": self.SessionToken, "keyManagerToken": self.KeyAuthToken,
                #                     "Content-Type": "application/json"}

                self.RESTHeaders = callout.BuildHeaders(self.SessionToken, self.KeyAuthToken)

                # Attempting to use requests.Session
                callout.agentSession.headers.update(self.RESTHeaders)

                botlog.LogSymphonyInfo('Session expires on ' + str(self.SessionExpirationDate))

                self.IsAuthenticated = True
            else:
                botlog.LogSystemError("Failed to obtain KM Token")
        else:
            botlog.LogSystemError("Failed to obtain Session Token")
示例#2
0
def Main():
    global loopCount

    botlog.LogSymphonyInfo('Starting Bot session...')

    botSession = botbuilder.SymSession()

    # Bot Loop Begins here
    loopControl = botSession.StartBot()
    loopCount = 0

    # Pre-load the command definitions
    cmdloader.LoadAllCommands()

    while loopControl:

        messages = datafeed.PollDataFeed(botSession.DataFeedId)

        if messages is not None:

            if len(messages) == 0:
                # botlog.LogConsoleInfo('204 - No Content')
                pass

            for msg in messages:
                if msg.IsValid and msg.Sender.IsValidSender:
                    hub.ProcessCommand(msg)

        else:
            botlog.LogSymphonyInfo(
                'Error detected reading datafeed. Invalidating session...')
            botSession.InvalidateSession()
            loopControl = False

            loopControl = botSession.StartBot()
示例#3
0
def RunSlashCommand(messageDetail):
    # Check to see if it's a default command
    command = None

    if messageDetail.Command.CommandName in cmdloader.DefaultCommands:
        command = cmdloader.DefaultCommands[messageDetail.Command.CommandName]
    elif messageDetail.Command.CommandName in cmdloader.PluginCommands:
        command = cmdloader.PluginCommands[messageDetail.Command.CommandName]

    if command is not None:
        if messageDetail.Command.IsHelp:
            SendHelp(messageDetail, command.HelpText, command.Description)
        else:
            mod = importlib.import_module(command.Module)

            if hasattr(mod, command.Function):
                func = getattr(mod, command.Function)

                # Allow for some commands to be processed immediately
                if command.IsImmediate or not config.UseRedisQueues:
                    func(messageDetail)
                else:
                    queue.AsyncCommand(func, messageDetail)
            else:
                #SendReply(messageDetail, "Apologies - I found a definition for that command, ""but the developer forgot to build the function.")
                botlog.LogSymphonyInfo(
                    "Apologies - I found a definition for that command, "
                    "but the developer forgot to build the function.")
    else:
        #SendReply(messageDetail, "I am sorry but I do not understand that command.")
        botlog.LogSymphonyInfo(
            "I am sorry but I do not understand that command.")
示例#4
0
def SubmitSFDCFeedbackRequest(messageDetail):
    ep = util.sfdcBaseURL + '/services/apexrest/symphony/feedback'

    # etree.findall()
    hashtags = messageDetail.Command.MessageXML.findall('.//hash')

    clients = []
    for ele in hashtags:
        if 'client' in ele.attrib['tag'] and ele.tail:
            clients = [x.strip() for x in ele.tail.split(',')]

    sfdcBody = {
        "messageid": messageDetail.MessageId,
        "streamid": messageDetail.StreamId,
        "submitteremail": messageDetail.Sender.Email,
        "hashtags": messageDetail.Command.Hashtags,
        "mentionedusers": messageDetail.Command.Mentions,
        "summary": messageDetail.Command.MessageFlattened[:50].replace('"', '\''),
        "comments": messageDetail.Command.MessageFlattened.replace(r'\"', '\'').replace('"', '\''),
        "companylist": clients
    }

    if messageDetail.Attachments:
        sfdcBody['attachments'] = messageDetail.Attachments

    log.LogSymphonyInfo(messageDetail.MessageRaw)

    return util.SFDC_REST('POST', ep, sfdcBody)
def GetGoogleTranslation(messageDetail):
    transText = messageDetail.Command.MessageText

    if transText:

        botlog.LogSymphonyInfo('Attempting to translate: ' + transText)

        payload = {
            "client": "gtx",
            "sl": "auto",
            "tl": "en",
            "dt": "t",
            "q": transText
        }
        transEP = "https://translate.googleapis.com/translate_a/single"

        response = requests.get(transEP, params=payload).json()
        translation = response[0][0][0]
        lang = response[2]

        msg = 'I think you said: ' + translation + ' (' + lang + ')'
    else:
        msg = 'Please include a word or sentence to be translated.'

    messaging.SendSymphonyMessage(messageDetail.StreamId, msg)
示例#6
0
def PollDataFeed(datafeedId):
    datafeedEP = config.SymphonyBaseURL + '/agent/v2/datafeed/' + datafeedId + '/read'
    #datafeedEP = config.SymphonyBaseURL + '/agent/v4/datafeed/' + datafeedId + '/read'

    response = callout.SymphonyGET(datafeedEP)

    # Messages coming from the API are formatted as an array of JSON objects
    # Thus, I need to break up the array, parse the individual objects, and pass
    # the list of python objects back to the engine
    messageItems = []
    if response.Success:
        for respItem in response.ResponseData:
            # Hopefully this will
            try:
                if respItem.v2messageType and respItem.v2messageType == 'V2Message':
                    detail = msg.MessageDetail(respItem)
                    detail.Sender = user.GetSymphonyUserDetail(
                        detail.FromUserId)
                    detail.ChatRoom = stream.GetStreamInfo(respItem.streamId)
                    botlog.LogSymphonyInfo(detail.GetConsoleLogLine())

                    if detail.Sender and detail.Sender.IsValidSender:
                        detail.InitiateCommandParsing()

                    messageItems.append(detail)
                elif respItem.v2messageType != 'V2Message':
                    botlog.LogConsoleInfo('Non-chat Message Type: ' +
                                          respItem.v2messageType)
                else:
                    botlog.LogConsoleInfo('Non-chat Message Type: unknown')

            except SystemExit:
                botlog.LogConsoleInfo('Exiting Symphony Zendesk Bot.')
                #messaging.SendSymphonyMessage(_configDef['BotStreamForPing'], "Exiting Symphony Zendesk Bot.")
            except Exception as ex:
                errorStr = "Symphony REST Exception (system): " + str(ex)
                #messaging.SendSymphonyMessage(_configDef['BotStreamForPing'], "Symphony REST Exception (system): " + str(ex))
                # stackTrace = 'Stack Trace: ' + ''.join(traceback.format_stack())
                exInfo = sys.exc_info()
                stackTrace = 'Stack Trace: ' + ''.join(
                    traceback.format_exception(exInfo[0], exInfo[1],
                                               exInfo[2]))
                botlog.LogSystemError(errorStr)
                botlog.LogSystemError(stackTrace)
                botlog.LogConsoleInfo(response.ResponseText)
                #messaging.SendSymphonyMessage(_configDef['BotStreamForPing'], response.ResponseText)

    elif response.ResponseCode == 204:
        return []
    else:
        botlog.LogConsoleInfo("datafeed.py error - Response Code: " +
                              str(response.ResponseCode))
        botlog.LogConsoleInfo("Response Message: " + response.ResponseText)
        #messaging.SendSymphonyMessage(_configDef['BotStreamForPing'], "datafeed.py error - Response Code: " + str(response.ResponseCode) + " Response Message: " + response.ResponseText)

        # if the response is not successful, return None. This way, I can tell the datafeed call was bad
        # and attempt to reconnect to the server.
        return None

    return messageItems
示例#7
0
def SendSymphonyMessage(streamId, message: str):
    if not message.startswith('<messageML>'):
        message = FormatSymphonyMessage(message)

    messageEP = config.GetSendMessageEndpoint(streamId, config.MessageMLVersion.v1)

    bodyJSON = {"message": message, "format": "MESSAGEML"}

    botlog.LogSymphonyInfo('Sending Symphony Message | StreamId: ' + streamId + ' | Message: ' + message)
    return callout.SymphonyPOST(messageEP, json.dumps(bodyJSON))
示例#8
0
    def ConnectDatafeed(self):
        self.BotUserId = user.GetBotUserId()
        botlog.LogSymphonyInfo('Bot User Id: ' + str(self.BotUserId))

        if self.DataFeedId == '':
            botlog.LogSymphonyInfo('Creating Datafeed...')
            self.DataFeedId = datafeed.CreateDataFeed()
        else:
            botlog.LogSymphonyInfo('Attempting to Reuse Existing Datafeed in 5 seconds...')
            for sleepIndex in range(0, 5):
                botlog.LogConsoleInfo(str(sleepIndex) + '...')
                time.sleep(1)

            botlog.LogSymphonyInfo('Reconnecting to Datafeed...')

        if self.DataFeedId != '':
            botlog.LogSymphonyInfo('Datafeed Connected! Id: ' + self.DataFeedId)
            self.IsDatafeedConnected = True
        else:
            botlog.LogSymphonyError('Failed to connect to Datafeed.')
示例#9
0
    def LimitedAuth(self):
        botlog.LogSymphonyInfo('Authenticating...')
        for index in range(0, 5):
            self.Authenticate()

            if self.IsAuthenticated:
                return
            else:
                botlog.LogSymphonyError('Authentication attmept ' + str(index) + 'failed. Trying again in 5 seconds.')
                time.sleep(5)

        botlog.LogSymphonyError('Maximum authentication attempts reached. Halting bot.')
        exit(1)
示例#10
0
    def LimitedDatafeedConnect(self):
        botlog.LogSymphonyInfo('Connecting to the Datafeed...')
        for index in range(0, 5):
            self.ConnectDatafeed()

            if self.IsDatafeedConnected:
                return
            else:
                botlog.LogSymphonyError('Datafeed Connect attmpt ' + str(index) + 'failed. Trying again in 5 seconds.')
                time.sleep(5)

        botlog.LogSymphonyError('Maximum datafeed connection attempts reached. Halting bot.')
        exit(1)
示例#11
0
def SendSymphonyMessage(streamId, message: str):
    if not message.startswith('<messageML>'):
        message = FormatSymphonyMessage(message)

    # messageEP = config.SymphonyBaseURL + '/agent/v2/stream/' + streamId + '/message/create'
    # messageEP = endpointRoom.substitute(host=config.SymphonyBaseURL, roomVersion='v2', streamId=streamId)
    messageEP = config.GetSendMessageEndpoint(streamId,
                                              config.MessageMLVersion.v1)

    bodyJSON = {"message": message, "format": "MESSAGEML"}

    botlog.LogSymphonyInfo('Sending Symphony Message | StreamId: ' + streamId +
                           ' | Message: ' + message)
    return callout.SymphonyPOST(messageEP, json.dumps(bodyJSON))
示例#12
0
def SendSymphonyMessageV2(streamId, message: str, data=None):
    if not message.startswith('<messageML>'):
        message = FormatSymphonyMessage(message)

    # messageEP = endpointRoom.substitute(host=config.SymphonyBaseURL, roomVersion='v4', streamId=streamId)
    messageEP = config.GetSendMessageEndpoint(streamId, config.MessageMLVersion.v2)

    # The data payload has to be converted to a JSON string - the MultipartEncoder won't
    # convert a dict automatically
    if data is not None:
        data = json.dumps(data)

    bodyObj = {"message": message, "data": data}

    botlog.LogSymphonyInfo('Sending Symphony Message Create V4 | StreamId: ' + streamId + ' | Message: ' + message)
    return callout.SymphonyPOSTV2(messageEP, bodyObj)
示例#13
0
def SendSymphonyMessageAttachment(streamId, message: str, attach_data: str):
    chat = GetStreamInfo(streamId)
    if chat.CrossPod == True:
        return

    if not message.startswith('<messageML>'):
        message = FormatSymphonyMessage(message)

    #messageEP = config.SymphonyBaseURL + '/agent/v2/stream/' + streamId + '/message/create'
    messageEP = config.SymphonyBaseURL + '/agent/v4/stream/' + streamId + '/message/create'

    #bodyJSON = {"message": message, "format": "MESSAGEML"}

    botlog.LogSymphonyInfo('Sending Symphony Message | StreamId: ' + streamId + ' | Message: ' + message)
    #return callout.SymphonyPOST(messageEP, json.dumps(bodyJSON))
    return callout.SymphonyPOSTv4(messageEP, message, attach_data)
示例#14
0
def RunHashCommand(messageDetail):
    for command in cmdloader.HashCommands:
        # Set intersection is a clever way to compare the two lists of hashtags
        intersection = set(messageDetail.Command.Hashtags).intersection(
            command.Trigger)

        if len(intersection) > 0:
            mod = importlib.import_module(command.Module)

            if hasattr(mod, command.Function):
                func = getattr(mod, command.Function)
                func(messageDetail)
            else:
                #SendReply(messageDetail, "Sadly, I found triggers for those hashtags, ""but the related function is incomplete or missing.")
                botlog.LogSymphonyInfo(
                    "Sadly, I found triggers for those hashtags, "
                    "but the related function is incomplete or missing.")
            break
def GetSymphonyMessages(endpoint):
    response = callout.SymphonyGET(endpoint)

    # Messages coming from the API are formatted as an array of JSON objects
    # Thus, I need to break up the array, parse the individual objects, and pass
    # the list of python objects back to the engine
    messageItems = []
    if response.Success:
        for respItem in response.ResponseData:
            # Hopefully this will
            try:
                if respItem.v2messageType and respItem.v2messageType == 'V2Message':
                    detail = msg.MessageDetail(respItem)
                    detail.Sender = user.GetSymphonyUserDetail(
                        detail.FromUserId)
                    detail.ChatRoom = stream.GetStreamInfo(respItem.streamId)
                    botlog.LogSymphonyInfo(detail.GetConsoleLogLine())

                    if detail.Sender and detail.Sender.IsValidSender:
                        detail.InitiateCommandParsing()

                    messageItems.append(detail)
                elif respItem.v2messageType != 'V2Message':
                    botlog.LogConsoleInfo('Non-chat Message Type: ' +
                                          respItem.v2messageType)
                else:
                    botlog.LogConsoleInfo('Non-chat Message Type: unknown')

            except SystemExit:
                botlog.LogConsoleInfo('Exiting Ares.')
            except Exception as ex:
                errorStr = "Symphony REST Exception (system): " + str(ex)
                # stackTrace = 'Stack Trace: ' + ''.join(traceback.format_stack())
                exInfo = sys.exc_info()
                stackTrace = 'Stack Trace: ' + ''.join(
                    traceback.format_exception(exInfo[0], exInfo[1],
                                               exInfo[2]))
                botlog.LogSystemError(errorStr)
                botlog.LogSystemError(stackTrace)
                botlog.LogConsoleInfo(response.ResponseText)

    return messageItems
示例#16
0
def Main():
    global loopCount
    once = True

    botlog.LogSymphonyInfo('Starting Symphony Zendesk Bot session...')
    botSession = botbuilder.SymSession()

    # Bot Loop Begins here
    loopControl = botSession.StartBot()
    loopCount = 0

    # Pre-load the command definitions
    cmdloader.LoadAllCommands()

    #messaging.SendSymphonyMessage(_configDef['BotStreamForPing'], "Starting Bot session")

    while loopControl:

        messages = datafeed.PollDataFeed(botSession.DataFeedId)

        #print(datetime.datetime.now())
        #For Tasker
        now = datetime.datetime.now()
        #print("Now: " + str(now))
        week = datetime.datetime.today().weekday()

        if messages is not None:

            if len(messages) == 0:
                # botlog.LogConsoleInfo('204 - No Content')
                # messaging.SendSymphonyMessage(_configDef['BotStreamForPing'], "Just a ping to keep the bot alive")
                pass

            for msg in messages:
                if msg.IsValid and msg.Sender.IsValidSender:
                    hub.ProcessCommand(msg)

            #################################

            now = datetime.datetime.now()
            #print(str(now))
            ## Return the day of the week as an integer, where Monday is 0 and Sunday is 6.
            #week = datetime.datetime.today().weekday()

            #print(week)
            #print("###############################")
            #print(now.strftime("%Y-%m-%d %H:%M:%S"))

            #deff.listAllTasksTask()

            # for deff.task in Tasker:
            #
            #     tasklist = deff.task + " : " + str(Tasker[deff.task])
            #     tasklist_split = str(tasklist).split(":")
            #     #print(tasklist_split)
            #
            #     searchOrgTicketorg = tasklist_split[0]
            #     #print(str(searchOrgTicketorg).strip())
            #     searchOrgTicketstream_id = tasklist_split[1]
            #     #print(str(searchOrgTicketstream_id).strip())
            #     searchOrgTicketweekday = tasklist_split[2]
            #     #print(str(searchOrgTicketweekday).strip())
            #     searchOrgTickethour = tasklist_split[3]
            #     #print(str(searchOrgTickethour).strip())
            #     searchOrgTicketmin = tasklist_split[4]
            #     #print(str(searchOrgTicketmin).strip())

            ## Need to intent if used with tasker to be in side for loop
            if now.hour == int(
                    _configDef['quoteOfTheDay']['hour']) and now.minute == int(
                        _configDef['quoteOfTheDay']['minute']) and once:
                once = False
                deff.QoDTask()
                # messaging.SendSymphonyMessage(_configDef['quoteofthedayStream'], "Hello, test for QOD")

                ## TODO Scheduler to continue next stream when executed once

                # # if week == _configDef['searchOrgTicket']['weekday'] and now.hour == _configDef['searchOrgTicket']['hour'] and now.minute == _configDef['searchOrgTicket']['minute'] and once:
                # #     print("Inside")
                # #     once = False
                # #     comm.searchCompanyTicketsTask((_configDef['searchOrgTicket']['org']),(_configDef['searchOrgTicket']['stream']))
                #
                # if week == int(searchOrgTicketweekday) and now.hour == int(searchOrgTickethour) and now.minute == int(searchOrgTicketmin) and once:
                #     #print("Inside")
                #     #once = False
                #     comm.searchCompanyTicketsTask(str(searchOrgTicketorg),(str(searchOrgTicketstream_id)))

            if now.hour == 23:
                once = True
            #################################

        else:
            botlog.LogSymphonyInfo(
                'Error detected reading datafeed. Invalidating session...')
            #messaging.SendSymphonyMessage(_configDef['BotStreamForPing'], "Error detected reading datafeed. Invalidating session...")
            botSession.InvalidateSession()
            loopControl = False

            loopControl = botSession.StartBot()
def LogSymphonyMessageDebug(messageDetail):
    botlog.LogSymphonyInfo('Message for Debugging: ' +
                           repr(messageDetail.MessageRaw))
    messageDetail.ReplyToChat('Thank you for helping improve my code!')