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;
}
📮  Subscribe to our Email Newsletter for Google tips and tutorials!
Published in: Google Apps Script - Twitter

Looking for something? Find here!

Meet the Author

Web Geek, Google Developer Expert
A
Amit Agarwal

Amit Agarwal is a Google Developer Expert in Google Workspace and Google Apps Script. He holds an engineering degree in Computer Science (I.I.T.) and is the first professional blogger in India. He is the developer of Mail Merge for Gmail and Document Studio. Read more on Lifehacker and YourStory

Get in touch

Google Add-ons

Do more with your Gmail and GSuite account
G

We build bespoke solutions that use the capabilities and the features of Google Workspace for automating business processes and driving work productivity.

  1. Mail Merge with Attachments
    Send personalized email to your Google Contact with a Google Sheet and Gmail
  2. Save Emails and Attachments
    Download email messages and file attachments from Gmail to your Google Drive
  3. Google Forms Email Notifications
    Send email notifications to multiple people when a new Google Form is submitted
  4. Document Studio
    Create beautiful pixel perfect documents merging data from Google Sheets and Google Forms
  5. Creator Studio for Google Slides
    Turn your Google Slides presentations into animated GIFs and videos for uploading to YouTube