Skip to content

Instantly share code, notes, and snippets.

@jptrsn
Created December 1, 2015 15:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jptrsn/e5a61108c8e9789ee5c1 to your computer and use it in GitHub Desktop.
Save jptrsn/e5a61108c8e9789ee5c1 to your computer and use it in GitHub Desktop.
/**
// Twitter Translator for the GEG Montreal
// Written by James Petersen, some time during 2014.
//
// Website: http://www.opensourceteacher.ca
//
// Code built on top of the
// T W I T T E R A R C H I V E R
// - - - - - - - - - - - - - - -
//
// Originally written by Amit Agarwal www.ctrlq.org
// Tutorial : http://www.labnol.org/?p=6505
// YouTube : https://www.youtube.com/watch?v=sjRTSkBHnyo
//
// Please note that changes to oAuthConfig mean that this code will break
// in the very near future if it hasn't already.
//
*/
var CONSUMER_KEY = "_________________________";
var CONSUMER_SECRET = "____________________________________________________";
var LANG_API_KEY = "______________________"
function onOpen(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [];
menuEntries.push({name: 'Check for new Tweets', functionName: 'saveTweets'});
menuEntries.push({name: 'Authorize', functionName: 'authorizeTwitter_'});
menuEntries.push({name: 'Reset', functionName: 'Initialize'});
menuEntries.push({name: 'Stop checking automatically', functionName: 'Stop'});
ss.addMenu('Twitter', menuEntries );
}
function encodeString (q) {
var str = q.replace(/\(/g,'{')
.replace(/\)/g,'}')
.replace(/\[/g,'{')
.replace(/\]/g,'}')
.replace(/\!/g, '|')
.replace(/\*/g, 'x')
.replace(/\'/g, '');
return encodeURIComponent(str);
}
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(CONSUMER_KEY);
oauthConfig.setConsumerSecret(CONSUMER_SECRET);
}
function logTweet_(sheet, tweet) {
var log = [];
var data = [];
log.push(new Date(tweet.created_at));
log.push(tweet.user.screen_name);
data[0] = tweet.user.screen_name;
log.push(tweet.user.followers_count);
log.push(tweet.user.friends_count);
log.push(tweet.retweet_count);
log.push(tweet.favorite_count);
data[1] = tweet.text.replace(/\r\n|\n|\r/g, " ").replace("&lt;", "<").replace("&gt;", ">");
log.push(data[1]);
data[2] = detectLang(data[1]);
data[3] = (tweet.id_str);
sheet.insertRowBefore(3).getRange(3,1, 1, sheet.getLastColumn()).setValues([log]);
return data;
}
function detectLang(text) {
var api = "http://ws.detectlanguage.com/0.2/detect?";
api += "key=" + LANG_API_KEY;
api += "&q=" + encodeString(text);
var parsed = JSON.parse(UrlFetchApp.fetch(api).getContentText());
var language = parsed.data.detections[0].language;
Logger.log(language);
return language;
}
function parseTweet(tweet) {
var startId = tweet.indexOf('@');
var endId = tweet.indexOf(' ',startId);
if (startId > 0) {
tweet = tweet.substring(endId+1, tweet.length);
}
return tweet;
}
function translate(data) {
var sheet2 = SpreadsheetApp.getActiveSpreadsheet().getSheets()[1];
var user = data[0];
var origData = extractTags(data[1]);
var origText = origData[0];
var origLang = data[2];
var destLang;
if (origLang == 'en') { destLang = 'fr';} else { destLang = 'en';}
var translation = LanguageApp.translate(origText, origLang, destLang) + origData[1] + origData[2];
var inReplyTo = data[3];
var values = [[ origLang,
destLang,
translation,
user,
inReplyTo
]];
var newRow = sheet2.insertRowBefore(2).getRange(2,1,1,5);
newRow.setValues(values);
var newTweet = [translation, user, inReplyTo];
if (user != 'GEGMontreal') {
postTweet(newTweet);
}
}
function retrieveTweet() {
var sheet2 = SpreadsheetApp.getActiveSpreadsheet().getSheets()[1];
var cell = sheet2.getRange(2,5).getValue();
Browser.msgBox(cell);
}
function encodeString(q) {
var str = encodeURIComponent(q);
str = str.replace(/\'/g, "%27")
.replace(/\)/g,"%29")
.replace(/\[/g,"%5B")
.replace(/\]/g,"%5D")
.replace(/\!/g,"%21")
.replace(/\*/g,"%2A")
.replace(/\(/g,"%28");
return str;
}
function authorize() {
authorizeTwitter_();
}
function authorizeTwitter_() {
var authorized = PropertiesService.getScriptProperties().getProperty('authStatus');
try {
var api = "https://api.twitter.com/1.1/application/rate_limit_status.json";
var options = {
"method": "GET",
"oAuthServiceName":"twitter",
"oAuthUseToken":"always"
};
oAuth_();
var result = UrlFetchApp.fetch(api, options);
if ( result.getResponseCode() === 200 )
PropertiesService.getScriptProperties().setProperty('authStatus',true);
return true;
} catch (e) {
writeError('error in authorizeTwitter');
writeError(e);
Logger.log(e.toString());
}
PropertiesService.getScriptProperties().setProperty('authStatus', false);
return false;
}
/*
function postTweet(tweet) {
//tweet = "Special (characters) aren't making me happy";
try {
var payload = "status=" + encodeString(tweet);
var options = {
"method": "POST",
"oAuthServiceName": "twitter",
"oAuthUseToken": "always",
"escaping": false,
"payload": payload
};
authorizeTwitter_();
var url = "https://api.twitter.com/1.1/statuses/update.json";
Logger.log('begin post');
var request = UrlFetchApp.fetch(url, options);
Logger.log('post complete');
} catch (e) {
writeError('Error in Post Tweet');
writeError(e);
return;
}
return request.getResponseCode();
}
*/
function Initialize() {
try {
var tweet_text, sinceID, maxID, api, sheet, search;
var options, result, json, tweets, tweet, sender;
Stop();
if ( authorizeTwitter_() ) {
sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
search = sheet.getName();
options = {
"method": "get",
"oAuthServiceName":"twitter",
"oAuthUseToken":"always"
};
api = "https://api.twitter.com/1.1/search/tweets.json?count=50&include_entities=false";
api += "&result_type=recent&q=" + encodeString_(search);
result = UrlFetchApp.fetch(api, options);
if (result.getResponseCode() == 200) {
json = Utilities.jsonParse(result.getContentText());
if (json) {
tweets = json.statuses;
doProperty_("SINCEID", tweets[0].id_str);
doProperty_("MAXID", tweets[tweets.length-1].id_str);
for (var i=tweets.length-1; i>=0; i--) {
logTweet_(sheet, tweets[i]);
}
}
}
ScriptApp.newTrigger("saveTweets")
.timeBased().everyMinutes(1).create();
}
} catch (e) {
writeError('error in intialize');
writeError(e);
Logger.log(e.toString());
}
}
function Clear() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
sheet.getRange("A3:G" + (sheet.getLastRow() > 3 ? sheet.getLastRow() : "3")).clear();
var sheet2 = SpreadsheetApp.getActiveSpreadsheet().getSheets()[1];
sheet2.getRange(2,1,sheet2.getLastRow(),sheet2.getLastColumn()).clear();
Stop();
}
function postTweet(newTweet) {
//writeError(newTweet);
try {
var textAndTags = extractTags(newTweet[0]);
var status = ('TR: @' + newTweet[1] + ' ' + textAndTags[0]).substring(0,140 - (textAndTags[1].length + textAndTags[2].length));
status += textAndTags[1] + textAndTags[2];
var inReplyTo = newTweet[2];
status = encodeString(status);
var payload = "status=" + status + "&in_reply_to_status_id=" + inReplyTo;
var options = {
"method": "POST",
"oAuthServiceName": "twitter",
"oAuthUseToken": "always",
"escaping": false,
"payload": payload,
"muteHttpExceptions": true,
};
authorizeTwitter_();
var url = "https://api.twitter.com/1.1/statuses/update.json";
Logger.log('begin post');
var request = UrlFetchApp.fetch(url, options);
Logger.log('post complete');
} catch (e) {
writeError('Error in Post Tweet');
writeError(e);
}
}
function saveTweets() {
var tweet_text, sinceID, maxID, api, sheet, search;
var options, result, json, tweets, tweet, sender;
try {
sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
search = sheet.getName();
sinceID = doProperty_("SINCEID");
options = {
"method": "get",
"oAuthServiceName":"twitter",
"oAuthUseToken":"always"
};
authorizeTwitter_()
api = "https://api.twitter.com/1.1/search/tweets.json?count=50&include_entities=false";
api += "&result_type=recent&q=" + encodeString(search) + "&since_id=" + sinceID;
result = UrlFetchApp.fetch(api, options);
Logger.log(result.getResponseCode());
if (result.getResponseCode() === 200) {
json = JSON.parse(result.getContentText());
if (json) {
tweets = json.statuses;
if (tweets.length) {
doProperty_("SINCEID", tweets[0].id_str);
}
for (var i=tweets.length-1; i>=0; i--) {
var user = logTweet_(sheet, tweets[i]);
var text = tweets[i].text;
var lang = detectLang(text);
translate(user);
}
}
} else {
if (result.getResponseCode() === 503 || result.getResponseCode() === 504) {
Utilities.sleep(2000);
result = UrlFetchApp.fetch(api, options);
}
}
}
catch (e) {
writeError('error in saveTweets');
writeError(e);
Logger.log(e.toString());
}
}
function writeError(e) {
var sheet3 = SpreadsheetApp.getActiveSpreadsheet().getSheets()[2];
var range = sheet3.getRange(2,1,sheet3.getLastRow(),sheet3.getLastColumn());
range.setBackgroundRGB(200,200,200);
var row = sheet3.insertRowAfter(1);
var now = new Date();
sheet3.getRange(2,1).setValue(now);
if (e != null) {
sheet3.getRange(2,2).setValue(e.toString());
}
}
function doProperty_(key, value) {
var properties = PropertiesService.getScriptProperties();
if (value) {
properties.setProperty(key, value);
} else {
return properties.getProperty(key) || "";
}
}
function Stop() {
var triggers = ScriptApp.getScriptTriggers();
for(var i=0; i < triggers.length; i++) {
ScriptApp.deleteTrigger(triggers[i]);
}
doProperty_("SINCEID", "");
doProperty_("MAXID", "");
}
function extractTags(text) {
//text = "This is a test tweet with a @user";
var hashtags = [];
var hashString = '';
var users = [];
var userString = '';
var words = text.split(' ');
var newText = '';
for (var i in words) {
if (words[i][0] == '#') {
hashtags.push(words[i]);
}
if (words[i][0] == '@' || words[i][1] == '@') {
users.push(words[i]);
}
if (words[i][0] != '#' && words[i][0] != '@') {
newText += words[i] + ' ';
}
}
if (hashtags.length > 0) {
hashString += ' ';
for (i in hashtags) {
hashString += hashtags[i];
if (hashtags.length > 1 && i != hashtags.length - 1) {
hashString += ' ';
}
}
}
if (users.length > 0) {
userString += ' ';
for (i in users) {
userString += users[i];
if (users.length > 1 && i != users.length - 1) {
userString += ' ';
}
}
}
var values = [newText, hashString, userString];
return values;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment