def send_postback(recipient_id, message_text, button_title, payload): log("sending postback button to {recipient}: {text}".format(recipient=recipient_id, text=message_text)) data = json.dumps({ "recipient": { "id": recipient_id }, "message": { "attachment": { "type": "template", "payload": { "template_type": "button", "text": message_text, "buttons": [ { "type": "postback", "title": button_title, "payload": payload } ] } } } }) res = send(data) return res
def on_post(self, req, resp): # endpoint for processing incoming messaging events data = json.loads(req.stream.read().decode('utf-8')) log( data ) # you may not want to log every incoming message in production, but it's good for testing if data["object"] == "page": for entry in data["entry"]: for messaging_event in entry["messaging"]: if messaging_event.get( "message"): # someone sent us a message Messaging.handle_text_message(messaging_event) if messaging_event.get( "postback" ): # user clicked/tapped "postback" button in earlier message Messaging.handle_postback_message(messaging_event) if messaging_event.get( "delivery"): # delivery confirmation pass if messaging_event.get("optin"): # optin confirmation pass resp.status = falcon.HTTP_200 resp.content_type = "text/html" resp.body = "ok"
def get_user(facebook_id): fields = "first_name,last_name,profile_pic,locale,timezone,gender" access_token = os.environ["PAGE_ACCESS_TOKEN"] r = requests.get("https://graph.facebook.com/v2.8/{user_id}?fields={fields}&access_token={access_token}" .format(user_id=facebook_id, fields=fields, access_token=access_token)) if r.status_code != 200: log("{status_code} encountered when sending Facebook data".format(status_code=r.status_code)) log(r.text) return False return r.json()
def send_message(recipient_id, message_text, quick_replies=None): log("sending message to {recipient}: {text}".format(recipient=recipient_id, text=message_text)) data = json.dumps({ "recipient": { "id": recipient_id }, "message": { "text": message_text, "quick_replies": quick_replies } }) res = send(data) return res
def get_random_task(user_id, longitude=None, latitude=None): location = "" order = "random" if longitude is not None and latitude is not None: location = "&range=0.02&longitude={longitude}&latitude={latitude}".format(longitude=str(longitude), latitude=str(latitude)) order = "location" log("Location: " + location) res = call_api("GET", "/worker/{user_id}/tasks?order={order}&limit=1{location}".format(user_id=user_id, location=location, order=order)) if not res: return False task = res[0] # Pick the only question in the list return task
def send_image(recipient_id, image_url): log("sending image to {recipient}: {image}".format(recipient=recipient_id, image=image_url)) data = json.dumps({ "recipient": { "id": recipient_id }, "message": { "attachment": { "type": "image", "payload": { "url": image_url } } } }) res = send(data) return res
def send_list(recipient_id, elements): log("sending list of {num} elements to {recipient}".format(recipient=recipient_id, num=len(elements))) data = json.dumps({ "recipient": { "id": recipient_id }, "message": { "attachment": { "type": "template", "payload": { "template_type": "list", "top_element_style": "compact", "elements": elements } } } }) res = send(data) return res
def handle_message_given_task_options(message): message_text = message["text"] if message.get("postback"): try: message_text = message["postback"] except: pass # Find digits in the string found_digits = re.findall("\d+", message_text) if len(found_digits) < 1: Facebook.send_message(message["sender_id"], "I did not understand your choice of task") return chosen_task_id = int(found_digits[0]) tasks = user_states[message["sender_id"]]["data"]["tasks"] chosen_task = tasks[chosen_task_id - 1] questions = chosen_task["questions"] task_content = chosen_task["content"] log(chosen_task) send_task(task_content, questions, message["sender_id"], chosen_task)
def call_api(method, url, data=None): r_method = api_methods.get(method.upper()) if r_method is None: log("Unknown method {method} for API call".format(method=method)) return False call_url = api_url + url r = r_method(call_url, json=data) if r.status_code != 200: log("{status_code} encountered when calling {url}".format(status_code=r.status_code, url=call_url)) log(r.text) return False return r.json()
def send(data): params = { "access_token": os.environ["PAGE_ACCESS_TOKEN"] } headers = { "Content-Type": "application/json" } log("Sending to Facebook: {data}".format(data=data)) r = requests.post("https://graph.facebook.com/v2.8/me/messages", params=params, headers=headers, data=data) if r.status_code != 200: log("{status_code} encountered when sending Facebook data".format(status_code=r.status_code)) log(r.text) return False return True
def handle_message_idle(message): sender_id = message["sender_id"] user_state = user_states[sender_id] user_id = user_state["user_id"] name = user_state["name"] # Handle giving task if message.get("coordinates") or message.get("quick_reply_payload") == "random_task" or \ message["text"] == "Random task": coordinates = message.get("coordinates", {}) task = Api.get_random_task(user_id, coordinates.get("long"), coordinates.get("lat")) if not task: Facebook.send_message( sender_id, "Unfortunately, I could not find a task for you. " "The most likely reason for this is that there are no available tasks " "at the moment. Be sure to check back later!") return questions = task["questions"] task_content = task["content"] send_task(task_content, questions, sender_id, task) # Handle giving multiple tasks elif message.get("quick_reply_payload" ) == "list_task" or message["text"] == "List of tasks": tasks = Api.get_tasks(user_id) if not tasks: Facebook.send_message( sender_id, "Sorry, something went wrong when retrieving your task") return user_state["state"] = "given_task_options" user_state["data"] = {"tasks": tasks} log(user_states) elements = [] mes = "I have " + str(len(tasks)) + " tasks for you:" for i, task in enumerate(tasks): elements.append({ "title": "Task " + str(i + 1), "subtitle": task["description"], "buttons": [{ "type": "postback", "title": "Do task " + str(i + 1), "payload": "task_" + str(i + 1) }] }) Facebook.send_message(sender_id, mes) Facebook.send_list(sender_id, elements) # Handle initial message else: # str.lower(message["text"]) in greetings: balance = Decimal(-1) user_data = Api.get_user_data(user_id) if user_data: balance = Decimal(user_data["score"]) quick_replies = [{ "content_type": "location" }, { "content_type": "text", "title": "Random task", "payload": "random_task" }, { "content_type": "text", "title": "List of tasks", "payload": "list_task" }] welcome_back_message = "" if balance < 0: pass elif balance == 0: welcome_back_message = "I see you are new here, welcome!" else: welcome_back_message = ( "Welcome back! You have earned €{balance} with us so far, good job!" .format(balance=balance)) Facebook.send_message(sender_id, "Hey " + name + "! " + welcome_back_message) Facebook.send_message( sender_id, "I can give you a random task or a list of tasks to choose from. " "If you send your location I can give you a task which can be done near you.", quick_replies)