Facebook Graph API: Send message from page - python

I have been trying to send an automated message from my Facebook page to an open conversation. I have been using Graph API's /me/messages endpoint using Page Access Token, but it doesn't seem to work.
Following is the code
def sendMessage(to_id, msg):
print(f"Sending message to {to_id}")
url = f"https://graph.facebook.com/v13.0/me/messages?access_token={page_access_token}"
payload = {
"messaging_type": "RESPONSE",
"recipient": {
"id": to_id
},
"message":{
"text": msg
}
}
res = requests.post(url, payload)
print(res.content)
After calling this function, when I print the content of the response, it shows this:
b'{"error":{"message":"(#100) param recipient must be non-empty.","type":"OAuthException","code":100,"fbtrace_id":"A4QA9xqFj9Uch12oi6KRPQb"}}'

The error message is quite straightforward.
I think you should check again your param: to_id, it could be empty or undefined/null in your case.
Further check msg if needed.

Related

Open the url with Access Token which comes in API response

I have a set of api calls which can be accessible by Access Token and I'm able to get responses from the apis but one of the responses contain URL but when I try to access it, url asks for Log in which i'm already Logged in because thats how I got Access Token.
API response:
{
"root": "some value",
"blocks": {
"some value": {
"display_name": "some display name",
"block_id": "abc123",
"view_url": "https://www.abc.come",
"web_url": "https://www.abv.com",
"type": "some type",
"id": "some id"
}
}
}
So from this response I want to access "web_url" so when i do a Get request, it asks for Log in.
So how can I access web_url without Log in ?
You can access the url from the response using the access token
access_token = "your_access_token"
web_url_response = requests.get(response['blocks']['some value']['web_url'], headers={"Authorization": "Bearer " + access_token})

Dialogflow query HTTP Request

I am trying to create a very simple chatbot using dialogflow that I can ask a question and get a fulfillment message back. I was able to use python's dialogflow library to get this working, but when I tried to change it to a regular request it did not work. Here is the working code:
import os
import dialogflow
from google.api_core.exceptions import InvalidArgument
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = PATH_TO_JSON
DIALOGFLOW_PROJECT_ID = PROJECT_ID
DIALOGFLOW_LANGUAGE_CODE = 'en'
SESSION_ID = 'me'
text_to_be_analyzed = "How are my stocks"
session_client = dialogflow.SessionsClient()
session = session_client.session_path(DIALOGFLOW_PROJECT_ID, SESSION_ID)
text_input = dialogflow.types.TextInput(text=text_to_be_analyzed, language_code=DIALOGFLOW_LANGUAGE_CODE)
query_input = dialogflow.types.QueryInput(text=text_input)
try:
response = session_client.detect_intent(session=session, query_input=query_input)
except InvalidArgument:
raise
#print(response)
print("Response:", response.query_result.fulfillment_text)
and it prints
your stocks are good
Using the request library I tried a similar setup and wrote this:
my_key = CLIENT_ACCESS_TOKEN
url = "https://api.dialogflow.com/v1/query?v=20170712"
headers = {
'Authorization': 'Bearer ' + my_key ,
'Content-Type' : 'application/json'
}
body = {
"lang": "en",
"query": "how are my stocks",
"sessionId": "me",
}
r.post(url,headers=headers,data=body).text
and I get an error:
{
"status": {
"code": 400,
"errorType": "bad_request",
"errorDetails": "Cannot parse json. Please validate your json. Code: 400"
}
}
I am getting my example from this url for the query post request. The reason I want this to work as an http request is because I would like to be able to use it in other applications and want to have a consistent way of accessing my intents. Thanks for the help!
Upon more research I found the error at this link. So the question was less about integration with dialogflow and more about making a request in python.

Reservation message in django

I am making a chatbot using a messenger called KakaoTalk.
I wrote a function that sends a message when the current request is received.
However, I can not implement the function of sending notification characters in the morning.
I need your help.
Here is my code sample.
def message(request):
json_str = ((request.body).decode('utf-8'))
received_json_data = json.loads(json_str)
content = received_json_data['content']
data_will_be_send = {
'message': {
'text': connect_apiai.get_apiai(papago.get_papago(content))
}
}
return JsonResponse(data_will_be_send)
How can I send JsonResponse without a request?

logging into the MATCHBOOK API with Python Requests

I am trying (legitimately and with the go ahead from the site)to log into the betting exchange matchbook.com through their api.
The documentation states:
To Login: https://www.matchbook.com/bpapi/rest/security/session
and
Example Request
POST /security/session
{
"username": "j_henry",
"password": "******"
}
Example Response
{
"session-token": "1418_1234567890",
"user-id": 1418,
"account": { // Same as GET /account API response.
...
}
}
I am using Requests and have the following code:
payload = {"username": "********", "password": "************"}
r = requests.post('https://www.matchbook.com/edge/rest/security/session', data=payload)
print (r.status_code)
I get error code 415? I must be getting the wrong type of response??
I have looked at a lot of very similar posts on here, and I am about to ask matchbook's team, but before I do has anybody got any ideas?
You might have to specify Content-Type, try to add a header to tell the server it's JSON formatted:
payload = {"username": "********", "password": "************"}
headers = {"Content-Type": "application/json;"}
r = requests.post('https://www.matchbook.com/edge/rest/security/session', data=payload, headers=headers)
print (r.status_code)
It does not appear from your code that you are JSON-encoding your payload. The endpoint is likely expecting JSON.
Try this:
payload = '{"username": "********", "password": "************"}'

Facebook Messenger with Flask

I'm trying to get the FB messenger API working using Python's Flask, adapting the following instructions: https://developers.facebook.com/docs/messenger-platform/quickstart
So far, things have been going pretty well. I have verified my callback and am able to receive the messages I send using Messenger on my page, as in the logs in my heroku server indicate the appropriate packets of data are being received by my server. Right now I'm struggling a bit to send responses to the client messenging my app. In particular, I am not sure how to perform the following segment from the tutorial in Flask:
var token = "<page_access_token>";
function sendTextMessage(sender, text) {
messageData = {
text:text
}
request({
url: 'https://graph.facebook.com/v2.6/me/messages',
qs: {access_token:token},
method: 'POST',
json: {
recipient: {id:sender},
message: messageData,
}
}, function(error, response, body) {
if (error) {
console.log('Error sending message: ', error);
} else if (response.body.error) {
console.log('Error: ', response.body.error);
}
});
}
So far, I have this bit in my server-side Flask module:
#app.route('/', methods=["GET", "POST"])
def chatbot_response():
data = json.loads(req_data)
sender_id = data["entry"][0]["messaging"][0]["sender"]["id"]
url = "https://graph.facebook.com/v2.6/me/messages"
qs_value = {"access_token": TOKEN_OMITTED}
json_response = {"recipient": {"id": sender_id}, "message": "this is a test response message"}
response = ("my response text", 200, {"url": url, "qs": qs_value, "method": "POST", "json": json_response})
return response
However, running this, I find that while I can process what someone send my Page, it does not send a response back (i.e. nothing shows up in the messenger chat box). I'm new to Flask so any help would be greatly appreciated in doing the equivalent of the Javascript bit above in Flask.
Thanks!
This is the code that works for me:
data = json.loads(request.data)['entry'][0]['messaging']
for m in data:
resp_id = m['sender']['id']
resp_mess = {
'recipient': {
'id': resp_id,
},
'message': {
'text': m['message']['text'],
}
}
fb_response = requests.post(FB_MESSAGES_ENDPOINT,
params={"access_token": FB_TOKEN},
data=json.dumps(resp_mess),
headers = {'content-type': 'application/json'})
key differences:
message needs a text key for the actual response message, and you need to add the application/json content-type header.
Without the content-type header you get the The parameter recipient is required error response, and without the text key under message you get the param message must be non-empty error response.
This is the Flask example using fbmq library that works for me:
echo example :
from flask import Flask, request
from fbmq import Page
page = fbmq.Page(PAGE_ACCESS_TOKEN)
#app.route('/webhook', methods=['POST'])
def webhook():
page.handle_webhook(request.get_data(as_text=True))
return "ok"
#page.handle_message
def message_handler(event):
page.send(event.sender_id, event.message_text)
In that scenario in your tutorial, the node.js application is sending an HTTP POST request back to Facebook's servers, which then forwards the content on to the client.
So far, sounds like your Flask app is only receiving (AKA serving) HTTP requests. The reason is that that's what the Flask library is all about, and it's the only thing that Flask does.
To send an HTTP request back to Facebook, you can use any Python HTTP client library you like. There is one called urllib in the standard library, but it's a bit clunky to use... try the Requests library.
Since your request handler is delegating to an outgoing HTTP call, you need to look at the response to this sub-request also, to make sure everything went as planned.
Your handler may end up looking something like
import json
import os
from flask import app, request
# confusingly similar name, keep these straight in your head
import requests
FB_MESSAGES_ENDPOINT = "https://graph.facebook.com/v2.6/me/messages"
# good practice: don't keep secrets in files, one day you'll accidentally
# commit it and push it to github and then you'll be sad. in bash:
# $ export FB_ACCESS_TOKEN=my-secret-fb-token
FB_TOKEN = os.environ['FB_ACCESS_TOKEN']
#app.route('/', method="POST")
def chatbot_response():
data = request.json() # flasks's request object
sender_id = data["entry"][0]["messaging"][0]["sender"]["id"]
send_back_to_fb = {
"recipient": {
"id": sender_id,
},
"message": "this is a test response message"
}
# the big change: use another library to send an HTTP request back to FB
fb_response = requests.post(FB_MESSAGES_ENDPOINT,
params={"access_token": FB_TOKEN},
data=json.dumps(send_back_to_fb))
# handle the response to the subrequest you made
if not fb_response.ok:
# log some useful info for yourself, for debugging
print 'jeepers. %s: %s' % (fb_response.status_code, fb_response.text)
# always return 200 to Facebook's original POST request so they know you
# handled their request
return "OK", 200
When doing responses in Flask, you have to be careful. Simply doing a return statement won't return anything to the requester.
In your case, you might want to look at jsonify(). It will take a Python dictionary and return it to your browser as a JSON object.
from flask import jsonify
return jsonify({"url": url, "qs": qs_value, "method": "POST", "json": json_response})
If you want more control over the responses, like setting codes, take a look at make_response()

Categories