def handle_response(self, status, data): if status == 400: raise BadRequest(json_to_py(data)) elif status == 401: json_data = json_to_py(data) if json_data.Code == 121: raise ExpiredOAuthToken(json_data) raise Unauthorized(json_data) elif status == 404: raise NotFound() elif status in range(400, 500): raise ClientError() elif status in range(500, 600): raise ServerError() return data
def add(self, email_address, name): """Adds an administrator to an account.""" body = { "EmailAddress": email_address, "Name": name} response = self._post("/admins.json", json.dumps(body)) return json_to_py(response)
def transfer_credits(self, credits, can_use_my_credits_when_they_run_out): """Transfer credits to or from this client. :param credits: An Integer representing the number of credits to transfer. This value may be either positive if you want to allocate credits from your account to the client, or negative if you want to deduct credits from the client back into your account. :param can_use_my_credits_when_they_run_out: A Boolean value representing which, if set to true, will allow the client to continue sending using your credits or payment details once they run out of credits, and if set to false, will prevent the client from using your credits to continue sending until you allocate more credits to them. :returns: An object of the following form representing the result: { AccountCredits # Integer representing credits in your account now ClientCredits # Integer representing credits in this client's account now } """ body = { "Credits": credits, "CanUseMyCreditsWhenTheyRunOut": can_use_my_credits_when_they_run_out } response = self._post(self.uri_for('credits'), json.dumps(body)) return json_to_py(response)
def create_webhook(self, events, url, payload_format): """Creates a new webhook for the specified events (an array of strings). Valid events are "Subscribe", "Deactivate", and "Update". Valid payload formats are "json", and "xml".""" body = {"Events": events, "Url": url, "PayloadFormat": payload_format} response = self._post(self.uri_for("webhooks"), json.dumps(body)) return json_to_py(response)
def create(self, client_id, name, html_url, zip_url): """Creates a new email template.""" body = {"Name": name, "HtmlPageURL": html_url, "ZipFileURL": zip_url} response = self._post("/templates/%s.json" % client_id, json.dumps(body)) self.template_id = json_to_py(response) return self.template_id
def import_subscribers(self, list_id, subscribers, resubscribe, queue_subscription_based_autoresponders=False, restart_subscription_based_autoresponders=False): """Imports subscribers into a subscriber list.""" body = { "Subscribers": subscribers, "Resubscribe": resubscribe, "QueueSubscriptionBasedAutoresponders": queue_subscription_based_autoresponders, "RestartSubscriptionBasedAutoresponders": restart_subscription_based_autoresponders } try: response = self._post("/subscribers/%s/import.json" % list_id, json.dumps(body)) except BadRequest as br: # Subscriber import will throw BadRequest if some subscribers are not imported # successfully. If this occurs, we want to return the ResultData property of # the BadRequest exception (which is of the same "form" as the response we'd # receive upon a completely successful import) if hasattr(br.data, 'ResultData'): return br.data.ResultData else: raise br return json_to_py(response)
def get(self, client_id=None, email_address=None): """Gets a person by client ID and email address.""" params = {"email": email_address or self.email_address} response = self._get("/clients/%s/people.json" % (client_id or self.client_id), params=params) return json_to_py(response)
def add(self, list_id, email_address, name, custom_fields, resubscribe, consent_to_track, restart_subscription_based_autoresponders=False): """Adds a subscriber to a subscriber list.""" consent_to_track = validate_consent_to_track(consent_to_track) body = { "EmailAddress": email_address, "Name": name, "CustomFields": custom_fields, "Resubscribe": resubscribe, "ConsentToTrack": consent_to_track, "RestartSubscriptionBasedAutoresponders": restart_subscription_based_autoresponders } response = self._post("/subscribers/%s.json" % list_id, json.dumps(body)) return json_to_py(response)
def get(self, list_id=None, email_address=None): """Gets a subscriber by list ID and email address.""" params = {"email": email_address or self.email_address} response = self._get("/subscribers/%s.json" % (list_id or self.list_id), params=params) return json_to_py(response)
def create(self, client_id, subject, name, from_name, from_email, reply_to, html_url, text_url, list_ids, segment_ids): """Creates a new campaign for a client. :param client_id: String representing the ID of the client for whom the campaign will be created. :param subject: String representing the subject of the campaign. :param name: String representing the name of the campaign. :param from_name: String representing the from name for the campaign. :param from_email: String representing the from address for the campaign. :param reply_to: String representing the reply-to address for the campaign. :param html_url: String representing the URL for the campaign HTML content. :param text_url: String representing the URL for the campaign text content. Note that text_url is optional and if None or an empty string, text content will be automatically generated from the HTML content. :param list_ids: Array of Strings representing the IDs of the lists to which the campaign will be sent. :param segment_ids: Array of Strings representing the IDs of the segments to which the campaign will be sent. :returns String representing the ID of the newly created campaign. """ body = { "Subject": subject, "Name": name, "FromName": from_name, "FromEmail": from_email, "ReplyTo": reply_to, "HtmlUrl": html_url, "TextUrl": text_url, "ListIDs": list_ids, "SegmentIDs": segment_ids} response = self._post("/campaigns/%s.json" % client_id, json.dumps(body)) self.campaign_id = json_to_py(response) return self.campaign_id
def external_session_url(self, email, chrome, url, integrator_id, client_id): """ Get a URL which initiates a new external session for the user with the given email. Full details: http://www.campaignmonitor.com/api/account/#single_sign_on :param email: String The representing the email address of the Campaign Monitor user for whom the login session should be created. :param chrome: String representing which 'chrome' to display - Must be either "all", "tabs", or "none". :param url: String representing the URL to display once logged in. e.g. "/subscribers/" :param integrator_id: String representing the Integrator ID. You need to contact Campaign Monitor support to get an Integrator ID. :param client_id: String representing the Client ID of the client which should be active once logged in to the Campaign Monitor account. :returns Object containing a single field SessionUrl which represents the URL to initiate the external Campaign Monitor session. """ body = { "Email": email, "Chrome": chrome, "Url": url, "IntegratorID": integrator_id, "ClientID": client_id} response = self._put('/externalsession.json', json.dumps(body)) return json_to_py(response)
def classic_email_groups(self, client_id=None): """Gets the list of classic email groups.""" if client_id is None: response = self._get("/transactional/classicEmail/groups") else: response = self._get( "/transactional/classicEmail/groups?clientID=%s" % client_id) return json_to_py(response)
def create(self, list_id, title, rulegroups): """Creates a new segment.""" body = { "Title": title, "RuleGroups": rulegroups} response = self._post("/segments/%s.json" % list_id, json.dumps(body)) self.segment_id = json_to_py(response) return self.segment_id
def create(self, list_id, title, rulegroups): """Creates a new segment.""" body = { "Title": title, "RuleGroups": rulegroups} response = self._post("/segments/%s.json" % list_id, json.dumps(body)) self.segment_id = json_to_py(response) return self.segment_id
def recipients(self, page=1, page_size=1000, order_field="email", order_direction="asc"): """Retrieves the recipients of this campaign.""" params = { "page": page, "pagesize": page_size, "orderfield": order_field, "orderdirection": order_direction} response = self._get(self.uri_for("recipients"), params=params) return json_to_py(response)
def smart_email_list(self, status="all", client_id=None): """Gets the smart email list.""" if client_id is None: response = self._get( "/transactional/smartEmail?status=%s" % status) else: response = self._get( "/transactional/smartEmail?status=%s&clientID=%s" % (status, client_id)) return json_to_py(response)
def suppressionlist(self, page=1, page_size=1000, order_field="email", order_direction="asc"): """Gets this client's suppression list.""" params = { "page": page, "pagesize": page_size, "orderfield": order_field, "orderdirection": order_direction} response = self._get(self.uri_for("suppressionlist"), params=params) return json_to_py(response)
def get(self, list_id=None, email_address=None, include_tracking_preference=False): """Gets a subscriber by list ID and email address.""" params = { "email": email_address or self.email_address, "includetrackingpreference": include_tracking_preference, } response = self._get("/subscribers/%s.json" % (list_id or self.list_id), params=params) return json_to_py(response)
def add(self, client_id, email_address, name, access_level, password): """Adds a person to a client. Password is optional and if not supplied, an invitation will be emailed to the person""" body = { "EmailAddress": email_address, "Name": name, "AccessLevel": access_level, "Password": password} response = self._post("/clients/%s/people.json" % client_id, json.dumps(body)) return json_to_py(response)
def create_custom_field(self, field_name, data_type, options=[], visible_in_preference_center=True): """Creates a new custom field for this list.""" body = { "FieldName": field_name, "DataType": data_type, "Options": options, "VisibleInPreferenceCenter": visible_in_preference_center} response = self._post(self.uri_for("customfields"), json.dumps(body)) return json_to_py(response)
def create(self, client_id, name, html_url, zip_url): """Creates a new email template.""" body = { "Name": name, "HtmlPageURL": html_url, "ZipFileURL": zip_url} response = self._post("/templates/%s.json" % client_id, json.dumps(body)) self.template_id = json_to_py(response) return self.template_id
def create_webhook(self, events, url, payload_format): """Creates a new webhook for the specified events (an array of strings). Valid events are "Subscribe", "Deactivate", and "Update". Valid payload formats are "json", and "xml".""" body = { "Events": events, "Url": url, "PayloadFormat": payload_format} response = self._post(self.uri_for("webhooks"), json.dumps(body)) return json_to_py(response)
def bounces(self, date="", page=1, page_size=1000, order_field="date", order_direction="asc"): """Retrieves the bounces for this campaign.""" params = { "date": date, "page": page, "pagesize": page_size, "orderfield": order_field, "orderdirection": order_direction} response = self._get(self.uri_for("bounces"), params=params) return json_to_py(response)
def create(self, company, timezone, country): """Creates a client.""" body = { "CompanyName": company, "TimeZone": timezone, "Country": country} response = self._post("/clients.json", json.dumps(body)) self.client_id = json_to_py(response) return self.client_id
def active(self, date="", page=1, page_size=1000, order_field="email", order_direction="asc"): """Gets the active subscribers for this list.""" params = { "date": date, "page": page, "pagesize": page_size, "orderfield": order_field, "orderdirection": order_direction} response = self._get(self.uri_for("active"), params=params) return json_to_py(response)
def update_custom_field(self, custom_field_key, field_name, visible_in_preference_center): """Updates a custom field belonging to this list.""" custom_field_key = quote(custom_field_key, '') body = { "FieldName": field_name, "VisibleInPreferenceCenter": visible_in_preference_center} response = self._put(self.uri_for("customfields/%s" % custom_field_key), json.dumps(body)) return json_to_py(response)
def update_custom_field(self, custom_field_key, field_name, visible_in_preference_center): """Updates a custom field belonging to this list.""" custom_field_key = quote(custom_field_key, '') body = { "FieldName": field_name, "VisibleInPreferenceCenter": visible_in_preference_center} response = self._put(self.uri_for("customfields/%s" % custom_field_key), json.dumps(body)) return json_to_py(response)
def create_custom_field(self, field_name, data_type, options=[], visible_in_preference_center=True): """Creates a new custom field for this list.""" body = { "FieldName": field_name, "DataType": data_type, "Options": options, "VisibleInPreferenceCenter": visible_in_preference_center} response = self._post(self.uri_for("customfields"), json.dumps(body)) return json_to_py(response)
def add(self, client_id, email_address, name, access_level, password): """Adds a person to a client. Password is optional and if not supplied, an invitation will be emailed to the person""" body = { "EmailAddress": email_address, "Name": name, "AccessLevel": access_level, "Password": password } response = self._post("/clients/%s/people.json" % client_id, json.dumps(body)) return json_to_py(response)
def smart_email_send(self, smart_email_id, to, cc=None, bcc=None, attachments=None, data=None, add_recipients_to_list=None): """Sends the smart email.""" body = { "To": to, "CC": cc, "BCC": bcc, "Attachments": attachments, "Data": data, "AddRecipientsToList": add_recipients_to_list} response = self._post("/transactional/smartEmail/%s/send" % smart_email_id, json.dumps(body)) return json_to_py(response)
def create(self, client_id, title, unsubscribe_page, confirmed_opt_in, confirmation_success_page, unsubscribe_setting="AllClientLists"): """Creates a new list for a client.""" body = { "Title": title, "UnsubscribePage": unsubscribe_page, "ConfirmedOptIn": confirmed_opt_in, "ConfirmationSuccessPage": confirmation_success_page, "UnsubscribeSetting": unsubscribe_setting} response = self._post("/lists/%s.json" % client_id, json.dumps(body)) self.list_id = json_to_py(response) return self.list_id
def create(self, client_id, title, unsubscribe_page, confirmed_opt_in, confirmation_success_page, unsubscribe_setting="AllClientLists"): """Creates a new list for a client.""" body = { "Title": title, "UnsubscribePage": unsubscribe_page, "ConfirmedOptIn": confirmed_opt_in, "ConfirmationSuccessPage": confirmation_success_page, "UnsubscribeSetting": unsubscribe_setting} response = self._post("/lists/%s.json" % client_id, json.dumps(body)) self.list_id = json_to_py(response) return self.list_id
def active(self, date="", page=1, page_size=1000, order_field="email", order_direction="asc", include_tracking_preference=False): """Gets the active subscribers for this list.""" params = { "date": date, "page": page, "pagesize": page_size, "orderfield": order_field, "orderdirection": order_direction, "includetrackingpreference": include_tracking_preference, } response = self._get(self.uri_for("active"), params=params) return json_to_py(response)
def subscribers(self, date="", page=1, page_size=1000, order_field="email", order_direction="asc", include_tracking_information=False): """Gets the active subscribers in this segment.""" params = { "date": date, "page": page, "pagesize": page_size, "orderfield": order_field, "orderdirection": order_direction, "includetrackinginformation": include_tracking_information } response = self._get(self.uri_for("active"), params=params) return json_to_py(response)
def add(self, list_id, email_address, name, custom_fields, resubscribe, consent_to_track, restart_subscription_based_autoresponders=False): """Adds a subscriber to a subscriber list.""" validate_consent_to_track(consent_to_track) body = { "EmailAddress": email_address, "Name": name, "CustomFields": custom_fields, "Resubscribe": resubscribe, "ConsentToTrack": consent_to_track, "RestartSubscriptionBasedAutoresponders": restart_subscription_based_autoresponders} response = self._post("/subscribers/%s.json" % list_id, json.dumps(body)) return json_to_py(response)
def get(self, list_id=None, email_address=None, include_tracking_preference=False): """Gets a subscriber by list ID and email address.""" params = { "email": email_address or self.email_address, "includetrackingpreference": include_tracking_preference, } response = self._get("/subscribers/%s.json" % (list_id or self.list_id), params=params) return json_to_py(response)
def get_journey_email_response(self, date, page, page_size, order_direction, uri): """Retrieves information for the journey email - based on theuri""" params = {} if date is not None: params["date"] = date if page is not None: params["page"] = page if page_size is not None: params["pagesize"] = page_size if order_direction is not None: params["orderdirection"] = order_direction response = self._get(self.uri_for(uri), params=params) return json_to_py(response)
def recipients(self, page=1, page_size=1000, order_field="email", order_direction="asc"): """Retrieves the recipients of this campaign.""" params = { "page": page, "pagesize": page_size, "orderfield": order_field, "orderdirection": order_direction } response = self._get(self.uri_for("recipients"), params=params) return json_to_py(response)
def bounces(self, date="", page=1, page_size=1000, order_field="date", order_direction="asc"): """Retrieves the bounces for this campaign.""" params = { "date": date, "page": page, "pagesize": page_size, "orderfield": order_field, "orderdirection": order_direction } response = self._get(self.uri_for("bounces"), params=params) return json_to_py(response)
def deleted(self, date="", page=1, page_size=1000, order_field="email", order_direction="asc", include_tracking_preference=False): """Gets the deleted subscribers for this list.""" params = { "date": date, "page": page, "pagesize": page_size, "orderfield": order_field, "orderdirection": order_direction, "includetrackingpreference": include_tracking_preference, } response = self._get(self.uri_for("deleted"), params=params) return json_to_py(response)
def subscribers(self, date="", page=1, page_size=1000, order_field="email", order_direction="asc", include_tracking_information=False): """Gets the active subscribers in this segment.""" params = { "date": date, "page": page, "pagesize": page_size, "orderfield": order_field, "orderdirection": order_direction, "includetrackinginformation": include_tracking_information } response = self._get(self.uri_for("active"), params=params) return json_to_py(response)
def classic_email_send(self, subject, from_address, to, consent_to_track, client_id=None, cc=None, bcc=None, html=None, text=None, attachments=None, track_opens=True, track_clicks=True, inline_css=True, group=None, add_recipients_to_list=None): """Sends a classic email.""" validate_consent_to_track(consent_to_track) body = { "Subject": subject, "From": from_address, "To": to, "CC": cc, "BCC": bcc, "HTML": html, "Text": text, "Attachments": attachments, "TrackOpens": track_opens, "TrackClicks": track_clicks, "InlineCSS": inline_css, "Group": group, "AddRecipientsToList": add_recipients_to_list, "ConsentToTrack": consent_to_track, } if client_id is None: response = self._post("/transactional/classicEmail/send", json.dumps(body)) else: response = self._post( "/transactional/classicEmail/send?clientID=%s" % client_id, json.dumps(body)) return json_to_py(response)
def import_subscribers(self, list_id, subscribers, resubscribe, queue_subscription_based_autoresponders=False, restart_subscription_based_autoresponders=False): """Imports subscribers into a subscriber list.""" body = { "Subscribers": subscribers, "Resubscribe": resubscribe, "QueueSubscriptionBasedAutoresponders": queue_subscription_based_autoresponders, "RestartSubscriptionBasedAutoresponders": restart_subscription_based_autoresponders} try: response = self._post("/subscribers/%s/import.json" % list_id, json.dumps(body)) except BadRequest as br: # Subscriber import will throw BadRequest if some subscribers are not imported # successfully. If this occurs, we want to return the ResultData property of # the BadRequest exception (which is of the same "form" as the response we'd # receive upon a completely successful import) if hasattr(br.data, 'ResultData'): return br.data.ResultData else: raise br return json_to_py(response)
def exchange_token(self, client_id, client_secret, redirect_uri, code): """Exchange a provided OAuth code for an OAuth access token, 'expires in' value and refresh token.""" params = [ ('grant_type', 'authorization_code'), ('client_id', client_id), ('client_secret', client_secret), ('redirect_uri', redirect_uri), ('code', code), ] response = self._post('', urlencode(params), CreateSend.oauth_token_uri, "application/x-www-form-urlencoded") access_token, expires_in, refresh_token = None, None, None r = json_to_py(response) if hasattr(r, 'error') and hasattr(r, 'error_description'): err = "Error exchanging code for access token: " err += "%s - %s" % (r.error, r.error_description) raise Exception(err) access_token, expires_in, refresh_token = r.access_token, r.expires_in, r.refresh_token return [access_token, expires_in, refresh_token]
def create_from_template(self, client_id, subject, name, from_name, from_email, reply_to, list_ids, segment_ids, template_id, template_content): """Creates a new campaign for a client, from a template. :param client_id: String representing the ID of the client for whom the campaign will be created. :param subject: String representing the subject of the campaign. :param name: String representing the name of the campaign. :param from_name: String representing the from name for the campaign. :param from_email: String representing the from address for the campaign. :param reply_to: String representing the reply-to address for the campaign. :param list_ids: Array of Strings representing the IDs of the lists to which the campaign will be sent. :param segment_ids: Array of Strings representing the IDs of the segments to which the campaign will be sent. :param template_id: String representing the ID of the template on which the campaign will be based. :param template_content: Hash representing the content to be used for the editable areas of the template. See documentation at campaignmonitor.com/api/campaigns/#creating_a_campaign_from_template for full details of template content format. :returns String representing the ID of the newly created campaign. """ body = { "Subject": subject, "Name": name, "FromName": from_name, "FromEmail": from_email, "ReplyTo": reply_to, "ListIDs": list_ids, "SegmentIDs": segment_ids, "TemplateID": template_id, "TemplateContent": template_content } response = self._post("/campaigns/%s/fromtemplate.json" % client_id, json.dumps(body)) self.campaign_id = json_to_py(response) return self.campaign_id
def refresh_token(self): """Refresh an OAuth token given a refresh token.""" if (not self.auth_details or not 'refresh_token' in self.auth_details or not self.auth_details['refresh_token']): raise Exception( "auth_details['refresh_token'] does not contain a refresh token.") refresh_token = self.auth_details['refresh_token'] params = [ ('grant_type', 'refresh_token'), ('refresh_token', refresh_token) ] response = self._post('', urlencode(params), CreateSend.oauth_token_uri, "application/x-www-form-urlencoded") new_access_token, new_expires_in, new_refresh_token = None, None, None r = json_to_py(response) new_access_token, new_expires_in, new_refresh_token = r.access_token, r.expires_in, r.refresh_token self.auth({ 'access_token': new_access_token, 'refresh_token': new_refresh_token}) return [new_access_token, new_expires_in, new_refresh_token]
def create_from_template(self, client_id, subject, name, from_name, from_email, reply_to, list_ids, segment_ids, template_id, template_content): """Creates a new campaign for a client, from a template. :param client_id: String representing the ID of the client for whom the campaign will be created. :param subject: String representing the subject of the campaign. :param name: String representing the name of the campaign. :param from_name: String representing the from name for the campaign. :param from_email: String representing the from address for the campaign. :param reply_to: String representing the reply-to address for the campaign. :param list_ids: Array of Strings representing the IDs of the lists to which the campaign will be sent. :param segment_ids: Array of Strings representing the IDs of the segments to which the campaign will be sent. :param template_id: String representing the ID of the template on which the campaign will be based. :param template_content: Hash representing the content to be used for the editable areas of the template. See documentation at campaignmonitor.com/api/campaigns/#creating_a_campaign_from_template for full details of template content format. :returns String representing the ID of the newly created campaign. """ body = { "Subject": subject, "Name": name, "FromName": from_name, "FromEmail": from_email, "ReplyTo": reply_to, "ListIDs": list_ids, "SegmentIDs": segment_ids, "TemplateID": template_id, "TemplateContent": template_content} response = self._post("/campaigns/%s/fromtemplate.json" % client_id, json.dumps(body)) self.campaign_id = json_to_py(response) return self.campaign_id
def clients(self): """Gets your clients.""" response = self._get('/clients.json') return json_to_py(response)
def billing_details(self): """Gets your billing details.""" response = self._get('/billingdetails.json') return json_to_py(response)
def countries(self): """Gets valid countries.""" response = self._get('/countries.json') return json_to_py(response)
def systemdate(self): """Gets the current date in your account's timezone.""" response = self._get('/systemdate.json') return json_to_py(response).SystemDate
def timezones(self): """Gets valid timezones.""" response = self._get('/timezones.json') return json_to_py(response)
def administrators(self): """Gets administrators associated with the account""" response = self._get('/admins.json') return json_to_py(response)
def get_primary_contact(self): """Retrieves the primary contact for this account""" response = self._get('/primarycontact.json') return json_to_py(response)
def set_primary_contact(self, email): """Assigns the primary contact for this account""" params = {"email": email} response = self._put('/primarycontact.json', params=params) return json_to_py(response)
def get(self, client_id=None, email_address=None): """Gets a person by client ID and email address.""" params = {"email": email_address or self.email_address} response = self._get("/clients/%s/people.json" % (client_id or self.client_id), params=params) return json_to_py(response)