32
loading...
This website collects cookies to deliver better user experience
If you are looking to get started, check out this basic node express tutorial.
mkdir twitter_header
cd twitter_header
-y
, so it won't ask all the basic setup questions.npm init -y
npm install axios dotenv fs jimp sharp twitter-api-client
axios
: To make our request and download the imagesdotenv
: For using .env
files, so our API credentials are safefs
: The node filesystem package, we need this to write our downloaded images to the folderjimp
: A super cool package to do image manipulationstwitter-api-client
: Simon's wrapper for the Twitter API in Node.jspackage.json
file and change the script to look like this:"scripts": {
"start": "node index.js"
}
"type": "module"
dotenv
, we should go ahead and make an actual .env
file and place our secrets in it.API_KEY={TWITTER_API_KEY}
API_SECRET={TWITTER_API_SECRET}
CONSUMER_KEY={TWITTER_CONSUMER_KEY}
CONSUMER_SECRET={TWITTER_CONSUMER_SECRET}
TWITTER_HANDLE={TWITTER_HANDLE}
SITEMAP={SITEMAP}
{STRING}
with your actual strings. I'll show you where you can find them in the next section.twitter_header
..env
file..env
file as well!index.js
.import dotenv from 'dotenv';
dotenv.config();
import {TwitterClient} from 'twitter-api-client';
import axios from 'axios';
import fs from 'fs';
import Jimp from 'jimp';
import {parseString} from 'xml2js';
import sharp from 'sharp';
const twitterClient = new TwitterClient({
apiKey: process.env.API_KEY,
apiSecret: process.env.API_SECRET,
accessToken: process.env.CONSUMER_KEY,
accessTokenSecret: process.env.CONSUMER_SECRET
});
async function getLatestFollowers() {
const data = await twitterClient.accountsAndUsers.followersList({
screen_name: process.env.TWITTER_HANDLE,
count: 3
});
let count = 0;
const downloads = new Promise((resolve, reject) => {
data.users.forEach((user, index, arr) => {
downloadImage(user.profile_image_url_https, `${index}.png`).then(() => {
count++;
if (count === arr.length) resolve();
});
});
});
downloads.then(() => {
drawBanner();
});
}
profile_image_url_https
.drawBanner
.downloadImage
function does.${index}.png
as parameters.async function downloadImage(url, image_path) {
await axios({
url,
responseType: 'arraybuffer'
}).then(
response =>
new Promise((resolve, reject) => {
resolve(
sharp(response.data)
.resize(96, 96)
.toFile(image_path)
);
})
);
}
drawBanner
function. The name states it already; it will draw our banner!0.png
, 1.png
, and 2.png
.1500x500.jpg
.async function drawBanner() {
const images = ['1500x500.jpg', '0.png', '1.png', '2.png'];
const promiseArray = [];
images.forEach(image => promiseArray.push(Jimp.read(image)));
promiseArray.push(getLatestArticleHeadline());
promiseArray.push(Jimp.loadFont(Jimp.FONT_SANS_32_BLACK));
Promise.all(promiseArray).then(
([banner, imageOne, imageTwo, imageThree, headline, font]) => {
console.log(`Current headline: ${headline}`);
banner.composite(imageOne, 1050, 80);
banner.composite(imageTwo, 1158, 80);
banner.composite(imageThree, 1264, 80);
banner.print(font, 410, 410, headline);
banner.write('1500x500.png', function() {
uploadBanner();
});
}
);
}
Jimp.read
. This is needed because Jimp needs to load all the images before it can use them.getLatestArticleHeaderline
. This function will retrieve the latest article based on our sitemap.xml file.1500x500.png
and invoke the uploadBanner
function..env
file, we state where our sitemap.xml file could be found.async function getLatestArticleHeadline() {
let title = '';
await axios.get(process.env.SITEMAP).then(data => {
parseString(data.data, function(err, data) {
title = data.feed.entry[0].title[0];
});
});
return title;
}
parseString
function to convert it to a readable object.uploadBanner
function.async function uploadBanner() {
const base64 = await fs.readFileSync('1500x500.png', {encoding: 'base64'});
await twitterClient.accountsAndUsers
.accountUpdateProfileBanner({
banner: base64
})
.then(d => {
console.log('Upload to Twitter done');
});
}
base64
string.accountUpdateProfileBanner
function.getLatestFollowers();
setInterval(() => {
getLatestFollowers();
}, 60000);