I'm developing my chatbot backend using detect intent API in Python, once the intent recognized, it goes to my webhook and gets the appropriate data.
here is my detectIntent code to get data from text
def detect_intent_texts(project_id, session_id, text, language_code='en-US'):
session_client = dialogflow.SessionsClient().from_service_account_file(
'my_service_account_json.json')
session = session_client.session_path(project_id, session_id)
print('Session path: {}\n'.format(session))
text_input = dialogflow.types.TextInput(text=text, language_code=language_code)
query_input = dialogflow.types.QueryInput(text=text_input)
response = session_client.detect_intent(session=session, query_input=query_input)
data = MessageToDict(response.query_result)
print (json.dumps(data, indent=4))
response = parse_response(data)
return response
How can I sent access_token with it so that my webhook can identify
which user is accessing the bot
P.S. my webhook is looking for an access token in this path
req.get("originalDetectIntentRequest").get("payload").get("user").get("accessToken")
Everything under the "payload" attribute is platform dependent. The Assistant platform puts user information under here, for example, and this is what your webhook is currently trying to process.
If you wanted to put the access token in the same place, you can pass a query_params named parameter to the call to detect_intent() along with the text you're querying, and anything else that may be relevant. (Reference) That parameter can be a dict and, if so, has to have the same field names as a QueryParameters object.
Related
I'm writing a Telegram bot that must send an image to a user, get a reply and store it as a string.
I managed to write the script to start the bot and send the image (very basic, I know), but I can't figure out how to get the answer. Here is a MWE of my script:
import telegram.ext
token = '1234567890:ABCdEffGH-IJKlm1n23oPqrst_UVzAbcdE4'
bot=telegram.Bot(token=token)
user_id = 567890123
image_path='./image.png'
with open(image_path,'rb') as my_image:
bot.send_photo(chat_id=user_id,photo=my_image,caption='What is this?')
% Somehow store the answer
% Do some other stuff
How can I get and store user's answer?
I can change the script as needed, but to interact with Telegram's API I must use python-telegram-bot only.
You can make a flag called waiting_for_response and after sending the image make it True.
after that you should add a handler to the bot to recieve users reply. You can do it this way:
from telegram.ext import Updater, CommandHandler
updater = Updater(token=TOKEN, use_context=True)
dispatcher = updater.dispatcher
handler = RegexHandler(r'.+', function_name)
dispatcher.add_handler(handler)
Note: You should replace TOKEN with your own token.
by adding this lines, when user sends a message it calls the function_name function and you can define it like this:
def function_name(update, context):
global waiting_for_response
if waiting_for_response:
pass
You can add whatever you want to do with that message inside of this function using update and context.
I have Angular 8 web app. It needs to send some data for analysis to python flask App. This flask App will send it to 3rd party service and get response through webhook.
My need is to provide a clean interface to the client so that there is no need to provide webhook from client.
Hence I am trying to initiate a request from Flask app, wait until I get data from webhook and then return.
Here is the code.
#In autoscaled micro-service this will not work. Right now, the scaling is manual and set to 1 instance
#Hence keeping this sliding window list in RAM is okay.
reqSlidingWindow =[]
#app.route('/handlerequest',methods = ['POST'])
def Process_client_request_and_respond(param1,param2,param3):
#payload code removed
#CORS header part removed
querystring={APIKey, 'https://mysvc.mycloud.com/postthirdpartyresponsehook'}
response = requests.post(thirdpartyurl, json=payload, headers=headers, params=querystring)
if(response.status_code == SUCCESS):
respdata = response.json()
requestId = respdata["request_id"]
requestobject = {}
requestobject['requestId'] = requestId
reqSlidingWindow.append(requestobject)
#Now wait for the response to arrive through webhook
#Keep checking the list if reqRecord["AllAnalysisDoneFlag"] is set to True.
#If set, read reqRecord["AnalysisResult"] = jsondata
jsondata = None
while jsondata is None:
time.sleep(2)
for reqRecord in reqSlidingWindow:
if(reqRecord["requestId"] == da_analysis_req_Id ):
print("Found matching req id in req list. Checking if analysis is done.")
print(reqRecord)
if(reqRecord["AllAnalysisDoneFlag"] == True):
jsondata = reqRecord["AnalysisResult"]
return jsonify({"AnalysisResult": "Success", "AnalysisData":jsondata})
#app.route('/webhookforresponse',methods = ['POST'])
def process_thirdparty_svc_response(reqIdinResp):
print(request.data)
print("response receieved at")
data = request.data.decode('utf-8')
jsondata = json.loads(data)
#
for reqRecord in reqSlidingWindow:
#print("In loop. current analysis type" + reqRecord["AnalysisType"] )
if(reqRecord["requestId"] == reqIdinResp ):
reqRecord["AllAnalysisDoneFlag"] = True
reqRecord["AnalysisResult"] = jsondata
return
I'm trying to maintain sliding window of requests in list. Upon the
Observations so far:
First, this does not work. The function of 'webhookforresponse' does not seem to run until my request function comes out. i.e. my while() loop appears to block everything though I have a time.sleep(). My assumption is that flask framework would ensure that callback is called since sleep in another 'route' gives it adequate time and internally flask would be multithreaded?
I tried running python threads for the sliding window data structure and also used RLocks. This does not alter behavior. I have not tried flask specific threading.
Questions:
What is the right architecture of the above need with flask? I need clean REST interface without callback for angular client. Everything else can change.
If the above code to be used, what changes should I make? Is threading required at all?
Though I can use database and then pick from there, it still requires polling the sliding window.
Should I use multithreading specific to flask? Is there any specific example with skeletal design, threading library choices?
Please suggest the right way to proceed to achieve abstract REST API for angular client which hides the back end callbacks and other complexities.
I am a newbie working with facebook python sdk. I found this file that enabled me to obtain event data from my facebook business page.
However, I am unable to fetch all of the fields I need. The missing field I am unable to obtain is the event videos. I am unable to retrieve the video source or video_url for the video that was posted with the event.
I have tried many different variations of fields =
to no avail. Thank You
import facebook
import requests
def some_action(post):
""" Here you might want to do something with each post. E.g. grab the
post's message (post['message']) or the post's picture (post['picture']).
In this implementation we just print the post's created time.
"""
print(post["id"])
# You'll need an access token here to do anything. You can get a temporary one
# here: https://developers.facebook.com/tools/explorer/
access_token = "My_Access_Token"
# Look at Bill Gates's profile for this example by using his Facebook id.
user = "397894520722082"
graph = facebook.GraphAPI(access_token)
profile = graph.get_object(user)
posts = graph.get_connections(profile['id'], 'posts')
print(graph.get_object(id=397894520722082,
fields='events{videos,id,category,name,description,cover,place,start_time,end_time,interested_count,attending_count,declined_count,event_times,comments}'))
# Wrap this block in a while loop so we can keep paginating requests until
# finished.
while True:
try:
# Perform some action on each post in the collection we receive from
# Facebook.
[some_action(post=post) for post in posts["data"]]
# Attempt to make a request to the next page of data, if it exists.
posts = requests.get(posts["paging"]["next"]).json()
except KeyError:
# When there are no more pages (['paging']['next']), break from the
# loop and end the script.
break
I am working on a chatbot with Botman. I want to integrate Dialogflow's NLP so I'm calling the middleware and one of it's actions. The problem is that Botman is not hearing it. I just keep getting this error:
This is my intent's action name
This is the way I'm calling the middleware
I'm using my Client access token. I tried calling the action different names like 'input.automovil', 'automovil', (.*), but it's still failing and I haven't found enough examples.
The documentation is not updated. ApiAi is renamed as Dialogflow
Replace
use BotMan\BotMan\Middleware\ApiAi; with
use BotMan\BotMan\Middleware\Dialogflow;
and
$dialogflow = ApiAi::create('your-key')->listenForAction(); with $dialogflow = Dialogflow::create('your-key')->listenForAction();
try changing your lines 27 to 33 the the below
$botman->hears('automovil', function (BotMan $bot) {
// The incoming message matched the "my_api_action" on Dialogflow
// Retrieve Dialogflow information:
$extras = $bot->getMessage()->getExtras();
$apiReply = $extras['apiReply'];
$apiAction = $extras['apiAction'];
$apiIntent = $extras['apiIntent'];
$bot->reply($apiReply);
})->middleware($dialogflow);
I'm currently attempting to accept voice input from the user, feed it into the Bing Speech API to get text, and pass that text as a user response. I've gotten as far as receiving the text back from Bing, but I'm not sure how to send that text as a user response. I've been scouring GitHub, so any feedback is appreciated. Relevant code is below:
function(session){
var bing = new client.BingSpeechClient('mykey');
var results = '';
var wave = fs.readFileSync('./new.wav');
const text = bing.recognize(wave).then(result => {
console.log('Speech To Text completed');
console.log(result.header.lexical)
console.log('\n');
results.response = result.header.lexical;
});
}]
You should use session.send.
I recommend you to take a look to the intelligence-SpeechToText sample, where a similar scenario is being shown.
Update: Figured it out (sorta). In order to take advantage of sending this user input back, I had to use another card. Within the context of the card, I'm able to use the imBack function