Skip to content

MyAffiliates API Integration

MyAffiliates API Integration model details:

As per the MyAffiliates API integration Documentation unlike other API authentication MyAffiliates uses Basic HTTP1.0 authentication with username and password. To store the basic authentication details for Cubed clients we have APIMyAffiliatesConnection with records username, password and cubed_user_id.

APIMyAffiliatesConnection model looks like this:

class APIMyAffiliatesConnection(DeactivateBase):

    username = models.CharField(max_length=200)
    password = models.CharField(max_length=200)
    domain = models.CharField(max_length=200)
    active = models.BooleanField(default=True)
    cubed_user_id = models.IntegerField()
    created =   models.DateField(auto_now_add=True, db_index=True)
    updated =   models.DateTimeField(auto_now=True, db_index=True)



    def save(self, *args, **kwargs):
        fernet = Fernet(settings.CUBED_ATTRIB_FERNET_KEY)
        encrypted_password = fernet.encrypt(str.encode(self.password, 'utf-8')).decode()
        self.password = encrypted_password
        super().save(*args, **kwargs)

A username and password belongs to admin account of MyAffiliates. cubed_user_id is related to Auth User to recognize which Cubed user it belongs to.

To protect and hide the MyAffiliates admin account password we are using Fernet from cryptography.fernet python module to encrypt and then decrypt when needed the password. Fernet module uses a URL-safe base64-encoded 32-byte secret key which will be once generated should be stored safe and securely. This secret key is different for each cubed environment such as Local, UAT, Staging and Production. We have added the secret key as backend_fernet_key in YAML files.

For UAT, Staging and Prod are sharing same Fernet keys by adding this to YAML file:

backend_fernet_key: "{{ lookup('env', 'CUBED_ATTRIB_FERNET_KEY') }}"

Command to pull MyAffiliates token based data:

To pull data and decode tokens from API, MyAffiliates uses XML API interface with Basic HTTP/1.0 authentication request with admin username and password. A GET request with parameters FEED_ID and list of comma separated tokens is passed. Response is in xml format and for that we are using ElementTree XML parsing python module to extract desired information from tokens. We are then storing this data in MyAffiliatesVisit model and it is as follows:

class MyAffiliatesVisit(models.Model):
    referrer_url = models.CharField(max_length=2000, db_index=True)
    token = models.CharField(max_length=1000, unique=True)
    visit = models.ForeignKey('Visit', related_name="my_affiliates_tokens", on_delete=models.PROTECT)
    user_id = models.CharField(max_length=100)
    campaign_id = models.CharField(max_length=100, db_index=True)
    description = models.CharField(max_length=500)

    class Meta:
        db_table = "myaffiliates_visit"

We request the the data as follows:

response = requests.get(domain, params = {'FEED_ID': 4, 'TOKENS': LIST OF TOKENS }, auth = HTTPBasicAuth(username, password))

GET request is built-up url of MyAffiliates admin domain, params {'FEED_ID': 4, 'TOKENS': LIST OF TOKENS } and HTTPBasicAuth credentials stored in APIMyAffiliatesConnection. FEED_ID: 4 is specifically to pull decoded tokens from the XML API.

An example of XML response from API:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<TOKENS>
    <TOKEN PREFIX="iPf0f63L7Qdhg6WO2I1rgWNd7ZgqdRLk" USER_ID="7" SETUP_ID="3" MEDIA_ID="0" BANNER_ID="1" CAMPAIGN_ID="1" AUTHCODE="0" REFERRING_URL="http://www.google.com" IP_ADDRESS="127.0.0.1" COUNTRY="ES" TIME_STAMP="2010-12-14T09:36:26+10:00">
        <USER USERNAME="testuser" STATUS="new"/>
        <SETUP SITE_ID="1" SITE_NAME="Test Site" SITE_URL="http://www.yoursite.com" OPERATION_ID="1" PLAN_ID="3" OBJECT_ID="3" OBJECT_DESCRIPTION="Home Page, with shorter query strings.">
            <OBJECT_DATA>
                <DATA VALUE="http://www.yoursite.com?s=%USER_VAR:subordinate%&t=%PREFIX%"/>
            </OBJECT_DATA>
        </SETUP>
    </TOKEN>
</TOKENS>

From Above XML response we are extracting by details such as TOKEN PREFIX, USER_ID, CAMPAIGN_ID, REFERRING_URL and OBJECT_DESCRIPTION using ElementTree XML parsing python module