Next IVR

Providing innovative contact center solutions and services.

Use Twitter Direct Messages to Support Your Customers


Recently, Twitter changed the rules for Direct Messaging, so you can message with someone you are not following. That makes it as clean as SMS/texting. I put together a simple app to illustrate how easy it is. You can grab the source with git:

git clone https://bitbucket.org/ericp56/ericp56.bitbucket.org

The following script simply returns the current weather for the US ZIP code provided. You can extend this to provide a wealth of features:

  • Leverage your organizations web services in novel ways.
  • Follow hashtags and raise alerts in your organization.
  • Maintain session state, so you can provide fruitful dialog.

I was able to get this up and running on a basic hosted Linux server; you could do the same for roughly $5/month. There's no reason why it can't be used for your organization. Here's a high level list of the steps to take:

  1. Set up a Twitter app and generate access tokens.
  2. Provision a Linux server.
  3. Install node using package manager
  4. Create/use a user-level Linux account
  5. Create a twitter-app folder and npm install the required modules (twitter-js-client, twitter-node-client and user-stream).
  6. Copy the sample .js and .sh files to the twitter-app folder.
  7. In the start_weather.sh file, set the variables as defined by your Twitter app.
  8. Verify firewall rules to allow Twitter traffic and access to web services.
  9. Run start_weather.sh

Here's the source of twitter_weather_pm.js:

//node libraries
var http = require('http');  //used for Web service calls
var Stream = require('user-stream'); //used to recieve twitter feed
var Twitter = require('twitter-node-client').Twitter; //used to send messages

//Set up the twitter API
var config = {
    "consumerKey": process.env.CKEY,
    "consumerSecret": process.env.CSEC,
    "accessToken": process.env.ATOKEN,
    "accessTokenSecret": process.env.ATOKENSEC,
    "callBackUrl": process.env.CALLBACKURL
}

var twitter = new Twitter(config);

//Set up twitter stream
var stream = new Stream({
    "consumer_key": config.consumerKey,
    "consumer_secret": config.consumerSecret,
    "access_token_key": config.accessToken,
    "access_token_secret": config.accessTokenSecret
});

//Common Callback functions
var error = function (err, response, body) {
    console.log('ERROR [%s]', JSON.stringify(err));
};
var success = function (data) {
    console.log('Data [%s]', data);
};

//Business Rule Callbacks
function handleIncomingPM(json) {
    console.log(json);
    if(json && json.direct_message && json.direct_message.text && json.direct_message.sender_id)
        getAndReportWeather(json.direct_message.text, json.direct_message.sender_id);
}
function getAndReportStatus(zipCode, twitterId) {
    var get_options = {
        host: 'api.openweathermap.org',
        port: '80',
        path: '/data/2.5/weather?zip=ZIPCODE,us'.replace(/ZIPCODE/, zipCode);
        method: 'GET',
        headers: { }
    };
    var get_req = http.request(get_options, function(res) {processGetResponse(res, twitterId)});
    get_req.end();
}
function processGetResponse(res, twitterId) {
    var bodyChunks = [];
    res.setEncoding('utf8');
    res.on('data', function (chunk) {
        bodyChunks.push(chunk);
    }).on('end', function() {
        processStatusResults(eval(Buffer.concat(bodyChunks)), twitterId);
    });
}
function processStatusResults(result, twitterId) {
    var status = "No status available";
    try {
        status = result.weather[0].description;
    } catch(e) {
    }
    twitter.postCustomApiCall('/direct_messages/new.json',{user_id: twitterId, status}, error, success);
}

//OK, create the stream listener and get to work
stream.stream();
    stream.on('data', handleIncomingPM);

Here's the source of start_weather.sh:

#!/bin/bash
export CKEY="consumer key from twitter"
export CSEC="consumer secret"
export ATOKEN="access token"
export ATOKENSEC="access token secret"
export CALLBACKURL="callback url for oAuth"

node twitter_weather_pm.js
# once you are happy with observing the app running
# use the following line to let it run in the background
# and log all output to apilog
# node twitter_weather_pm.js > apilog 2>&1 &