Exemplo n.º 1
0
def serialize_contact(contact):
    from temba.contacts.models import URN

    field_values = {}
    for field in contact.org.cached_contact_fields.values():
        field_values[field.key] = contact.get_field_json(field)

    # augment URN values with preferred channel UUID as a parameter
    urn_values = []
    for u in contact.urns.order_by("-priority", "id"):
        # for each URN we include the preferred channel as a query param if there is one
        if u.channel and u.channel.is_active:
            scheme, path, query, display = URN.to_parts(u.urn)
            urn_str = URN.from_parts(scheme, path, query=urlencode({"channel": str(u.channel.uuid)}), display=display)
        else:
            urn_str = u.urn

        urn_values.append(urn_str)

    return {
        "uuid": contact.uuid,
        "id": contact.id,
        "name": contact.name,
        "language": contact.language,
        "urns": urn_values,
        "groups": [serialize_ref(group) for group in contact.user_groups.filter(is_active=True)],
        "fields": field_values,
    }
Exemplo n.º 2
0
    def parse_contacts(cls, org, json_obj):
        contacts = []
        for contact in json_obj.get(VariableContactAction.CONTACTS):
            name = contact.get(VariableContactAction.NAME, None)
            phone = contact.get(VariableContactAction.PHONE, None)
            contact_uuid = contact.get(VariableContactAction.UUID, None)

            urns = []
            for urn in contact.get(VariableContactAction.URNS, []):
                scheme = urn.get(VariableContactAction.SCHEME)
                path = urn.get(VariableContactAction.PATH)

                if scheme and path:
                    urns.append(URN.from_parts(scheme, path))

            if phone:  # pragma: needs cover
                urns.append(URN.from_tel(phone))

            contact = Contact.objects.filter(uuid=contact_uuid, org=org).first()

            if not contact:
                contact = Contact.get_or_create_by_urns(org, org.created_by, name=None, urns=urns)

                # if they don't have a name use the one in our action
                if name and not contact.name:  # pragma: needs cover
                    contact.name = name
                    contact.save(update_fields=["name"], handle_update=True)

            if contact:
                contacts.append(contact)

        return contacts
Exemplo n.º 3
0
def update_dart_hub9_ext_scheme_urns(apps, schema_editor):
    ContactURN = apps.get_model('contacts', 'ContactURN')

    encrypted_urns = ContactURN.objects.filter(channel__channel_type__in=['DA', 'H9']).exclude(identity__icontains="+")
    for contact_urn in encrypted_urns:
        contact_urn.scheme = 'ext'
        contact_urn.identity = URN.from_parts('ext', contact_urn.path)
        contact_urn.save()
Exemplo n.º 4
0
 def clean_number(self):
     # check that our phone number looks sane
     country = self.data["country"]
     number = URN.normalize_number(self.data["number"], country)
     if not URN.validate(URN.from_parts(URN.TEL_SCHEME, number),
                         country):
         raise forms.ValidationError(
             _("Please enter a valid phone number"))
     return number
Exemplo n.º 5
0
        def clean(self):
            # first check that our phone number looks sane
            country = self.cleaned_data["country"]
            normalized = URN.normalize_number(self.cleaned_data["number"], country)
            if not URN.validate(URN.from_parts(URN.TEL_SCHEME, normalized), country):
                raise forms.ValidationError(_("Please enter a valid phone number"))
            self.cleaned_data["number"] = normalized

            return self.cleaned_data
Exemplo n.º 6
0
def update_dart_hub9_ext_scheme_urns(apps, schema_editor):
    ContactURN = apps.get_model("contacts", "ContactURN")

    encrypted_urns = ContactURN.objects.filter(
        channel__channel_type__in=["DA", "H9"]).exclude(
            identity__icontains="+")
    for contact_urn in encrypted_urns:
        contact_urn.scheme = "ext"
        contact_urn.identity = URN.from_parts("ext", contact_urn.path)
        contact_urn.save()
Exemplo n.º 7
0
        def clean(self):
            # first check that our phone number looks sane
            country = self.cleaned_data["country"]
            normalized = URN.normalize_number(self.cleaned_data["number"],
                                              country)
            if not URN.validate(URN.from_parts(URN.TEL_SCHEME, normalized),
                                country):
                raise forms.ValidationError(
                    _("Please enter a valid phone number"))
            self.cleaned_data["number"] = normalized

            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

            if self.cleaned_data[
                    "facebook_template_list_domain"] != "graph.facebook.com":
                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
Exemplo n.º 8
0
    def default(self, line):
        """
        Sends a message as the current contact's highest priority URN
        """
        urn = self.contact.get_urn()

        incoming = Msg.create_incoming(None, URN.from_parts(urn.scheme, urn.path),
                                       line, date=timezone.now(), org=self.org)

        self.echo((Fore.GREEN + "[%s] " + Fore.YELLOW + ">>" + Fore.MAGENTA + " %s" + Fore.WHITE) % (urn.urn, incoming.text))

        # look up any message responses
        outgoing = Msg.all_messages.filter(org=self.org, pk__gt=incoming.pk, direction=OUTGOING).order_by('sent_on')
        for response in outgoing:
            self.echo((Fore.GREEN + "[%s] " + Fore.YELLOW + "<<" + Fore.MAGENTA + " %s" + Fore.WHITE) % (urn.urn, response.text))
Exemplo n.º 9
0
def serialize_contact(contact):
    from temba.contacts.models import URN

    field_values = {}
    for field in contact.org.cached_contact_fields.values():
        field_values[field.key] = contact.get_field_json(field)

    # augment URN values with preferred channel UUID as a parameter
    urn_values = []
    for u in contact.urns.order_by("-priority", "id"):
        # for each URN we resolve the preferred channel and include that as a query param
        channel = contact.org.get_send_channel(contact_urn=u)
        if channel:
            scheme, path, query, display = URN.to_parts(u.urn)
            urn_str = URN.from_parts(scheme,
                                     path,
                                     query=urlencode(
                                         {"channel": str(channel.uuid)}),
                                     display=display)
        else:
            urn_str = u.urn

        urn_values.append(urn_str)

    return {
        "uuid":
        contact.uuid,
        "id":
        contact.id,
        "name":
        contact.name,
        "language":
        contact.language,
        "timezone":
        "UTC",
        "urns":
        urn_values,
        "groups": [
            serialize_group_ref(group)
            for group in contact.user_groups.filter(is_active=True)
        ],
        "fields":
        field_values,
    }
Exemplo n.º 10
0
    def default(self, line):
        """
        Sends a message as the current contact's highest priority URN
        """
        urn = self.contact.get_urn()

        incoming = Msg.create_incoming(None, URN.from_parts(urn.scheme, urn.path), line, org=self.org)

        self.echo(
            (Fore.GREEN + "[%s] " + Fore.YELLOW + ">>" + Fore.MAGENTA + " %s" + Fore.WHITE) % (str(urn), incoming.text)
        )

        # look up any message responses
        outgoing = Msg.objects.filter(org=self.org, pk__gt=incoming.pk, direction=OUTGOING).order_by("sent_on")
        for response in outgoing:
            self.echo(
                (Fore.GREEN + "[%s] " + Fore.YELLOW + "<<" + Fore.MAGENTA + " %s" + Fore.WHITE)
                % (str(urn), response.text)
            )
Exemplo n.º 11
0
def reduce_event(event):
    new_event = copy_keys(event, {"type", "msg"})

    if "msg" in new_event:
        new_event["msg"] = copy_keys(event["msg"], {"text", "urn", "channel", "attachments"})
        new_msg = new_event["msg"]

        # legacy events are re-constructed from real messages which have their text stripped
        if "text" in new_msg:
            new_msg["text"] = new_msg["text"].strip()

        # legacy events have absolute paths for attachments, new have relative
        if "attachments" in new_msg:
            abs_prefix = f"https://{settings.AWS_BUCKET_DOMAIN}/"
            new_msg["attachments"] = [a.replace(abs_prefix, "") for a in new_msg["attachments"]]

        # new engine events might have params on URNs that we're not interested in
        if "urn" in new_msg:
            scheme, path, query, fragment = URN.to_parts(new_msg["urn"])
            new_msg["urn"] = URN.from_parts(scheme, path, None, fragment)

    return new_event
Exemplo n.º 12
0
 def add_contact_urn(self, scheme, path):
     urns = [str(u) for u in self.contact.get_urns()]
     urns.append(URN.from_parts(scheme, path))
     self._log_event("contact_urns_changed", urns=urns)
     return self