In the last post, we started building Bot Print. Our redundant chapp.

Walgreens prints from Facebook Messenger. Send pictures to Walgreens. Prints ready in 1 hr. Nothing could be easier.

In this post, we’ll dive into the Walgreens API.

The Sample Wrapper

On the Walgreens developer site, they provide a sample php wrapper for the Photo Prints API. We’ll use this as our basis for building the logic for our Bot Print chapp.

First, let create the file we’ll be working with in this post…

tcp@home:~$ touch walgreens-api.js; touch facebook-graph.js

Vidya Rajaram a Cognizant Partner For Walgreens is the author of the sample wrapper, so credit goes where credit is due. All we’re doing here is porting PHP to Javascript. So open walgreens-api.js and add the required bits ‘n pieces…

var Curl = require('node-libcurl').Curl;
var infoTypes = Curl.info.debug;
var gmdate = require('phpdate-js').gmdate;
var crypto = require('crypto');

Then port this …

$affiliateId = "extest1";
$apiKey = "d12ddc87a36f1cfb422dccb4ff0a7184";
$apiEndPoint = "https://services-qa.walgreens.com/api/util/mweb5url";
$headers = array('Content-type: application/json; charset=utf-8');

To this …

var affiliateId = "extest1";
var token = "d12ddc87a36f1cfb422dccb4ff0a7184";
var endPoint = "https://services-qa.walgreens.com/api/util/mweb5url";
var walgreensHeaders = [
    'Access-Token: Access-Token',
    'Content-Type: application/json',
    'User-Agent: Print Bot (Splace.io)'
];

Add that to our walgreens-api.js file, and start to build out our exports…

module.exports = {
    landingPage: function(bot, message, photos, cb) { },
    debugCallback: function(infoType, content) { }
};

Because Facebook Messenger handles the uploading and storage of photos, we only need to pass a list of url to Walgreens. This vastly simplifies the leg work Bot Print has to do.

Now CURL can be a horrific experience to debug, so the debugCallback function is included simply to ease that pain. Trust me, without this helper function, trying to find out why calls to the Walgreens API wasn’t working was near impossible

debugCallback: function(infoType, content) {
    var text = '';

    switch (infoType) {
        case infoTypes.TEXT:
            text = content;
            break;
        case infoTypes.DATA_IN:
            text = '-- RECEIVING DATA: ' + EOL + content;
            break;
        case infoTypes.DATA_OUT:
            text = '-- SENDING DATA: ' + EOL + content;
            break;
        case infoTypes.HEADER_IN:
            text = '-- RECEIVING HEADER: ' + EOL + content;
            break;
        case infoTypes.HEADER_OUT:
            text = '-- SENDING HEADER: ' + EOL + content;
            break;
        case infoTypes.SSL_DATA_IN:
            text = '-- RECEIVING SSL DATA: ' + EOL + content;
            break;
        case infoTypes.SSL_DATA_OUT:
            text = '-- SENDING SSL DATA: ' + EOL + content;
            break;
    }

    console.log(text);
    return 0;
}

Landing

The last bit of work required by our walgreens-api.js file is passing a list of URLs to the Walgreens API, and receiving the HTML checkout URL for the order. So, lets port this …

// Generating the Check Out URL - Starts
$checkOutData = array(
    "transaction"=>"photoCheckoutv2",
    "apiKey"=>$apiKey,
    "devinf"=>"IE,11",
    "appver"=> "0.0",
    "act"=>"mweb5UrlV2",
    "view"=> "mweb5UrlV2JSON",
    "affId"=> $affiliateId,
    "expiryTime"=>"",
    "images"=>array(),
    "lat"=>"",
    "lng"=>"",
    "customer"=> array(
        "firstName"=> "",
        "lastName"=> "",
        "email"=> "",
        "phone"=> ""),
    "channelInfo"=>"web",
    "callBackLink"=>"http://www.walgreens.com",
    "publisherId"=>"7356282",
    "affNotes"=>""
);

array_push($checkOutData['images'], $fileDownloadURL);
$checkOutRequestData = json_encode($checkOutData);
$ch = curl_init($apiEndPoint);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, $checkOutRequestData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

$checkOutResponse = curl_exec($ch);
$checkOutResponse = json_decode($checkOutResponse,TRUE);

To this …

landingPage: function(bot, message, photos, cb) {
    var curl = new Curl();
    var checkOutData = {
        "transaction": "photoCheckoutv2",
        "apiKey": token,
        "devinf": "IE,11",
        "appver": "1.0.0",
        "act": "mweb5UrlV2",
        "view": "mweb5UrlV2JSON",
        "affId": affiliateId,
        "expiryTime": "",
        "images": photos,
        "lat": "",
        "lng": "",
        "customer": {
            "firstName": "",
            "lastName": "",
            "email": "",
            "phone": ""
        },
        "channelInfo": "web",
        "callBackLink": "http://splace.nz/printbot.html",
        "publisherId": 7356282,
        "affNotes": ""
    };

    curl.setOpt(Curl.option.URL, endPoint);
    curl.setOpt(Curl.option.POSTFIELDS, JSON.stringify(checkOutData));
    curl.setOpt(Curl.option.HTTPHEADER, walgreensHeaders);
    curl.setOpt(Curl.option.VERBOSE, true);
    curl.setOpt(Curl.option.DEBUGFUNCTION, module.exports.debugCallback);

    curl.perform();
    curl.on('end', function(statusCode, body) {
        console.log(body);

        if (cb) {
            cb(statusCode, body);
        }

        this.close();
    });
    curl.on('error', curl.close.bind(curl));
}

The only thing happening in that snippet from the sample PHP wrapper is sending a JSON file via HTTP POST, using CURL. That makes it an easy port to Javascript.

Next steps

With all that out of the way, we can head back to bot-print.js and make Bot Print seem like it has some form of intelligence.

Want to work with me?

Let's Talk!

Recently I've worked with ...