def updatePastResponse(id, feedback, conn): cur = conn.cursor() feedback = feedback.lower() now = datetime.now() now.strftime('%m/%d/%Y') if (feedback == 'y' or feedback == 'yes'): print id sql = "update sentresponses set CurrentScore = CurrentScore + 1, Timestamp = '%s' where ID = '%d'" % (now, id) cur.execute(sql) log.writetofile("CurrentScore incremented in db") conn.commit() isPositive = 1 isNegative = 0 elif (feedback == 'n' or feedback == 'no'): sql = "update sentresponses set CurrentScore = CurrentScore - 1, Timestamp = '%s' where ID = '%d'" % (now, id) cur.execute(sql) log.writetofile("CurrentScore decremented in db") conn.commit() isPositive = 0 isNegative = 1 es = Elasticsearch() es.index(index="feedback", doc_type="metrics", id=now, body={"isPositive": isPositive, "isNegative": isNegative, "timestamp": now})
def send_message(channel_id, message): log.writetofile("posting reponse to channel: "+channel_id) slack_client.api_call( "chat.postMessage", channel=channel_id, text=message, as_user=True, icon_emoji=':robot_face:' )
def send_image(channel_id,attachments): log.writetofile("posting response image to channel: "+channel_id) slack_client.api_call( "chat.postMessage", channel=channel_id, text="", attachments =attachments, as_user=True, icon_emoji=':robot_face:' )
def checkIDExists(id, conn): cur = conn.cursor() sql = "select ID from sentresponses where ID = '%d'" % id rows_count = cur.execute(sql) if rows_count > 0: log.writetofile("ID exists in DB") return True else: log.writetofile("ID does not exist in DB") return False
def removeUnwantedWords(input): userInputWithOnlyQuestionAndKeywords = [] posTagged = nltk.pos_tag(input) simplifiedTags = [(word, nltk.map_tag('en-ptb', 'universal', tag)) for word, tag in posTagged] for key,value in simplifiedTags: if (key.lower() in config.questionList) or (value not in 'ADP' and value not in 'PRON' and value not in 'DET' and value not in 'CONJ' and value not in 'PRT' and key not in 'is'): userInputWithOnlyQuestionAndKeywords.append(key) else: log.writetofile("blacklisted word: " + key) return userInputWithOnlyQuestionAndKeywords
def getPastResponse(id, conn): cur = conn.cursor() dblist = [] sql = "select * from sentresponses where ID = '%d'" % id cur.execute(sql) result = cur.fetchall() for row in result: dblist.append({"ID": "%d" % row[0], "UserQuestion": "%s" % row[1], "Answer": "%s" % row[2], "MatchingKeywords": "%s" % row[3], "QuestionPart": "%s" % row[4], "CurrentScore": "%d" % row[5], "Timestamp": "%s" % row[6], "Image_Url": "%s" % row[7]}) log.writetofile(str(dblist)) return dblist
def checkRowExists(ques, ans, keywordList, conn): cur = conn.cursor() log.writetofile("..user input keywords" + " " + str(keywordList)) UserkeywordList = str(keywordList) if not keywordList: print "keyword list is empty or null" return False else: sql = "select Keywords from responses where Question = '%s' and Answer = '%s'" % (ques, ans) rows_count = cur.execute(sql) result = cur.fetchall() for i in result: resultrow = i[0] if rows_count > 0: if (set(resultrow) == set(UserkeywordList)): log.writetofile("Row exists in response table") return True else: return False else: log.writetofile("Row does not exist in response table") log.writetofile("not exists") return False
def slackListeToChannel(): READ_WEBSOCKET_DELAY = 1 # 1 second delay between reading from firehose if slack_client.rtm_connect(): log.writetofile("Sara is up and running!") print("Sara is up and running running!") greetings = botController.getMessage() send_message(config.channel,greetings + config.initialDisplayMessage) while True: command, channel, user = parse_slack_output(slack_client.rtm_read()) if command and channel and channel==config.channel and user!="U4P2K7U07": handle_command(command, channel, user) time.sleep(READ_WEBSOCKET_DELAY) else: log.writetofile("Connection failed. Invalid Slack token or bot ID?") print("Connection failed. Invalid Slack token or bot ID?")
def getAllPastResponses(questions, keywords, conn): log.writetofile("sending query to sentresponses db") cur = conn.cursor() sql = "SELECT * FROM sentresponses WHERE QuestionPart = '%s' and MatchingKeywords = '%s'" % ( questions, ','.join(keywords)) cur.execute(sql) result = cur.fetchall() dblist = [] for row in result: id, quest, ans, matchkeyw, QP, CS, TS, img_url = row dblist.append({"id": "%d" % id, "user question": "%s" % quest, "Answer": "%s" % ans, "Matching Keywords": "%s" % matchkeyw, "Question Part": "%s" % QP, "Current Score": "%s" % CS, "Time Stamp": "%s" % TS, "Image_Url": "%s" % img_url}) log.writetofile(str(dblist)) return dblist
def storeNewResponse(ans, matchedKeywordList, ques, conn): if not matchedKeywordList: print "List is empty or null" else: # matchedKeywordsListToCsv = ','.join(map(str,matchedKeywordList)) cur = conn.cursor() # decodedKeyword = (unicode.encode(matchedKeywordList)) # decodedQuestion = ((unicode.encode(ques))) matchedKeywordList=lang_processor.removeSpaceKeyword(matchedKeywordList) insertStmt = "insert into responses (Answer,Keywords,Question,image_url) values ('%s','%s','%s','none')" % ( ans, matchedKeywordList, ques) print insertStmt cur.execute(insertStmt) log.writetofile("New Responses inserted to db") conn.commit()
def getPastResponseFromUserInput(userInp, conn): cur = conn.cursor() sql = "select * from sentresponses where UserQuestion = '%s'" % userInp dblist = [] cur.execute(sql) result = cur.fetchall() rowExists = False for row in result: dblist.append({"ID": "%d" % row[0], "UserQuestion": "%s" % row[1], "Answer": "%s" % row[2], "MatchingKeywords": "%s" % row[3], "QuestionPart": "%s" % row[4], "CurrentScore": "%d" % row[5], "Timestamp": "%s" % row[6], "Image_Url": "%s" % row[7]}) rowExists = True log.writetofile(str(dblist)) return dblist, rowExists
def getAllResponses(conn): log.writetofile("Sending query to DB") cur = conn.cursor() sql = "SELECT * FROM responses" cur.execute(sql) result = cur.fetchall() dblist = [] for row in result: id, ans, keyw, ques, img_url = row numberOfDbKeywords = len(keyw.split(',')) dblist.append({"id": "%d" % id, "question": "%s" % ques.lower(), "answer": "%s" % ans.lower(), "numberOfDbKeywords": "%d" % numberOfDbKeywords, "DbKeywords": "%s" % keyw.lower(), "numberOfUserInputKeywords": 0, "numberOfMatchingKeywords": 0, "matchingKeyWords": "", "nonMatchingKeyWords": "", "image_url": img_url, "nonMatchingKeywordsInDB": ""}) # log.writetofile(str(dblist)) return dblist
def getAllResponsesExceptAnswerWithNegativeScore(conn, previousAnswer): log.writetofile("Getting responses without answer with negative score") cur = conn.cursor() sql = "SELECT * FROM responses where Answer!='%s'" % previousAnswer cur.execute(sql) result = cur.fetchall() dblist = [] for row in result: id, ans, keyw, ques, img_url = row numberOfDbKeywords = len(keyw.split(',')) dblist.append({"id": "%d" % id, "question": "%s" % ques.lower(), "answer": "%s" % ans.lower(), "numberOfDbKeywords": "%d" % numberOfDbKeywords, "DbKeywords": "%s" % keyw.lower(), "numberOfUserInputKeywords": 0, "numberOfMatchingKeywords": 0, "matchingKeyWords": "", "nonMatchingKeyWords": "", "image_url": img_url, "nonMatchingKeywordsInDB": ""}) # log.writetofile(str(dblist)) return dblist
def storeSentResponse(userInput, answer, keywords, questions, conn, img_url): log.writetofile("storing sent response to DB..") now = datetime.now() now.strftime('%m/%d/%Y') cur = conn.cursor() insertstmt = "insert into sentresponses (UserQuestion,Answer,MatchingKeywords,QuestionPart,CurrentScore,Timestamp,image_url) values ('%s', '%s', '%s ', '%s', '%d', '%s', '%s')" % ( userInput, answer, ','.join(keywords), questions, 1, now, img_url) cur.execute(insertstmt) timestamp = datetime.now() es = Elasticsearch() es.index(index="sararesponses", doc_type="metrics", id=timestamp, body={"question": userInput, "answer": answer, "timestamp": timestamp}) log.writetofile("Insert to db successfully done") sentResponseID = conn.insert_id() conn.commit() return sentResponseID
def pickBestResponse(keywords, userInput, userInputArray, questionPartInUserInput, conn): image_url = "none" pastResponses, isPastResponseExists = database.getPastResponseFromUserInput( userInput, conn) if isPastResponseExists: pastResponses.sort(key=operator.itemgetter('CurrentScore'), reverse=True) pastResponse = pastResponses[0] if int(pastResponse['CurrentScore']) > 0: log.writetofile("I am giving a reply from my past experiences") response = lang_processor.generateResponse( userInputArray, questionPartInUserInput, pastResponse['Answer'], keywords) response = response + config.giveFeedback + str(pastResponse['ID']) image_url = pastResponse['Image_Url'] database.storeMetricInES(userInput, response) else: log.writetofile( "Score for my past experiences does not look good. I am gonna look for new responses in the DB" ) response, image_url = getBestResponseFromDB( keywords, userInput, userInputArray, questionPartInUserInput, conn, True, pastResponse['Answer']) else: log.writetofile("Getting new response from DB") response, image_url = getBestResponseFromDB(keywords, userInput, userInputArray, questionPartInUserInput, conn, False, "none") return response, image_url
def connectToDB(): log.writetofile("entering connectToDB function") try: myConnection = pymysql.connect(host=config.dbHost, user=config.dbUser, passwd=config.dbPassword, db=config.dbName) log.writetofile("DB connection succesfull") except Exception, ex: myConnection = "error" log.writetofile("Error : %s" % ex)
def getBotID(): log.writetofile("entering getBotID function") BOT_NAME = "sara_sjsu" api_call = slack_client.api_call("users.list") if api_call.get('ok'): # retrieve all users so we can find our bot users = api_call.get('members') for user in users: if 'name' in user and user.get('name') == BOT_NAME: log.writetofile("found bot user "+ BOT_NAME) return user.get('id') else: log.writetofile("could not find bot user with the name " + BOT_NAME)
def seperateQuestionAndKeywords(input): questionsInUserInput = [] keyWordsInUserInput = [] log.writetofile("seperating the questions and keywords from user input") for inp in input: if inp in questionList: questionsInUserInput.append(inp) log.writetofile("Question: " + inp) else: keyWordsInUserInput.append(inp) log.writetofile("keyword: " + inp) if(checkIfOneElementMatches(config.whQuestionList,questionsInUserInput)): questionsInUserInput.sort(reverse=True) return questionsInUserInput, keyWordsInUserInput
import sara import log if __name__ == "__main__": log.truncateFile() log.writetofile("*****Starting the log file*****") sara.slackListeToChannel()
def defaultMode(): global currentMode currentMode = "default" log.writetofile("Returning to default mode") return config.initialDisplayMessage
def handle_command(userInput, channel, user): """ Receives commands directed at the bot and determines if they are valid commands. If so, then acts on the commands. If not, returns back what it needs for clarification. """ log.writetofile("entering handle command function") log.writetofile("User Input: " + userInput) timestamp1 = datetime.now() userInput = lang_processor.getAlphaNumericString(userInput) previousMode = botController.currentMode response,image_url,question = botController.currentWorkingMode(userInput) print response log.writetofile("bot reply: " + response) user = '******'.format(user=user) send_message(channel,"Hi" + user + "!. "+response) timetaken = datetime.now() - timestamp1 log.writetofile("Time taken: " + str(timetaken)) if (image_url!="none"): attachments = [{"title":response,"image_url": image_url}] send_image(channel,attachments) log.writetofile("Sending Image") creatinglogfile() else: log.writetofile("No Image to be sent") creatinglogfile() if(question == "where"): attachments = [ { "fallback": "http://www.sjsu.edu/map/docs/campus-map.pdf", "title": "SJSU campus map", "title_link": "http://www.sjsu.edu/map/docs/campus-map.pdf", "color": "#36a64f", } ] send_image(channel, attachments) log.writetofile("Sending map") if botController.currentMode=="chat" and previousMode != "default": database.pushTimeTakenToES(timetaken)
def closeDbConnection(conn): log.writetofile("closing the db connection") conn.close()
def isCorrectAnswer(keywords, conn): log.writetofile("sending query to responses db") cur = conn.cursor() userkeylist = [] for i in keywords: userkeylist.append(i) log.writetofile(str(userkeylist)) sql = "select Keywords from responses" cur.execute(sql) result = cur.fetchall() resultrow = [] for i in result: resultrow.append(i[0]) resultlist = ','.join(resultrow) a = resultlist.split(",") newwordslist = [x for x in userkeylist if x not in a] answer = newwordslist[0:] userinputlist = [x for x in userkeylist if x not in newwordslist] for i in userinputlist: listuser = '******'.join(userinputlist) sql = "select Keywords from responses where Answer = '%s'" % (' '.join(answer)) rows_count = cur.execute(sql) log.writetofile(sql) if rows_count > 0: result = cur.fetchall() dblist = result[0] log.writetofile(str(dblist)) if (set(listuser) == set(dblist[0])): log.writetofile("Row exists in response table") return True else: log.writetofile("no matching found") return False else: return False
def currentWorkingMode(userInput): image_url = "none" questionPart = "none" global currentMode if (currentMode == "default"): if (userInput == "1"): currentMode = "chat" response = config.chatResponse log.writetofile(response) elif (userInput == "2"): currentMode = "training" response = config.trainingResponse1 log.writetofile(response) elif (userInput == "3"): currentMode = "feedback" response = config.feedbackResponse1 log.writetofile(response) elif (userInput == "4"): currentMode = "statistics" response = config.statisticsResponse log.writetofile(response) elif (userInput == "5"): currentMode = "weather" response = config.weatherResponse log.writetofile(response) elif (userInput.lower() == "Exit".lower()): response = defaultMode() else: response = "Invalid Input. Please input the number to choose your mode" log.writetofile(response) elif (currentMode == "chat"): if (userInput.lower() == "Exit".lower()): response = defaultMode() else: response, image_url, questionPart = getReply(userInput) log.writetofile("Calling function botController getReply") elif (currentMode == "training"): if (userInput.lower() == "Exit".lower()): response = defaultMode() else: global userInputQuestions, userInputKeywords userInputQuestions, userInputKeywords = userInputQuestionKeyword( userInput) # print type(userInputQuestions) # print userInputQuestions if (len(userInputQuestions)): currentMode = "training2" response = config.trainingResponse2 elif (currentMode == "training2"): if (userInput.lower() == "Exit".lower()): response = defaultMode() else: global userInputQuestions, userInputKeywords unicodeKeywords = [] conn = database.connectToDB() unicodeKeywords = ','.join(userInputKeywords) if (database.checkRowExists(userInputQuestions[0], userInput, unicodeKeywords, conn)): log.writetofile("row already exist so not inserting") response = "Thanks for the information. " + config.moreTraining currentMode = "moretraining" else: database.storeNewResponse(userInput, unicodeKeywords, userInputQuestions[0], conn) currentMode = "moretraining" response = "Thanks for the information. " + config.moreTraining elif (currentMode == "moretraining"): if (userInput.lower() == "Exit".lower()): response = defaultMode() if (userInput.lower() == "yes".lower() or userInput.lower() == "y"): currentMode = "training" response = config.trainingResponse1 elif (userInput.lower() == "no".lower() or userInput.lower() == "n"): response = defaultMode() else: response = "Please enter yes or no" elif (currentMode == "feedback"): if (userInput.lower() == "Exit".lower()): response = defaultMode() elif (userInput.isalpha()): response = "Please enter the number for Response ID" else: id = int((unicode.encode(userInput))) conn = database.connectToDB() if (database.checkIDExists(id, conn)): global responseID responseID = userInput currentMode = "feedback2" dblist = database.getPastResponse(id, conn) for var1 in dblist: response = "Question is: " + var1[ 'UserQuestion'] + "\n" + config.feedbackResponse2 else: response = "Response ID does not exist" elif (currentMode == "feedback2"): if (userInput.lower() == "Exit".lower()): response = defaultMode() else: global responseID conn = database.connectToDB() id = int((unicode.encode(responseID))) database.updatePastResponse(id, userInput, conn) if (userInput.lower() == "yes".lower() or userInput.lower() == "y"): response = config.feedbackResponseYes currentMode = "morefeedback" if (userInput.lower() == "no".lower() or userInput.lower() == "n"): currentMode = "wrongfeedback" response = config.feedbackResponseNo elif (currentMode == "morefeedback"): if (userInput.lower() == "Exit".lower()): response = defaultMode() if (userInput.lower() == "yes".lower() or userInput.lower() == "y"): currentMode = "feedback" response = config.feedbackResponse1 elif (userInput.lower() == "no".lower() or userInput.lower() == "n"): response = defaultMode() else: response = "Please enter yes or no" elif (currentMode == "wrongfeedback"): if (userInput.lower() == "Exit".lower()): response = defaultMode() else: global responseID id = int((unicode.encode(responseID))) conn = database.connectToDB() dblist = database.getPastResponse(id, conn) for var1 in dblist: if (database.checkRowExists(var1['QuestionPart'], userInput, var1['MatchingKeywords'], conn)): log.writetofile("row already exist so not inserting") else: log.writetofile("new row inserted") database.storeNewResponse(userInput, var1['MatchingKeywords'], var1['QuestionPart'], conn) response = config.feedbackResponseYes currentMode = "morefeedback" elif (currentMode == "weather"): if (userInput.lower() == "Exit".lower()): response = defaultMode() else: questions, keywords = userInputQuestionKeyword(userInput) response = weather.getWeather(keywords) #response = "weather mode initiated" else: if (userInput.lower() == "Exit".lower()): response = defaultMode() else: #driver = webdriver.Chrome() #driver.get('http://localhost:5601/goto/2d0d499fbddc57172334c009f2ab5614') #driver.save_screenshot('vivek.png') #driver.quit() response = "to view statistics visit, visit http://localhost:5601/goto/a7858fc1a3f85a385f6e926a1f776629" return response, image_url, questionPart
def getBestResponseFromDB(keywords, userInput, userInputArray, questionPartInUserInput, conn, isNegativeScore, previousAnswer): image_url = "none" if isNegativeScore: DBResponses = database.getAllResponsesExceptAnswerWithNegativeScore( conn, previousAnswer) else: DBResponses = database.getAllResponses(conn) DBResponses = getMatchingKeywords(DBResponses, keywords) DBResponses.sort(key=operator.itemgetter('numberOfMatchingKeywords'), reverse=True) #log.writetofile("sorted:" + str(DBResponses)) for dbResponse in DBResponses: # 100% match for the keywords in user input with atleast one response in db. NO need to autocorrect or find synonyms for other responses if dbResponse['nonMatchingKeyWords'] == "" and dbResponse[ 'nonMatchingKeywordsInDB'] == "": break # not 100%. # perform spell check and find similar words else: nonMatchingKeywords = dbResponse['nonMatchingKeyWords'].split(',') nonMatchingKeywordsinDB = dbResponse[ 'nonMatchingKeywordsInDB'].split(',') for nonMatchingKeyword in nonMatchingKeywords: correctedKeyword = lang_processor.autocorrect( nonMatchingKeyword) synonyms = lang_processor.getSynonyms(correctedKeyword) # log.writetofile("synonyms for user input " + correctedKeyword + ":" + str(synonyms)) for nonMatchingKeyword in nonMatchingKeywordsinDB: DBsynonyms = lang_processor.getSynonyms(nonMatchingKeyword) # log.writetofile("synonyms for DB " + nonMatchingKeyword + ":" + str(DBsynonyms)) if (set(DBsynonyms) == set(synonyms)): log.writetofile("matching synonym found.") dbResponse["numberOfMatchingKeywords"] = dbResponse[ "numberOfMatchingKeywords"] + 1 DBResponses.sort(key=operator.itemgetter('numberOfMatchingKeywords'), reverse=True) log.writetofile("after synonyms : " + str(DBResponses)) isAmbiguousReply = False responseNumber = 1 for dbResponse in DBResponses: if responseNumber == 1: firstResponseMatchingCount = dbResponse["numberOfMatchingKeywords"] response = dbResponse["answer"] responseNumber = responseNumber + 1 questionPart = dbResponse["question"] image_url = dbResponse["image_url"] else: if (firstResponseMatchingCount != 0): if firstResponseMatchingCount == dbResponse[ "numberOfMatchingKeywords"]: if questionPart == questionPartInUserInput: log.writetofile( "2 responses.picking bases on question") elif questionPartInUserInput == dbResponse["question"]: response = dbResponse["answer"] image_url = dbResponse["image_url"] log.writetofile( "2 responses.picking 2nd based on question") else: log.writetofile("2 responses.ambiguos") isAmbiguousReply = True image_url = dbResponse["image_url"] response = config.ambiguousInput else: log.writetofile("0 matching keywords") isAmbiguousReply = True image_url = dbResponse["image_url"] response = config.ambiguousInput if (isAmbiguousReply): log.writetofile("not storing in sent responses") else: sentResponseID = database.storeSentResponse( userInput, response, keywords, questionPartInUserInput, conn, image_url) log.writetofile("storing sent response") print sentResponseID response = lang_processor.generateResponse( userInputArray, questionPartInUserInput, response, keywords) response = response + config.giveFeedback + str(sentResponseID) return response, image_url # pastResponses = database.getPastResponseFromUserInput(userInput,conn) return config.noAppropriateResponseFound
def common_replies(user_input_array, conn): question1 = user_input_array[0] train = [('hi', 'pos'), ('hello', 'pos'), ('please improve your answers', 'pos'), ('can you give me this?', 'pos'), ('i love your answers.', 'pos'), ('this is an amazing answer!', 'pos'), ('a very Good Morning', 'pos'), ('this is your best work.', 'pos'), ("this is an awesome answer", 'pos'), ('i do not like this', 'neg'), ('sorry', 'neg'), ('i am tired of this stuff.', 'neg'), ("i can't deal with this", 'neg'), ('you have to improve', 'neg'), ('you are taking so much time to learn.', 'neg')] cl = NaiveBayesClassifier(train) for i in user_input_array: ques = ' '.join(user_input_array) blob = TextBlob(ques, classifier=cl) sentiment = blob.classify() print(sentiment) log.writetofile("entering positive or negative checking") common_questions = [ 'request appointment', 'text books references download', 'sjsu main campus map', 'share cmpe273 greensheet', 'slack manual assistance error problem', 'help', 'improve', 'great day', 'bye tata cya see you later', 'thank you thanks', 'thanks Sara', 'please improve your answers', 'are you feeling good today?', 'amazing answers', 'bye' ] for i in common_questions: if (sentiment == 'pos' and question1 != "is" and question1 != "does" and (ques not in ' '.join(common_questions))): response = check_for_greeting(ques) elif (sentiment == 'neg' and question1 != "is" and question1 != "does" and (ques not in ' '.join(common_questions))): response = check_for_complaints(ques) elif (question1 == "is" or question1 == "does"): keywords = lang_processor.removeUnwantedWords(user_input_array) resp = database.isCorrectAnswer(keywords, conn) if (resp == True): response = "yes" else: response = "no" elif (ques in "request appointment"): response = sendemail.SendEmail() elif (ques in "share cmpe273 greensheet"): attachments = [{ "fallback": "Greensheet Cmpe 273 spring 2017 semester - https://www.dropbox.com/sh/qrzvf659cw2k4uv/AACrelHpOwJTX88TDN-PQ8o9a?dl=0&preview=cmpe273-greensheet.docx", "pretext": "Cmpe 273 Greensheet", "title": "Cmpe 273 Spring 2017 Semester Greensheet", "title_link": "https://www.dropbox.com/sh/qrzvf659cw2k4uv/AACrelHpOwJTX88TDN-PQ8o9a?dl=0&preview=cmpe273-greensheet.docx", "color": "#36a64f", }] response = "click on this link for greensheet" sara.send_image(config.channel, attachments) elif (ques in "thank you thanks"): response = "You are welcome! :thumbsup:" elif (ques in "sjsu main campus map"): attachments = [{ "title": "Sjsu Main Campus", "title_link": "http://www.sjsu.edu/map/docs/campus-map.pdf", "color": "#36a64f" }] response = "Check out this link for main campus map!" sara.send_image(config.channel, attachments) elif (ques in "more clear"): response = "sure :ok_hand:" elif (ques in "text books references download"): response = "Check these links to download text books! :thumbsup:" attachments = [{ "text": "Text Books/Readings -", "fallback": "text book 1 - https://books.google.com/books?id=CclkovBDqJkC&printsec=frontcover&source=gbs_ge_summary_r&cad=0#v=onepage&q&f=false", "fields": [{ "title": "Web Services, by Gustavo Alonso, Fabio Casati, Harumi Kuno and Vijay Machiraju (2003) ", "value": "<https://books.google.com/books?id=CclkovBDqJkC&printsec=frontcover&source=gbs_ge_summary_r&cad=0#v=onepage&q&f=false|Download here>", "short": True }, { "title": "Enterprise Integration Patterns, by Gregor Hohpe and Bobby Woolf (2003)", "value": "<http://ptgmedia.pearsoncmg.com/images/9780321200686/samplepages/0321200683.pdf|Download here>", "short": True }, { "title": "Restful Web Services, by Leonard Richardson, Sam Ruby and David Hansson (2007)", "value": "<https://www.crummy.com/writing/RESTful-Web-Services/RESTful_Web_Services.pdf|Download here>", "short": True }], "color": "#F35A00" }] sara.send_image(config.channel, attachments) elif (ques in "great day"): response = "Yes,Thanks. Wish you a Wonderful Day. :ok_hand:" elif (ques in "please improve your answers"): response = "Yes..sure, I will definitely improve them. :ok_hand:" elif (ques in "are you feeling good today?"): response = "Hi! I'm good..How are you feeling this week?" elif (ques in "amazing answers"): response = "Thanks! I know im so good at it!. :heart_eyes:" elif (ques in "bye tata cya see you later"): response = "Bye! Adios! Have a good day! :wave: " elif (ques in "help :rolling_eyes:"): response = "Sure! What help do u need? " elif (ques in "slack manual assistance error problem"): attachments = [{ "fallback": "help with slack - https://get.slack.help/hc/en-us", "pretext": "Slack help center", "title": "Hi, How can we help?", "title_link": "https://get.slack.help/hc/en-us", "color": "#36a64f" }] response = "Check out this link for help center!" sara.send_image(config.channel, attachments) elif (ques in "improve"): response = "Yes..sure, I will definitely improve them.:thumbsup: " else: response = "I'm sorry, I don't understand! Sometimes I have an easier time with a few simple keywords.\n " return response