A few functions in Python for Unisender email marketing automation. Tested on Unisender. Probably works on Selzy too.
Advantages:
1. As vanilla as it can be - no dependencies. Only uses built-in JSON and requests python libraries
2. As simple as it can be - first function combines parameters into payload and URL for the API, the second function is used for sending the request.
3. It uses https and sends all sensitive data as a payload, not in URL (though Unisender/Selzy allows that as well). Therefore your sensitive data won't end up being visible (probably :))
import json
import requests
UNI_TOKEN = "your token"
UNI_BASE_URL = "https://api.unisender.com/ru/api/"
def combine_params(param_dict):
url_params = ""
if param_dict != {}:
for param in param_dict:
if url_params =="":
url_params = url_params + param + "=" + param_dict.get(param)
else:
url_params = url_params + "&" + param + "=" + param_dict.get(param)
return url_params
def post_request(function, param_dict, data):
url = UNI_BASE_URL
data['api_key'] = UNI_TOKEN
param_dict["format"] = "json"
final_url = url + function + "?" + combine_params(param_dict)
response = requests.post(final_url,data = data)
return response
# ------------------------------------------- GET LISTS -----------------------------------------------------
# https://www.unisender.com/ru/support/api/contacts/getlists/
# https://selzy.com/en/support/api/contacts/getlists/
def getLists ():
response = post_request("getLists",param_dict={},data={})
list_IDs = {}
for l in json.loads(response.text)['result']:
list_IDs[l["id"]]=l["title"]
list_IDs = {y:x for x,y in list_IDs.items()} # Switching keys and values in dict to get name - ID dict
return list_IDs
"""
example response:
{'list1': 8,
'list2': 5}
"""
# ------------------------------------------- GET CONTACT ----------------------------------------------------
# inputs email
# https://www.unisender.com/ru/support/api/contacts/getcontact/
# https://selzy.com/en/support/api/contacts/getcontact/
def getContact (email, include_lists="1", include_fields="1", include_details="1"):
response = post_request("getContact",param_dict={"include_lists":include_lists,
"include_fields":include_fields,
"include_details":include_details},data={'email':email})
contact_info = json.loads(response.text)["result"]
return contact_info
# example response:
# {'email': {'added_at': '2022-04-07 20:00:52',
# 'availability': 'available',
# 'email': 'contact_email_AT_domain_DOT_zone',
# 'last_click_datetime': None,
# 'last_delivery_datetime': None,
# 'last_read_datetime': None,
# 'last_send_datetime': None,
# 'rating': None,
# 'status': 'new'},
# 'fields': {},
# 'lists': [{'added_at': '2022-04-07 20:00:52', 'id': 8, 'status': 'active'}]}
#--------------------------------------SUBSCRIBE -----------------------------------------
# https://www.unisender.com/ru/support/api/contacts/subscribe/
# https://selzy.com/en/support/api/contacts/subscribe/
#
# email
# list_ids [list]
# tags [list]
# doi - double opt-in mode (0 - doi will be sent,
# 3 - silent adding
# 4 - check if contact is in other lists. If active/new then no doi. If not = doi)
# 0 and 4 subscribe only after contact gets confirmation
# overwrite modes 0 - only add news, don't overwrite existing
# 1 - full overwrite and deleting all !!! contact is removed from all other lists!!!
# 2 - update existing and preserving existing
# field_values_dict - {field_name (from unisender, no {}), : value}
#
def subscribe (email, list_ids, tags, doi, overwrite,field_values_dict=None):
data = {}
data ["fields[email]"] = email
if field_values_dict !=None:
for field in field_values_dict:
data["fields["+str(field)+"]"]=field_values_dict.get(field)
data ["list_ids"] = ",".join([str(id) for id in list_ids])
param_dict = {}
param_dict["tags"]=",".join(tags)
param_dict["double_optin"] = str(doi)
param_dict["overwrite"] = str(overwrite)
print(data)
print(param_dict)
response = post_request("subscribe", param_dict, data)
return json.loads(response.text)
"""
output example:
{ID:"person"}
"""
# --------------------------------------UNSUBSCRIBE------------------------------------------
# https://www.unisender.com/ru/support/api/contacts/unsubscribe/
# https://selzy.com/en/support/api/contacts/unsubscribe/
#
# NOT TESTED !!! reason - not needed. Using exclusions instead
# input email
# input list_ids [list]
# ATTENTION ! AFTER THIS CONTACT CAN ONLY BE SUBSCRIBED BY MANUALLY CONFIRMING (DOI)
def unsubscribe(email, list_ids):
data, param_dict = {}, {}
data ["contact_type"] = "email" #!!!! can also be phone if needed !!!
data ["contact"] = email
param_dict ["list_ids="] = ",".join([str(id) for id in list_ids])
response = post_request("unsubscribe", param_dict, data)
return response.text
# on sucess - empty object
# on error/notification - msg
# -------------------------------------- EXCLUDE --------------------------------------
# https://www.unisender.com/ru/support/api/contacts/exclude/
# https://selzy.com/en/support/api/contacts/exclude/
# input email
# input list_ids [list]
# removes contact from the list, but does not mark as unsubscribed
# can be re-subscribed using api. DEFAULT METHOD!!!
def exclude(email, list_ids):
data, param_dict = {},{}
data ["contact_type"] = "email" #!!!! can also be phone if needed !!!
data ["contact"] = email
param_dict ["list_ids"] = ",".join([str(id) for id in list_ids])
response = post_request("exclude", param_dict, data)
return response.text
# empty object on success
# ----------------------------- IS CONTACT IN LISTS? ---------------------------------------------
# https://www.unisender.com/ru/support/api/contacts/iscontactinlists/
# https://selzy.com/en/support/api/contacts/iscontactinlists/
# input email
# input list_ids [list]
# condition "or" "and" as string
def isContactInLists(email, list_ids, condition):
data, param_dict = {},{}
data ["email"] = email
data ["list_ids"] = ",".join([str(id) for id in list_ids])
data ["condition"] = condition
response = post_request("isContactInLists", param_dict, data)
return json.loads(response.text)["result"]
# true/false
# ------------------------------- GET FIELD VALUES FOR A CONTACT -------------------------------------------
# https://www.unisender.com/ru/support/api/inputs/getcontactfieldvalues/
# https://selzy.com/en/support/api/inputs/getcontactfieldvalues/
# email
# field_ids - [list]
def getContactFieldValues(email, field_ids):
data, param_dict = {},{}
data ["email"] = email
data ["field_ids"] = ",".join([str(id) for id in field_ids])
response = post_request("getContactFieldValues", param_dict, data)
return json.loads(response.text)["result"]
"""
Response:
{'fieldValues': {'1': None,
'2': None,
'3': None,
'4': None,
'5': None,
'6': None,
'7': None,
'8': None,
'9': None}}
"""
# ------------------------------- GET ALL FIELDS - IDS & PARAMETERS ---------------------------------------
# https://www.unisender.com/ru/support/api/inputs/getfields/
# https://selzy.com/en/support/api/inputs/getfields/
# list all fields and field descriptions
def getFields():
response = post_request("getFields", param_dict={}, data={})
field_IDs={}
for field in json.loads(response.text)['result']:
field_IDs[field["id"]] = field["name"]
field_IDs = {y:x for x,y in field_IDs.items()} # Switching keys and values in dict to get name - ID dict
return json.loads(response.text)["result"]
# example:
"""
Out:
[{'id': 1,
'is_visible': 1,
'name': 'FName',
'public_name': 'First Name',
'type': 'string',
'view_pos': 1},
{'id': 3,
'is_visible': 1,
'name': 'LName',
'public_name': 'Last name',
'type': 'text',
'view_pos': 1},
{'id': 4,
'is_visible': 1,
'name': 'Last_Action_Date',
'public_name': 'Last action date',
'type': 'date',
'view_pos': 1}]
"""
# ----------------------------- GET ALL TAG IDs ---------------------------------------
# https://www.unisender.com/ru/support/api/inputs/gettags/
# https://selzy.com/en/support/api/inputs/gettags/
#
def getTags ():
response = post_request("getTags", param_dict={}, data={})
tag_IDs = {}
for tag in json.loads(response.text)['result']:
tag_IDs[tag["id"]] = tag["name"]
tag_IDs = {y:x for x,y in tag_IDs.items()} # Switching keys and values in dict to get name - ID dict
return tag_IDs
"""
{'tag1': 3,
'tag2': 5,
'tag3': 3,
'tag4': 4}
"""