Skip to content

Instantly share code, notes, and snippets.

@Plutor
Last active December 6, 2019 08:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Plutor/4a7bb314ddc59b5f343f to your computer and use it in GitHub Desktop.
Save Plutor/4a7bb314ddc59b5f343f to your computer and use it in GitHub Desktop.
Script that runs @UberBut
// Get a Wordnik API key: http://developer.wordnik.com/
var WORDNIK_API_KEY = "XXXX";
// Get a Twitter app key: https://apps.twitter.com/
var TWITTER_CONSUMER_KEY = "XXXX";
var TWITTER_CONSUMER_SECRET = "XXXX";
function Start() {
// Delete exiting triggers, if any
var triggers = ScriptApp.getProjectTriggers();
for (var i = 0; i < triggers.length; i++) {
ScriptApp.deleteTrigger(triggers[i]);
}
// Setup trigger to post a Tweet every hour.
ScriptApp.newTrigger("UberBut")
.timeBased()
.everyHours(1)
.create();
}
// From https://github.com/googlesamples/apps-script-oauth1
function GetTwitterService() {
// Create a new service with the given name. The name will be used when
// persisting the authorized token, so ensure it is unique within the
// scope of the property store.
return OAuth1.createService('twitter')
// Set the endpoint URLs.
.setAccessTokenUrl('https://api.twitter.com/oauth/access_token')
.setRequestTokenUrl('https://api.twitter.com/oauth/request_token')
.setAuthorizationUrl('https://api.twitter.com/oauth/authorize')
// Set the consumer key and secret.
.setConsumerKey(TWITTER_CONSUMER_KEY)
.setConsumerSecret(TWITTER_CONSUMER_SECRET)
// Set the name of the callback function in the script referenced
// above that should be invoked to complete the OAuth flow.
.setCallbackFunction('AuthCallback')
// Set the property store where authorized tokens should be persisted.
.setPropertyStore(PropertiesService.getScriptProperties());
}
function TwitterFetch(url) {
var twit = GetTwitterService();
if (!twit.hasAccess()) {
var authorization_url = twitterService.authorize();
Logger.log("No Twitter access -- go to " + authorization_url + " to authorize");
return;
}
return twit.fetch(url);
}
function TwitterPost(url, payload) {
var twit = GetTwitterService();
if (!twit.hasAccess()) {
var authorization_url = twitterService.authorize();
Logger.log("No Twitter access -- go to " + authorization_url + " to authorize");
return;
}
return twit.fetch(url, {
"method" : "post",
"payload" : payload
});
}
function AuthCallback(request) {
var twit = GetTwitterService();
if (twit.handleCallback(request)) {
Logger.log('Success!');
} else {
Logger.log('Denied.');
}
}
// Makes an HTTP request to the Wordnik API for a random word, given the part of speech
// Modified from: https://gist.github.com/scazon/a427f58974b6e7c80827
function RandomWord(part_of_speech){
var content = UrlFetchApp.fetch(
"http://api.wordnik.com/v4/words.json/randomWord?includePartOfSpeech=" +
part_of_speech +
"&minCorpusCount=8000&maxCorpusCount=-1&minDictionaryCount=8&" +
"maxDictionaryCount=-1&minLength=4&maxLength=-1&api_key=" +
WORDNIK_API_KEY);
var word = JSON.parse(content)["word"];
//Logger.log("Got random word: " + word);
return word;
}
function WordIsPartOfSpeech(word, part_of_speech){
var content = UrlFetchApp.fetch(
"http://api.wordnik.com/v4/word.json/" + word + "/definitions?limit=1&partOfSpeech=" + part_of_speech +
"&api_key=" + WORDNIK_API_KEY);
var defs = JSON.parse(content);
return defs.length;
}
// For pluralizing: https://code.google.com/p/inflection-js/
function Pluralize(noun) {
return noun.pluralize();
}
function StandaloneTweet() {
var text = "";
while (text == "") {
var noun = RandomWord("noun");
text = Pluralize(noun);
if (text == noun) {
text = "";
}
}
// An adjective 50% of the time
if (Math.random() < 0.5) {
var adjective = RandomWord("adjective");
if (adjective != "") {
text = adjective + " " + text;
}
}
return "Like Uber, but for " + text + ".";
}
function ReplyTweet() {
var props = PropertiesService.getScriptProperties();
var max_id = props.getProperty("MAX_TWITTER_ID");
if (max_id && max_id > 0) {
max_id = "&since_id=" + max_id;
} else {
max_id = "";
}
var url = "https://api.twitter.com/1.1/search/tweets.json?q=" + encodeURIComponent("-from:uberbut @uberbut") + "&count=50" + max_id;
Logger.log(url);
response = TwitterFetch(url);
if (response.getResponseCode() !== 200) {
Logger.log("Got response code: " + response.getResponseCode());
return StandaloneTweet();
}
data = JSON.parse(response.getContentText());
if (!data) {
Logger.log("Can't parse json from '" + data + "'");
return StandaloneTweet();
}
var tweets = data.statuses;
for (var t in tweets.reverse()) {
tweet = tweets[t]
props.setProperty("MAX_TWITTER_ID", tweet.id_str);
if (!tweet.possibly_sensitive && !tweet.retweeted_status) {
// For each word, in reverse order, try to find a noun.
var words = tweet.text.split(" ").reverse().filter(function(w) {
// If the word has any non-alphabetic characters or is less than 6 letters long, skip it.
return (w.length >= 6 && w.match('^[a-zA-Z]*$'));
});
for (var w = 0; w < words.length; w++) {
word = words[w];
if (WordIsPartOfSpeech(word, "noun")) {
var choice = Pluralize(word);
// Check to see if the previous word is an adjective.
if ((w < words.length - 1) && WordIsPartOfSpeech(words[w+1], "adjective")) {
choice = words[w+1] + " " + choice;
}
// Done!
var url = 'https://twitter.com/' + tweet.user.screen_name + '/status/' + tweet.id_str;
var text = "Like Uber, but for " + choice + ".\n" + url;
Logger.log(text);
return text;
}
}
}
}
return StandaloneTweet();
}
function UberBut() {
try {
var text = ReplyTweet();
Logger.log("Tweeting: '" + text + "'");
// Post to twitter:
TwitterPost("https://api.twitter.com/1.1/statuses/update.json", {'status': text})
} catch (f) {
Logger.log("Error: " + f);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment