Passing Thread Control Facebook messenger bot - facebook

I am trying the Handover Protocal for my bot but I am not able to get
about passing thread control though I read the documentation still, I am confused
curl -X POST -H "Content-Type: application/json" -d '{
"recipient":{"id":"<PSID>"},
"target_app_id":123456789,
"metadata":"String to pass to secondary receiver app"
}' "https://graph.facebook.com/v2.6/me/pass_thread_control?access_token=<PAGE_ACCESS_TOKEN>"
Example pass_thread_control Event
{
"sender":{
"id":"<PSID>"
},
"recipient":{
"id":"<PAGE_ID>"
},
"timestamp":1458692752478,
"pass_thread_control":{
"new_owner_app_id":"123456789",
"metadata":"Additional content that the caller wants to set"
}
}
I am trying to know what is PSID here and what can be target_app_id.
can anyone help me with proper example.

It took me a bit to figure out, so I totally understand your frustration! There isn't adequate documentation when it comes to working with the handover protocol.
My current use case is a bot that offers the option to speak to a representative if it's unable to understand the user. This is done through the use of a postback button, which means the handover is activated by the user. After the user clicks on the button, the following code is run:
graph.setAccessToken(<YOUR_APP_ACCESS_TOKEN>);
graph.setAppSecret(<YOUR_APP_SECRET>);
graph.setVersion("2.12");
graph.post(
`me/pass_thread_control?access_token=${functions.config().messenger.token}`,
handoverMessage,
(err, res) => {
if(err) {
console.log('HANDOVER ERROR:', err);
return;
}
console.log('HANDOVER SUCCESS:', res);
});
The handoverMessage variable is where you will place the psid and target_app_id:
let handoverMessage = {
"recipient": {
"id": <PSID>
},
"target_app_id": <YOUR_TARGET_APP_ID>
}
Calling this code will handover the control of the conversation to whatever your target_app_id is.
If you're wondering what 'graph' is, it is a node package called 'fbgraph' that I've found very useful when dealing with the facebook graph api. It's certainly not the only wrapper and there are likely better packages out there, but it has worked for me up to now.

Related

Watson Assistant API V2 "manages the context automatically" - more details?

This is a question about Watson Assistant API V1/V2 difference. The doc says like this:
Note that if your app uses the v1 API, it communicates directly with the dialog skill, bypassing the orchestration and state-management capabilities of the assistant. This means that your application is responsible for maintaining state information. This is done using the context, an object that is passed back and forth between your application and the Watson Assistant service. Your application must maintain the context by saving the context received with each response and sending it back to the service with each new message request.
An application using the v2 API can also use the context to access and store persistent information, but the context is maintained automatically (on a per-session basis) by the assistant.
It seems that in V2, "the context is maintained automatically by the assistant". What does this mean exactly ? If I'd like to pass some data to the dialog flow, I might use context on "/message". Is is allowed in V2?( yes, it seems.) Then in V1 days, I have to receive context from responses and send it back on every request. Does assistant also send the context back in V2? What should my client-app do in V2? Any detailed info is welcomed ..Thanks.
Answering your second question first - If you check the API docs for Watson Assistant V2 here, there is a MessageContext object in the response with Global Context and skill specific context values.
You also have a sample Request where you can manually pass the context (both global and user-defined)
curl -u "apikey:{apikey}" -X POST -H "Content-Type:application/json" -d "{\"input\": {\"text\": \"Hello\"}, \"context\": {\"global\": {\"system\": {\"user_id\": \"my_user_id\"}}}}" "https://gateway.watsonplatform.net/conversation/api/v2/assistants/{assistant_id}/sessions/{session_id}/message?version=2018-11-08"
From the client side, you can use this code
service.message({
assistant_id: '{assistant_id}',
session_id: '{session_id}',
input: {
'message_type': 'text',
'text': 'Hello'
},
context: {
'global': {
'system': {
'user_id': 'my_user_id'
}
},
"skills": {
"main skill": {
"user_defined": {
"my_result_variable": "result_value"
}
}
}
}
}
Reference link
Check the API Methods Summary to understand what is supported in V2 as of today.
There is a new concept in V2 called Session. A session is used to send user input to a skill and receive responses. It also maintains the state of the conversation which is Context automatically for you.
V2 API as of today supports Runtime Methods, methods that enable a client application to interact with (but not modify) an existing assistant or skill. You can use these methods to develop a user-facing client that can be deployed for production use, an application that brokers communication between an assistant and another service (such as a chat service or back-end system), or a testing application.
The complete cURL example that works for me
curl -u "apikey:<API_KEY>" -X POST -H "Content-Type:application/json" -d "{
\"input\": {
\"text\": \"What's the time?\",
\"options\": {
\"alternate_intents\": true,
\"debug\": true,\"return_context\": true
}
},
\"context\": {
\"global\": {
\"system\": {
\"user_id\": \"derp\",\"turn_count\":1
}
}
},
\"skills\": {
\"main_skill\":{\"user_defined\": {
\"chosen_service\": \"dental\"
}}
}
}" "https://gateway.watsonplatform.net/assistant/api/v2/assistants/{ASSISTANT_ID}/sessions/{SESSION_ID}/message?version=2018-11-08"
for session ID, run this command
curl -u "apikey:<API_KEY>" -X POST "https://gateway.watsonplatform.net/assistant/api/v2/assistants/{ASSISTANT_ID}/sessions?version=2018-11-08"
The response includes user_defined skill context
{"output":{"generic":[{"response_type":"text","text":"Hey ! how are you today? Let me know if you need any help or get stuck looking for information."}],"debug":{"nodes_visited":[{"dialog_node":"node_6_1475611948267","title":null,"conditions":"conversation_start"}],"log_messages":[],"branch_exited":true,"branch_exited_reason":"completed"},"intents":[{"intent":"General_Greetings","confidence":0.32179955244064334},{"intent":"General_Jokes","confidence":0.296911633014679},{"intent":"goodbye","confidence":0.2852578103542328},{"intent":"General_Ending","confidence":0.2513303637504578},{"intent":"off_topic","confidence":0.24435781836509707},{"intent":"select_detail","confidence":0.24206179082393647},{"intent":"list_options","confidence":0.22829059958457948},{"intent":"still-here","confidence":0.22606439888477325},{"intent":"select_service","confidence":0.22488142400979996},{"intent":"General_Security_Assurance","confidence":0.2210852071642876}],"entities":[]},"context":{"global":{"system":{"turn_count":1,"user_id":"derp"}},"skills":{"main skill":{"user_defined":{"chosen_service":"dental"}}}}}
Thanks, #Vidyasagar Machupalli #data_henrik.
(I created "answer" section to paste the images below .)
1) Now it worked fine. I set the variable reference in dialog editor like this.
Then I post user-variable in context like this.
context={
"skills": {
"main skill": {
"user_defined": {
"myname": "ishida"
}
}
}
}
then the response was:
{'output': {'generic': [{'response_type': 'text', 'text': 'Hi, ishida .'}], 'intents': [], 'entities': []}}
It seems that "skills"->"main skill"->"user_defined" section is a case-sensitive / FIXED keyword.
From what I see, if I change one of them, I cannot read the variable on dialog editor.
2) I also found the documentation issue. The starting point of my question was : "API V2 doc says that I should use "skills" entry to handle the user variables, but no detailed info more than that .. ". #Vidyasagar Machupalli says "As per the V2 API documentation, user_defined is arbitrary variables ".. but I cannot find the paragraph in the API doc.
Then I found that
a) when I select "curl" tab, "user_defined" explanation appears.
b) when I select other(Java/Node/Python) tab, no explanation appears.
I knew that the info was not there as I refered the "Python" tab. I'd appreciate this be fixed soon to avoid same confusion. And I think that the fact of "skills->main skill->user_defined section is a case-sensitive / FIXED keyword" should be noted, as it is not clear in the current description. Thanks!

Setting up daily notifications for a Google Assistant App via DialogFlow

I apologize if this is a stupid question. I have been spending quite a while trying to get daily updates for my google assistant app to work (found at https://developers.google.com/actions/assistant/updates/daily).
I get the prompt on my phone to initiate the daily updates because my server gets the configure updates event. However, I think I am not sending the correct response back because I just get the error "UnparseableJsonResponse: API Version 2: Failed to parse JSON response string with 'INVALID_ARGUMENT' error: ": Cannot find the field."
Usually, my server just responds with a JSON in the structure:
return{
"speech": 'sample text',
"DisplayText": 'sample text',
"source": "sample"
}
However, according to the Google documentation, I need to return the JSON
{
"conversationToken":"",
"expectUserResponse":true,
"expectedInputs":[
{
"inputPrompt":{
"initialPrompts":[
{
"textToSpeech":"PLACEHOLDER_FOR_REGISTER_UPDATE"
}
],
"noInputPrompts":[
]
},
"possibleIntents":[
{
"intent":"actions.intent.REGISTER_UPDATE",
"inputValueData":{
"":"",
"intent":"tell.tip",
"triggerContext":{
"timeContext":{
"frequency":"DAILY"
}
},
}
}
]
}
]
}
I tried returning this exact JSON but as I suspected it's not that simple. I'm not sure how to adapt this format to one that dialogflow expects. Any help would be much appreciated. Note that I'm looking at the response structure at https://dialogflow.com/docs/fulfillment. I also considered the actions on google structure too at https://developers.google.com/actions/reference/rest/Shared.Types/AppResponse. I'm just very confused on how to do this since the guide is mostly suited for people using node js and the SDK.

How to make a correct HTTP Post request with Meteor.js to Domino Datalab's Rest API

In my server side Meteor.js method, I'm trying to correctly make a request to Domino Data Lab's (DDL) Rest API.
DDL provides a platform for makes it possible to call a data science model via a REST API. Their documentation on this API is here:
http://support.dominodatalab.com/hc/en-us/articles/204173149-API-Endpoints-Model-Deployment
But, I doubt the documentation is helpful because I think an experienced Meteor developer will see the request examples in CURL or Python and know how to get the params correctly into the JSON format that DDL is looking for.
Domino Datalab provides the instructions for 4 methods, but not for Meteor.js. I'll post the examples for Curl and Python:
Examples
CURL Request
curl -v -X POST \
https://app.dominodatalab.com/MYURL \
-H 'Content-Type: application/json' \
-H 'X-Domino-Api-Key: YOUR_API_KEY' \
-d '{"parameters": [ "FOO", "BAR", "ETC"]}'
Python Request
import requests
response =
requests.post("https://app.dominodatalab.com/MYURL",
headers = {
"X-Domino-Api-Key": "YOUR_API_KEY",
"Content-Type": "application/json"
},
json = {
"parameters": ["FOO", "BAR", "ETC"]
}
)
print(response.status_code)
print(response.headers)
print(response.json())
I've tried a few different ways (using both the dataand paramsoptions) based on the documentation for Meteor, but here is my best try:
Meteor.methods({
score_app: function(){
var test = HTTP.call("POST", "https://app.dominodatalab.com/MYURL",
{ headers: {
"Content-Type": "application/json",
"X-Domino-Api-Key": "YOUR_API_KEY"
},
// This is where the problem is. Have tried multiple syntax versions and tried using the `params`options for the HTTP call instead of `data`
data: {'params': [143]
}
},
function (error, result) {
// The syntax below should be if not an error, log the result (for testing etc, otherwise, log "http post error". I may have incorrectly switched this around, but the original version I got from an online example had it the console.log statements in the reverse order.
if (!error) {
console.log(result);
} else{
console.log("http post error");
};
});
}
});
I've been using this entry in the Meteor documentation to send the parameters as a JSON object correctly:
http://docs.meteor.com/api/http.html
The connection to Data Domino Lab (DDL) is made correctly, but it doesn't recognize the parameters correctly because the request is not sending the parameters in the JSON format that DDL wants.
result: 'You must provide a JSON object in your request body
with a parameters key containing an array of parameters.' } }
I'm on the DDL free plan, but I will email a link to this question to their tech support. This is a niche issue, but it could be important to Meteor.js developers in the future wishing to link to a data science model in DDL.
I'm one of the engineers at Domino who has worked on the API Endpoints feature recently. The error
message you're getting means that the JSON object you're sending to our server doesn't contain the
key "parameters". I'm not an expert in Meteor, but it looks like you're using "params" where you
should use "parameters" in your JSON payload.
Around line 9 can you change...
{'data': {'params': [143]}}
to
{'data': {'parameters': [143]}}
If my understanding of your code is correct, that'll work correctly.
Cheers!

IBM Watson Tone Analyzer service credentials

I have been trying to run a query against IBM Watson Tone Analyzer service and keep getting an error that my service credentials are not recognized.
I am sure that I am entering the correct credentials. Here are the steps that I took to get the service credentials:
Signed up with bluemix.net.
Clicked on Tone Analyzer icon.
Clicked on service credentials.
Clicked on add credentials and used the credentials that were obtained from this step.
I followed these steps multiple times but keep running into same error:
watson_developer_cloud.watson_developer_cloud_service.WatsonException: Unauthorized: Access is denied due to invalid credentials
I would really appreciate any insights here.
I was just able to run a test without any errors. Here are the steps I took:
1. Created a new IBM Watson Tone Analyzer instance:
2. Looked at the service credentials page:
(I've changed the username to "abcuser" and the password to "abcpass" for this example.)
3. I ran this curl command to test out my service:
curl -u "{username}":"{password}" -H "Content-Type: application/json" -d "{\"text\": \"Hi Team, I know the times are difficult! Our sales have been disappointing for the past three quarters for our data analytics product suite. We have a competitive data analytics product suite in the industry. But we need to do our job selling it! \"}" "https://gateway.watsonplatform.net/tone-analyzer/api/v3/tone?version=2016-05-19"
so replacing the username and password, I get...
curl -u "abcuser":"abcpass" -H "Content-Type: application/json" -d "{\"text\": \"Hi Team, I know the times are difficult! Our sales have been disappointing for the past three quarters for our data analytics product suite. We have a competitive data analytics product suite in the industry. But we need to do our job selling it! \"}" "https://gateway.watsonplatform.net/tone-analyzer/api/v3/tone?version=2016-05-19"
4. Finally, I got this response:
{
"document_tone":{
"tone_categories":[
{
"tones":[
{
"score":0.455891,
"tone_id":"anger",
"tone_name":"Anger"
},
{
"score":0.156707,
"tone_id":"disgust",
"tone_name":"Disgust"
},
{
"score":0.17315,
"tone_id":"fear",
"tone_name":"Fear"
},
{
"score":0.190073,
"tone_id":"joy",
"tone_nam e":"Joy"
},
{
"score":0.291627,
"tone_id":"sadness",
"tone_name":"Sadness"
}
],
"category_id":"emotion_tone",
"category_name":"Emotion Tone"
},
{
"tones":[
{
"score":0.459,
"tone_id":"analytical",
"tone_name":"Analytical"
},
{
"score":0.0,
"tone_id":"confident",
"tone_name":"Confide nt"
},
{
"score":0.0,
"tone_id":"tentative",
"tone_name":"Tentative"
}
],
"category_id":"language_tone",
"category_name":"Language Tone"
},
{
"tones":[
{
"score":0.03,
"tone_id":"openness_big5",
"tone_name":"Openness"
},
{
"score":0.188,
"tone_id":"conscientiousness_big5",
"tone_nam e":"Conscientiousness"
},
{
"score":0.405,
"tone_id":"extraversion_big5",
"tone_name":"Extraversion"
},
{
"score":0.879,
"tone_id":"agreeableness_big5",
"tone_name":"Agreeableness"
},
{
"score":0.962,
"tone_id":"emotional_range_big5",
"tone_name":"Emotional Range"
}
],
"category_ id":"social_tone",
"category_name":"Social Tone"
}
]
}
}
Edit:
If you are having trouble with the Python SDK, try this:
import json
from watson_developer_cloud import ToneAnalyzerV3Beta
tone_analyzer = ToneAnalyzerV3Beta(
url='https://gateway.watsonplatform.net/tone-analyzer/api',
username='USERNAME',
password='PASSWORD',
version='2016-02-11')
print(json.dumps(tone_analyzer.tone(text='I am very happy'), indent=2))
From your post above it looks you are doing the right thing with credentials, but trying to use them against a Beta instance of Tone Analyzer service.
As some background to understand any comments below: Tone Analyzer became "GA" on May 20th. Previously, it was "Beta". The Beta plan has URL https://gateway.watsonplatform.net/tone-analyzer-beta/api, while GA uses .../tone-analyzer/api (no -beta). Additionally if you are doing Python, there are two wrappers: ToneAnalyzerV3Beta (Beta) and ToneAnalyzerV3 (GA). Since we are still transitioning, some people still use existing instances of Beta plans, and also wrappers for Beta still exist.
Most importantly, credentials for the Beta plan will not work in GA, and vice versa.
That said, you need to make sure you are consistently using the GA or "standard" plan everywhere:
In your app, bind a "Tone Analyzer" (not Beta) plan.
Make sure the API URL contains /tone-analyzer/api (no -beta)
In the wrapper (python, node, java, or your URL if you did your own), use the "GA" (anything without "Beta" suffix).
Another detail (which wrappers will handle for you transparently) is that ?version argument is 2016-05-19 for the last API version. You should be using this one to get the latest features...
Joe's answer is very detailed about the process, just make sure you distinguish this Beta vs GA thing. Please add another comment if you have more questions. I hope this helps!

Get Reactions using the Github api

Github issues may contain "reactions" for quite a while (as described here: https://github.com/blog/2119-add-reactions-to-pull-requests-issues-and-comments)
I would like to receive that information using the Github api, but there doesn't seem to be anything like that when getting an issue e.g.
api.github.com/repos/twbs/bootstrap/issues/19575
that information does not seem to be inside that response. Also, I did not find another API call that could retrieve that information. How to get those "reactions"?
This is now possible, being the preview state (meaning, you have to pass a custom Accept header in the request). Check out the GitHub API documentation page
Example
$ curl -H 'Accept: application/vnd.github.squirrel-girl-preview' https://api.github.com/repos/twbs/bootstrap/issues/19575/reactions
[
{
"id": 257024,
"user_id": 947110,
"content": "+1"
},
...
{
"id": 888868,
"user_id": 1889800,
"content": "+1"
}
]
The endpoint looks like this:
GET /repos/:owner/:repo/issues/:number/reactions
You can even pass a content parameter (querystring) indicating what kind of reaction you want to retrieve.