Skip to content

Instantly share code, notes, and snippets.

@charlescrtr
Last active February 7, 2019 16:05
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 charlescrtr/55e5933b338bca2db3ff5044b51cf865 to your computer and use it in GitHub Desktop.
Save charlescrtr/55e5933b338bca2db3ff5044b51cf865 to your computer and use it in GitHub Desktop.
Get a tweet with OAuth
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