In my last post: http://www.mathewjenkinson.co.uk/twilio-sms-conversations-using-cookies/ I used HTTP Cookies to ask multiple questions to a handset. This got me thinking, what if I could use that conversation to generate a lead in Salesforce.

For example, your at an event, ‘CloudForce’ for example ūüėČ and you want to ask your guests about the experience they are having as well as capture the guests phone number in a lead campaign in Salesforce ready to pick up with the lead after the event. This gives you instant feedback on how people are enjoying the event, an incoming lead stream and verified phone numbers from potential customers.

In this post, Im going to build on using Twilio cookies to populate a lead campaign in Salesforce. To initiate this setup, I want¬†to get the interested lead to message a keyword “CloudForceEU” for example. Once the initial message comes in, I want to ask 4 questions to the lead and then pass the captured data to our Salesforce instance.

To replicate this setup you will need:

  • An account with Twilio (https://www.twilio.com/try-twilio)
  • A SMS capable number within your Account Portal.
  • A Salesforce instance where you can add custom lead fields and use Web2Lead Form generator
  • A PHP¬†based server to host the script found on my Github. ¬†– If your savy you can make your own in another language such as Ruby or Python ūüôā

Setting up Salesforce

To begin we need to add 4 custom fields to our salesforce lead’s panel. As I am choosing to ask 4 questions to our potential lead I want to capture this information so I can get an overall feel for the event as well as capturing info about our potential lead.

To add a custom field in Salesforce go to : salesforce.com/p/setup/layout/LayoutFieldList?type=Lead&setupid=LeadFields

or: ¬†Setup > Leads > Fields and scroll to the bottom for ‘Custom Fields’ It should look something like:

Leads Generation SalesForce

Leads Generation SalesForce

Here we want the button marked ‘New’. Following the steps, we want a new text box of no more than 150 (This is WAY more than we need as we are only gathering simple responses). Fill in the details for the new field and then continue along. I tend to add the details of the question in the description so that I know what Question1 relates to. Continue this until you have all your question fields added.

Now we are going to build our Web2Lead form and capture the ID’s needed for our SMS Script.

Navigate to: Customize > Leads > Web-To-Lead

Remove all the initial fields from the box marked ‘Selected Fields’ and then import:

  • PhoneNumber
  • Campaign
  • Question1
  • Question2
  • Question3
  • Question4

You could add first name to this setup but you would need add a name collection to the SMS conversation, while its easy to do. Its not something I will be doing in this setup.

In the end your setup should look something like:

SF Web2Lead

SF Web2Lead

Then click generate. Salesforce will spit you out some code that you could use in a webform but we are going to grab the details of this code and use it in our SMS lead tracker. The code will look something like:

 

<!– ———————————————————————- –>
<!– NOTE: Please add the following <META> element to your page <HEAD>. –>
<!– If necessary, please modify the charset parameter to specify the –>
<!– character set of your HTML page. –>
<!– ———————————————————————- –>

<META HTTP-EQUIV=”Content-type” CONTENT=”text/html; charset=UTF-8″>

<!– ———————————————————————- –>
<!– NOTE: Please add the following <FORM> element to your page. –>
<!– ———————————————————————- –>

<form action=”https://www.salesforce.com/servlet/servlet.WebToLead?encoding=UTF-8″ method=”POST”>

<input type=hidden name=”oid” value=”ABC123″>
<input type=hidden name=”retURL” value=”http://”>

<!– ———————————————————————- –>
<!– NOTE: These fields are optional debugging elements. Please uncomment –>
<!– these lines if you wish to test in debug mode. –>
<!– <input type=”hidden” name=”debug” value=1> –>
<!– <input type=”hidden” name=”debugEmail” –>
<!– value=”[email protected]”> –>
<!– ———————————————————————- –>

<label for=”phone”>Phone</label><input id=”phone” maxlength=”40″ name=”phone” size=”20″ type=”text” /><br>

<label for=”Campaign_ID”>Campaign</label><select id=”Campaign_ID” name=”Campaign_ID”><option value=””>–None–</option></select><br>

Question1:<input id=”Question1″ maxlength=”174″ name=”Question1″ size=”20″ type=”text” /><br>

Question2:<input id=”Question2″ maxlength=”174″ name=”Question2″ size=”20″ type=”text” /><br>

Question3:<input id=”Question3″ maxlength=”174″ name=”Question3″ size=”20″ type=”text” /><br>

Question4:<input id=”Question4″ maxlength=”174″ name=”Question4″ size=”20″ type=”text” /><br>

<input type=”submit” name=”submit”>

</form>

 

As you can see its quite comprehensive, what we need from this code snippet; is the form URL, formID and then the ID’s for our phone number, campaign and questions. From the script above we get

  • URL Endpoint: ‘https://www.salesforce.com/servlet/servlet.WebToLead?encoding=UTF-8’
  • FormID: ‘ABC123’
  • Phone Number: ‘phone’
  • Campaign ID : ‘Campaign_ID’
  • Question 1 : ‘Question1’
  • Question 2 : ‘Question2’
  • Question 3 : ‘Question3’
  • Question 4 : ‘Question4’

This is the data we need to plug into our SMS cookie script.

At the end of the Twilio SMS conversation, the script will bundle up the details of the conversation and HTTPS POST to the salesforce URL.

Using Twilio cookies to mange the SMS Conversation

In the last post: http://www.mathewjenkinson.co.uk/twilio-sms-conversations-using-cookies/ I used HTTP Cookies to ask multiple questions to a handset. Now we are going to do the same thing, except at the end of this conversation we are going to post the data to Salesforce. You can find a copy of the script on my Github Twilio 2 SalesforceLeads.

The full script Im going to use is:

<?php
// Load the questions we want:
$question1 = ‘Hello. Welcome to the event! We would like to ask you some questions about your experience.</Message><Message>What did you think of the venue & refreshments? 5 (Exceptional) 0 (Poor)’; // by adding the </Message><Message> you can break up the initial response into a welcome message and then question1.
$question2 = ‘And the content of the Presentations? 5 (Exceptional) 0 (Poor)’;
$question3 = ‘How likely are you to attend future Twilio events from 5 (Definitely would) to 0 (definitely would not)’;
$question4 = ‘Is there anything specific you would like to discuss with Twilio? 5 (Yes, please asks someone to call) 0 (I‚Äôll contact you if I need anything)’;
// After we have all 4 questions we can upload to the DB and thank the user for their input
$endStatement = ‘Thanks for your time. Hope you have a fun day!’;

// If we have no cookies we need to set all the cookies to nil and ask the opening question.
if(!isset($_COOKIE[‘question1’])) {
$TwiMLResponse = $question1;
//setcookie(‘question1’, ‘nil’);
setcookie(‘event’, $_POST[‘Body’]);
setcookie(‘question1’, ‘nil’);
setcookie(‘question2’, ‘nil’);
setcookie(‘question3’, ‘nil’);
setcookie(‘question4’, ‘nil’);
}
// If Question 1 is blank we can pair the answer to question 1
elseif ($_COOKIE[‘question1’] == ‘nil’) {
setcookie(‘question1’, $_POST[‘Body’]);
$TwiMLResponse = $question2;
}
// If Question 1 is not blank we find out if question 2 is blank and move up the ladder
elseif (($_COOKIE[‘question2’] == ‘nil’)) {
setcookie(‘question2’, $_POST[‘Body’]);
$TwiMLResponse = $question3;
}
elseif (($_COOKIE[‘question3’] == ‘nil’)) {
setcookie(‘question3’, $_POST[‘Body’]);
$TwiMLResponse = $question4;
}
// After we get the response for question 4, we can assign it to the question.
// Now we have all 4 questions answered and can pass the thank you note and also make a HTTP POST to our end point
elseif (($_COOKIE[‘question4’] == ‘nil’)) {
// With the last question answered, we can reply with our end statement and POST all the data from the conversation.
$TwiMLResponse = $endStatement;
// So now we have the cookies for the event and questions 1 to 3 and the BODY tag for answer 4. Now we can make a POST request to our form with that data.

// Get cURL resource
$curl = curl_init();
// Set some options – we are passing in a useragent too here
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => ‘https://www.salesforce.com/servlet/servlet.WebToLead?encoding=UTF-8’,
CURLOPT_USERAGENT => ‘TwilioSMS’,
CURLOPT_POST => 1,
// POST fields for salesforce input:
CURLOPT_POSTFIELDS => array(‘oid’ => ‘ABC123’, ‘phone’ => $_POST[‘From’], ‘Campaign_ID’ => $_COOKIE[‘event’], ‘Question1’ => $_COOKIE[‘question1’], ‘Question2’ => $_COOKIE[‘question2’], ‘Question3’ => $_COOKIE[‘question3’], ‘Question4’ => $_POST[‘Body’])

));
// Send the request & save response to $resp
$resp = curl_exec($curl);
// Close request to clear up some resources
curl_close($curl);
}
header(‘content-type: text/xml’);
?>
<Response><Message><?php echo $TwiMLResponse; ?></Message></Response>

As you can see Im only use one script to manage the conversation, updating the cookies and working out where the data needs to be updated to and eventually POSTed too. As we are capturing questions about our SalesForceEU event Im going to need 4 questions:

$question1 = ‘Hello. Welcome to the event! We would like to ask you some questions about your experience.</Message><Message>What did you think of the venue & refreshments? 5 (Exceptional) 0 (Poor)’; // by adding the </Message><Message> you can break up the initial response into a welcome message and then question1.
$question2 = ‘And the content of the Presentations? 5 (Exceptional) 0 (Poor)’;
$question3 = ‘How likely are you to attend future Twilio events from 5 (Definitely would) to 0 (definitely would not)’;
$question4 = ‘Is there anything specific you would like to discuss with Twilio? 5 (Yes, please asks someone to call) 0 (I‚Äôll contact you if I need anything)’;

As the script gets more replies from Twilio it populates the questions cookies until they are all full of data. Then we thank the user for their time, assemble the POST request and send it off to SalesForce.

CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => ‘https://www.salesforce.com/servlet/servlet.WebToLead?encoding=UTF-8’,
CURLOPT_USERAGENT => ‘TwilioSMS’,
CURLOPT_POST => 1,
// POST fields for salesforce input:
CURLOPT_POSTFIELDS => array(‘oid’ => ‘ABC123’, ‘phone’ => $_POST[‘From’], ‘Campaign_ID’ => $_COOKIE[‘event’], ‘Question1’ => $_COOKIE[‘question1’], ‘Question2’ => $_COOKIE[‘question2’], ‘Question3’ => $_COOKIE[‘question3’], ‘Question4’ => $_POST[‘Body’])

If we run a test between my phone and Salesforce we get:

Twilio2SalesForceSMS

Twilio2SalesForceSMS

 

and in SalesForce:

SalesForce Leed Capture from SMS

SalesForce Leed Capture from SMS

 

As you can see this opens up lots of possibilities of lead capture and accurate number sourcing from events. You can even have a campaign manager back at HQ reaching back out to leads while they are still at the event.

 

When I talk to people about using Twilio (Twilio.com) SMS to engage with their customers I get a lot of push back on the technical side of how to manage a two way conversation.

If you think back to the old days before iPhones and threaded messages. We had whats now called ‘Nokia’ style messages. This is just a continuous list of messages that arrive into your mailbox, messages between two handsets were not threaded or connected in anyway. Twilio operates in the same fashion, a message out to a handset is not connected to a message in from a handset, there is no ID that links them and no function to make parent child relationships.

Step in Twilio Cookies. In the internet world you can use cookies to track a clients events and navigation throughout your website, you can use it to log if a customer viewed a product or read an article and then clicked on a related one. A visual example :

Cookies Example

Cookies Example (Taken from Twilio.com)

Using Cookies with Twilio we can imitate a conversation with the handset / end user, collecting data along the way and at the end of the conversation we can do something meaningful with the information – such as POST the data to a database or store in a file somewhere.

Why would conversations / cookies be handy to use with Twilio? Well, imagine your hosting an event and you want to get feedback from your guests, you can pass your guests a Twilio powered phone number which when they message will initiate a conversation with them.  At the end of the conversation we will have meaningful answers about the event, not to mention the guests phone number so we can follow up with that all important sales call!

 

The example Im using here is a single page PHP powered script that when your guests message will ask them favourite colour, meal, drink and if they want to go to the movies next week. We will then take this data and make a HTTP POST request to any server with the data. You can use Google Forms here to capture all your responses by amending the URL and POST ID’s. See:¬†https://www.twilio.com/blog/2012/11/connecting-twilio-sms-to-a-google-spreadsheet.html¬†as an example here.

If you just want the code its hosted at: TwilioSMSConversationCookies/TwilioSMSConversation.php

Below is a break down of the script:

These are the questions we want to ask when the user sends us a message:

// Load the questions we want:
$question1 = ‘Hello. What is your favourite colour’;
$question2 = ‘Thanks! Whats your favourite meal’;
$question3 = ‘Tasty! What about to Drink?’;
$question4 = ‘Delish! Do you want to go to the movies next week?’;

At the end of our conversation we want to thank the user so they know that no more questions are coming, and its polite!

// After we have all 4 questions we can upload to the DB and thank the user for their input
$endStatement = ‘Thanks for your time. Hope you have a fun day!’;

We are going to use cookies to track the conversation, I find that its better to pass all the cookies info we want with nil values and add data to these values as the conversation goes rather than adding them as we go. This way we can logically track the conversation.

if(!isset($_COOKIE[‘question1’])) {
$TwiMLResponse = $question1;
//setcookie(‘question1’, ‘nil’);
setcookie(‘event’, $_POST[‘Body’]);
setcookie(‘question1’, ‘nil’);
setcookie(‘question2’, ‘nil’);
setcookie(‘question3’, ‘nil’);
setcookie(‘question4’, ‘nil’);
}

As this conversation is kicked off by the user and not by us, we set all the question cookies to nil, load the first question into $TwiMLResponse and set the event cookie to be the current data in the original message. So for example if our event was called ‘Mats BBQ’ and I asked all my users to send the opening message as¬†‘Mats BBQ’¬†the event cookie would be¬†‘Mats BBQ’.

Because no question has been asked yet, all our cookie values are blank and we can ask our questions:

// If Question 1 is blank we can pair the answer to question 1
elseif ($_COOKIE[‘question1’] == ‘nil’) {
setcookie(‘question1’, $_POST[‘Body’]);
$TwiMLResponse = $question2;
}
// If Question 1 is not blank we find out if question 2 is blank and move up the ladder
elseif (($_COOKIE[‘question2’] == ‘nil’)) {
setcookie(‘question2’, $_POST[‘Body’]);
$TwiMLResponse = $question3;
}
elseif (($_COOKIE[‘question3’] == ‘nil’)) {
setcookie(‘question3’, $_POST[‘Body’]);
$TwiMLResponse = $question4;
}

Questions 1 to 3¬†are the same, its a case of moving through the questions, assigning the ‘Body’ value to the last question asked. When we get to the answer for Question 4 we have all our answers, so no need to set any more cookies.

Now we can take all our data, wrap it up into an array and make a HTTP POST request with this data:

// After we get the response for question 4, we can assign it to the question.
// Now we have all 4 questions answered and can pass the thank you note and also make a HTTP POST to our end point
elseif (($_COOKIE[‘question4’] == ‘nil’)) {
// With the last question answered, we can reply with our end statement and POST all the data from the conversation.
$TwiMLResponse = $endStatement;
// So now we have the cookies for the event and questions 1 to 3 and the BODY tag for answer 4. Now we can make a POST request to our form with that data.

// Get cURL resource
$curl = curl_init();
// Set some options – we are passing in a useragent too here
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => ‘HTTP://YOUR.Domain.TLD/POST’,
CURLOPT_USERAGENT => ‘TwilioSMS’,
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => array(‘From’ => $_POST[‘From’], ‘Event’ => $_COOKIE[‘event’], ‘Question1’ => $_COOKIE[‘question1’], ‘Question2’ => $_COOKIE[‘question2’], ‘Question3’ => $_COOKIE[‘question3’], ‘Question4’ => $_POST[‘Body’])
));
// Send the request & save response to $resp
$resp = curl_exec($curl);
// Close request to clear up some resources
curl_close($curl);
}

I’ve removed my POST URL and ID’s to forms so you can see what question tally’s to what data and it should be easy enough to input your own details.

At then end of the php processing loop we need to pass all the information needed by Twilio:

header(‘content-type: text/xml’);
?>
<Response><Sms><?php echo $TwiMLResponse; ?></Sms></Response>

TwiML needs to pass strict XML  to operate so we set the header as XML file and then use the variable $TwiMLResponse to manage what we actually say back to our users.

I hope this helps your events get more data and keep your customers more engaged with your brand.

With the PCB now built and soldered, my attention can turn to the software that powers the BeeSafe and the cloud API that it runs on.

The software is broken down into two parts; software run locally on each BeeSafe and software run in the cloud that manages all inputs, requests, alerts and data.

This post will focus on the software, hosted locally on the Raspberry Pi – the brain of each BeeSafe.

The focus of Raspberry Pi is to help teach people (children) the basics via Python (for more information visit: http://www.raspberrypi.org), so that is the language I have chosen to use on the Pi.

While the BeeSafe PCB has a variety of sensors (Temperature, GPS, Trip Switch and Accelerometer) the main one this post will focus on is temperature. On the board itself I have included a ds18b20 temperature sensor which uses the 1-wire thermal probe. Information on this can be found at: http://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/temperature/ and http://learn.adafruit.com/adafruits-raspberry-pi-lesson-11-ds18b20-temperature-sensing/hardware

Once we have a powered and working Pi, we need to activate the 1-Wire probes, in the command line of your Pi type in :

sudo modprobe w1-gpio

then

sudo modprobe w1-therm

then

cd /sys/bus/w1/devices/

ls

On the page now you should have something that looks like:

w1_bus_master1 and another that looks like “28-000004bb8e9b“. The “28-000004bb8e9b” will be the serial number of the thermal probe, if you have more than one then, they should all be presented alongside each other.

You can directly interface with the thermal probe by typing in

cd /28-000004bb8e9b

and then

cat w1_slave

This will present you with a 2 line read out of data from the thermal probe, it should look something like:

19 01 4b 46 7f ff 07 10 eb : crc=eb YES

19 01 4b 46 7f ff 07 10 eb t=17562

From the output you can see a value called t=17562 which is the temperature but presented raw format, The actual value here is 17.562C. What we need is some code to read this temperature device and give us a useful temperature value.

The code found on the tutorial page at Cambridge (http://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/temperature/) is a perfect starting point for building out with. A copy of the code is below:

# Open the file that we viewed earlier so that python can see what is in it. Replace the serial number as before.
tfile = open(“/sys/bus/w1/devices/YOURW1PROBE/w1_slave”)
# Read all of the text in the file.
text = tfile.read()
# Close the file now that the text has been read.
tfile.close()
# Split the text with new lines (\n) and select the second line.
secondline = text.split(“\n”)[1]
# Split the line into words, referring to the spaces, and select the 10th word (counting from 0).
temperaturedata = secondline.split(” “)[9]
# The first two characters are “t=”, so get rid of those and convert the temperature from a string to a number.
temperature = float(temperaturedata[2:])
# Put the decimal point in the right place and display it.
temperature = temperature / 1000
print temperature

Change to your user directory folder by:

cd ~

and open a new file by typing in:

sudo nano read_temp.py

Copy and paste the above code into the nano editor and be sure to change YOURW1PROBE to the serial number of your probe. If you saved this file as read_temp.py you can run it by typing in:

sudo python ./read_temp.py

it will read the thermal probe for data and print out the temperature in the correct format.. i.e. 17.562C not 17562

Now we can read real world temperature into our software! The next step is to install the libraries to allow us to send this data in an SMS message to our phones!

In your command line update APT using the following commands:

sudo apt-get update

sudo apt-get upgrade

Next we need to install PIP, this is done by:

sudo apt-get install python-pip python-dev build-essential
sudo pip install –upgrade pip
sudo pip install –upgrade virtualenv

and then

sudo pip install twilio

Twilio is a global voice and SMS API provider, they allow you to make & receive voice and SMS (as well as MMS) messages to and from phones to and web services. For this post we are particularly interested in the Sending SMS API which will allow us to send SMS messages from our local device to a cloud service to our mobile phone.

Twilio can be found online at: http://www.twilio.com

If you haven’t already done so, sign up for a trial account. You get $30 of credit to play with the Twilio system. Once you have signed up, you will need to buy a number (these cost $1 per calendar month, but will come out from the trial credit) and verify a phone number that you currently have (such as your mobile).

Once your signed up, in your account page you will need to note down your account SID and auth token. These can be found on the top of:  https://www.twilio.com/user/account

Now we need to start to form a more complex python code, fortunately we can build onto of the code we have written before! To maintain a logical evolution of our files we are going to make a copy of read_temp.py by typing in:

sudo cp ./read_temp.py ./send_sms_temp.py

This will make a copy of our read temp file and save it as send_sms_temp.py

Open up your text editor by typing:

sudo nano send_sms_temp.py

You should see an identical copy of the code we have written before; now we are going to modify this file so that it can assemble an SMS message from our temperature data.

Start by adding:

from twilio.rest import TwilioRestClient

to the top of the page, this will call the Twilio REST API client when the file loads.

Underneath the temperature code, we need to add the following lines:

account_sid = "ACXXXXXXXXXXXXXXXXX"
auth_token = "YYYYYYYYYYYYYYYYYY"
client = TwilioRestClient(account_sid, auth_token)
message = client.messages.create(to="+12316851234", from_="+15555555555",
body="Hello there! The temperature is: " + srt(temperature) + "c")
Substitute the account SID and auth tokens with the ones you wrote down from your user account page:¬†https://www.twilio.com/user/account, then you will need to adjust the ‘to’ value to be a number you wish to SMS. Twilio uses international number standards, so a number in the United States would be ‘+14155555555’ and one from the UK would be ‘+447971234567’.
You will also have to adjust the ‘from’ variable to be the number you have provisioned when you signed up for your trial account. A word of warning, not all numbers from Twilio support SMS messages, particularly SMS messages across geographic locations.
To check which counties can receive messages from which number, check out: https://www.twilio.com/international Рwhen you have signed up test your number works by sending yourself a message from your account portal  (https://www.twilio.com/user/account/developer-tools/api-explorer#POST/2010-04-01/Accounts/{AccountSid}/SMS/Messages.{format})
The srt(temperature) is us telling python to convert the numerical value of temperature into a string value so that it can be added to our outgoing SMS message. Strings and Strings go together, Numbers and Numbers go together, Strings and Numbers do not.
By now your code should look something like this:

from twilio.rest import TwilioRestClient

# Open the file that we viewed earlier so that python can see what is in it. Replace the serial number as before.
tfile = open(“/sys/bus/w1/devices/YOURW1PROBE/w1_slave”)
# Read all of the text in the file.
text = tfile.read()
# Close the file now that the text has been read.
tfile.close()
# Split the text with new lines (\n) and select the second line.
secondline = text.split(“\n”)[1]
# Split the line into words, referring to the spaces, and select the 10th word (counting from 0).
temperaturedata = secondline.split(” “)[9]
# The first two characters are “t=”, so get rid of those and convert the temperature from a string to a number.
temperature = float(temperaturedata[2:])
# Put the decimal point in the right place and display it.
temperature = temperature / 1000
print temperature

account_sid = “ACXXXXXXXXXXXXXXXXX” #Replace this with your account SID
auth_token = “YYYYYYYYYYYYYYYYYY” # Replace this with your auth token
client = TwilioRestClient(account_sid, auth_token)

message = client.messages.create(to=”+12316851234″, from_=”+15555555555″,
body=”Hello there! The temperature is: ” + srt(temperature) + “c”)

This is our complete SMS temperature application!

You should now be able to send yourself a temperature based SMS message by typing in:

sudo python ./send_sms_temp.py

Tada! If all has gone according to plan you should have sent yourself an SMS with the temperature your Raspberry Pi has read from the thermal probe.

How. Cool. Is. That!

Now that you have the basics, the world is your oyster. Imagine being sent a text message when your house is getting too cold. Or a morning message of the temperature outside before you leave the house. Or sending data from an SMS device into a database.. But thats another post..