Make a Twitter Auto Reply Bot with Google Scripts

M
Published in: Google Apps Script - Twitter

Use this Google Script to setup Out of Office auto-replies in Twitter. The script reads all the Twitter @mentions and sends them a tweet with a custom status message.


/*     O U T   O F   O F F I C E   F O R   T W I T T E R    */
/*     - - -   - -   - - - - - -   - - -   - - - - - - -    */

/*     Written by Amit Agarwal http://labnol.org?p=27911    */
/*     For help, email amit@labnol.org or tweet @labnol     */

function start() {

  // Please enter dates in YYYY-MM-DD HH:MM format

  var OUTOFOFFICE_START_DATE  = "03/11/2013 18:13";
  var OUTOFOFFICE_END_DATE    = "03/11/2013 19:00";

  // This is your Out-Of-Office reply. Keep it less than 120 characters.

  var OUTOFOFFICE_TEXT = "I am currently out of the office,
                              with limited access to Twitter. Thanks!";

  // Get your Twitter keys from dev.twitter.com

  var CONSUMER_KEY     = "AAA";
  var CONSUMER_SECRET  = "BBB";

  // Change this with your Twitter handle

  var TWITTER_HANDLE   = "labnol";

  // DO NOT MODIFY ANYTHING AFTER THIS LINE

  storeKeys ( CONSUMER_KEY, CONSUMER_SECRET,
                       OUTOFOFFICE_TEXT, TWITTER_HANDLE );

  initialize ( OUTOFOFFICE_START_DATE, OUTOFOFFICE_END_DATE );

  // Make sure that Twitter oAuth is working

  doTwitter();

}


// Delete exiting Apps Script triggers, if any

function removeTriggers() {

  var triggers = ScriptApp.getScriptTriggers();

  for(var i=0; i < triggers.length; i++) {
    ScriptApp.deleteTrigger(triggers[i]);
  }

  clearDatabase();

}

function storeKeys(key, secret, text, handle) {

  ScriptProperties.setProperty("TWITTER_CONSUMER_KEY",    key);
  ScriptProperties.setProperty("TWITTER_CONSUMER_SECRET", secret);

  ScriptProperties.setProperty("OUTOFOFFICE_TEXT", text);
  ScriptProperties.setProperty("MAX_TWITTER_ID",   0);
  ScriptProperties.setProperty("TWITTER_HANDLE",   handle);

}

// Clean and Initialize the ScriptDB database

function clearDatabase() {

  var db = ScriptDb.getMyDb();
  while (true) {

    var result = db.query({});

    if (result.getSize() == 0) {
      break;
    }

    while (result.hasNext()) {
      db.remove(result.next());
    }
  }
}

// Setup triggers for the START and END dates

function initialize(start, end) {

  var startDate = new Date(start);
  var endDate   = new Date(end);

  removeTriggers();

  ScriptApp.newTrigger("autoReply")
           .timeBased()
           .at(startDate)
           .create();

  ScriptApp.newTrigger("removeTriggers")
           .timeBased()
           .at(endDate)
           .create();

}

function autoReply() {

  clearDatabase();

  ScriptApp.newTrigger("outOfOffice")
           .timeBased()
           .everyMinutes(5)
           .create();

}

function oAuth() {

 var oauthConfig = UrlFetchApp.addOAuthService("twitter");
 oauthConfig.setAccessTokenUrl("https://api.twitter.com/oauth/access_token");
 oauthConfig.setRequestTokenUrl("https://api.twitter.com/oauth/request_token");
 oauthConfig.setAuthorizationUrl("https://api.twitter.com/oauth/authorize");
 oauthConfig.setConsumerKey(
                 ScriptProperties.getProperty("TWITTER_CONSUMER_KEY"));
 oauthConfig.setConsumerSecret(
                 ScriptProperties.getProperty("TWITTER_CONSUMER_SECRET"));

}

// This function will poll twitter every 5 minutes for any @mentions

function outOfOffice() {

  oAuth();

  var twitter_handle = ScriptProperties.getProperty("TWITTER_HANDLE");

  var phrase = "to:" + twitter_handle;
  var search = "https://api.twitter.com/1.1/search/tweets.json?count=10"
             + "&include_entities=false&result_type=recent&q="
             + encodeString(phrase) + "&since_id="
             + ScriptProperties.getProperty("MAX_TWITTER_ID");

  var options =
  {
    "method": "get",
    "oAuthServiceName":"twitter",
    "oAuthUseToken":"always"
  };

  try {

    var result = UrlFetchApp.fetch(search, options);

    if (result.getResponseCode() === 200) {

      var data = Utilities.jsonParse(result.getContentText());

      if (data) {

        var tweets = data.statuses;

        if (tweets.length) {

          var db    = ScriptDb.getMyDb();
          var reply = ScriptProperties.getProperty("OUTOFOFFICE_TEXT");

          for (var i=tweets.length-1; i>=0; i--) {

            var sender = tweets[i].user.screen_name;
            var found = db.query({user: sender});

            if ( ! found.hasNext() ) {
              db.save({user:sender});
              sendTweet(sender, tweets[i].id_str, reply);
            }
          }
        }
      }
    }
  } catch (e) {
    Logger.log(e.toString());
  }
}

// If an @mention is found, send an Out of Office tweet to that user.

function sendTweet(user, reply_id, tweet) {

  var options =
  {
    "method": "POST",
    "oAuthServiceName":"twitter",
    "oAuthUseToken":"always"
  };

  var text   =  "@" + user + " " + tweet;
  text   =  encodeString(text.substr(0, 140));

  var status = "https://api.twitter.com/1.1/statuses/update.json"
             + "?status=" + text + "&in_reply_to_status_id=" + reply_id;

  try {
    var result = UrlFetchApp.fetch(status, options);
    ScriptProperties.setProperty("MAX_TWITTER_ID", reply_id);
  }
  catch (e) {
    Logger.log(e.toString());
  }

}

function doTwitter() {

  oAuth();

  var req = "https://api.twitter.com/1.1/application/rate_limit_status.json";

  var options =
  {
    "method": "get",
    "oAuthServiceName":"twitter",
    "oAuthUseToken":"always"
  };

  try {

    var result = UrlFetchApp.fetch(req, options);

  } catch (e) {
    Logger.log(e.toString());
  }
}


function encodeString (q) {
   var str =  encodeURIComponent(q);
   str = str.replace(/!/g,'%21');
   str = str.replace(/\*/g,'%2A');
   str = str.replace(/\(/g,'%28');
   str = str.replace(/\)/g,'%29');
   str = str.replace(/\'/g,'%27');
   return str;
}
Published in: Google Apps Script - Twitter

Looking for something? Find here!

Meet the Author

Web Geek, Tech Columnist
A
Amit Agarwal

Amit Agarwal is a Google Developer Expert in GSuite and Google Apps Script. He holds an engineering degree in Computer Science (I.I.T.) and is the first professional blogger in India. Read more on Lifehacker and YourStory

Get in touch