Get a tweet with OAuth
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const OAuth = require('oauth-1.0a'); | |
const crypto = require('crypto'); | |
const fetch = require('isomorphic-unfetch'); | |
const linkifyHTML = require('linkifyjs/html'); | |
const sanitizeHtml = require('sanitize-html'); | |
// Don't put your config where people can see it folks | |
const { Config } = require('../config'); | |
// \n doesn't work in HTML :/ | |
const nl2br = string => { | |
const html = string.replace(/(?:\r\n|\r|\n)/g, '<br>'); | |
return sanitizeHtml(html, { | |
allowedTags: ['br'], | |
}); | |
}; | |
const populateHashtags = (text, hashtags) => { | |
hashtags.forEach(hashtag => { | |
// Add space around the search so we don't accidentally grab hashes | |
// from a url (e.g. https://wearecreator.uk/#clients) | |
text = text.replace( | |
` #${hashtag.text} `, | |
` <a href="https://twitter.com/hashtag/${ | |
hashtag.text | |
}" target="_blank" rel="nofollow noopener">#${hashtag.text}</a> ` | |
); | |
}); | |
return text; | |
}; | |
const populateMentions = (text, mentions) => { | |
mentions.forEach(mention => { | |
text = text.replace( | |
`@${mention.screen_name}`, | |
`<a href="https://twitter.com/${ | |
mention.screen_name | |
}" target="_blank" rel="nofollow noopener">@${mention.screen_name}</a>` | |
); | |
}); | |
return text; | |
}; | |
const getLatestTweet = async screenName => { | |
const oauth = OAuth({ | |
consumer: { | |
key: Config.twitter.consumerKey, | |
secret: Config.twitter.consumerSecret, | |
}, | |
signature_method: 'HMAC-SHA1', | |
hash_function(base_string, key) { | |
return crypto | |
.createHmac('sha1', key) | |
.update(base_string) | |
.digest('base64'); | |
}, | |
}); | |
const token = { | |
key: Config.twitter.accessToken, | |
secret: Config.twitter.accessTokenSecret, | |
}; | |
const requestData = { | |
url: `https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=${screenName}&count=1&tweet_mode=extended`, | |
method: 'GET', | |
}; | |
const headers = oauth.toHeader(oauth.authorize(requestData, token)); | |
const tweetRes = await fetch(requestData.url, { | |
headers, | |
mode: 'no-cors', | |
}); | |
const [tweet] = await tweetRes.json(); | |
// If no tweet was returned, like for instance if | |
// the twitter feed hasn't posted anything yet... | |
if (typeof tweet === 'undefined') return ''; | |
const withLineBreaks = nl2br(tweet.full_text); | |
const withLinks = linkifyHTML(withLineBreaks); | |
const withHashtags = populateHashtags(withLinks, tweet.entities.hashtags); | |
const withMentions = populateMentions( | |
withHashtags, | |
tweet.entities.user_mentions | |
); | |
return withMentions; | |
}; | |
exports.getLatestTweet = getLatestTweet; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment