Beispiel #1
0
def sendWebhookMessage(message):
    message = message.encode('utf-8').replace(b'\n',
                                              b'\\n').decode('utf-8').replace(
                                                  '"', '\\"')
    webhookurl = os.environ['WEBHOOKURL']
    message = '{"text":"' + message + ' "}'
    response = io.BytesIO()
    c = pycurl.Curl()
    c.setopt(c.URL, webhookurl)
    c.setopt(c.WRITEFUNCTION, response.write)
    c.setopt(c.HTTPHEADER, ["Content-Type: application/json"])
    c.setopt(c.POSTFIELDS, message.encode('utf-8'))

    try:
        c.perform()
    except pycurl.error:
        common.conMsg('dialog', 'Pycurl error')
        return "Pycurl error. 404?"

    c.close()

    try:
        json.loads(response.getvalue())
    except json.decoder.JSONDecodeError:
        return "JSON not found in response from resource. Unauthorized?"

    response.close()

    return common.now() + " : Message sent successfully"
def removeFromQueue(queue_id):
    i = 0
    while i < len(queue):
        if queue_id == queue[i][0]:
            queue.pop(i)
        i += 1
    common.conMsg('bot','Removed from queue with queue_id=' + str(queue_id))
def testvarsAttempt():
    try:
        import testvars
    except ImportError:
        common.conMsg('bot','Predefined test variables not found, continue with environment variables')
        return None
    else:
        common.conMsg('bot','Predefined test variables found, environment variables ignored')
        return None
def generateButtons(queue_id):
    requestTypes = os.environ['ISSUE_TYPE_CONFIG'].split(',')
    buttons = []
    i = 0
    while i < len(requestTypes):
        requestTypeName = jira.getIssueTypeNameByIssueTypeId(credentials,requestTypes[i])
        buttons = buttons + [interactive_media.InteractiveMedia(1,interactive_media.InteractiveMediaButton("type," + requestTypes[i] + ","+queue_id, requestTypeName))]
        i += 1
    buttons = buttons + [interactive_media.InteractiveMedia(1,interactive_media.InteractiveMediaButton("delete,request,"+queue_id, translate(lang,'cancelTicketButton')))]
    common.conMsg('bot','Generated buttons ' + str(buttons))
    return buttons
def heartbeat():
    threadsList = []
    for thread in threading._enumerate():
        threadsList.append(thread.name)

    workingThreads = fnmatch.filter(threadsList, 'Thread-*')

    if len(workingThreads) >= 1:
        return True
    else:
        common.conMsg('bot', 'Bot dropped, trying to reinit')
        return False
def task_manager():
    if heartbeat() == False:
        time.sleep(2)
        initializeBot()
    if mode == '1' and len(queue) > 0:
        print (queue)
        common.conMsg('bot_debug','Mode 1 Tick Autosend')
        sendTicketAuto()
    if mode == '2' and len(queue) > 0:
        common.conMsg('bot_debug','Mode 2 Tick Request Timeout')
        checkRequestByTimeout()
#    common.conMsg('bot_debug','Task Manager Tick')
    time.sleep(1)
def on_click(*params):
    buttonValue = str(params[0].value).split(',')
    message = returnFromQueueByQueueId(buttonValue[2])
    if message != None:
        common.conMsg('bot','Clicked button ' + str(buttonValue))
        if buttonValue[0] == 'delete':
            replyToReporter(queue_id=buttonValue[2],keep=False,ticketText=message)
            removeFromQueue(buttonValue[2])
            removeFromBanList(params[0].uid)
        else:
            sendTicketManually(buttonValue[2],buttonValue[1])
    else:
        message = bot.messaging.get_messages_by_id([params[0].mid])[0]
        bot.messaging.update_message(message, translate(lang,'requestError'))
def checkIfUserExists(credentials, username):
    rawjson = getRawData(
        credentials,
        '/rest/api/2/user?username='******'&expand=applicationRoles')
    if 'applicationRoles' in rawjson:
        i = 0
        while i < len(rawjson['applicationRoles']['items']):
            if rawjson['applicationRoles']['items'][i][
                    'key'] == 'jira-software':
                return True
            i += 1
        common.conMsg('jira', 'User >' + username + '< not found')
        return False
    else:
        common.conMsg('jira', 'User >' + username + '< not found')
        return False
def checkRequestByTimeout():
    nowTime = int(calendar.timegm(time.gmtime()))

    i = 0
    while i < len(queue):
        if int(queue[i][1]) < int(nowTime-int(os.environ['REQUEST_TIMEOUT'])):
            mids = findMidsWithQueueId(str(queue[i][0]))
            message = bot.messaging.get_messages_by_id(mids)[0]
            bot.messaging.update_message(message, translate(lang,'cancelledByTimeout'))
            common.conMsg('bot','Ticket cancelled by timeout queue_id=' + str(queue[i][0]))
            removeFromBanList(queue[i][2])
            removeFromRequestMessageList(str(queue[i][0]))
            removeFromQueue(str(queue[i][0]))
            return None
        i += 1
    else:
        return None
def getRawData(credentials, url):
    if checkAuth(credentials, 'TECHSUP') == True:
        response = io.BytesIO()
        c = pycurl.Curl()
        c.setopt(c.URL, credentials[2] + url)
        c.setopt(c.WRITEFUNCTION, response.write)
        c.setopt(c.HTTPHEADER, ["Content-Type: application/json"])
        c.setopt(pycurl.COOKIEFILE, 'jira.cookie')
        c.setopt(pycurl.TIMEOUT, 10)

        c.perform()
        c.close()
        rawjson = json.loads(response.getvalue())
        response.close()
        return rawjson
    else:
        common.conMsg('jira', "Authorization failed!")
def on_msg(*params):
    if params[0].sender_uid != None and params[0].peer.type != 2:

        #request array creating
        request = [None]*4
        request[0] = getNewQueueId()
        request[1] = params[0].date // 1000
        request[2] = params[0].sender_uid
        request[3] = str(params[0].message.textMessage.text)

        #getting peer for further actions
        if checkRequest(request) == '0':
            banList.append(request)
            if mode == '1' or mode == '2':
                optional = [None]*2
                optional[0] = link
                optional[1] = projectId
                common.conMsg('bot','Message accepted from uid ' + str(params[0].peer.id))
                addToQueue(request)
                sendConfirmationMessage(optional,request)
            if mode == '0':
                common.conMsg('bot','Message accepted from uid ' + str(params[0].peer.id))
                addToQueue(request)
                requestTypeId = os.environ['ISSUE_TYPE_CONFIG'].split(',')[0]
                sendTicketManually(request[0],requestTypeId)
        elif checkRequest(request) == '100':
            returnError('100',request[2])
        elif checkRequest(request) == '101':
            returnError('101',request[2])
        elif checkRequest(request) == '200':
            returnError('200',request[2])
        elif checkRequest(request) == '300':
            returnError('300',request[2])
    else:
        common.conMsg('bot','Ignoring message from group with id ' + str(params[0].peer.id))
def checkAuth(credentials, projectName):
    jiraurl = credentials[2]
    url = jiraurl + "/rest/api/2/mypermissions?projectKey=" + projectName
    #print (url)
    response = io.BytesIO()
    c = pycurl.Curl()
    c.setopt(c.URL, url)
    c.setopt(c.WRITEFUNCTION, response.write)
    c.setopt(c.HTTPHEADER, ["Content-Type: application/json"])
    c.setopt(pycurl.COOKIEFILE, 'jira.cookie')
    c.setopt(pycurl.TIMEOUT, 10)

    try:
        c.perform()
    except pycurl.error:
        return False
    c.close()
    #print ('ALALA'+str(response.getvalue()))
    try:
        rawjson = json.loads(response.getvalue())
    except json.decoder.JSONDecodeError:
        common.conMsg(
            'jira',
            'Lost auth cookie, trying to auth again (failed to parse JSON)')
        response.close()
        return basicAuth(credentials, projectName)
    response.close()
    if 'permissions' in rawjson:
        if rawjson['permissions']['BROWSE_PROJECTS']['havePermission'] == True:
            return True
        else:
            common.conMsg(
                'jira',
                'Lost auth cookie, trying to auth again (Cant obtain permissions)'
            )
            return basicAuth(credentials, projectName)
    else:
        return False
def sendConfirmationMessage(optional,request):
    try:
        postRequest = translate(lang,'ticketConfirmation') + request[3] + '\n***\n' + translate(lang,'creatingTicket',optional)

        buttons = generateButtons(request[0])

        messageId = bot.messaging.send_message(bot.users.get_user_peer_by_id(request[2]),postRequest,
            [interactive_media.InteractiveMediaGroup(buttons)]).message_id

        requestMessage = []
        requestMessage.append(request[0])
        requestMessage.append(messageId)
        requestMessageList.append(requestMessage)
        
        return True
    except (TypeError,json.decoder.JSONDecodeError):
        common.conMsg('bot','Failed to send ticket cause failed to authorize or connect to Jira')
        peer = bot.users.get_user_peer_by_id(request[2])
        bot.messaging.send_message(peer,translate(lang,'jiraAuthError',optional))
        removeFromQueue(str(request[0]))
        removeFromRequestMessageList(str(request[0]))
        removeFromBanList(request[2])
        return False
def returnError(code,userId):
    peer = bot.users.get_user_peer_by_id(userId)
    if code == '100':
        bot.messaging.send_message(peer,translate(lang,'imTooSeriousForYourMedia'))
        common.conMsg('bot','Attempting to send request from id ' + str(userId) + ' with media')
        return None
    if code == '101':
        bot.messaging.send_message(peer,translate(lang,'invalidInput'))
        common.conMsg('bot','Attempting to send invalid command from id ' + str(userId))
        return None
    if code == '200':
        bot.messaging.send_message(peer,translate(lang,'greetings'))
        common.conMsg('bot','New user with id ' + str(userId) + ' started session')
        return None
    if code == '300':
        bot.messaging.send_message(peer,translate(lang,'tooManyRequests'))
        common.conMsg('bot','Attempting to send request from id ' + str(userId) + ' with non-expired delay')
        return None
def replyToReporter(response='',queue_id='',uid='',keep=True,ticketText=''):
    if keep == True:
        if mode == '1' or mode == '2':
            mids = findMidsWithQueueId(str(queue_id))
            message = bot.messaging.get_messages_by_id(mids)[0]
            bot.messaging.update_message(message, translate(lang,'ticketConfirmation') + ticketText + '\n***\n' + translate(lang,'ticketSent') + ' [' + response[1] + '](' + response[0] + ')')
            common.conMsg('bot','Replied to reporter with editing queue_id=' + str(queue_id) + ' response=' + str(response))
        elif mode == '0':
            bot.messaging.send_message(bot.users.get_user_peer_by_id(int(uid)),translate(lang,'ticketConfirmation') + ticketText + '\n***\n' + translate(lang,'ticketSent') + ' [' + response[1] + '](' + response[0] + ')')
            common.conMsg('bot','Replied to reporter with messaging uid=' + str(uid) + ' response=' + str(response))
    else:
        mids = findMidsWithQueueId(str(queue_id))
        message = bot.messaging.get_messages_by_id(mids)[0]
        bot.messaging.update_message(message, translate(lang,'ticketConfirmation') + ticketText + '\n***\n' + translate(lang,'cancelRequest'))
        common.conMsg('bot','Cancelling Replied to reporter with editing queue_id=' + str(queue_id))
        removeFromRequestMessageList(queue_id)
def sendTicketManually(queue_id,requestTypeId):
    try:
        i = 0
        while i < len(queue):
            if queue_id == queue[i][0]:
                queueMember = queue[i]
                reporter = bot.users.get_user_by_id(int(queueMember[2])).data.nick.value
                requestMessage = queueMember[3]
                if jira.checkIfUserExists(credentials,reporter) == True:
                    response = jira.parseResponseCreatingTicket(jira.createTicket(credentials,projectId,requestTypeId,reporter,requestMessage))
                    jira.deleteUserFromWatchers(credentials,response[1])
                    replyToReporter(response=response,queue_id=queueMember[0],uid=queueMember[2],ticketText=requestMessage)
                    common.conMsg('bot','Ticket sent request manually TypeId=' + str(requestTypeId) + ' reporter=' + str(reporter))
                    removeFromRequestMessageList(queue_id)
                    removeFromQueue(str(queueMember[0]))
                    return response
                else:
                    optional = [None]*2
                    optional[0] = link
                    optional[1] = projectId
                    common.conMsg('bot','Cannot send message because missing user in Jira')
                    message = bot.messaging.get_messages_by_id(findMidsWithQueueId(queue_id))[0]
                    bot.messaging.update_message(message, translate(lang,'ticketConfirmation') + requestMessage + '\n***\n' + translate(lang,'jiraUserNotExists',optional))
                    removeFromBanList(findUidWithQueueId(queue_id))
                    removeFromRequestMessageList(queue_id)
                    removeFromQueue(queue_id)
                    return None
            i += 1
        else:
            return None
    except (TypeError,json.decoder.JSONDecodeError):
        optional = [None]*2
        optional[0] = link
        optional[1] = projectId
        common.conMsg('bot','Failed to send ticket cause failed to authorize or connect to Jira')
        message = bot.messaging.get_messages_by_id(findMidsWithQueueId(queue_id))[0]
        bot.messaging.update_message(message, translate(lang,'jiraAuthError',optional))
        removeFromBanList(findUidWithQueueId(queue_id))
        removeFromRequestMessageList(queue_id)
        removeFromQueue(queue_id)
        return None
def initializeBot():
    common.conMsg('bot','Bot initialized ')
    bot.messaging.on_message_async(on_msg,on_click)

def testvarsAttempt():
    try:
        import testvars
    except ImportError:
        common.conMsg('bot','Predefined test variables not found, continue with environment variables')
        return None
    else:
        common.conMsg('bot','Predefined test variables found, environment variables ignored')
        return None

if __name__ == '__main__':
    common.conMsg('bot','Starting bot')
    testvarsAttempt()
    lang = os.environ['LANGUAGE']
    mode = os.environ['ISSUE_TYPE_MODE']
    bot = DialogBot.get_secure_bot(os.environ['ENDPOINT'],grpc.ssl_channel_credentials(),os.environ['BOT_API_KEY'], verbose=False)

    if checkEnvs():
        credentials = common.parseCreds(os.environ['JIRA_CREDS'])
        link = credentials[2]
        projectId = jira.getProjectIdByProjectKey(credentials,os.environ['PROJECT_KEY'])
        if projectId:
            initializeBot()
            #dbInit()
            common.conMsg('bot','Started bot. Mode: ' + mode)
            while True:
                task_manager()
def addToQueue(request):
    queue.append(request)
    common.conMsg('bot','Added to queue with queue_id=' + str(request[0]) + ' uid=' + str(request[2]))
    return None
def initializeBot():
    common.conMsg('bot','Bot initialized ')
    bot.messaging.on_message_async(on_msg,on_click)