def contact_resolve(self, org_id: int, channel_id: int, urn: str): org = Org.objects.get(id=org_id) user = get_anonymous_user() contact_urn = ContactURN.lookup(org, urn) if contact_urn: contact = contact_urn.contact else: contact = create_contact_locally(org, user, name="", language="", urns=[urn], fields={}, group_uuids=[]) contact_urn = ContactURN.lookup(org, urn) return { "contact": { "id": contact.id, "uuid": str(contact.uuid), "name": contact.name }, "urn": { "id": contact_urn.id, "identity": contact_urn.identity }, }
def create_contact_locally(org, user, name, language, urns, fields, group_uuids, status=Contact.STATUS_ACTIVE, last_seen_on=None): orphaned_urns = {} for urn in urns: existing = ContactURN.lookup(org, urn) if existing: if existing.contact_id: raise MailroomException( "contact/create", None, {"error": "URNs in use by other contacts"}) else: orphaned_urns[urn] = existing contact = Contact.objects.create( org=org, name=name, language=language, created_by=user, modified_by=user, created_on=timezone.now(), status=status, last_seen_on=last_seen_on, ) update_urns_locally(contact, urns) update_fields_locally(user, contact, fields) update_groups_locally(contact, group_uuids, add=True) return contact
def create_group_contacts(self, spec, org, user): self._log(f"Generating group contacts...") for g in spec["groups"]: size = int(g.get("size", 0)) if size > 0: group = ContactGroup.user_groups.get(org=org, name=g["name"]) contacts = [] for i in range(size): urn = f"tel:+250788{i:06}" contact = ContactURN.lookup(org, urn) if not contact: contact = Contact.create(org, user, name="", language="", urns=[urn], fields={}, groups=[]) contacts.append(contact) Contact.bulk_change_group(user, contacts, group, add=True) self._log(self.style.SUCCESS("OK") + "\n")
def contact_resolve(self, org_id: int, channel_id: int, urn: str): org = Org.objects.get(id=org_id) user = get_anonymous_user() try: urn = URN.normalize(urn, org.default_country_code) if not URN.validate(urn, org.default_country_code): raise ValueError() except ValueError: raise MailroomException("contact/resolve", None, {"error": "invalid URN"}) contact_urn = ContactURN.lookup(org, urn) if contact_urn: contact = contact_urn.contact else: contact = create_contact_locally(org, user, name="", language="", urns=[urn], fields={}, group_uuids=[]) contact_urn = ContactURN.lookup(org, urn) return { "contact": { "id": contact.id, "uuid": str(contact.uuid), "name": contact.name }, "urn": { "id": contact_urn.id, "identity": contact_urn.identity }, }
def update_urns_locally(contact, urns: list[str]): country = contact.org.default_country_code priority = ContactURN.PRIORITY_HIGHEST urns_created = [] # new URNs created urns_attached = [] # existing orphan URNs attached urns_retained = [] # existing URNs retained for urn_as_string in urns: normalized = URN.normalize(urn_as_string, country) urn = ContactURN.lookup(contact.org, normalized) if not urn: urn = ContactURN.create(contact.org, contact, normalized, priority=priority) urns_created.append(urn) # unassigned URN or different contact elif not urn.contact or urn.contact != contact: urn.contact = contact urn.priority = priority urn.save() urns_attached.append(urn) else: if urn.priority != priority: urn.priority = priority urn.save() urns_retained.append(urn) # step down our priority priority -= 1 # detach any existing URNs that weren't included urn_ids = [u.pk for u in (urns_created + urns_attached + urns_retained)] urns_detached = ContactURN.objects.filter(contact=contact).exclude( id__in=urn_ids) urns_detached.update(contact=None)
def create_channel_event(self, channel, urn, event_type, occurred_on=None, extra=None): urn_obj = ContactURN.lookup(channel.org, urn, country_code=channel.country) if urn_obj: contact = urn_obj.contact else: contact = self.create_contact(urns=[urn]) urn_obj = contact.urns.get() return ChannelEvent.objects.create( org=channel.org, channel=channel, contact=contact, contact_urn=urn_obj, occurred_on=occurred_on or timezone.now(), event_type=event_type, extra=extra, )