Skip to content

Instantly share code, notes, and snippets.

@lachesis
Last active February 25, 2020 23:56
Show Gist options
  • Save lachesis/30c375ffdc4ad30dd47623d51e5318fd to your computer and use it in GitHub Desktop.
Save lachesis/30c375ffdc4ad30dd47623d51e5318fd to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
# Subscribes contacts in a CSV file to a Close campaign
# Requires python3.7 or newer (f-strings)
# Prepare: save this script in close_sub.py and `pip3 install closeio`
# CSV should be two columns with email followed by exact Sequence name on Close
# Usage: KEY=api_yourcloseiokey LIVE=0 python3 close_sub.py leads.csv
import csv
import fileinput
import os
import re
import sys
import traceback
import urllib
import logging
from closeio_api import Client as CloseIO_API
API_KEY = os.getenv('KEY')
LIVE = os.getenv('LIVE') == '1'
g_sender_email = None
g_sender_name = None
g_sender_account_id = None
logger = logging.getLogger(__name__)
def subscribe(client, seq_id, contact_id, contact_email):
d = client.post('sequence_subscription', data={
"sequence_id": seq_id,
"contact_id": contact_id,
"contact_email": contact_email,
"sender_account_id": g_sender_account_id,
"sender_name": g_sender_name,
"sender_email": g_sender_email,
})
print(d)
def main():
global g_sender_name, g_sender_email, g_sender_account_id
c = CloseIO_API(API_KEY, development=False)
logging.basicConfig(level=logging.INFO)
if not API_KEY:
print("error: supply API key with `KEY=api_xyz python3 close_sub.py`", file=sys.stderr)
return
# Find us
me = c.get('me')
g_sender_email = me['email']
g_sender_name = me['first_name'] + ' ' + me['last_name']
g_sender_account_id = me['email_accounts'][0]['id']
print(f"Running in {'live' if LIVE else 'dry'} mode as {g_sender_email!r} / {g_sender_name!r}", file=sys.stderr)
# find sequence IDs for all sequences by name
d2 = c.get('sequence')
seq_lookup = {n['name']: n['id'] for n in d2['data']}
failures = []
# import the CSV from fileinput
# expects: (email, campaign_name)
csvreader = csv.reader(fileinput.input(mode='r'), delimiter=',')
for row in csvreader:
if len(row) != 2:
continue
email, campaign_name = row
try:
# Find the sequence they deserve
seq_id = seq_lookup.get(campaign_name)
if seq_id is None:
print(f"cannot find sequence {campaign_name!r} for email {email!r}", file=sys.stderr)
# Find the lead
leads = c.get('lead/?query=' + urllib.parse.quote(email))
# Find all contacts for the lead
contacts = [contact for row in leads['data'] for contact in row['contacts']]
# Find our contact for the lead
ours = [ct for ct in contacts if any(e['email'].lower() == email.lower() for e in ct['emails'])]
if len(ours) != 1:
print(f"weird... email {email} has non-unique contacts {ours}", file=sys.stderr)
continue
lead = ours[0]
# Find which of the exact lead emails matches our inputs - corrects for different email casings
lead_email = [
e['email']
for e in lead['emails']
if e['email'].lower() == email.lower()
][0]
# Subscribe our contact!
print(f"would subscribe {email!r} aka {lead['name']!r} {lead['title']!r} with id {lead['id']} to campaign {campaign_name!r} (id {seq_id})", file=sys.stderr)
if LIVE:
subscribe(c, seq_id, lead['id'], lead_email)
except Exception:
logger.exception("Exception processing email %r", email)
failures.append(email)
print("The following contacts failed to subscribe:\n" + "\n".join(failures))
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment