connecting dialogflow voicebot to twilio number - python

I am a noob to dialogflow as well as twilio. I am trying to connect my dialogflow bot to a Twilio number.
I got a twilio number and i am using dialogflow small talk set of intents.
What are the steps to connect a dialogflow (voice)bot to a twilio number with voice (not sms, or chat messaging) ?
On twilio side, i found this code
from flask import Flask
from twilio.twiml.voice_response import Gather, Redirect, VoiceResponse, Say
app = Flask(name)
#app.route("/answer", methods=['GET', 'POST'])
def answer_call():
"""Respond to incoming phone calls with a brief message."""
# Start our TwiML response
response = VoiceResponse()
# Read a message aloud to the caller
gather = Gather(input='speech',action='some_url')
gather.say('Welcome to Paradise, please tell us why you\'re calling')
response.append(gather)
return str(response)
if __name__ == "__main__":
app.run(debug=True)
1) I understood that i should put the url of my dialogflow bot into the action argument. Am I right?
2) If yes, where do i find this url? Is it related to this ? => https://cloud.google.com/dialogflow-enterprise/docs/reference/rest/v2/projects.agent.sessions/detectIntent
3) Then, what would be the session name?
I am trying to use the box on the right "Try this API": but whatever string i write, the output received is :
"name does not match pattern: /^projects/[^/]+/agent/sessions/[^/]+/contexts/[^/]+$/"
As mentionned i am a newby, so any insights on the above would be greatly appreciated!
Thank you so much in advance!

Twilio developer evangelist here.
I've not worked with Dialogflow and Twilio Voice directly (I prefer to connect voice with Twilio Autopilot as it works out of the box). However I know that there is no direct connect between Twilio Voice and Dialogflow.
You are on the right track though. Using <Gather> will capture the user's speech and translate it to text (actually using Google's Cloud Speech API). That text will be sent to your action URL as the SpeechResult. You can't connect that directly to your Dialogflow API endpoint because Dialogflow will expect the parameter to be different and Twilio will expect the result to be TwiML.
Instead you will want to setup the action endpoint on your own server, retrieve the SpeechResult and then send that on to Dialogflow for the result. You might find it easier to interact with the Dialogflow API by installing the Dialogflow Python client and using it to send the request (check out the documentation here). Once you get the result back from Dialogflow you can then use it to construct TwiML to create a new <Gather> for further input or just a <Say> to return the response.
Let me know if this points you in the right direction.

Related

Get last message/s from Telegram channel with Python

I'm using the python-telegram-bot library to write a bot in Python that sends URLs into a channel where the bot is administrator.
Now, I would like to have the bot reading, let's say, the last 5 messages (I don't really care about the number as I just need to read the message on the chat) and store them into a list in the code for further elaborations.
I already have my bot working with:
bot = telegram.Bot(token='mytoken')
bot.sendMessage(chat_id='#mychatid', text=entry.link)
But I can't find a bot.getLastMessage or bot.getMessage kind of class into the python-telegram-bot library.
In case there's already no written class that does that, how can I implement it via the Telegram API as I'm a bit of a beginner when it comes to API implementation?
Thanks.
That's not possible in Bots unfortunately.
Here you can find all available methods (that python-telegram-bot invokes behind the scenes) and there's no such method available to fetch messages on demand.
The closest you can get through the api is getChat (which would return the pinned_message in that chat).
What you can do in this case is, store the messages the bot sends as well as the message updates the bot receives (by setting up a handler) in some storage (database) and fetch from there later on.
Have you tried the other type of Telegram API, Telegram [client] API and TDLib?
Using telethon library makes it easy to read channels history (see telethon docs).
For this, we need an api_id and an api_hash.
To get these parameters, we need to log in to our Telegram core
and go to the API development tools area.
There is a simple form that needs to be filled out, after which, we can receive our api_id and api_hash. See Telegram's help documentation about how to get your API credentials.
Here is an example code that gets the last 5 messages of targetChannelId:
from telethon import TelegramClient
API_ID = 123456 # See above for how to get it
API_HASH = '123abc' # See above for how to get it
client = TelegramClient('my-client', API_ID, API_HASH)
async def main():
async for message in client.iter_messages('targetChannelId', limit=5):
print(message.id, message.text)
with client:
client.loop.run_until_complete(main())
The first time you run this code it asks your phone number or bot token. Enter your phone number in the format +9912345... where 99 is your country code and the rest is your phone number.
It then may send a login code to your Telegram app; enter it in the console.
Note: Bots cannot see channel history messages (at least in telethon) but users (phone numbers) can. Bots can only listen for channel updates only if they are one of its administrators.
The client.iter_messages() accepts other parameters like min_id which can be used so we get messages only after a specific message (for example, we can save the last message id that we have processed and next time pass that id as min_id so only messages after that message are returned).

Unable to get bot to initiate a dialog with the user at a particular point in the conversation, using 'Event' or 'FollowupEvent'. What's the solution?

There is a defined conversation flow for my agent. Using some metric, at a certain point within that conversation flow, the agent is supposed to prompt something to the user, the user hasn't said anything, the bot isn't reacting, it is initiating letting something know to the user at this point of time.
So from my web search and previous dialogflow forum discussions, 'Events' seemed to be the tool to be able to do this. So I have a Python Django-based web server which takes in and responds to webhooks from my Dialogflow agent. ANd my chatbot interface is an Android app which I made based on the 'Dialogflow-android-client' sample app present in Dialogflow's github account (https://github.com/dialogflow/dialogflow-android-client). With this setup the basic conversation chatbot is working well. Now I am trying to implement the scenario described in the paragraph above.
Now, to do this I implemented sending a POST /query Request to the Dialogflow agent to invoke an event (as given in the Dialogflow documentation: https://dialogflow.com/docs/events#invoking_event_from_webhook). It is successfully invoking the intent which has that particular event associated with it. On the invocation of that intent using EVENT webhook, I get back a json response from the agent back to my server in the format described in the documentation. But the client end (neither the Android app nor the Dialogflow developer dialog check console) is showing the text or speaking out the Output text that the event triggered intent. I am only getting all JSON info at my server, nothing is going to the client app. Why is this? In previous Dialogflow forum discussions, one experienced person said that with Event triggering through webhook, you only get information back to where you initiated the trigger from and nowhere else.Is that true? At that same place it was said the best way to get the response at the client app for the event trigger is to use FollowupEvent tool instead.
So that's what I am doing, in the webhook response from my server for 1 intent that was activated by something the user said, I am including the FollowupEvent info in the response JSON. But still no response from the event triggered intent comes at the client app. I think in this case the intent to be triggered is not getting triggered only, since if it was triggered, a POST webhook request for that intent would have come to the server, which it has not. Why is it not working? What is the resolution?
Here is the JSON being sent to the Dialogflow agent from my server (using FollowupEvent):
{
"contextOut": [],
"speech": " ",
"displayText": " ",
"source": "PSVA-server",
"followupEvent": {
"event": {
"name": "testr",
"data": {}
}
}
}
In my Dialogflow agent, I have created an intent which doesn't have any user_says
example in it, has one event "testr" named in it, has an answer text and 'webhook'
option checked in fulfillment.
And finally is there any better method to implement what I am trying to implement?

Proper way to use Twilio Add-ons for "Lookups" in Python

What is the proper way to us a Twilio Add-on that provides intelligence on a phone number for "Lookups" in Python?
Currently, I have it working with "Incoming Voice Call" and "Incoming SMS Message" (Note: you can see "lookups", "Incoming Voice Call: and "Incoming SMS Message" in the attached picture).
With "Incoming Voice Call" and "Incoming SMS Message", the information is automatically provided with the rest of the information pertaining to the call or SMS when Twilio makes it's initial request to my application. The problem with this is that in practice, I am paying 10 times over for many spam numbers that are constantly dialing in.
Instead, I would like to look up the information manually, only when I do not already have the information cached.
It looks like I can make a raw HTTPS request from Python to do this. Example:
https://lookups.twilio.com/v1/PhoneNumbers/+16505399600/?AddOns=nomorobo_spamscore&AddOns.nomorobo_spamscore.secondary_address=+15108675309
However, it seems like a more "proper" way would be to use the TwilioRestClient that comes with the Twilio python helper library. However, its not clear get this Add-on information through the Twilio python helper library. If I'm being honest, I have a lot of trouble understanding those docs.
Twilio developer evangelist here.
You can use the Twilio Python library to achieve this with Lookups too. You can do a lookup, with the example URL you gave, like this:
import os
from twilio.rest import Client
account_sid = os.environ['TWILIO_ACCOUNT_SID']
auth_token = os.environ['TWILIO_AUTH_TOKEN']
client = Client(account_sid, auth_token)
number = client.lookups.phone_numbers("+16505399600").fetch(
add_ons="nomorobo_spamscore",
add_ons_data={
"nomorobo_spamscore": {
"secondary_address": "+15108675309"
}
}
)
print(number.add_ons)
number.add_ons will be a dict of the returned data from the Add-on. You pass the Add-ons you want to use with the add_ons argument (as a string or array of strings) and any further data in the add_ons_data argument.
Let me know if that helps at all.

How to submit a POST request to the Calls resource? (making outgoing calls in Twilio)

I'm having trouble with making outgoing calls using Twilio and I believe I skipped this step where I should submit a POST request to the Calls resource. I don't really understand what to do with this and I need someone to explain it for me since I'm just a beginner. And by the way, my Twilio account is just free trial. Does this have something to do as to why I can't make local calls?
Thanks.
Twilio developer evangelist here.
Best place for you to start would be the Python making calls quick start. Follow that tutorial through and you should understand how to make a call with Python.
Though, as you say, the key is the POST request to the calls resource. It's easiest to perform this using our Python helper library and looks a bit like this:
from twilio.rest import TwilioRestClient
# Get these credentials from http://twilio.com/user/account
account_sid = "ACXXXXXXXXXXXXXXXXX"
auth_token = "YYYYYYYYYYYYYYYYYY"
client = TwilioRestClient(account_sid, auth_token)
# Make the call
call = client.calls.create(to="+14085551234", # Any phone number
from_="+12125551234", # Must be a valid Twilio number
url="http://twimlets.com/holdmusic?Bucket=com.twilio.music.ambient") # Just plays hold music
Let me know if that helps at all.

How do I retrieve inbound SMS phone number from twilio request in Python

I'm attempting to get the "from" number from an SMS message that I send to my Twilio number.
I have a Django server running that takes this message and performs some back-end processing, but I can't seem to retrieve the "from" number that sends that SMS to the Twilio number via Python. I keep getting 500 errors that state that this 'from' attribute doesn't exist but the Twilio documentation states otherwise.
def respond_to_sms(request):
# save the http request message
twilio_request = decompose(request)
# this works fine
twilio_message_body = twilio_request.body
# this does not
from_number = twilio_request.from
# perform backend stuff on from_number
Anyone know how to do this? I'm using the Django-Twilio package.
Twilio developer evangelist here.
You almost got it right, but it turns out that in the Python library, the name of the attribute is from_ as opposed to just from. That's because in Python, from is a reserved keyword as you can see here.
So try changing your code to the following:
from_number = twilio_request.from_
And you'll get it working. More information about the library can be found here.
Hope this helps you out!

Categories

Resources