def send(self, channel, msg, text): # build our payload payload = {'message': {'text': text}} # this is a ref facebook id, temporary just for this message if URN.is_path_fb_ref(msg.urn_path): payload['recipient'] = dict( user_ref=URN.fb_ref_from_path(msg.urn_path)) else: payload['recipient'] = dict(id=msg.urn_path) url = "https://graph.facebook.com/v2.5/me/messages" params = {'access_token': channel.config[Channel.CONFIG_AUTH_TOKEN]} headers = {'Content-Type': 'application/json'} start = time.time() payload = json.dumps(payload) event = HttpEvent('POST', url, json.dumps(payload)) try: response = requests.post(url, payload, params=params, headers=headers, timeout=15) event.status_code = response.status_code event.response_body = response.text except Exception as e: raise SendException(six.text_type(e), event=event, start=start) # for now we only support sending one attachment per message but this could change in future attachments = Msg.get_attachments(msg) media_type, media_url = attachments[0] if attachments else (None, None) if media_type and media_url: media_type = media_type.split('/')[0] payload = json.loads(payload) payload['message'] = { 'attachment': { 'type': media_type, 'payload': { 'url': media_url } } } payload = json.dumps(payload) event = HttpEvent('POST', url, payload) try: response = requests.post(url, payload, params=params, headers=headers, timeout=15) event.status_code = response.status_code event.response_body = response.text except Exception as e: raise SendException(six.text_type(e), event=event, start=start) if response.status_code != 200: raise SendException("Got non-200 response [%d] from Facebook" % response.status_code, event=event, start=start) # grab our external id out, Facebook response is in format: # "{"recipient_id":"997011467086879","message_id":"mid.1459532331848:2534ddacc3993a4b78"}" external_id = None try: external_id = response.json()['message_id'] except Exception as e: # pragma: no cover # if we can't pull out our message id, that's ok, we still sent pass # if we sent Facebook a user_ref, look up the real Facebook id for this contact, should be in 'recipient_id' if URN.is_path_fb_ref(msg.urn_path): contact_obj = Contact.objects.get(id=msg.contact) org_obj = Org.objects.get(id=channel.org) channel_obj = Channel.objects.get(id=channel.id) try: real_fb_id = response.json()['recipient_id'] # associate this contact with our real FB id ContactURN.get_or_create(org_obj, contact_obj, URN.from_facebook(real_fb_id), channel=channel_obj) # save our ref_id as an external URN on this contact ContactURN.get_or_create( org_obj, contact_obj, URN.from_external(URN.fb_ref_from_path(msg.urn_path))) # finally, disassociate our temp ref URN with this contact ContactURN.objects.filter(id=msg.contact_urn).update( contact=None) except Exception as e: # pragma: no cover # if we can't pull out the recipient id, that's ok, msg was sent pass Channel.success(channel, msg, WIRED, start, event=event, external_id=external_id)