From 23ab6769ff7f31230f40d9e1010ba5373916e5f3 Mon Sep 17 00:00:00 2001 From: Denilson Velasquez <66847768+DeeTheDev@users.noreply.github.com> Date: Mon, 29 Jul 2024 17:06:34 -0400 Subject: [PATCH] Fix migration and add contact search capability Fix migration file numbers naming. Add search cabaility to oye contacts GET http call. Use it to search for members by phone number. Update method namings and descriptions --- ...49_oye_contacts.rb => 050_oye_contacts.rb} | 0 lib/suma/api/preferences.rb | 2 +- lib/suma/member/oye_attributes.rb | 25 +++++++------------ lib/suma/message/preferences.rb | 4 +-- lib/suma/oye.rb | 9 ++++--- spec/data/oye/contacts_search_get.json | 17 +++++++++++++ spec/suma/api/preferences_spec.rb | 6 +++-- 7 files changed, 39 insertions(+), 24 deletions(-) rename db/migrations/{049_oye_contacts.rb => 050_oye_contacts.rb} (100%) create mode 100644 spec/data/oye/contacts_search_get.json diff --git a/db/migrations/049_oye_contacts.rb b/db/migrations/050_oye_contacts.rb similarity index 100% rename from db/migrations/049_oye_contacts.rb rename to db/migrations/050_oye_contacts.rb diff --git a/lib/suma/api/preferences.rb b/lib/suma/api/preferences.rb index ad0d9fd5..8826a75e 100644 --- a/lib/suma/api/preferences.rb +++ b/lib/suma/api/preferences.rb @@ -16,7 +16,7 @@ def update_preferences(member) subscr = member.preferences!.subscription(k) invalid!("subscription #{k} is invalid") if subscr.nil? subscr.set_from_opted_in(optin) - subscr.sync_oye_contact_marketing_preferences + subscr.update_oye_contact_marketing_preferences end member.preferences.save_changes end diff --git a/lib/suma/member/oye_attributes.rb b/lib/suma/member/oye_attributes.rb index 225e7647..ccec7bf2 100644 --- a/lib/suma/member/oye_attributes.rb +++ b/lib/suma/member/oye_attributes.rb @@ -8,23 +8,16 @@ def initialize(member) @marketing_key = Suma::Oye.sms_marketing_preferences_key end - # If contact ID is missing, add it to member. Always update oye contact - # sms preferences so that member sms preferences stay in sync. - def upsert_sms_status + # If contact ID is missing, attempt to find and add it to member. + # Only sync/update contact status when contact ID is set. + def update_contact_sms_status return unless Suma::Oye.configured? - self._add_contact_id if self.contact_id.blank? - self._update_contact_status - end - - def _add_contact_id - contacts = Suma::Oye.get_contacts - return unless (contact = contacts.find { |c| Suma::PhoneNumber::US.normalize(c.fetch("number")) === @member.phone }) - @member.update(oye_contact_id: contact.fetch("id").to_s) - end - - def _update_contact_status - marketing_subscr = self.marketing_subscription - oye_sms_status = Suma::Oye::STATUS_MATCH.invert.fetch(marketing_subscr[:opted_in]) + if self.contact_id.blank? + contacts = Suma::Oye.get_contacts(Suma::PhoneNumber.format_e164(@member.phone)) + return if contacts.empty? + @member.update(oye_contact_id: contacts.first.fetch("id").to_s) + end + oye_sms_status = Suma::Oye::STATUS_MATCH.invert.fetch(self.marketing_subscription[:opted_in]) Suma::Oye.bulk_update_contacts(contacts: [{id: self.contact_id, status: oye_sms_status}]) end diff --git a/lib/suma/message/preferences.rb b/lib/suma/message/preferences.rb index 7cb06622..864c87da 100644 --- a/lib/suma/message/preferences.rb +++ b/lib/suma/message/preferences.rb @@ -19,8 +19,8 @@ def set_from_opted_in(optin) self.model.set(self.optout_field => !optin) end - def sync_oye_contact_marketing_preferences - self.model.member.oye.upsert_sms_status if self.key === Suma::Oye.sms_marketing_preferences_key + def update_oye_contact_marketing_preferences + self.model.member.oye.update_contact_sms_status if self.key === Suma::Oye.sms_marketing_preferences_key end end diff --git a/lib/suma/oye.rb b/lib/suma/oye.rb index 0d1d90b3..8feade31 100644 --- a/lib/suma/oye.rb +++ b/lib/suma/oye.rb @@ -30,9 +30,12 @@ def self.api_headers } end - def self.get_contacts + # Query contacts by phone number, first name or last name + def self.get_contacts(search=nil) + query = {} + query = query.merge(search:) unless search.nil? response = Suma::Http.get( - self.api_root + "/contacts", headers: self.api_headers, logger: self.logger, + self.api_root + "/contacts", query, headers: self.api_headers, logger: self.logger, ) return response.parsed_response end @@ -55,7 +58,7 @@ def self.sync_contact_sms_preferences contacts = self.get_contacts contacts.each do |c| member = Suma::Member[oye_contact_id: c.fetch("id")] - unless member + if member.nil? phone = Suma::PhoneNumber::US.normalize(c.fetch("number")) next unless Suma::PhoneNumber::US.valid_normalized?(phone) next unless (member = Suma::Member[phone:]) diff --git a/spec/data/oye/contacts_search_get.json b/spec/data/oye/contacts_search_get.json new file mode 100644 index 00000000..195509f7 --- /dev/null +++ b/spec/data/oye/contacts_search_get.json @@ -0,0 +1,17 @@ +[ + { + "id": "1", + "number": "+12223334444", + "first_name": "Hola", + "last_name": "Adios", + "created_at": "Mon, 03 Jun 2024 16:20:39.567013000 EDT -04:00", + "updated_at": "Mon, 03 Jun 2024 16:20:39.567013000 EDT -04:00", + "organization_id": "1", + "status": "inactive", + "state": null, + "aasm_state": null, + "state_metadata": null, + "language": "", + "eid": "" + } +] \ No newline at end of file diff --git a/spec/suma/api/preferences_spec.rb b/spec/suma/api/preferences_spec.rb index 1809f89c..6de89584 100644 --- a/spec/suma/api/preferences_spec.rb +++ b/spec/suma/api/preferences_spec.rb @@ -59,6 +59,7 @@ Suma::Oye.auth_token = "fake token" member.update(oye_contact_id: "1") contact_status_update_req = stub_request(:put, "https://app.oyetext.org/api/v1/contacts/bulk_update"). + with(body: {contacts: [{id: "1", status: "inactive"}]}). to_return(fixture_response("oye/bulk_update_contacts"), status: 200) post "/v1/preferences/public", @@ -72,9 +73,10 @@ it "updates contact id on member if it is blank" do Suma::Oye.auth_token = "fake token" - member.update(phone: "12223334444", oye_contact_id: "") + member.update(oye_contact_id: "") get_contacts_req = stub_request(:get, "https://app.oyetext.org/api/v1/contacts"). - to_return(fixture_response("oye/contacts_get"), status: 200) + with(query: {search: Suma::PhoneNumber.format_e164(member.phone)}). + to_return(fixture_response("oye/contacts_search_get"), status: 200) status_update_req = stub_request(:put, "https://app.oyetext.org/api/v1/contacts/bulk_update"). to_return(fixture_response("oye/bulk_update_contacts"), status: 200)