Status code from Graph API after successful communication - facebook

my Facebook messenger based Echo-bot gives a wrong status code. Though the end user(admin until now) receives the accurate echoed message, the feedback my webhook receives gives from Graph API is:
{"error":{"message":"(#100) No matching user found","type":"OAuthException","code":100,"error_subcode":2018001,"fbtrace_id":"Fan1swU4dF8"}}
Even after much reviewing and surfing, I haven't been able to find out the problem with my webhook code.Below it is:
import os, sys
import requests
from flask import Flask, request
import json
from random import random, choice
page_access_token="page_access_code"
chatbot=Flask(__name__)
#chatbot.route('/', methods=['GET'])
def verify():
print("Handling verification...")
if request.args.get('hub.verify_token', '')=='verify_token':
print("Verified!!")
return request.args.get("hub.challenge",'')
else:
print("Wrong request!!")
return "error!!"
#chatbot.route('/', methods=['POST'])
def webhook():
data=request.get_json()
log(data)
if data["object"]=="page":
for entry in data["entry"]:
for things in entry["messaging"]:
if things.get("message"):
s_id= things["sender"]["id"]
r_id= things["recipient"]["id"]
log("Sender id:"+ s_id)
log("Receiver id: "+ r_id)
try:
messaging_text= things["message"]["text"]
send_message(s_id, str(messaging_text))
except:
send_message(s_id, "Sorry!! Couldn't understand that..")
if things.get("delivery"):
log("message delivered..")
elif things.get("optin"):
pass
elif things.get("postback"):
pass
return 'ok', 200
def send_message(r_id, messaging_text):
r_id=str(r_id)
log("sending message to {recipient}: {text}".format(recipient=r_id, text=messaging_text))
params = {
"access_token": page_access_token
}
headers = {
"Content-Type": "application/json"
}
data = json.dumps({
"recipient": {
"id": r_id
},
"message": {
"text": str(messaging_text)
}
})
r = requests.post("https://graph.facebook.com/v2.12/me/messages", params=params, headers=headers, data=data)
if r.status_code != 200:
log(r.status_code)
log(r.text)
def log(message):
print(message)
sys.stdout.flush()
if __name__=="__main__":
chatbot.run(debug=True, port=5000)
PS. I am a noob so a proper description or a link will be really helpful for me to know the flaw.

Related

facebook messenger curl request returns <Response [400]>

I am new to the messenger API, I want to send a message using a curl post request, this is my code:
import requests
ACCESS_TOKEN = an Active access token
fb_url = "https://graph.facebook.com/v10.0/me/messages"
data = {
'recipient': '{"id":4098757906843152}',
"message": {
"text": "hello, world!"
},
"messaging_type": "MESSAGE_TAG",
"tag": "ACCOUNT_UPDATE"
}
params = {'access_token': ACCESS_TOKEN}
resp = requests.post(fb_url, params=params, data=data)
print(resp)
unfortunately, I got this message <Response [400]>
any help would be appreciated
You need to change data to json.
See https://stackoverflow.com/a/26344315/603756
Starting with Requests version 2.4.2, you can use the json= parameter (which takes a dictionary) instead of data= (which takes a string) in the call
import requests
ACCESS_TOKEN = '<access_token>'
fb_url = 'https://graph.facebook.com/v10.0/me/messages'
data = {
'recipient': '{"id":<psid>}',
"message": {
"text": "hello, world!"
}
}
params = {'access_token': ACCESS_TOKEN}
resp = requests.post(fb_url, json=data, params=params)
print(resp)

Groovy rest client without libraries

I am using a rest client to do Post
My code is
def postRequest() {
def message = "{ \"fields\": { \"project\": { \"id\": \"001\" },\"summary\": \"Test Issue For Jira Integration\",\"description\": \"Creating of an issue for for projects and issue types using the REST API\", \"issuetype\": { \"id\": \"5\" } }}"
// POST
def post = new URL("https://jira/rest/api/latest/issue").openConnection();
//def message = '{"message":"this is a message"}'
post.setRequestMethod("POST")
String userpass = "user:pass" ;
String basicAuth = "Basic " + new String(Base64.getEncoder().encode(userpass.getBytes()));
post.setRequestProperty ("Authorization", basicAuth);
post.setDoOutput(true)
post.setRequestProperty("Content-Type", "application/json")
post.getOutputStream().write(message.getBytes("UTF-8"));
def postRC = post.getResponseCode();
println(postRC);
if(postRC.equals(201)) {
println(post.getInputStream().getText());
}else
{
println(post.getInputStream().getText());
print(postRC)
}
}
I am getting 400 error code , where its getting wrong
I am successfully able to do the get request with URL
400 = bad request.
it means server tried to validate your post data and it's wrong.
usually this response contains body with explanation...
for 400+ status codes the body comes through getErrorStream() and not through getInputStream()
So, I would do it like this:
def postRequest(url, message) {
def post = new URL(url).openConnection();
//def message = '{"message":"this is a message"}'
post.setRequestMethod("POST")
String userpass = "user:pass" ;
String basicAuth = "Basic " + userpass.getBytes("UTF-8").encodeBase64()
post.setRequestProperty("Authorization", basicAuth);
post.setRequestProperty("Content-Type", "application/json")
post.setDoOutput(true)
if( !(message instanceof String) )message = new groovy.json.JsonBuilder(message).toPrettyString()
post.getOutputStream().write(message.getBytes("UTF-8"))
def response=[:]
response.code = post.getResponseCode()
response.message = post.getResponseMessage()
if( response.code>=400 ){
try{
response.body = post.getErrorStream()?.getText("UTF-8")
}catch(e){}
}else{
response.body = post.getInputStream()?.getText("UTF-8")
}
assert response.code in [200,201] : "http call failure ${response.code}: ${ response.body ?: response.message }"
return response
}
def msg = [
fields: [
project : [ id: "001" ],
summary : "Test Issue For Jira Integration",
description : "Creating of an issue for for projects and issue types using the REST API",
issuetype : [ id: "5" ]
]
]
def r = postRequest("http://httpbin.org/post", msg)
println r
The issue was related to certificate , I have to bypass the certificate validation and its working fine. Since both the application are under same network and behind same company's firewall , I have bypass the certificate validations.
Adding the skipping certificate validation part to the above code is working for me

scheduling facebook chatbot to speak at a certain time of the day in Flask

Below an chatbot app; the app is working well and the bot answer maybe to every message; i would like the chat bot to speak to the user everyday at 3pm; i use "schedule" at the end of the code to start the function hello;
The all thing just does not work and i don't get any error; the python is loading infinitely;
from what i understand, there would be 2 infinite loop, the one for python and the one for scheduling; So would i need to use concurrency or something like this ?
from flask import Flask, request
import requests
import time
import schedule
from datetime import datetime
app = Flask(__name__)
FB_API_URL = 'https://graph.facebook.com/v2.6/me/messages'
VERIFY_TOKEN = "blabla"
PAGE_ACCESS_TOKEN = "blabla"
def Hello(message):
return "Hello, how are you doing today '{}'".format(message)
def get_bot_response(message):
"""this is a dummy response to what the user says."""
return "maybe '{}'".format(message)
def verify_webhook(req):
if req.args.get("hub.verify_token") == VERIFY_TOKEN:
return req.args.get("hub.challenge")
else:
return "incorrect"
def respond(sender, message):
response = get_bot_response(message)
send_message(sender, response)
def is_user_message(message):
"""Check if the message is a message from the user"""
return (message.get('message') and
message['message'].get('text') and
not message['message'].get("is_echo"))
#app.route("/webhook",methods=['GET','POST'])
def listen():
"""This is the main function flask uses to
listen at the `/webhook` endpoint"""
if request.method == 'GET':
return verify_webhook(request)
if request.method == 'POST':
payload = request.json
event = payload['entry'][0]['messaging']
for x in event:
if is_user_message(x):
text = x['message']['text']
sender_id = x['sender']['id']
respond(sender_id, text)
return "ok"
def send_message(recipient_id, text):
"""Send a response to Facebook"""
payload = {
'message': {
'text': text
},
'recipient': {
'id': recipient_id
},
'notification_type': 'regular'
}
auth = {
'access_token': PAGE_ACCESS_TOKEN
}
response = requests.post(
FB_API_URL,
params=auth,
json=payload
)
return response.json()
if __name__ == "__main__":
app.run(port=5000)
schedule.every().sunday.at("15:00").do(hello)

How to validate response in Postman?

I am trying to validate response body including errors in postman. How can I validate the response and text below?
{
"responseHeader": {
"publisherId": "12345",
"responseId": "abbcb15d79d54f5dbc473e502e2242c4abbcb15d79d54f5dbc473e502e224264",
"errors": [
{
"errorCode": "1004",
"errorMessage": "XXXX Not Found"
}
]
}
}
These are my tests which are failing:
tests['response json contains responseHeader'] = _.has(responseJSON, 'responseHeader');
tests['response json contains errors'] = _.has(responseJSON, 'responseHeader.publisherId');
tests["Response has publisher id"] = responseJSON.publisherId === 10003;
In the "Test" tab, parse your response body into an object, then use JavaScript to perform your tests.
var data = JSON.parse(responseBody);
tests["publisherId is 12345"] = data.responseHeader.publisherId === "12345";
Take a look at the test examples at the Postman site:
https://www.getpostman.com/docs/postman/scripts/test_scripts
https://www.getpostman.com/docs/postman/scripts/test_examples

Is there a Python port for the new FB Messenger webhook?

Couldn't find anything in python for FB Messenger webhook quickstart page. (https://developers.facebook.com/docs/messenger-platform/quickstart)
I went ahead and ported it myself. Figured I should share the riches. This snippet response to every message with " to you!":
import json
import requests
from django.views.decorators.csrf import csrf_exempt
FB_MESSENGER_ACCESS_TOKEN = "<Your Access Token>"
def respond_FB(sender_id, text):
json_data = {
"recipient": {"id": sender_id},
"message": {"text": text + " to you!"}
}
params = {
"access_token": FB_MESSENGER_ACCESS_TOKEN
}
r = requests.post('https://graph.facebook.com/v2.6/me/messages', json=json_data, params=params)
print(r, r.status_code, r.text)
#this allows the requst to come in without requiring CSRF token
#csrf_exempt
def fb_webhook(request):
if request.method == "GET":
if (request.GET.get('hub.verify_token') == 'this_is_a_verify_token_created_by_sean'):
return HttpResponse(request.GET.get('hub.challenge'))
return HttpResponse('Error, wrong validation token')
if request.method == "POST":
body = request.body
print("BODY", body)
messaging_events = json.loads(body.decode("utf-8"))
print("JSON BODY", body)
sender_id = messaging_events["entry"][0]["messaging"][0]["sender"]["id"]
message = messaging_events["entry"][0]["messaging"][0]["message"]["text"]
respond_FB(sender_id, message)
return HttpResponse('Received.')
And here is the FB Messenger Chatbot port on Gist
I've written a Python client for Facebook Messenger Platform: messengerbot
This is the python sample 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)