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

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)

Related

React Native socket.io client connecting successfully, but emits are not received on either end

I'm trying to get communication working between a socket-io server and an iOS app. The devices connect according to both logs, but any socket.emit() actions from either the client or the server are not triggering the respective .on() event on the other end. Here is a minimal example that produces this problem.
Server code:
from aiohttp import web
import socketio
sio = socketio.AsyncServer()
app = web.Application()
sio.attach(app)
#sio.on('connect', namespace='/mp')
async def connect(sid, environ):
print("connect ", sid)
#sio.on('chat message', namespace='/mp')
async def message(sid, data):
print("message ", data)
#sio.on('disconnect', namespace='/mp')
def disconnect(sid):
print('disconnect ', sid)
if __name__ == '__main__':
web.run_app(app)
Client code (React Native app)
window.navigator.userAgent = 'ReactNative';
import React from "react"
import openSocket from "socket.io-client"
import { StyleSheet, Text, View, FlatList } from "react-native"
console.ignoredYellowBox = ["Remote debugger"]
import { YellowBox } from "react-native"
YellowBox.ignoreWarnings([
"Unrecognized WebSocket connection option(s) `agent`, `perMessageDeflate`, `pfx`, `key`, `passphrase`, `cert`, `ca`, `ciphers`, `rejectUnauthorized`. Did you mean to put these under `headers`?"
])
var app = null
var socket = openSocket("http://localhost:8080/mp", {
jsonp: false,
reconnection: true,
reconnectionDelay: 500,
reconnectionAttempts: Infinity,
transports: ["websocket"]
})
export default class App extends React.Component {
constructor(props) {
super(props)
app = this
socket.on("connect", function() {
console.log("connected")
socket.emit("message", "test")
})
}
render() {
app = this
return (
<View style={styles.container}>
<Text>Open up App.js to start working on your app!</Text>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
marginLeft:20,
marginTop: 40,
}
})
Turns out the issue was that I was sending event message to the server, but the server was listening for event chat message (I mixed up the event name and its function). Even then, server to client communication still doesn't work so I guess it's more debugging :P

Status code from Graph API after successful communication

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.

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)

Functional Test: Upload File via REST API in Grails

I am preparing Functional Test cases for my RESTful API project, using the functional test plugin of Grails.
I am unable to upload a file using the technique that works for everything else in my case.
class CreateFunctionalSpec{
final String CREATE_API = '/document-file'
def "Upload Document to temporary location"() {
File nfile = new File('test/test-data/myfile.jpg')
nfile.createNewFile()
when:
post("$RESTFUL_API_BASE_URL${CREATE_API}") {
headers['Accept'] = 'application/json'
headers['Authorization'] = authHeader()
body{
"file:nfile"
}
}
then:
assert file
}}
I am unsure how to place a file in the body, I have tried adding it as parameter but nothing works.
This code works !!!
def "Upload Document to temporary location"() {
setup:
def testDocument = new File('test/test-data/test-document.jpg')
when:
post("$RESTFUL_API_BASE_URL${BDM_CREATE_API}") {
headers['Accept'] = 'application/json'
headers['Authorization'] = authHeader()
body{
setProperty("file",testDocument)
}
}
then:
201 == response.status
def jsonData = JSON.parse response.text
jsonData["status"]=="Success"
}

Redirects in Flask/Werkzeug are not changing the URL

I am very knew to python web development, so please bear with me.
I am trying setup a very basic log-in using Flask and the below code:
#app.route('/')
def index():
if verifyLoggedIn():
someData = gatherSomeData()
return render_template('main.html', data=someData)
else:
return redirect(url_for('login'))
#app.route('/login/', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
if request.form['usr'] == user and request.form['pwd'] == password:
session['user'] = request.form['usr']
session['passwd'] = request.form['pwd']
return redirect(url_for('index'))
else:
return render_template('out.html',name=request.form['usr'])
else:
return render_template('login.html')
When I access the page by going to 'localhost:5000/', I correctly get forwarded to
'localhost:5000/login/'. After I log-in, however, the page loads 'main.html' but the url bar still shows 'localhost:5000/login/'. The problem with this, is that if I hit refresh button to get the new value of 'someData' I end up back at the log-in screen. I find that this is the case after any post action. Am I missing something very fundamental here?
Thanks to those who responded, but after much more searching, I managed to find that the answer was already on stackoverflow :p (sorry, I really did look around a lot before asking)
Url in browser not updated after call of redirect( url_for('xxx' )) in Flask with jQuery mobile
The problem was actually being caused by jquery mobile and my lack of a data-url attribute.
The following code works for me, it's basically the same as what you're doing:
from flask import Flask, request, render_template, session, redirect, url_for
app = Flask(__name__)
app.config['SECRET_KEY'] = 'sldkf'
#app.route('/')
def index():
if session['user']:
return render_template('main.html')
else:
return redirect(url_for('login'))
#app.route('/login/', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
user = 'test'
password = 'test'
if request.form['usr'] == user and request.form['pwd'] == password:
session['user'] = request.form['usr']
session['passwd'] = request.form['pwd']
return redirect(url_for('index'))
else:
return render_template('login.html')
else:
return render_template('login.html')
#app.route('/logout/', methods=['GET'])
def logout():
session['user'] = None
return redirect(url_for('login'))
if __name__ == '__main__':
app.run(debug=True)
You should check to see if the user is authenticated in your 'login' route. If so redirect to the 'index' route using return redirect(url_for('index')).