Skip to content

Commit

Permalink
Allow ActionNetwork upsert_person to not change mobile opt-in status
Browse files Browse the repository at this point in the history
Prior behavior opted-in all phone numbers by default, and the only
alternative would be to opt-out phone numbers sent to the API. This
update allows for not changing the opt-in status of the number, and
changes the default from opt-in to no change. This is a more
reasonable and legally compliant default behavior than opting-in.
  • Loading branch information
austinweisgrau committed Dec 12, 2024
1 parent a9b45c2 commit 1ff2790
Showing 1 changed file with 22 additions and 14 deletions.
36 changes: 22 additions & 14 deletions parsons/action_network/action_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import logging
import re
import warnings
from typing import Dict, List, Union
from typing import Dict, List, Union, Literal
from parsons import Table
from parsons.utilities import check_env
from parsons.utilities.api_connector import APIConnector
Expand Down Expand Up @@ -1127,7 +1127,7 @@ def upsert_person(
languages_spoken=None,
postal_addresses=None,
mobile_number=None,
mobile_status="subscribed",
mobile_status: Literal["subscribed", "unsubscribed", None] = None,
background_processing=False,
**kwargs,
):
Expand Down Expand Up @@ -1181,7 +1181,10 @@ def upsert_person(
- "subscribed"
- "unsubscribed"
mobile_status:
'subscribed' or 'unsubscribed'
None, 'subscribed' or 'unsubscribed'. If included, will update the SMS opt-in
status of the phone in ActionNetwork. If not included, won't update the status.
None by default, causes no updates to mobile number status. New numbers are set
to "unsubscribed" by default.
background_request: bool
If set `true`, utilize ActionNetwork's "background processing". This will return
an immediate success, with an empty JSON body, and send your request to the
Expand Down Expand Up @@ -1211,27 +1214,31 @@ def upsert_person(

mobile_numbers_field = None
if isinstance(mobile_number, str):
mobile_numbers_field = [
{"number": re.sub("[^0-9]", "", mobile_number), "status": mobile_status}
]
mobile_numbers_field = [{"number": re.sub("[^0-9]", "", mobile_number)}]
elif isinstance(mobile_number, int):
mobile_numbers_field = [{"number": str(mobile_number), "status": mobile_status}]
mobile_numbers_field = [{"number": str(mobile_number)}]
elif isinstance(mobile_number, list):
if len(mobile_number) > 1:
raise ("Action Network allows only 1 phone number per activist")
if isinstance(mobile_number[0], list):
mobile_numbers_field = [
{"number": re.sub("[^0-9]", "", cell), "status": mobile_status}
for cell in mobile_number
{"number": re.sub("[^0-9]", "", cell)} for cell in mobile_number
]
mobile_numbers_field[0]["primary"] = True
if isinstance(mobile_number[0], int):
mobile_numbers_field = [
{"number": cell, "status": mobile_status} for cell in mobile_number
]
mobile_numbers_field = [{"number": cell} for cell in mobile_number]
mobile_numbers_field[0]["primary"] = True
if isinstance(mobile_number[0], dict):
mobile_numbers_field = mobile_number

# Including status in this field changes the opt-in status in
# ActionNetwork. This is not always desireable, so we should
# only do so when a status is included.
if mobile_status and mobile_numbers_field:
for field in mobile_numbers_field:
field["status"] = mobile_status

# If the mobile_number field is passed a list of dictionaries, just use that directly
if mobile_number and isinstance(mobile_number, list) and isinstance(mobile_number[0], dict):
mobile_numbers_field = mobile_number

if not email_addresses_field and not mobile_numbers_field:
raise (
Expand Down Expand Up @@ -1261,6 +1268,7 @@ def upsert_person(
url = f"{self.api_url}/people"
if background_processing:
url = f"{url}?background_processing=true"

response = self.api.post_request(url, data=json.dumps(data))

identifiers = response["identifiers"]
Expand Down

0 comments on commit 1ff2790

Please sign in to comment.