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)
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'])
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"])
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
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"])
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
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',))
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
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
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
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)
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)
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))
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)
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))
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)
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)
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)
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)