Skip to content

Instantly share code, notes, and snippets.

@vincelwt
Last active February 4, 2019 19:11
Show Gist options
  • Save vincelwt/01d7121c1f524c857a563509d407dbc6 to your computer and use it in GitHub Desktop.
Save vincelwt/01d7121c1f524c857a563509d407dbc6 to your computer and use it in GitHub Desktop.
Free alternative to Buffer based on Airtable and Webtask.io
const Twit = require('twit')
const T = new Twit({
consumer_key: 'xxx',
consumer_secret: 'xxx',
access_token: 'xxx',
access_token_secret: 'xxx',
})
const Airtable = require('airtable')
Airtable.configure({
endpointUrl: 'https://api.airtable.com',
apiKey: 'xxx'
})
let baseName = 'Scheduled'
let base = Airtable.base('xxx')
const request = require('request').defaults({ encoding: null })
const uploadTweetMedia = (url, callback) => {
request.get(url, (error, response, body) => {
if (error) return callback(err)
let b64content = new Buffer(body).toString('base64')
// first we must post the media to Twitter
T.post('media/upload', { media_data: b64content }, (err, data, response) => {
if (err) return callback(err)
console.log('Media uploaded.')
callback(null, data.media_id_string)
})
})
}
const postTweet = (text, mediaIdStr, callback) => {
//var altText = "Small flowers in a planter on a sunny balcony, blossoming."
//var meta_params = { media_id: mediaIdStr, alt_text: { text: altText } }
//T.post('media/metadata/create', meta_params, function (err, data, response) {
//console.log(err, data)
// now we can reference the media and post a tweet (media will attach to the tweet)
if (mediaIdStr) {
var params = { status: text, media_ids: mediaIdStr }
} else {
var params = { status: text }
}
T.post('statuses/update', params, (err, data, response) => {
if (err) return callback(err)
console.log('Tweet posted.')
callback()
})
//})
}
// Fetch all Tweets from Airtable
const getAllTweets = (callback) => {
let final = []
base('Scheduled').select({
// Selecting the first 3 records in Grid view:
maxRecords: 100,
view: "Grid view"
}).eachPage(function page(records, fetchNextPage) {
// This function (`page`) will get called for each page of records.
final = final.concat(records)
fetchNextPage()
}, function done(err) {
console.log(final.length + ' tweets found.')
callback(final)
if (err) { console.error(err); return cb(err) }
})
}
/**
* @param context {WebtaskContext}
*/
module.exports = (context, cb) => {
const HOUR = 1000 * 60 * 60
// 2019-01-29 format
getAllTweets(records => {
for (let tweet of records) {
if (!tweet.get('Schedule') || tweet.get('Tweeted')) continue
let now = new Date()
let publishDate = new Date(tweet.get('Publish'))
let publishDelay = (now - publishDate)
console.log('Publish date: '+publishDate)
console.log('Publish delay: '+publishDelay)
let shouldPublish = Math.abs(publishDelay) < HOUR
if (!shouldPublish) {
console.log("Tweet isn't scheduled for now. Next.")
continue
}
console.log("Tweet scheduled for now!")
base('Scheduled').update(tweet.getId(), {
"Tweeted":true
}, (err, newTweet) => {
if (err) return cb(err)
console.log(newTweet.get('Media'))
let text = newTweet.get('Text')
if (newTweet.get('Media') && newTweet.get('Media').length) {
let imageLink = newTweet.get('Media')[0].url
uploadTweetMedia(imageLink, (err, mediaId) => {
if (err) return cb(err)
console.log('Successfully uploaded: '+mediaId)
postTweet(text, mediaId, (err) => {
if (err) return cb(err)
cb(null, { status: 'success' })
})
})
} else {
postTweet(text, null, (err) => {
if (err) return cb(err)
cb(null, { status: 'success' })
})
}
});
}
return cb(null, { status: 'success' })
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment