Пример #1
0
    def form_valid(self, form):
        org = self.request.user.get_org()

        cleaned_data = form.cleaned_data
        api_key = cleaned_data['api_key']
        api_secret = cleaned_data['api_secret']
        access_token = cleaned_data['access_token']
        access_token_secret = cleaned_data['access_token_secret']

        twitter = TembaTwython(api_key, api_secret, access_token,
                               access_token_secret)
        account_info = twitter.verify_credentials()
        handle_id = account_info['id']
        screen_name = account_info['screen_name']

        config = {
            'handle_id': handle_id,
            'api_key': api_key,
            'api_secret': api_secret,
            'access_token': access_token,
            'access_token_secret': access_token_secret,
            Channel.CONFIG_CALLBACK_DOMAIN: org.get_brand_domain(),
        }

        self.object = Channel.create(org,
                                     self.request.user,
                                     None,
                                     self.channel_type,
                                     name="@%s" % screen_name,
                                     address=screen_name,
                                     config=config)

        return super(ClaimView, self).form_valid(form)
Пример #2
0
    def deactivate(self, channel):
        config = channel.config_json()
        client = TembaTwython(config['api_key'], config['api_secret'],
                              config['access_token'],
                              config['access_token_secret'])

        client.delete_webhook(config['webhook_id'])
Пример #3
0
 def deactivate(self, channel):
     config = channel.config
     if "webhook_id" in config:
         client = TembaTwython(config["api_key"], config["api_secret"],
                               config["access_token"],
                               config["access_token_secret"])
         client.delete_webhook(config["env_name"], config["webhook_id"])
Пример #4
0
        def clean(self):
            cleaned_data = super(ClaimView.Form, self).clean()
            api_key = cleaned_data.get('api_key')
            api_secret = cleaned_data.get('api_secret')
            access_token = cleaned_data.get('access_token')
            access_token_secret = cleaned_data.get('access_token_secret')

            org = self.request.user.get_org()

            if api_key and api_secret and access_token and access_token_secret:
                twitter = TembaTwython(api_key, api_secret, access_token,
                                       access_token_secret)
                try:
                    user = twitter.verify_credentials()

                    # check there isn't already a channel for this Twitter account
                    if org.channels.filter(channel_type=self.channel_type.code,
                                           address=user['screen_name'],
                                           is_active=True).exists():
                        raise ValidationError(
                            _("A Twitter channel already exists for that handle."
                              ))

                except TwythonError:
                    raise ValidationError(
                        _("The provided Twitter credentials do not appear to be valid."
                          ))

            return cleaned_data
Пример #5
0
 def deactivate(self, channel):
     config = channel.config
     if "webhook_id" in config:
         client = TembaTwython(
             config["api_key"], config["api_secret"], config["access_token"], config["access_token_secret"]
         )
         client.delete_webhook(config["env_name"], config["webhook_id"])
Пример #6
0
    def pre_process(self, *args, **kwargs):
        response = super().pre_process(*args, **kwargs)

        api_key = settings.TWITTER_API_KEY
        api_secret = settings.TWITTER_API_SECRET
        oauth_token = self.request.session.get(SESSION_TWITTER_OAUTH_TOKEN)
        oauth_token_secret = self.request.session.get(
            SESSION_TWITTER_OAUTH_SECRET)
        oauth_verifier = self.request.GET.get("oauth_verifier")

        # if we have all required values, then we must be returning from an authorization callback
        if api_key and api_secret and oauth_token and oauth_token_secret and oauth_verifier:
            twitter = TembaTwython(api_key, api_secret, oauth_token,
                                   oauth_token_secret)
            final_step = twitter.get_authorized_tokens(oauth_verifier)
            screen_name = final_step["screen_name"]
            handle_id = final_step["user_id"]
            oauth_token = final_step["oauth_token"]
            oauth_token_secret = final_step["oauth_token_secret"]

            org = self.request.user.get_org()

            del self.request.session[SESSION_TWITTER_OAUTH_TOKEN]
            del self.request.session[SESSION_TWITTER_OAUTH_SECRET]

            # check there isn't already a channel for this Twitter account
            if self.org.channels.filter(channel_type=self.channel_type.code,
                                        address=screen_name,
                                        is_active=True).exists():
                messages.error(
                    self.request,
                    _("A Twitter channel for that handle already exists, and must be removed"
                      "before another channel can be created for that handle."
                      ),
                )
                return response
            else:
                config = {
                    "handle_id": int(handle_id),
                    "oauth_token": oauth_token,
                    "oauth_token_secret": oauth_token_secret,
                }
                self.object = Channel.create(
                    org,
                    self.request.user,
                    None,
                    self.channel_type,
                    name="@%s" % screen_name,
                    address=screen_name,
                    config=config,
                )

            return redirect(self.get_success_url())

        return response
Пример #7
0
    def activate(self, channel):
        config = channel.config_json()
        client = TembaTwython(config['api_key'], config['api_secret'], config['access_token'], config['access_token_secret'])

        callback_url = 'https://%s%s' % (settings.HOSTNAME, reverse('courier.twt', args=[channel.uuid]))
        webhook = client.register_webhook(callback_url)
        client.subscribe_to_webhook(webhook['id'])

        # save this webhook for later so we can delete it
        config['webhook_id'] = webhook['id']
        channel.config = json.dumps(config)
        channel.save(update_fields=('config',))
Пример #8
0
    def get_context_data(self, **kwargs):
        context = super(ClaimView, self).get_context_data(**kwargs)

        # generate temp OAuth token and secret
        twitter = TembaTwython(settings.TWITTER_API_KEY, settings.TWITTER_API_SECRET)
        callback_url = "https://rapidpro.datos.gob.mx"+reverse('channels.claim_twitter')#self.request.build_absolute_uri(reverse('channels.claim_twitter'))
        auth = twitter.get_authentication_tokens(callback_url=callback_url)

        # put in session for when we return from callback
        self.request.session[SESSION_TWITTER_OAUTH_TOKEN] = auth['oauth_token']
        self.request.session[SESSION_TWITTER_OAUTH_SECRET] = auth['oauth_token_secret']

        context['twitter_auth_url'] = auth['auth_url']
        return context
Пример #9
0
        def clean(self):
            cleaned_data = super().clean()
            api_key = cleaned_data.get("api_key")
            api_secret = cleaned_data.get("api_secret")
            access_token = cleaned_data.get("access_token")
            access_token_secret = cleaned_data.get("access_token_secret")

            if api_key and api_secret and access_token and access_token_secret:
                twitter = TembaTwython(api_key, api_secret, access_token, access_token_secret)
                try:
                    twitter.verify_credentials()
                except TwythonError:
                    raise ValidationError(_("The provided Twitter credentials do not appear to be valid."))

            return cleaned_data
Пример #10
0
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        # generate temp OAuth token and secret
        twitter = TembaTwython(settings.TWITTER_API_KEY,
                               settings.TWITTER_API_SECRET)
        callback_url = self.request.build_absolute_uri(
            reverse("channels.types.twitter.claim"))
        auth = twitter.get_authentication_tokens(callback_url=callback_url)

        # put in session for when we return from callback
        self.request.session[SESSION_TWITTER_OAUTH_TOKEN] = auth["oauth_token"]
        self.request.session[SESSION_TWITTER_OAUTH_SECRET] = auth[
            "oauth_token_secret"]

        context["twitter_auth_url"] = auth["auth_url"]
        return context
Пример #11
0
    def send(self, channel, msg, text):
        twitter = TembaTwython.from_channel(channel)
        start = time.time()

        try:
            urn = getattr(msg, "urn", URN.from_twitter(msg.urn_path))
            (scheme, path, query, display) = URN.to_parts(urn)

            # this is a legacy URN (no display), the path is our screen name
            if scheme == TWITTER_SCHEME:
                dm = twitter.send_direct_message(screen_name=path, text=text)
                external_id = dm["id"]

            # this is a new twitterid URN, our path is our user id
            else:
                metadata = msg.metadata if hasattr(msg, "metadata") else {}
                quick_replies = metadata.get("quick_replies", [])
                formatted_replies = [dict(label=item[: self.quick_reply_text_size]) for item in quick_replies]

                if quick_replies:
                    params = {
                        "event": {
                            "type": "message_create",
                            "message_create": {
                                "target": {"recipient_id": path},
                                "message_data": {
                                    "text": text,
                                    "quick_reply": {"type": "options", "options": formatted_replies},
                                },
                            },
                        }
                    }
                    dm = twitter.post("direct_messages/events/new", params=params)
                    external_id = dm["event"]["id"]
                else:
                    dm = twitter.send_direct_message(user_id=path, text=text)
                    external_id = dm["id"]

        except Exception as e:
            error_code = getattr(e, "error_code", 400)
            fatal = False

            if error_code == 404:  # handle doesn't exist
                fatal = True
            elif error_code == 403:
                for err in self.FATAL_403S:
                    if str(e).find(err) >= 0:
                        fatal = True
                        break

            # if message can never be sent, stop them contact
            if fatal:
                contact = Contact.objects.get(id=msg.contact)
                contact.stop(contact.modified_by)

            raise SendException(str(e), events=twitter.events, fatal=fatal, start=start)

        Channel.success(channel, msg, WIRED, start, events=twitter.events, external_id=external_id)
Пример #12
0
    def form_valid(self, form):
        org = self.request.user.get_org()

        cleaned_data = form.cleaned_data
        api_key = cleaned_data["api_key"]
        api_secret = cleaned_data["api_secret"]
        access_token = cleaned_data["access_token"]
        access_token_secret = cleaned_data["access_token_secret"]
        env_name = cleaned_data["env_name"]

        twitter = TembaTwython(api_key, api_secret, access_token,
                               access_token_secret)
        account_info = twitter.verify_credentials()
        handle_id = str(account_info["id"])
        screen_name = account_info["screen_name"]

        config = {
            "handle_id": handle_id,
            "api_key": api_key,
            "api_secret": api_secret,
            "access_token": access_token,
            "access_token_secret": access_token_secret,
            "env_name": env_name,
            Channel.CONFIG_CALLBACK_DOMAIN: settings.HOSTNAME,
        }

        try:
            self.object = Channel.create(
                org,
                self.request.user,
                None,
                self.channel_type,
                name="@%s" % screen_name,
                address=screen_name,
                config=config,
            )
        except ValidationError as e:
            self.form.add_error(None, e)
            return self.form_invalid(form)

        return super().form_valid(form)
Пример #13
0
    def form_valid(self, form):
        org = self.request.user.get_org()

        cleaned_data = form.cleaned_data
        api_key = cleaned_data["api_key"]
        api_secret = cleaned_data["api_secret"]
        access_token = cleaned_data["access_token"]
        access_token_secret = cleaned_data["access_token_secret"]
        env_name = cleaned_data["env_name"]

        twitter = TembaTwython(api_key, api_secret, access_token, access_token_secret)
        account_info = twitter.verify_credentials()
        handle_id = str(account_info["id"])
        screen_name = account_info["screen_name"]

        config = {
            "handle_id": handle_id,
            "api_key": api_key,
            "api_secret": api_secret,
            "access_token": access_token,
            "access_token_secret": access_token_secret,
            "env_name": env_name,
            Channel.CONFIG_CALLBACK_DOMAIN: settings.HOSTNAME,
        }

        try:
            self.object = Channel.create(
                org,
                self.request.user,
                None,
                self.channel_type,
                name="@%s" % screen_name,
                address=screen_name,
                config=config,
            )
        except ValidationError as e:
            self.form.add_error(None, e)
            return self.form_invalid(form)

        return super().form_valid(form)
Пример #14
0
    def activate(self, channel):
        config = channel.config
        client = TembaTwython(config['api_key'], config['api_secret'], config['access_token'], config['access_token_secret'])

        callback_url = 'https://%s%s' % (channel.callback_domain, reverse('courier.twt', args=[channel.uuid]))
        try:
            client.register_webhook(config['env_name'], callback_url)
            client.subscribe_to_webhook(config['env_name'])
        except Exception as e:  # pragma: no cover
            logger.exception(six.text_type(e))
Пример #15
0
    def send(self, channel, msg, text):
        twitter = TembaTwython.from_channel(channel)
        start = time.time()

        try:
            urn = getattr(msg, 'urn', URN.from_twitter(msg.urn_path))
            (scheme, path, display) = URN.to_parts(urn)

            # this is a legacy URN (no display), the path is our screen name
            if scheme == TWITTER_SCHEME:
                dm = twitter.send_direct_message(screen_name=path, text=text)

            # this is a new twitterid URN, our path is our user id
            else:
                dm = twitter.send_direct_message(user_id=path, text=text)

        except Exception as e:
            error_code = getattr(e, 'error_code', 400)
            fatal = False

            if error_code == 404:  # handle doesn't exist
                fatal = True
            elif error_code == 403:
                for err in self.FATAL_403S:
                    if six.text_type(e).find(err) >= 0:
                        fatal = True
                        break

            # if message can never be sent, stop them contact
            if fatal:
                contact = Contact.objects.get(id=msg.contact)
                contact.stop(contact.modified_by)

            raise SendException(str(e),
                                events=twitter.events,
                                fatal=fatal,
                                start=start)

        external_id = dm['id']
        Channel.success(channel,
                        msg,
                        WIRED,
                        start,
                        events=twitter.events,
                        external_id=external_id)
Пример #16
0
    def activate(self, channel):
        config = channel.config
        client = TembaTwython(config["api_key"], config["api_secret"],
                              config["access_token"],
                              config["access_token_secret"])

        callback_url = "https://%s%s" % (channel.callback_domain,
                                         reverse("courier.twt",
                                                 args=[channel.uuid]))
        try:
            client.register_webhook(config["env_name"], callback_url)
            client.subscribe_to_webhook(config["env_name"])
        except Exception as e:  # pragma: no cover
            logger.exception(str(e))
Пример #17
0
    def activate(self, channel):
        config = channel.config
        client = TembaTwython(config["api_key"], config["api_secret"],
                              config["access_token"],
                              config["access_token_secret"])

        callback_url = "https://%s%s" % (channel.callback_domain,
                                         reverse("courier.twt",
                                                 args=[channel.uuid]))
        try:
            # check for existing hooks, if there is just one, remove it
            hooks = client.get_webhooks(config["env_name"])
            if len(hooks) == 1:
                client.delete_webhook(config["env_name"], hooks[0]["id"])

            resp = client.register_webhook(config["env_name"], callback_url)
            channel.config["webhook_id"] = resp["id"]
            channel.save(update_fields=["config"])
            client.subscribe_to_webhook(config["env_name"])
        except Exception as e:  # pragma: no cover
            logger.exception(str(e))
            raise ValidationError(e)
Пример #18
0
    def activate(self, channel):
        config = channel.config
        client = TembaTwython(
            config["api_key"], config["api_secret"], config["access_token"], config["access_token_secret"]
        )

        callback_url = "https://%s%s" % (channel.callback_domain, reverse("courier.twt", args=[channel.uuid]))
        try:
            # check for existing hooks, if there is just one, remove it
            hooks = client.get_webhooks(config["env_name"])
            if len(hooks) == 1:
                client.delete_webhook(config["env_name"], hooks[0]["id"])

            resp = client.register_webhook(config["env_name"], callback_url)
            channel.config["webhook_id"] = resp["id"]
            channel.save(update_fields=["config"])
            client.subscribe_to_webhook(config["env_name"])
        except Exception as e:  # pragma: no cover
            logger.exception(str(e))
            raise ValidationError(e)
Пример #19
0
    def send(self, channel, msg, text):
        twitter = TembaTwython.from_channel(channel)
        start = time.time()

        try:
            dm = twitter.send_direct_message(screen_name=msg.urn_path,
                                             text=text)
        except Exception as e:
            error_code = getattr(e, 'error_code', 400)
            fatal = False

            if error_code == 404:  # handle doesn't exist
                fatal = True
            elif error_code == 403:
                for err in self.FATAL_403S:
                    if six.text_type(e).find(err) >= 0:
                        fatal = True
                        break

            # if message can never be sent, stop them contact
            if fatal:
                contact = Contact.objects.get(id=msg.contact)
                contact.stop(contact.modified_by)

            raise SendException(str(e),
                                events=twitter.events,
                                fatal=fatal,
                                start=start)

        external_id = dm['id']
        Channel.success(channel,
                        msg,
                        WIRED,
                        start,
                        events=twitter.events,
                        external_id=external_id)
Пример #20
0
    def send(self, channel, msg, text):
        twitter = TembaTwython.from_channel(channel)
        start = time.time()

        try:
            urn = getattr(msg, 'urn', URN.from_twitter(msg.urn_path))
            (scheme, path, display) = URN.to_parts(urn)
            print("scheme %s" % (scheme))
            print("path %s" % (path))
            print("display %s" % (display))
            # this is a legacy URN (no display), the path is our screen name
            if scheme == TWITTER_SCHEME:
                dm = twitter.send_direct_message(screen_name=path, text=text)
                external_id = dm['id']

            # this is a new twitterid URN, our path is our user id
            else:
                metadata = msg.metadata if hasattr(msg, 'metadata') else {}
                quick_replies = metadata.get('quick_replies', [])
                formatted_replies = [
                    dict(label=item[:self.quick_reply_text_size])
                    for item in quick_replies
                ]

                if quick_replies:
                    params = {
                        'event': {
                            'type': 'message_create',
                            'message_create': {
                                'target': {
                                    'recipient_id': path
                                },
                                'message_data': {
                                    'text': text,
                                    'quick_reply': {
                                        'type': 'options',
                                        'options': formatted_replies
                                    }
                                }
                            }
                        }
                    }
                    dm = twitter.post('direct_messages/events/new',
                                      params=params)
                    external_id = dm['event']['id']
                else:
                    print(path)
                    print(text)
                    dm = twitter.send_direct_message(user_id=path, text=text)
                    external_id = dm['id']

        except Exception as e:
            error_code = getattr(e, 'error_code', 400)
            fatal = False
            print("Twitter type")
            print(e)

            if error_code == 404:  # handle doesn't exist
                fatal = True
            elif error_code == 403:
                for err in self.FATAL_403S:
                    if six.text_type(e).find(err) >= 0:
                        fatal = True
                        break

            # if message can never be sent, stop them contact
            if fatal:
                contact = Contact.objects.get(id=msg.contact)
                contact.stop(contact.modified_by)

            raise SendException(str(e),
                                events=twitter.events,
                                fatal=fatal,
                                start=start)

        Channel.success(channel,
                        msg,
                        WIRED,
                        start,
                        events=twitter.events,
                        external_id=external_id)