Exemplo n.º 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")
Exemplo n.º 2
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
Exemplo n.º 3
0
def SymphonyREST(method, endpoint, body):
    retVal = SymphonyAgentResponse()

    # Allowing for reauth from the async process
    if method != 'AUTH' and 'sessionToken' not in agentSession.headers:
        SymphonyReAuth()

    try:
        if method == 'GET':
            response = agentSession.get(endpoint)
        elif method == 'POST':
            response = agentSession.post(endpoint, data=body)
        elif method == 'POSTV2':
            response = PostV2(endpoint, body)
        elif method == 'POSTV2_1':
            response = PostV2_1(endpoint, body)
        elif method == 'AUTH':
            response = agentSession.post(endpoint)
        else:
            raise MethodNotImplementedException(method + ' is not yet implemented.')

        retVal.ResponseText = response.text
        retVal.ResponseCode = response.status_code

        if response.status_code == 200:
            retVal.Success = True
            retVal.ParseResponseJSON()
        elif response.status_code // 100 == 2:  # Any other 200 code, not success but don't throw exception
            retVal.Success = True
        else:
            response.raise_for_status()

    except requests.exceptions.HTTPError as httpex:
        errorStr = "Symphony REST Exception (http): " + str(httpex)
        botlog.LogConsoleInfo("Response Code: " + str(response.status_code))
        botlog.LogConsoleInfo("Response Message: " + response.text)
        retVal.ErrorMessage = errorStr
        stackTrace = 'Stack Trace: ' + ''.join(traceback.format_stack())
        botlog.LogSymphonyError(errorStr)
        botlog.LogSymphonyError(stackTrace)

    except requests.exceptions.RequestException as connex:
        errorStr = "Symphony REST Exception (connection - Status Code " + str(response.status_code) + \
                   "): " + str(connex)
        retVal.ErrorMessage = errorStr
        stackTrace = 'Stack Trace: ' + ''.join(traceback.format_stack())
        botlog.LogSymphonyError(errorStr)
        botlog.LogSymphonyError(stackTrace)

    except Exception as ex:
        errorStr = "Symphony REST Exception (system): " + str(ex)
        retVal.ErrorMessage = errorStr
        stackTrace = 'Stack Trace: ' + ''.join(traceback.format_stack())
        botlog.LogSystemError(errorStr)
        botlog.LogSystemError(stackTrace)

    finally:
        return retVal
def GetCommandDefinitions(definitionPath, pluginName, cType: CommandTypes):

    cmdDefs = []

    try:

        with codecs.open(definitionPath, 'r', 'utf-8-sig') as json_file:
            defJSON = json.load(json_file)

        if cType == CommandTypes.Hash:
            defCol = defJSON['hashcommands']
        else:
            defCol = defJSON['commands']

        for cmdDef in defCol:
            if cType == CommandTypes.Hash:
                cDef = CommandDefinition()
                cDef.ModuleName = pluginName
                cDef.Trigger = cmdDef['triggers']
                cDef.Function = cmdDef['function']

                if pluginName != 'default':
                    cDef.Module = 'modules.plugins.' + pluginName + '.commands'
                else:
                    cDef.Module = 'modules.command.defaultcommands'

                cmdDefs.append(cDef)

            else:
                for trigger in cmdDef['triggers']:
                    cDef = CommandDefinition()
                    cDef.ModuleName = pluginName

                    if pluginName != 'default':
                        cDef.Module = 'modules.plugins.' + pluginName + '.commands'
                    else:
                        cDef.Module = 'modules.command.defaultcommands'

                    cDef.Trigger = trigger
                    cDef.Description = cmdDef['description']
                    cDef.HelpText = cmdDef['helptext']
                    cDef.Function = cmdDef['function']

                    cDef.IsImmediate = cmdDef[
                        'immediate'] if 'immediate' in cmdDef else False

                    cmdDefs.append(cDef)

    except Exception as ex:
        errorStr = "Failed to load plugin: " + pluginName + ' - Error: ' + str(
            ex)
        stackTrace = 'Stack Trace: ' + ''.join(traceback.format_stack())
        botlog.LogSystemError(errorStr)
        botlog.LogSystemError(stackTrace)

    return cmdDefs
def GetGiphyImage(messageDetail):
    try:
        giphyAPIKey = botconfig.GetCommandSetting('giphy')['apikey']

        giphyText = messageDetail.Command.MessageText

        paramList = giphyText.split()

        isRandom = len(paramList) == 0 or paramList[0] == 'random'

        if isRandom:
            ep = "http://api.giphy.com/v1/gifs/random"
            payload = {"apikey": giphyAPIKey}
        else:
            ep = "http://api.giphy.com/v1/gifs/translate"
            payload = {"apikey": giphyAPIKey, "s": giphyText}

        response = requests.get(ep, params=payload).json()

        if isRandom:
            msg = "<a href='" + response['data']['image_original_url'] + "'/>"
        else:
            msg = "<a href='" + response['data']['images']['original'][
                'url'] + "'/>"

        messaging.SendSymphonyMessage(messageDetail.StreamId, msg)

    except Exception as ex:
        errorStr = "Symphony REST Exception (system): {}".format(ex)
        botlog.LogSystemError(errorStr)
        msg = "Sorry, I could not return a GIF right now."
        messaging.SendSymphonyMessage(messageDetail.StreamId, msg)
def GetAlphaVantageStockQuote(messageDetail):

    quoteText = messageDetail.Command.MessageText

    try:
        avAPIKey = botconfig.GetCommandSetting('alphavantage')['apikey']

        quoteSymbol = quoteText.split()[0]

        payload = {
            "function": "TIME_SERIES_DAILY",
            "apikey": avAPIKey,
            "symbol": quoteSymbol
        }
        avEP = 'https://www.alphavantage.co/query'
        response = requests.get(avEP, params=payload).json()

        tsDate = sorted(list(response['Time Series (Daily)'].keys()),
                        reverse=True)[0]
        tsOpen = response['Time Series (Daily)'][tsDate]['1. open']
        tsClose = response['Time Series (Daily)'][tsDate]['4. close']

        msg = 'Quote for: ' + quoteText + '<br/>Date: ' + tsDate + '<br/>Open: ' + tsOpen
        msg += '<br/>Close: ' + tsClose + ''

        messaging.SendSymphonyMessage(messageDetail.StreamId, msg)

    except Exception as ex:
        errorStr = "Symphony REST Exception (system): {}".format(ex)
        botlog.LogSystemError(errorStr)
        msg = "Sorry, I could not return a quote."
        messaging.SendSymphonyMessage(messageDetail.StreamId, msg)
Exemplo n.º 7
0
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
Exemplo n.º 8
0
def SubmitUserFeedbackCollection(messageDetailList):
    from modules.symphony.tokenizer import CommandTypes

    submitCount = 0
    successCount = 0
    if len(messageDetailList) > 0:
        for messageDetail in messageDetailList:
            if messageDetail.IsValid and messageDetail.Sender.IsValidSender:
                if messageDetail.Command.IsCommand and messageDetail.Command.CommandType == CommandTypes.Hash:

                    submitCount += 1
                    response = SubmitSFDCFeedbackRequest(messageDetail)

                    if response.IsSuccess:
                        successCount += 1
                    else:
                        log.LogSystemError('Failed to send SFDC message: ' + messageDetail.MessageRaw)

    if submitCount > 0:
        messageDetailList[0].ReplyToChat('Resubmitted ' + str(submitCount) + ' messages; '
                                         + str(successCount) + ' succeeded.')
    else:
        messageDetailList[0].ReplyToChat('No feedback-messages were found.')
Exemplo n.º 9
0
                pass

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

        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()


while loopCount < 10:
    try:
        Main()
    except SystemExit:
        loopCount = 99
        pass
    except Exception as ex:
        botlog.LogSystemError('Error: ' + str(ex))
        botlog.LogSymphonyError(
            'Unhandled error, probably network difficulties at the Agent. Retrying in 5s.'
        )
        #messaging.SendSymphonyMessage(_configDef['BotStreamForPing'],"There seems to be some network difficulties at the Agent. Please try again in 5s.")

        time.sleep(5)
        loopCount += 1
Exemplo n.º 10
0
def SubmitFeedbackJIRAv2(messageDetail):
    try:
        issueFieldsDict = {}
        watcherList = []
        labelSet = set(messageDetail.Command.Hashtags)

        reporter_field = {
            "name": util.FindJIRAUserByEmailV2(messageDetail.Sender.Email)
        }

        issueFieldsDict['reporter'] = reporter_field

        project = 'SFDC'
        type_name = 'Unknown'
        bodyDetail: str = messageDetail.Command.MessageFlattened

        # Conduct Epic Search
        epic_item = fbmatch.MatchEpic(bodyDetail)

        if epic_item is not None:
            issueFieldsDict['assignee'] = {"name": epic_item['assignTo']}

            if epic_item['epic'] != "":
                issueFieldsDict['customfield_10200'] = epic_item['epic']

            # Union (|=) the epic specific labels with the hashtag labels
            labelSet |= set(epic_item['labels'])

            watcherList = epic_item['mention']
        else:
            log.LogConsoleInfo('No epic match was returned!')

        # convert label set to list for JSON serialization
        issueFieldsDict['labels'] = list(labelSet)

        # Determine what type the feedback is
        type_dict = {
            "bug": "Bug",
            'bugs': 'Bug',
            'defect': 'Bug',
            'defects': 'Bug',
            'problem': 'Bug',
            'problems': 'Bug',
            'feature': 'New Feature',
            'features': 'New Feature',
            'featurerequest': 'New Feature',
            'missing': 'New Feature',
            'needed': 'New Feature',
            'required': 'New Feature',
            'newfeature': 'New Feature',
            'newfeaturerequest': 'New Feature',
            'usability': 'Usability Issue',
            'useability': 'Usability Issue',
            'performance': 'Usability Issue',
            'unstable': 'Usability Issue',
            'awkward': 'Usability Issue'
        }

        for tag in messageDetail.Command.Hashtags:
            if tag.lower() in type_dict:
                type_name = type_dict[tag.lower()]
                break

        # Regex to identify hash tags.
        regexHashtags = r"(\#[a-zA-Z]+\b)"
        summary = re.sub(regexHashtags, '',
                         messageDetail.Command.MessageFlattened)

        # Build dict of UID/Users
        for uid in messageDetail.Command.Mentions:
            try:
                userStr = '_u_' + uid
                userObj = user.GetSymphonyUserDetail(uid)

                if userObj.Id != '-1':
                    bodyReplace = userObj.FullName + '(' + userObj.Email + ')'
                    bodyDetail = bodyDetail.replace(userStr, bodyReplace)

                    # no need to include the mentioned users in the Summary
                    summary = summary.replace(userStr, '')

                    jiraUser = util.FindJIRAUserByEmailV2(userObj.Email)

                    if jiraUser is not None:
                        watcherList.append(jiraUser)

            except Exception as ex:
                log.LogSystemError(str(ex))

        # clean up summary
        # Regex to replace extra spaces with single space
        regexSpace = "\s\s+"
        summary = re.sub(regexSpace, ' ', summary)[:100]

        if messageDetail.Command.CommandRaw is not None:
            summary = summary.replace(messageDetail.Command.CommandRaw, '')
            summary = summary.strip()

        nosubmit = False
        debug = False
        for tag in messageDetail.Command.Hashtags:
            if tag.lower() == 'nosubmit':
                nosubmit = True
            elif tag.lower() == 'debug':
                debug = True

        if not nosubmit:
            new_issue = util.CreateIssueV2(projectKey=project,
                                           summary=summary,
                                           desc=bodyDetail,
                                           issueTypeName=type_name,
                                           jiraFields=issueFieldsDict)

            # add watchers
            util.AddWatchersV2(new_issue, watcherList)

            msg = 'JIRA created successfully.<br/>Key: ' + new_issue.key + "<br/>JIRA Link: <a href='" + \
                  new_issue.permalink() + "'/>"

            messageDetail.ReplyToSenderv2(msg)
        else:
            msg = 'Feedback received but #nosubmit was included. Issue not sent to JIRA.'
            messageDetail.ReplyToSenderv2(msg)

        if debug:
            issueFieldsDict['project'] = project
            issueFieldsDict['summary'] = summary
            issueFieldsDict['description'] = bodyDetail
            issueFieldsDict['issueType'] = type_name

            from modules.symphony.messaging import FormatDicttoMML2 as json_format
            json_str = json_format(issueFieldsDict)

            messageDetail.ReplyToSenderv2(json_str)

    except Exception as ex:
        errStr = 'Unable to submit JIRA. Error: ' + str(ex)
        messageDetail.ReplyToSenderv2(errStr)
        stackTrace = 'Stack Trace: ' + ''.join(traceback.format_exc())
        log.LogSymphonyError(errStr)
        log.LogSymphonyError(stackTrace)