Package: pylogflow
PylogflowPython library for Dialogflow webhook. / Biblioteca de python para webhooks en DialogflowContent Table / Tabla de contenidoLanguage / IdiomaEnglishDescriptionRequirementsInstallationUsageSupport meEspaÃ±olDescripcionRequisitosInstalaciÃ³nUsoApoyarEnglish documentationDescriptionThe purpouse of pylogflow is allow people to do chatbots easier without knowing how dialogflow works, and let proggrammer just focus on the process that they want to do (I think that their javascript library is complex in further level and i love python).This library can manage responses(messages) and intents in this version, in next versions i'll add context management and easy parameters management (just i make it for Actions on Google, i have to do for generic responses).RequirementsPython 3Python pipInstallationpip install pylogflowUsageBefore startTo start using pylogflow you must know how to setup a web server with python, read this if you dont know how to startIn examples below i'll use flask that is a web framework on python, it's really easy to use, you can learn more about it here.Intent HandlingIf you have some intents in your Dialogflow agent that points to webhook you have to manage them, so pylogflow includes intent handling that makes it easy.Suppose that you have an intent named "Test" and you want to handle in webhook, you will do something like this.frompylogflowimportIntentMapfromflaskimportrequest,jsonifyapp=flask.Flask(__name__)# We will receive POST request when webhook is called@app.route('/',methods=['POST'])defwebhook():# Send request as a json dictionary, result must be a dictionaryresult=intentMap.execute_intent(request.json)# Parse result into json response formatreturnjsonify(result)# Intent 'Test' function# They must receive a request in dictionary format.defintentTest(req):# Simpliest dialogflow responsereturn{'fulfillmentText':'This is a response from webhook'}# Intent Map for handle intents, this can be inside your request function (webhook)# or here, in this way you only setup onceintentMap=IntentMap()# add method appends new intent with their function# first parameter must be the Dialogflow intent name, second is the function nameintentMap.add('Test',intentTest)# flask run configurationif__name__=='__main__':app.run(host='0.0.0.0',port=5000)The code above it's the simpliest way to handle an intent in webhook, i just send request in dictionary format to intentMap with 'execute_intent' function, and then get response with 'get_response' function and return as json with jsonify feature from flask, the rest of the code is to make a function that build response and then return it, below of all must create intentMap object and then add respective intent with their respective name(must be same as we set in Dialogflow).Responses (messages)There are some responses that we can send to dilogflow, this version can make Generic responses and Google Assistant responses.Agent ResponsesAgent class can handle generic text and card responses( i don't recomend card responses for now, i'm searching why Google Assistant doesn't handle that cards and get error, if you want to add cards for Google, use GoogleResponse instead).Below i'll use same example to explain agent usage, we have to focus on 'intentTest' function, and remember to import Agent.frompylogflowimportIntentMap,Agentfromflaskimportrequest,jsonifyapp=flask.Flask(__name__)# Main Webhook route@app.route('/',methods=['POST'])defwebhook():result=intentMap.execute_intent(request.json)returnjsonify(result)defintentTest(req):# We create an Agent objectagent=Agent()# We can add messagesagent.add_message("Hi")agent.add_message("How are you?")# Or cards (just one recommended)agent.add_card("title","subtitle","imageURL","buttonName","buttonURL")# Then, we return the response in dictionary formatreturnagent.get_response()# Intent Map for handle intentsintentMap=IntentMap()intentMap.add('Test',intentTest)# flask run configurationif__name__=='__main__':app.run(host='0.0.0.0',port=5000)In this case, in 'intentTest' function we have to create agent, after that, we can add messages, cards and then send response back, it's really easy.Google AssistantGoogle Assistant Works in a similar way, you have to test responses in Gogle Assistant Test Sandbox, because inside dialogflow test tool responses aren't showed, we are working on this issue, but works fine in production.Simple ResponseAdd simple responses to Google Assistant as follows:importflaskfromflaskimportrequest,jsonify# Import GoogleResponsefrompylogflowimportIntentMap,GoogleResponse,Agentapp=flask.Flask(__name__)@app.route('/',methods=['POST'])defhome():result=intentMap.execute_intent(request.json)returnjsonify(result)# Intent Multiple simple responsedefintentSimpleResponse(req):agent=Agent()# Instantiate a GoogleResponse Object, you can optionaly# send a boolean if google must expect response, by default# is "True"gResponse=GoogleResponse()# Add simple response, Maximum 2 simple responsesgResponse.add_simple_response("This is a message")gResponse.add_simple_response("This is another message")# Add google message to your agentagent.add_custom_payload(gResponse.get_response())# Return agent in same wayreturnagent.get_response()# Set up intent mapintentMap=IntentMap()intentMap.add("Simple Response",intentSimpleResponse)if__name__=='__main__':app.run(host='0.0.0.0',port=5000)CardSugestion Chipsimportflaskfromflaskimportrequest,jsonify# Import GoogleResponsefrompylogflowimportIntentMap,GoogleResponse,Agentapp=flask.Flask(__name__)@app.route('/',methods=['POST'])defhome():result=intentMap.execute_intent(request.json)returnjsonify(result)# Intent Multiple simple responsedefintentSuggestionChips(req):agent=Agent()# Instantiate a GoogleResponse Object, you can optionaly# send a boolean if google must expect response, by default# is "True"gResponse=GoogleResponse()# Add suggestion chips, max 5gResponse.add_suggestion_chips("flask","algo")# Add google message to your agentagent.add_custom_payload(gResponse.get_response())returnagent.get_response()# Set up intent mapintentMap=IntentMap()intentMap.add("Suggestion Chips",intentSuggestionChips)if__name__=='__main__':app.run(host='0.0.0.0',port=5000)Listimportflaskfromflaskimportrequest,jsonify# Import GoogleResponsefrompylogflowimportIntentMap,GoogleResponse,Agentapp=flask.Flask(__name__)@app.route('/',methods=['POST'])defhome():result=intentMap.execute_intent(request.json)returnjsonify(result)# Intent Multiple simple responsedefintentList(req):agent=Agent()gResponse=GoogleResponse()gResponse.add_list(gResponse.generate_list_item("Elemento 1","ELEMENTO_1",["cosa 1","objeto 1"],"descripcion corta","https://files.realpython.com/media/Python_Exceptions_Watermark.47f814fbeced.jpg"),gResponse.generate_list_item("Elemento 2","ELEMENTO_2",["cosa 2","objeto 2"],"descripcion corta","https://files.realpython.com/media/Python_Exceptions_Watermark.47f814fbeced.jpg"),gResponse.generate_list_item("Elemento 3","ELEMENTO_#",["cosa 3","objeto 3"],"descripcion corta","https://files.realpython.com/media/Python_Exceptions_Watermark.47f814fbeced.jpg"),title="Titulo de la lista")agent.add_custom_payload(gResponse.get_response())returnagent.get_response()# Set up intent mapintentMap=IntentMap()intentMap.add("List",intentList)if__name__=='__main__':app.run(host='0.0.0.0',port=5000)Carrouselimportflaskfromflaskimportrequest,jsonify# Import GoogleResponsefrompylogflowimportIntentMap,GoogleResponse,Agentapp=flask.Flask(__name__)@app.route('/',methods=['POST'])defhome():result=intentMap.execute_intent(request.json)returnjsonify(result)defintentCarrousel(req):agent=Agent()gResponse=GoogleResponse()gResponse.add_carrousel(gResponse.generate_carrousel_item("Elemento 1","ELEMENTO_1",["cosa 1","objeto 1"],"descripcion corta","https://files.realpython.com/media/Python_Exceptions_Watermark.47f814fbeced.jpg"),gResponse.generate_carrousel_item("Elemento 2","ELEMENTO_2",["cosa 2","objeto 2"],"descripcion corta","https://files.realpython.com/media/Python_Exceptions_Watermark.47f814fbeced.jpg"),gResponse.generate_carrousel_item("Elemento 3","ELEMENTO_#",["cosa 3","objeto 3"],"descripcion corta","https://files.realpython.com/media/Python_Exceptions_Watermark.47f814fbeced.jpg"))agent.add_custom_payload(gResponse.get_response())returnagent.get_response()# Set up intent mapintentMap=IntentMap()intentMap.add("Carrousel",intentCarrousel)if__name__=='__main__':app.run(host='0.0.0.0',port=5000)Handle List and Carrousel optionsList and Carrousel use options in Google Assistant, we can handle this options easy by importing GoogleRequest, generaly this options prompts to another intent, this is an example that can handle any option.# Intent functiondefintentOption(req):agent=Agent()print(req)gResponse=GoogleResponse()# Instantiate a GoogleRequest object sending request received in this intent functiongRequest=GoogleRequest(req)# This is the option selected obtained from requestselection=gRequest.get_option_arguments()# It comes as a list, generally is only 1 elementforoptioninselection:gResponse.add_simple_response("selected : "+option)agent.add_custom_payload(gResponse.get_response())returnagent.get_response()Browse CarrouseldefintentBrowseCarrousel(req):# Set agentagent=Agent()gResponse=GoogleResponse()# You can make a list of itemsitems=[]# Append every item to listitems.append(gResponse.generate_browse_carrousel_item("titulo1","descripcion 1","piesillo 1","https://files.realpython.com/media/Python_Exceptions_Watermark.47f814fbeced.jpg","hola","https://files.realpython.com/media/Python_Exceptions_Watermark.47f814fbeced.jpg"))items.append(gResponse.generate_browse_carrousel_item("titulo2","descripcion 2","piesillo 2","https://files.realpython.com/media/Python_Exceptions_Watermark.47f814fbeced.jpg","hola","https://files.realpython.com/media/Python_Exceptions_Watermark.47f814fbeced.jpg"))# Send list as arguments with * operatorgResponse.add_browse_carrousel(*items)agent.add_custom_payload(gResponse.get_response())returnagent.get_response()TabledefintentTable(req):agent=Agent()gResponse=GoogleResponse()gResponse.add_table(# First parameter is Header RowgResponse.generate_table_header_row(# Necesary Table headers, you can add as list with * if you wantgResponse.generate_table_header("Titulo 1"),gResponse.generate_table_header("Titulo 2"),gResponse.generate_table_header("Titulo 3")),# Then add rows as arguments, or a list of table rows with *gResponse.generate_table_row("texto1","texto2","texto3"),gResponse.generate_table_row("texto1","texto2","texto3"),# KWargstitle="Titulo Prueba",subtitle="prueba subtitulo",# this needs a title to be placedimageUrl="https://files.realpython.com/media/Python_Exceptions_Watermark.47f814fbeced.jpg",buttonText="Hola soy un boton",buttonUrl="https://files.realpython.com/media/Python_Exceptions_Watermark.47f814fbeced.jpg",)agent.add_custom_payload(gResponse.get_response())returnagent.get_response()Media ResponseThis is an audio response.defintentMedia(req):# Set agentagent=Agent()# agent.add_Message("ayuda respondiendo")gResponse=GoogleResponse()gResponse.add_media_response("nombre","descripcion","https://storage.googleapis.com/automotive-media/album_art.jpg","Album cover of an ccean view","https://storage.googleapis.com/automotive-media/Jazz_In_Paris.mp3")agent.add_custom_payload(gResponse.get_response())# this return a dictionary formatreturnagent.get_response()importflaskfromflaskimportrequest,jsonifyfrompylogflowimportIntentMap,GoogleResponse,GoogleRequest,Agentapp=flask.Flask(__name__)@app.route('/',methods=['POST'])defhome():# Send request as a json, result must be a dictionaryresult=intentMap.execute_intent(request.json)# Parse result into json formatreturnjsonify(result)# Intent Multiple simple responsedefintentSimpleResponse(req):agent=Agent()gResponse=GoogleResponse()gResponse.add_simple_response("Hey")gResponse.add_simple_response("You")agent.add_custom_payload(gResponse.get_response())returnagent.get_response()# Intent ayudadefintentAyuda(req):# Set agentagent=Agent()# agent.add_Message("ayuda respondiendo")gResponse=GoogleResponse()gResponse.add_media_response("nombre","descripcion","https://storage.googleapis.com/automotive-media/album_art.jpg","Album cover of an ccean view","https://storage.googleapis.com/automotive-media/Jazz_In_Paris.mp3")gResponse.add_simple_response("Hola, esto es una prueba")gResponse.add_suggestion_chips("flask","algo")agent.add_custom_payload(gResponse.get_response())# this return a dictionary formatreturnagent.get_response()# Intent requestdefintentRequest(req):# Set agentagent=Agent()gResponse=GoogleResponse()gResponse.add_browse_carrousel(gResponse.generate_browse_carrousel_item("titulo1","descripcion 1","piesillo 1","https://files.realpython.com/media/Python_Exceptions_Watermark.47f814fbeced.jpg","hola","https://files.realpython.com/media/Python_Exceptions_Watermark.47f814fbeced.jpg"),gResponse.generate_browse_carrousel_item("titulo2","descripcion 2","piesillo 2","https://files.realpython.com/media/Python_Exceptions_Watermark.47f814fbeced.jpg","hola","https://files.realpython.com/media/Python_Exceptions_Watermark.47f814fbeced.jpg"))agent.add_custom_payload(gResponse.get_response())returnagent.get_response()# Intent algodefintentAlgo(req):agent=Agent()gResponse=GoogleResponse()gResponse.add_table(gResponse.generate_table_header_row(gResponse.generate_table_header("Titulo 1"),gResponse.generate_table_header("Titulo 2"),gResponse.generate_table_header("Titulo 3")),gResponse.generate_table_row("texto1","texto2","texto3"),gResponse.generate_table_row("texto1","texto2","texto3"),title="Titulo Prueba",subtitle="prueba subtitulo",imageUrl="https://files.realpython.com/media/Python_Exceptions_Watermark.47f814fbeced.jpg",buttonText="Hola soy un boton",buttonUrl="https://files.realpython.com/media/Python_Exceptions_Watermark.47f814fbeced.jpg",)agent.add_custom_payload(gResponse.get_response())returnagent.get_response()# intent listadefintentLista(req):agent=Agent()gResponse=GoogleResponse()gResponse.add_list(gResponse.generate_list_item("Elemento 1","ELEMENTO_1",["cosa 1","objeto 1"],"descripcion corta","https://files.realpython.com/media/Python_Exceptions_Watermark.47f814fbeced.jpg"),gResponse.generate_list_item("Elemento 2","ELEMENTO_2",["cosa 2","objeto 2"],"descripcion corta","https://files.realpython.com/media/Python_Exceptions_Watermark.47f814fbeced.jpg"),gResponse.generate_list_item("Elemento 3","ELEMENTO_#",["cosa 3","objeto 3"],"descripcion corta","https://files.realpython.com/media/Python_Exceptions_Watermark.47f814fbeced.jpg"),title="Titulo de la lista")agent.add_custom_payload(gResponse.get_response())returnagent.get_response()#Intent opcion listadefintentOpcionLista(req):agent=Agent()print(req)gResponse=GoogleResponse()gRequest=GoogleRequest(req)selection=gRequest.get_option_arguments()foroptioninselection:gResponse.add_simple_response("selected : "+option)capabilities=gRequest.get_capabilities()msg=""forcapincapabilities:msg+=cap["name"]gResponse.add_simple_response(msg)agent.add_custom_payload(gResponse.get_response())returnagent.get_response()# Intent carrouseldefintentCarrousel(req):agent=Agent()gResponse=GoogleResponse()gResponse.add_carrousel(gResponse.generate_carrousel_item("Elemento 1","ELEMENTO_1",["cosa 1","objeto 1"],"descripcion corta","https://files.realpython.com/media/Python_Exceptions_Watermark.47f814fbeced.jpg"),gResponse.generate_carrousel_item("Elemento 2","ELEMENTO_2",["cosa 2","objeto 2"],"descripcion corta","https://files.realpython.com/media/Python_Exceptions_Watermark.47f814fbeced.jpg"),gResponse.generate_carrousel_item("Elemento 3","ELEMENTO_#",["cosa 3","objeto 3"],"descripcion corta","https://files.realpython.com/media/Python_Exceptions_Watermark.47f814fbeced.jpg"))agent.add_custom_payload(gResponse.get_response())returnagent.get_response()# Default fallback intentdeffallback(req):agent=Agent()agent.add_message("default fallback")print(jsonify(req))returnagent.get_response()# Set up intent mapintentMap=IntentMap()intentMap.add("request",intentRequest)intentMap.add("Simple Response",intentSimpleResponse)intentMap.add("ayuda",intentAyuda)intentMap.add("algo",intentAlgo)intentMap.add("lista",intentLista)intentMap.add("Default Fallback Intent",fallback)intentMap.add("opcion lista",intentOpcionLista)intentMap.add("carrousel",intentCarrousel)if__name__=='__main__':app.run(host='0.0.0.0',port=5000)AdviceMy english is not good at all, if i got an error correct me please.