class Form(forms.Form): SLOT_CHOICES = (("staging", _("Staging")), ("production", _("Production"))) name = forms.CharField(help_text=_("The name of your LUIS app")) app_id = forms.CharField(label=_("App ID"), help_text=_("The ID of your LUIS app")) authoring_endpoint = ExternalURLField( help_text=_("The authoring resource endpoint URL")) authoring_key = forms.CharField( help_text=_("The authoring resource access key")) prediction_endpoint = ExternalURLField( help_text=_("The prediction resource endpoint URL")) prediction_key = forms.CharField( help_text=_("The prediction resource access key")) slot = forms.ChoiceField(help_text=_( "The slot where the prediction resource has been published"), choices=SLOT_CHOICES) def clean(self): cleaned = super().clean() if not self.is_valid(): return cleaned # first check authoring credentials work try: client = AuthoringClient(cleaned["authoring_endpoint"], cleaned["authoring_key"]) app_info = client.get_app(cleaned["app_id"]) app_endpoints = app_info["endpoints"] if cleaned["slot"].upper() not in app_endpoints: raise forms.ValidationError( _("App has not yet been published to %s slot.") % cleaned["slot"]) except requests.RequestException as e: raise forms.ValidationError( _("Check authoring credentials: %s") % str(e)) # then check prediction credentials work try: client = PredictionClient(cleaned["prediction_endpoint"], cleaned["prediction_key"]) client.predict(cleaned["app_id"], cleaned["slot"], "test") except requests.RequestException as e: raise forms.ValidationError( _("Check prediction credentials: %s") % str(e)) return cleaned
class Form(ClaimViewMixin.Form): country = forms.ChoiceField( choices=ALL_COUNTRIES, widget=SelectWidget(attrs={"searchable": True}), label=_("Country"), help_text=_("The country this phone number is used in"), ) number = forms.CharField( max_length=14, min_length=4, label=_("Number"), help_text=("The shortcode or phone number you are connecting."), ) url = ExternalURLField( label=_("URL"), help_text= _("The URL for the Junebug channel. ex: https://junebug.praekelt.org/jb/channels/3853bb51-d38a-4bca-b332-8a57c00f2a48/messages.json" ), ) username = forms.CharField( label=_("Username"), help_text=_("The username to be used to authenticate to Junebug"), required=False) password = forms.CharField( label=_("Password"), help_text=_("The password to be used to authenticate to Junebug"), required=False) secret = forms.CharField( label=_("Secret"), help_text=_("The token Junebug should use to authenticate"), required=False)
class PMClaimForm(ClaimViewMixin.Form): base_url = ExternalURLField(label=_("Base URL"), help_text=_("The base URL for PlayMobile")) shortcode = forms.CharField( label=_("Shortcode"), max_length=15, min_length=1, help_text=_("The short code you are connecting") ) username = forms.CharField(label=_("Username"), help_text=_("The username for your API account")) password = forms.CharField(label=_("Password"), help_text=_("The password for your API account"))
class Form(ClaimViewMixin.Form): number = forms.CharField( help_text=_("Your enterprise WhatsApp number")) country = forms.ChoiceField( choices=ALL_COUNTRIES, label=_("Country"), help_text=_("The country this phone number is used in")) base_url = ExternalURLField(help_text=_( "The base URL for your 360 Dialog WhatsApp enterprise installation" )) api_key = forms.CharField( max_length=256, help_text=_( "The 360 Dialog API key generated after account registration")) def clean(self): # first check that our phone number looks sane number, valid = URN.normalize_number(self.cleaned_data["number"], self.cleaned_data["country"]) if not valid: raise forms.ValidationError( _("Please enter a valid phone number")) self.cleaned_data["number"] = number return self.cleaned_data
class Form(forms.Form): name = forms.CharField(help_text=_("The name of your LUIS app")) app_id = forms.CharField(label=_("App ID"), help_text=_("The ID for your LUIS app")) version = forms.CharField( help_text=_("The name of the version of your LUIS app to use")) primary_key = forms.CharField( help_text=_("The primary key for your LUIS app")) endpoint_url = ExternalURLField( help_text=_("The endpoint URL for your LUIS app")) def clean(self): from .type import LuisType cleaned = super().clean() if not self.is_valid(): return cleaned endpoint = cleaned["endpoint_url"] # try to look up intents response = requests.get( endpoint + "/apps/" + cleaned["app_id"] + "/versions/" + cleaned["version"] + "/intents", headers={LuisType.AUTH_HEADER: cleaned["primary_key"]}, ) if response.status_code != 200: raise forms.ValidationError( _("Unable to get intents for your app, please check credentials and try again" )) return cleaned
class Form(BaseConnectView.Form): base_url = ExternalURLField( label=_("URL"), widget=forms.URLInput( attrs={ "placeholder": _("Ex.: https://my.rocket.chat/api/apps/public/51c5cebe-b8e4-48ae-89d3-2b7746019cc4" ) }), help_text=_("URL of the Rocket.Chat Tickets app"), ) admin_user_id = forms.CharField( label=_("Admin User ID"), help_text=_("User ID of an administrator user")) admin_auth_token = forms.CharField( label=_("Admin Auth Token"), help_text=_("Authentication token of an administrator user")) secret = forms.CharField( label=_("Secret"), widget=forms.HiddenInput(), help_text=_("Secret to be passed to Rocket.Chat"), ) def clean(self): secret = self.cleaned_data.get("secret") if not secret: raise forms.ValidationError(_("Invalid secret code.")) initial = self.initial.get("secret") if secret != initial: self.data = self.data.copy() self.data["secret"] = initial raise forms.ValidationError(_("Secret code change detected.")) return self.cleaned_data def clean_base_url(self): from .type import RocketChatType org = self.request.user.get_org() base_url = RE_BASE_URL.search( self.cleaned_data.get("base_url") or "") if base_url: base_url = base_url.group() else: raise forms.ValidationError( _("Invalid URL: %(base_url)s") % self.cleaned_data) base_url_exists = org.ticketers.filter( is_active=True, ticketer_type=RocketChatType.slug, **{ f"config__{RocketChatType.CONFIG_BASE_URL}": base_url }, ).exists() if base_url_exists: raise forms.ValidationError( _("There is already a ticketing service configured for this URL." )) return base_url
class ShaqodoonForm(ClaimViewMixin.Form): country = forms.ChoiceField( choices=ALL_COUNTRIES, label=_("Country"), help_text=_("The country this phone number is used in") ) number = forms.CharField( max_length=14, min_length=1, label=_("Number"), help_text=_("The short code you are connecting with.") ) url = ExternalURLField(label=_("URL"), help_text=_("The url provided to deliver messages")) username = forms.CharField(label=_("Username"), help_text=_("The username provided to use their API")) password = forms.CharField(label=_("Password"), help_text=_("The password provided to use their API"))
class KannelClaimForm(ClaimViewMixin.Form): number = forms.CharField( max_length=14, min_length=1, label=_("Number"), help_text=_("The phone number or short code you are connecting"), ) country = forms.ChoiceField( choices=ALL_COUNTRIES, widget=SelectWidget(attrs={"searchable": True}), label=_("Country"), help_text=_("The country this phone number is used in"), ) url = ExternalURLField( max_length=1024, label=_("Send URL"), help_text=_( "The publicly accessible URL for your Kannel instance for sending. " "ex: https://kannel.macklemore.co/cgi-bin/sendsms"), ) username = forms.CharField( max_length=64, required=False, help_text=_( "The username to use to authenticate to Kannel, if left blank we " "will generate one for you"), ) password = forms.CharField( max_length=64, required=False, help_text=_( "The password to use to authenticate to Kannel, if left blank we " "will generate one for you"), ) encoding = forms.ChoiceField( choices=Channel.ENCODING_CHOICES, label=_("Encoding"), help_text=_("What encoding to use for outgoing messages"), ) verify_ssl = forms.BooleanField( initial=True, required=False, label=_("Verify SSL"), help_text=_("Whether to verify the SSL connection (recommended)"), ) use_national = forms.BooleanField( initial=False, required=False, label=_("Use National Numbers"), help_text=_("Use only the national number (no country code) when " "sending (not recommended)"), )
class TwimlApiClaimForm(ClaimViewMixin.Form): ROLES = ( (Channel.ROLE_SEND + Channel.ROLE_RECEIVE, _("Messaging")), (Channel.ROLE_CALL + Channel.ROLE_ANSWER, _("Voice")), (Channel.ROLE_SEND + Channel.ROLE_RECEIVE + Channel.ROLE_CALL + Channel.ROLE_ANSWER, _("Both")), ) country = forms.ChoiceField( choices=ALL_COUNTRIES, widget=SelectWidget(attrs={"searchable": True}), label=_("Country"), help_text=_("The country this phone number is used in"), ) number = forms.CharField( max_length=14, min_length=1, label=_("Number"), help_text= _("The phone number without country code or short code you are connecting." ), ) url = ExternalURLField( max_length=1024, label=_("TwiML REST API Host"), help_text= _("The publicly accessible URL for your TwiML REST API instance ex: https://api.twilio.com" ), ) role = forms.ChoiceField( choices=ROLES, label=_("Role"), help_text=_("Choose the role that this channel supports")) account_sid = forms.CharField( max_length=64, required=False, help_text=_( "The Account SID to use to authenticate to the TwiML REST API" ), widget=forms.TextInput(attrs={"autocomplete": "off"}), ) account_token = forms.CharField( max_length=64, required=False, help_text=_( "The Account Token to use to authenticate to the TwiML REST API" ), widget=forms.TextInput(attrs={"autocomplete": "off"}), ) max_concurrent_events = forms.IntegerField( min_value=1, required=False, help_text=_("Max active calls at the same time"))
class SendClaimForm(ClaimViewMixin.Form): url = ExternalURLField( max_length=1024, label=_("Send URL"), help_text=_("The URL we will POST to when sending messages, with variable substitutions"), ) method = forms.ChoiceField( choices=(("POST", "HTTP POST"), ("GET", "HTTP GET"), ("PUT", "HTTP PUT")), help_text=_("What HTTP method to use when calling the URL"), ) encoding = forms.ChoiceField( choices=Channel.ENCODING_CHOICES, label=_("Encoding"), help_text=_("What encoding to use for outgoing messages"), ) content_type = forms.ChoiceField( choices=Channel.CONTENT_TYPE_CHOICES, help_text=_("The content type used when sending the request") ) max_length = forms.IntegerField( initial=160, validators=[MaxValueValidator(640), MinValueValidator(60)], help_text=_( "The maximum length of any single message on this channel. " "(longer messages will be split)" ), ) send_authorization = forms.CharField( max_length=2048, label=_("Authorization Header Value"), required=False, help_text=_("The Authorization header value added when calling the URL (if any)"), ) body = forms.CharField( max_length=2048, label=_("Request Body"), required=False, widget=forms.Textarea, help_text=_("The request body if any, with variable substitutions (only used for PUT or POST)"), ) mt_response_check = forms.CharField( max_length=2048, label=_("MT Response check"), required=False, widget=forms.Textarea, help_text=_("The content that must be in the response to consider the request successful"), )
class JasminForm(ClaimViewMixin.Form): country = forms.ChoiceField( choices=ALL_COUNTRIES, widget=SelectWidget(attrs={"searchable": True}), label=_("Country"), help_text=_("The country this phone number is used in"), ) number = forms.CharField( max_length=14, min_length=3, label=_("Number"), help_text=_("The short code or phone number you are connecting."), ) url = ExternalURLField( widget=forms.URLInput( attrs={"placeholder": _("Ex: https://jasmin.gateway.io/send") }), label=_("URL"), help_text=_("The URL for the Jasmin server send path"), ) username = forms.CharField( label=_("Username"), help_text=_("The username to be used to authenticate to Jasmin")) password = forms.CharField( label=_("Password"), help_text=_("The password to be used to authenticate to Jasmin")) def clean_number(self): number = self.data["number"] # number is a shortcode, accept as is if len(number) > 0 and len(number) < 7: return number # otherwise, try to parse into an international format if number and number[0] != "+": number = "+" + number try: cleaned = phonenumbers.parse(number, None) return phonenumbers.format_number( cleaned, phonenumbers.PhoneNumberFormat.E164) except Exception: # pragma: needs cover raise forms.ValidationError( _("Invalid phone number, please include the country code. ex: +250788123123" ))
class TelesomForm(ClaimViewMixin.Form): country = forms.ChoiceField( choices=ALL_COUNTRIES, widget=SelectWidget(attrs={"searchable": True}), label=_("Country"), help_text=_("The country this phone number is used in"), ) number = forms.CharField( max_length=14, min_length=1, label=_("Number"), help_text=_("The short code you are connecting with.")) url = ExternalURLField( label=_("URL"), help_text=_("The url provided to deliver messages")) username = forms.CharField( label=_("Username"), help_text=_("The username provided to use their API")) password = forms.CharField( label=_("Password"), help_text=_("The password provided to use their API")) secret = forms.CharField( label=_("Private Key"), help_text=_("The private key provided to use their API"))
class Form(ClaimViewMixin.Form): api_endpoint = ExternalURLField( label=_("API Endpoint"), help_text=_("The API endpoint for your TextIt WhatsApp number")) access_token = forms.CharField( label=_("Access Token"), max_length=256, help_text=_("The access token for your TextIt WhatsApp number")) def clean(self): cleaned = self.cleaned_data cleaned["api_endpoint"] = urljoin(cleaned["api_endpoint"], "/") headers = { "Authorization": f"Bearer {cleaned['access_token']}", "Content-Type": "application/json", } conf_url = urljoin(cleaned["api_endpoint"], "/conf") response = requests.get(conf_url, headers=headers) if response.status_code != 200: raise forms.ValidationError( "Error reaching endpoint, please check access token and URL" ) conf = response.json() if conf["status"] != "activated": raise forms.ValidationError( "WhatsApp number not active, cannot connect") self.cleaned_data["address"] = conf["address"] self.cleaned_data["country"] = conf["country"] self.cleaned_data["name"] = conf["name"] return self.cleaned_data
class Form(ClaimViewMixin.Form): number = forms.CharField( help_text=_("Your enterprise WhatsApp number")) country = forms.ChoiceField( choices=ALL_COUNTRIES, label=_("Country"), help_text=_("The country this phone number is used in")) base_url = ExternalURLField(help_text=_( "The base URL for your WhatsApp enterprise installation")) username = forms.CharField( max_length=32, help_text=_( "The username to access your WhatsApp enterprise account")) password = forms.CharField( max_length=64, help_text=_( "The password to access your WhatsApp enterprise account")) facebook_template_list_domain = forms.CharField( label=_("Templates Domain"), help_text=_("Which domain to retrieve the message templates from"), initial="graph.facebook.com", ) facebook_business_id = forms.CharField( max_length=128, help_text=_( "The Facebook waba-id that will be used for template syncing")) facebook_access_token = forms.CharField( max_length=256, help_text=_( "The Facebook access token that will be used for syncing")) facebook_namespace = forms.CharField( max_length=128, help_text=_("The namespace for your WhatsApp templates")) def clean(self): # first check that our phone number looks sane number, valid = URN.normalize_number(self.cleaned_data["number"], self.cleaned_data["country"]) if not valid: raise forms.ValidationError( _("Please enter a valid phone number")) self.cleaned_data["number"] = number try: resp = requests.post( self.cleaned_data["base_url"] + "/v1/users/login", auth=(self.cleaned_data["username"], self.cleaned_data["password"]), ) if resp.status_code != 200: raise Exception("Received non-200 response: %d", resp.status_code) self.cleaned_data["auth_token"] = resp.json( )["users"][0]["token"] except Exception: raise forms.ValidationError( _("Unable to check WhatsApp enterprise account, please check username and password" )) # check we can access their facebook templates from .type import TEMPLATE_LIST_URL response = requests.get( TEMPLATE_LIST_URL % (self.cleaned_data["facebook_template_list_domain"], self.cleaned_data["facebook_business_id"]), params=dict( access_token=self.cleaned_data["facebook_access_token"]), ) if response.status_code != 200: raise forms.ValidationError( _("Unable to access Facebook templates, please check user id and access token and make sure " + "the whatsapp_business_management permission is enabled") ) return self.cleaned_data
class ClaimForm(ClaimViewMixin.Form): scheme = forms.ChoiceField( choices=URN.SCHEME_CHOICES, label=_("URN Type"), help_text=_("The type of URNs handled by this channel")) number = forms.CharField( max_length=14, min_length=1, label=_("Number"), required=False, help_text=_( "The phone number or that this channel will send from"), ) address = forms.CharField( max_length=64, min_length=1, label=_("Address"), required=False, help_text=_( "The external address that this channel will send from"), ) country = forms.ChoiceField( choices=ALL_COUNTRIES, label=_("Country"), required=False, widget=SelectWidget(attrs={"searchable": True}), help_text=_("The country this phone number is used in"), ) method = forms.ChoiceField( choices=(("POST", "HTTP POST"), ("GET", "HTTP GET"), ("PUT", "HTTP PUT")), help_text=_("What HTTP method to use when calling the URL"), ) encoding = forms.ChoiceField( choices=Channel.ENCODING_CHOICES, label=_("Encoding"), help_text=_("What encoding to use for outgoing messages"), ) content_type = forms.ChoiceField( choices=Channel.CONTENT_TYPE_CHOICES, help_text=_("The content type used when sending the request")) max_length = forms.IntegerField( initial=160, validators=[MaxValueValidator(6400), MinValueValidator(60)], help_text=_( "The maximum length of any single message on this channel. " "(longer messages will be split)"), ) send_authorization = forms.CharField( max_length=2048, label=_("Authorization Header Value"), required=False, help_text= _("The Authorization header value added when calling the URL (if any)" ), ) url = ExternalURLField( max_length=1024, label=_("Send URL"), help_text= _("The URL we will call when sending messages, with variable substitutions" ), ) body = forms.CharField( max_length=2048, label=_("Request Body"), required=False, widget=forms.Textarea, help_text= _("The request body if any, with variable substitutions (only used for PUT or POST)" ), ) mt_response_check = forms.CharField( max_length=2048, label=_("MT Response check"), required=False, widget=forms.Textarea, help_text= _("The content that must be in the response to consider the request successful" ), ) def clean(self): cleaned_data = super().clean() scheme = cleaned_data.get("scheme") if scheme == URN.TEL_SCHEME and not cleaned_data.get("number"): raise ValidationError({"number": _("This field is required.")}) elif scheme != URN.TEL_SCHEME and not cleaned_data.get("address"): raise ValidationError( {"address": _("This field is required.")})
class ClaimForm(ClaimViewMixin.Form): scheme = forms.ChoiceField( choices=ContactURN.SCHEME_CHOICES, label=_("URN Type"), help_text=_("The type of URNs handled by this channel"), ) number = forms.CharField( max_length=14, min_length=1, label=_("Number"), required=False, help_text=_("The phone number or that this channel will send from"), ) handle = forms.CharField( max_length=32, min_length=1, label=_("Handle"), required=False, help_text=_("The Twitter handle that this channel will send from"), ) address = forms.CharField( max_length=64, min_length=1, label=_("Address"), required=False, help_text=_("The external address that this channel will send from"), ) country = forms.ChoiceField( choices=ALL_COUNTRIES, label=_("Country"), required=False, help_text=_("The country this phone number is used in"), ) method = forms.ChoiceField( choices=(("POST", "HTTP POST"), ("GET", "HTTP GET"), ("PUT", "HTTP PUT")), help_text=_("What HTTP method to use when calling the URL"), ) encoding = forms.ChoiceField( choices=Channel.ENCODING_CHOICES, label=_("Encoding"), help_text=_("What encoding to use for outgoing messages"), ) content_type = forms.ChoiceField( choices=Channel.CONTENT_TYPE_CHOICES, help_text=_("The content type used when sending the request") ) max_length = forms.IntegerField( initial=160, validators=[MaxValueValidator(640), MinValueValidator(60)], help_text=_( "The maximum length of any single message on this channel. " "(longer messages will be split)" ), ) url = ExternalURLField( max_length=1024, label=_("Send URL"), help_text=_("The URL we will call when sending messages, with variable substitutions"), ) body = forms.CharField( max_length=2048, label=_("Request Body"), required=False, widget=forms.Textarea, help_text=_("The request body if any, with variable substitutions (only used for PUT or POST)"), ) mt_response_check = forms.CharField( max_length=2048, label=_("MT Response check"), required=False, widget=forms.Textarea, help_text=_("The content that must be in the response to consider the request successful"), )