Unisender API functions in Python

A few functions in Python for Unisender email marketing automation. Tested on Unisender. Probably works on Selzy too (2022-2023).

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}
"""