Technologies Used
No stack info.
About
All transactional emails have 4 major components. We give empower marketing teams to make data driven decisions based on email content. Provide as many variations to each component, we'll calculate the number of permutations, and begin our tests. Once we hit a statistically significant threshold, we give you the champion templates with the best open and click through rates and give you the ability to save it as a template in SparkPost.
Comments
Wil Schroter - 2896d
Would be helpful to understand the UX a little bit more although the concept is pretty easy to understand.
Nicolas Kokkalis - 2896d
Notes: Transnational Email A/B testing.
Michael Vredenburgh - 2896d
from sparkpost import SparkPost
from urllib2 import Request, urlopen
from random import randrange, random, shuffle
import time
def sendEmail(recipients1,html1,subject1,campaign_id1):
# sendEmail will use SparkPost SDK to send an email's subject (str) and html body
# (str of valid html code) to recipients (list of email str). Function returns SparkPost
# validation infomation.
sp = SparkPost('d0b24115b40a035d46c98dd8a758f7b773029f55')
print recipients1, html1, campaign_id1, subject1
response = sp.transmission.send(
recipients=str(recipients1),
## recipients=[{'address':{'email':'michaelvredenburgh@gmail.com'}}],
html = html1,
## html='<p>Hello Test1 <a href="http://www.google.com">Click Here</a> </p>',
campaign = str(campaign_id1),
from_email='noreply@makory.com',
## subject='Hello from python-sparkpost'
subject = subject1
)
return response
def getData(campaign_id):
# Queries SparkPost servers for metrics about the email use.
headers = {
'Authorization': 'd0b24115b40a035d46c98dd8a758f7b773029f55',
'Accept': 'application/json'
}
request = Request('https://api.sparkpost.com/api/v1/metrics/deliverability?campaigns=%s&metrics=count_unique_confirmed_opened,count_clicked,count_unique_clicked&from=2015-04-24T00:01' % str(campaign_id), headers=headers)
response_body = urlopen(request).read()
return response_body
def initialSample(subjectArray,randRecipients,html):
# This program assumes that the number of email subjects in subjectArray < n/4. This function
# sends the first wave of emails.
n = len(subjectArray)
if len(subjectArray) != len(randRecipients):
print 'There is an error. Length of subjects should equal recipients'
k=0
while k != n-1:
sendEmail(randRecipients[k],html[k],subjectArray[k],str(k)+'_'+str(k))
k+=1
return k
def initProb(numOfSubjects, numOfhtml):
return [[1./numOfSubjects for x in range(numOfSubjects)] for x in range(2)]
def updateProb(probArray,k,campaign_id):
# Updates a multidimentional array that holds the weighting for each feature.
for count in range(0,k):
toBeParsed = getData(campaign_id)
ind1 = toBeParsed.index("count_unique_confirmed_opened")
EmailOpened = int(toBeParsed[ind1+31:toBeParsed.index(',')])
if EmailOpened > 0 & probArray[count][0] < .8:
probArray[count][0] += .05 * EmailOpened
ind2 = toBeParsed.index("count_clicked")
LinksClicked = toBeParsed[ind2+15:toBeParsed[ind2:].index(',')+ind2]
if LinksClicked > 0 & probArray[count][1] < .8:
probArray[count][0] += .05 * LinksClicked
return probArray
def sendRandEmail(subject, recipient, html, probArray):
while True:
random_index_subject = randrange(0,len(probArray[0]))
if probArray[0][random_index_subject] > random():
break
while True:
random_index_html = randrange(0,len(probArray[1]))
if probArray[1][random_index_html] > random():
break
campaign = str(random_index_subject) + "_" + str(random_index_html)
sendEmail(recipient,html[random_index_html],subject[random_index_subject],campaign)
def mainLoop(recipients,html,subject):
#print recipients
# recipients = shuffle(recipients)
#print subject,recipients,html
initialSample(subject,recipients[0:len(subject)],html)
recipients = recipients[len(subject):]
probTable = initProb(5,5)
time.sleep(120)
for subject in range(0, len(subject)-1):
for body in range (0, len(html)-1):
campain = str(subject) + "_" + str(body)
probTable = updateProb(probTable, len(subjects), campain)
while len(recipients) > 1:
sendRandEmail(subject, recipients[0], html, probTable)
recipients = recipients[1:]
for subject in range(0, len(subject)-1):
for body in range (0, len(html)-1):
campain = str(subject) + "_" + str(body)
probTable = updateProb(probTable, len(subjects), campain)
time.sleep(30)
print probTable
Michael Vredenburgh - 2896d
from sparkpost import SparkPost
from urllib2 import Request, urlopen
from random import randrange, random, shuffle
import time
def sendEmail(recipients1,html1,subject1,campaign_id1):
# sendEmail will use SparkPost SDK to send an email's subject (str) and html body
# (str of valid html code) to recipients (list of email str). Function returns SparkPost
# validation infomation.
sp = SparkPost('d0b24115b40a035d46c98dd8a758f7b773029f55')
print recipients1, html1, campaign_id1, subject1
response = sp.transmission.send(
recipients=str(recipients1),
## recipients=[{'address':{'email':'michaelvredenburgh@gmail.com'}}],
html = html1,
## html='<p>Hello Test1 <a href="http://www.google.com">Click Here</a> </p>',
campaign = str(campaign_id1),
from_email='noreply@makory.com',
## subject='Hello from python-sparkpost'
subject = subject1
)
return response
def getData(campaign_id):
# Queries SparkPost servers for metrics about the email use.
headers = {
'Authorization': 'd0b24115b40a035d46c98dd8a758f7b773029f55',
'Accept': 'application/json'
}
request = Request('https://api.sparkpost.com/api/v1/metrics/deliverability?campaigns=%s&metrics=count_unique_confirmed_opened,count_clicked,count_unique_clicked&from=2015-04-24T00:01' % str(campaign_id), headers=headers)
response_body = urlopen(request).read()
return response_body
def initialSample(subjectArray,randRecipients,html):
# This program assumes that the number of email subjects in subjectArray < n/4. This function
# sends the first wave of emails.
n = len(subjectArray)
if len(subjectArray) != len(randRecipients):
print 'There is an error. Length of subjects should equal recipients'
k=0
while k != n-1:
sendEmail(randRecipients[k],html[k],subjectArray[k],str(k)+'_'+str(k))
k+=1
return k
def initProb(numOfSubjects, numOfhtml):
return [[1./numOfSubjects for x in range(numOfSubjects)] for x in range(2)]
def updateProb(probArray,k,campaign_id):
# Updates a multidimentional array that holds the weighting for each feature.
for count in range(0,k):
toBeParsed = getData(campaign_id)
ind1 = toBeParsed.index("count_unique_confirmed_opened")
EmailOpened = int(toBeParsed[ind1+31:toBeParsed.index(',')])
if EmailOpened > 0 & probArray[count][0] < .8:
probArray[count][0] += .05 * EmailOpened
ind2 = toBeParsed.index("count_clicked")
LinksClicked = toBeParsed[ind2+15:toBeParsed[ind2:].index(',')+ind2]
if LinksClicked > 0 & probArray[count][1] < .8:
probArray[count][0] += .05 * LinksClicked
return probArray
def sendRandEmail(subject, recipient, html, probArray):
while True:
random_index_subject = randrange(0,len(probArray[0]))
if probArray[0][random_index_subject] > random():
break
while True:
random_index_html = randrange(0,len(probArray[1]))
if probArray[1][random_index_html] > random():
break
campaign = str(random_index_subject) + "_" + str(random_index_html)
sendEmail(recipient,html[random_index_html],subject[random_index_subject],campaign)
def mainLoop(recipients,html,subject):
#print recipients
# recipients = shuffle(recipients)
#print subject,recipients,html
initialSample(subject,recipients[0:len(subject)],html)
recipients = recipients[len(subject):]
probTable = initProb(5,5)
time.sleep(120)
for subject in range(0, len(subject)-1):
for body in range (0, len(html)-1):
campain = str(subject) + "_" + str(body)
probTable = updateProb(probTable, len(subjects), campain)
while len(recipients) > 1:
sendRandEmail(subject, recipients[0], html, probTable)
recipients = recipients[1:]
for subject in range(0, len(subject)-1):
for body in range (0, len(html)-1):
campain = str(subject) + "_" + str(body)
probTable = updateProb(probTable, len(subjects), campain)
time.sleep(30)
print probTable
Jim - 2896d