Example #1
0
    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)