def respond(intent_request): """ fulfill assign intent """ output_session_attributes = intent_request[ 'sessionAttributes'] if intent_request[ 'sessionAttributes'] is not None else {} current_user = getSlackUserById(intent_request['userId']) runbook_id = get_slots(intent_request)["RunbookId"] assignee = get_slots(intent_request)["SlackUser"] runbook = getRunbookById(runbook_id) runlog_entry = Runlog.create(runbook_id, runbook['name'], assignee, current_user) save(runlog_entry) print('respond save runlog={}'.format(str(runlog_entry))) output_session_attributes['runlog'] = json.dumps(runlog_entry.__dict__) print('respond output_session_attributes={}, slots={}'.format( str(output_session_attributes), str(get_slots(intent_request)))) return close( output_session_attributes, 'Fulfilled', { 'contentType': 'PlainText', 'content': 'Assigned \'' + runbook_id + '\' to ' + assignee })
def respond(intent_request): """ fulfill assign intent """ output_session_attributes = intent_request['sessionAttributes'] if intent_request['sessionAttributes'] is not None else {} runbook_id = get_slots(intent_request)["RunbookId"] current_user = getSlackUserById(intent_request['userId']) print('respond::fulfill intentName={}, slots={}'.format(str(intent_request['currentIntent']['name']), str(get_slots(intent_request)))) runbook=getRunbookById(runbook_id) runlog_entry = Runlog.create(runbook_id, runbook['name'], current_user, current_user) save(runlog_entry) print('respond save runlog={}'.format(str(runlog_entry))) output_session_attributes['runlog']=json.dumps(runlog_entry.__dict__) print('respond elicit_intent session={}, slots={}'.format(str(output_session_attributes), str(get_slots(intent_request)))) buttons = [ {"text":"Execute","value": "execute "+runlog_entry.runlogId} ] response_card = build_response_card('Execute '+runbook_id, runbook['name'], buttons) print('response elicit_intent_with_response_card = {}'.format(str(response_card))) return elicit_intent_with_response_card(output_session_attributes, 'Added \''+runbook_id+'\' to your TODOs, click Execute to run through now.', response_card)
def respond(intent_request): """ Performs dialog management for delegating runlog to a user """ intent = intent_request['currentIntent']['name'] current_user = getSlackUserById(intent_request['userId']) source = intent_request['invocationSource'] userInput = intent_request['inputTranscript'] if 'inputTranscript' in intent_request else None output_session_attributes = intent_request['sessionAttributes'] if intent_request['sessionAttributes'] is not None else {} #get runlog_id from user input or session runlog = None if userInput is not None and re.search('RL[0-9]+', userInput) is not None: #check if user has specified runbook id in utterance runlog_id=re.search('RL[0-9]+', userInput).group(0) intent_request['currentIntent']['slots']["RunlogId"]=runlog_id elif 'runlog' in output_session_attributes: # get runlog from session if present runlog=json.loads(output_session_attributes['runlog']) runlog_id=runlog['runlogId'] intent_request['currentIntent']['slots']["RunlogId"]=runlog['runlogId'] #get slack user from user input or from slot (unlikely this will work) if re.search('@\w+', userInput) is not None: #check if user has specified @user in utterance intent_request['currentIntent']['slots']["SlackUser"]=re.search('@\w+', userInput).group(0) runbook_id=intent_request['currentIntent']['slots']['RunbookId'] if 'RunbookId' in intent_request['currentIntent']['slots'] else None assignee=intent_request['currentIntent']['slots']["SlackUser"] if 'SlackUser' in intent_request['currentIntent']['slots'] else None print('respond intentName={}, slots={}'.format(str(intent_request['currentIntent']['name']), str(get_slots(intent_request)))) if source == 'DialogCodeHook': slots = get_slots(intent_request) validation_result = validate(runlog_id, assignee) print('respond validation result={}, invalid slot={}'.format(str(validation_result['isValid']),str(validation_result['violatedSlot']))) if not validation_result['isValid']: slots[validation_result['violatedSlot']] = None if validation_result['violatedSlot']=='RunlogId': print('respond elicit-slot session={}, invalid slot={}'.format(str(output_session_attributes),str(validation_result['violatedSlot']))) return elicit_slot_with_text_message(output_session_attributes, intent, slots, validation_result['violatedSlot'], 'Invalid Runbook, please provide a valid Runbook ID') else: print('respond elicit-slot session={}, invalid slot={}'.format(str(output_session_attributes),str(validation_result['violatedSlot']))) return elicit_slot_with_text_message(output_session_attributes, intent, slots, validation_result['violatedSlot'], 'Invalid slack user, mention slack users with \'@\' prefix') else: runbook_id=getRunbookIdForRunlog(runlog_id, current_user) runbook=getRunbookById(runbook_id) runlog_entry = Runlog.assign(runbook_id, runbook['name'], current_user, assignee) save(runlog_entry) print('respond save runlog={}'.format(str(runlog_entry))) output_session_attributes['runlog']=json.dumps(runlog_entry.__dict__) print('respond intentName={}, slots={}, output_session_attributes={}'.format(str(intent_request['currentIntent']['name']), str(slots), str(output_session_attributes))) return delegate(output_session_attributes, get_slots(intent_request))
def getNextStepAndTask(self): current_task = self.getLastTaskLogEntry() print('ExecutionContext::getNextStepAndTask log_entry={}'.format( str(current_task))) if current_task is None: # first task print('ExecutionContext::getNextStepAndTask first task, step={}'. format(str(self.runbook['steps'][0]))) return (0, 0, self.runbook['steps'][0]) current_task_index = -1 current_step_index = -1 for step_index in range(0, len(self.runbook['steps']) - 1): step = self.runbook['steps'][step_index] for task_index in range(0, len(step['tasks']) - 1): if current_task['name'] == step['tasks'][task_index]: current_task_index = task_index current_step_index = step_index print( 'ExecutionContext::getNextStepAndTask current step={}, step_index={}, current task={}, task_index={}' .format( str(self.runbook['steps'][current_step_index]), current_step_index, str(self.runbook['steps'][current_step_index] ['tasks'][current_task_index]), current_task_index)) break if current_task['status'] == 'START': if current_task_index < len(self.runbook['steps'][ current_step_index]) - 1: # next task in step print( 'ExecutionContext::getNextStepAndTask CURRENT_FINISH step={}, step_index={}, current task={}, task_index={}' .format( str(self.runbook['steps'][current_step_index]), current_step_index, str(self.runbook['steps'][current_step_index]['tasks'] [current_task_index]), current_task_index)) save( Runlog.finish(self.runlogId, current_task['id'], current_task['name'], current_task['level'], self.user, current_task['originator'], current_task['message'])) print( 'ExecutionContext::getNextStepAndTask NEXT_TASK step={}, step_index={}, current task={}, task_index={}' .format( str(self.runbook['steps'][current_step_index]), current_step_index, str(self.runbook['steps'][current_step_index]['tasks'][ current_task_index + 1]), current_task_index + 1)) return (current_step_index, current_task_index + 1, self.runbook['steps'][current_step_index]) elif current_step_index + 1 <= len( self.runbook['steps']) - 1: # next step in runbook print( 'ExecutionContext::getNextStepAndTask CURRENT_FINISH step={}, step_index={}, current task={}, task_index={}' .format( str(self.runbook['steps'][current_step_index]), current_step_index, str(self.runbook['steps'] [current_step_index].tasks[current_task_index]), current_task_index)) save( Runlog.finish(self.runlogId, current_task['id'], current_task['name'], current_task['level'], self.user, current_task['originator'], current_task['message'])) print( 'ExecutionContext::getNextStepAndTask NEXT_STEP step={}, step_index={}, current task={}, task_index={}' .format( str(self.runbook['steps'][current_step_index + 1]), current_step_index + 1, str(self.runbook['steps'][current_step_index]['tasks'] [0]), 0)) return (current_step_index + 1, 0, self.runbook['steps'][current_step_index + 1]) else: # last task in runbook print( 'ExecutionContext::getNextStepAndTask CURRENT_FINISH step={}, step_index={}, current task={}, task_index={}' .format( str(self.runbook['steps'][current_step_index]), current_step_index, str(self.runbook['steps'][current_step_index]['tasks'] [current_task_index]), current_task_index)) save( Runlog.finish(self.runlogId, current_task['id'], current_task['name'], current_task['level'], self.user, current_task['originator'], current_task['message'])) print('ExecutionContext::getNextStepAndTask LAST_STEP_TASK') return (-1, -1, None) else: # continue where you left off print( 'ExecutionContext::getNextStepAndTask CONTINUE_FROM_LAST step={}, step_index={}, current task={}, task_index={}' .format( str(self.runbook['steps'][current_step_index]), current_step_index, str(self.runbook['steps'][current_step_index]['tasks'] [current_task_index]), current_task_index)) return (current_step_index, current_task_index, self.runbook['steps'][current_step_index])
def respond(intent_request): """ Performs dialog management for executing runlog """ current_user = getSlackUserById(intent_request['userId']) source = intent_request['invocationSource'] userInput = intent_request['inputTranscript'] intent = intent_request['currentIntent']['name'] output_session_attributes = intent_request[ 'sessionAttributes'] if intent_request[ 'sessionAttributes'] is not None else {} #get runlog_id from user input or session or from slot runlog_id = get_slots( intent_request)["RunlogId"] if 'RunlogId' in get_slots( intent_request) else None if runlog_id is None: if re.search('RL[0-9]+', userInput) is not None: #check if user has specified runlog id in utterance runlog_id = re.search('RL[0-9]+', userInput).group(0) intent_request['currentIntent']['slots']["RunlogId"] = runlog_id elif 'runlog' in output_session_attributes: # get runlog from session if present runlog = json.loads(output_session_attributes['runlog']) runlog_id = runlog['runlogId'] intent_request['currentIntent']['slots']["RunlogId"] = runlog_id isDone = re.match('(?i)DONE', userInput) intent_request['currentIntent']['slots']['IsDone'] = isDone if source == 'DialogCodeHook': print('respond intentName={}, slots={}'.format( str(intent_request['currentIntent']['name']), str(get_slots(intent_request)))) slots = get_slots(intent_request) if not runlog_id: print('respond elicit-slot session={}, invalid slot={}'.format( str(output_session_attributes), 'RunlogId')) return elicit_slot_with_text_message( output_session_attributes, intent, slots, 'RunlogId', 'Invalid RunlogID, please provide a valid RunlogID') exec_context = ExecutionContext(runlog_id, current_user) runbook = exec_context.getRunbook() step_index, task_index, step = exec_context.getNextStepAndTask() if step is not None: #build response card to display step and task information buttons = [{ "text": "Done", "value": "execute " + runlog_id }, { "text": "Raise Issue", "value": "raise error " + runlog_id }] response_card = build_response_card( runbook['name'] + ': Step ' + str( (step_index + 1)) + ' of ' + str(len(runbook['steps'])), ' Task ' + str(task_index + 1), buttons) print('response elicit_intent_with_response_card = {}'.format( str(response_card))) runlog_entry = Runlog.start( runlog_id, runbook['steps'][step_index]['id'], runbook['steps'][step_index]['tasks'][task_index], 'TASK', current_user, current_user) save(runlog_entry) print('respond save runlog={}'.format(str(runlog_entry))) output_session_attributes['runlog'] = json.dumps( runlog_entry.__dict__) print('respond output_session_attributes={}'.format( str(output_session_attributes))) task_text = runbook['steps'][step_index]['tasks'][task_index] return elicit_intent_with_response_card(output_session_attributes, task_text, response_card) return close(output_session_attributes, 'Fulfilled', { 'contentType': 'PlainText', 'content': 'You have completed this task.' })
def respond(intent_request): """ Performs dialog management for listing runlogs querying for resolution """ intent = intent_request['currentIntent']['name'] current_user = getSlackUserById(intent_request['userId']) userInput = intent_request['inputTranscript'] source = intent_request['invocationSource'] output_session_attributes = intent_request[ 'sessionAttributes'] if intent_request[ 'sessionAttributes'] is not None else {} runlog_id = get_slots( intent_request)['RunlogId'] if 'RunlogId' in get_slots( intent_request) else None if runlog_id is None: if re.search('RL[0-9]+', userInput) is not None: #check if user has specified runlog id in utterance runlog_id = re.search('RL[0-9]+', userInput).group(0) intent_request['currentIntent']['slots']["RunlogId"] = runlog_id elif 'runlog' in output_session_attributes: # get runlog from session if present runlog = json.loads(output_session_attributes['runlog']) runlog_id = runlog['runlogId'] intent_request['currentIntent']['slots']["RunlogId"] = runlog_id resolve_issue = get_slots( intent_request)['ResolveIssue'] if 'ResolveIssue' in get_slots( intent_request) else None add_resolution = get_slots( intent_request)['AddResolution'] if 'AddResolution' in get_slots( intent_request) else None if source == 'DialogCodeHook': log = getLastRunlogEntryById( runlog_id) #search for last runlog entry with issue description if not resolve_issue: buttons = [{"text": "Mark Resolved", "value": "resolve-issue"}] response_card = build_response_card( log['runlogId'] + "-" + log['resolution']['summary'], log['resolution']['description'], buttons) return elicit_slot_with_response_card( output_session_attributes, intent, get_slots(intent_request), 'ResolveIssue', Issue(log['resolution']['issueType'], log['resolution']['severity'], log['resolution']['environment'], log['resolution']['summary'], log['resolution']['description'], add_resolution).__dict__, response_card) if resolve_issue == "resolve-issue": last_task_entry = getLastRunlogEntry(runlog_id, 'TASK', current_user) runlog_entry = Runlog.resolve( runlog_id, last_task_entry.id, last_task_entry.name, 'TASK', current_user, last_task_entry.originator, 'Resolution found for issue :\n' + log['resolution']['summary'], None, json.dumps( Issue(log['resolution']['issueType'], log['resolution']['severity'], log['resolution']['environment'], log['resolution']['summary'], log['resolution']['description'], add_resolution).__dict__), last_task_entry.resolutionCount) save(runlog_entry) print('respond save runlog={}'.format(str(runlog_entry))) output_session_attributes['runlog'] = json.dumps( runlog_entry.__dict__) return close( output_session_attributes, 'Fulfilled', { 'contentType': 'PlainText', 'content': '''Resolution has been added''' })
def respond(intent_request): """ Raises issue encountered while executing the runbook """ intent = intent_request['currentIntent']['name'] current_user = getSlackUserById(intent_request['userId']) userInput = intent_request['inputTranscript'] source = intent_request['invocationSource'] output_session_attributes = intent_request['sessionAttributes'] if intent_request['sessionAttributes'] is not None else {} #get runlog_id from user input or session or from slot runlog_id = get_slots(intent_request)["RunlogId"] if 'RunlogId' in get_slots(intent_request) else None if runlog_id is None: if re.search('RL[0-9]+', userInput) is not None: #check if user has specified runlog id in utterance runlog_id=re.search('RL[0-9]+', userInput).group(0) intent_request['currentIntent']['slots']["RunlogId"]=runlog_id elif 'runlog' in output_session_attributes: # get runlog from session if present runlog=json.loads(output_session_attributes['runlog']) runlog_id=runlog['runlogId'] intent_request['currentIntent']['slots']["RunlogId"]=runlog_id issue_type = get_slots(intent_request)["IssueType"] if 'IssueType' in get_slots(intent_request) else None severity = get_slots(intent_request)["Severity"] if 'Severity' in get_slots(intent_request) else None environment = get_slots(intent_request)["Environment"] if 'Environment' in get_slots(intent_request) else None summary = get_slots(intent_request)["Summary"] if 'Summary' in get_slots(intent_request) else None description = get_slots(intent_request)["Description"] if 'Description' in get_slots(intent_request) else None resolution_id =get_slots(intent_request)["ResolutionId"] if 'ResolutionId' in get_slots(intent_request) else None confirm_resolution = get_slots(intent_request)["ConfirmResolution"] if 'ConfirmResolution' in get_slots(intent_request) else None confirm_assign = get_slots(intent_request)["ConfirmAssign"] if 'ConfirmAssign' in get_slots(intent_request) else None assignee = get_slots(intent_request)["SlackUser"] if 'SlackUser' in get_slots(intent_request) else None if assignee is None and re.search('@\w+', userInput) is not None: #check if user has specified @user in utterance assignee=re.search('@\w+', userInput).group(0) intent_request['currentIntent']['slots']["SlackUser"]=assignee if source == 'DialogCodeHook': slots = get_slots(intent_request) if issue_type and severity and environment and summary and description: last_task_entry = getLastRunlogEntry(runlog_id, 'TASK', current_user) runlog_entry = Runlog.raise_error(runlog_id, last_task_entry['id'], last_task_entry['name'], 'TASK', current_user, last_task_entry['originator'], summary, None, json.dumps(Issue(issue_type, severity, environment, summary, description).__dict__)) save(runlog_entry) print('respond save runlog={}'.format(str(runlog_entry))) output_session_attributes['runlog']=json.dumps(runlog_entry.__dict__) resolution_list = getResolution(runlog_id) if not resolution_id: attachments=[] for resolution in resolution_list: buttons = [ {"text":"Select "+resolution['id'], "value":resolution['id']} ] response_card = { 'title': (resolution['source']), 'subTitle' :resolution['resolution'][:75]+"...", 'options': buttons } attachments.insert(0, response_card) response_cards=build_multiple_response_cards(attachments) return elicit_slot_with_response_card(output_session_attributes, intent, slots, 'ResolutionId', 'Please select from below list', response_cards) resolution = [item for item in resolution_list if resolution_id == item['id']][0] #TODO if not confirm_resolution: buttons = [{"text":"yes","value":"yes"},{"text":"no","value":"no"}] response_card = build_response_card('Details','Resolution available',buttons) return elicit_slot_with_response_card(output_session_attributes, intent, slots, 'ConfirmResolution', resolution['resolution']+'\n Did this resolve the issue?',response_card) if confirm_resolution=="yes" and resolution['source'] == "stackoverflow": runlog_entry = Runlog.resolve(runlog_id, last_task_entry.id, last_task_entry.name, 'TASK', current_user, last_task_entry.originator, 'Resolution found for issue :\n'+summary, None,json.dumps(Issue(issue_type, severity, environment, summary, description)),last_task_entry.resolutionCount) save(runlog_entry) print('respond save runlog={}'.format(str(runlog_entry))) output_session_attributes['runlog']=json.dumps(runlog_entry.__dict__) if confirm_resolution=="yes" and resolution['source'] == "runlog": runlog_entry = Runlog.resolve(runlog_id, last_task_entry.id, last_task_entry.name, 'TASK', current_user, last_task_entry.originator, summary, None,json.dumps(Issue(issue_type, severity, environment, summary, description)),last_task_entry.resolutionCount+1) save(runlog_entry) print('respond save runlog={}'.format(str(runlog_entry))) output_session_attributes['runlog']=json.dumps(runlog_entry.__dict__) if confirm_resolution=="no" and not confirm_assign: buttons = [{"text":"yes","value":"yes"},{"text":"no","value":"no"}] response_card = build_response_card('Delegate issue to user','Choose one',buttons) return elicit_slot_with_response_card(output_session_attributes, intent, slots, 'ConfirmAssign', 'Do you want to delegate this issue to someone?',response_card) if assignee is not None and confirm_assign=="yes": runlog_entry = Runlog.assign( runlog_id, last_task_entry.id, last_task_entry.name, last_task_entry.originator, assignee) save(runlog_entry) print('respond save runlog={}'.format(str(runlog_entry))) output_session_attributes['runlog']=json.dumps(runlog_entry.__dict__) # TODO add functionality when user doesn't want to assign issue if confirm_assign =="no": return delegate(output_session_attributes, get_slots(intent_request)) print('respond close session={}'.format(str(output_session_attributes))) return close(output_session_attributes, 'Fulfilled', {'contentType': 'PlainText', 'content': 'Noted your issue'})