forked from trungdq88/real-time-twitter-banner
-
Notifications
You must be signed in to change notification settings - Fork 0
/
emojiheader.js
145 lines (120 loc) · 3.52 KB
/
emojiheader.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
const fs = require('fs');
const TwitterV2 = require('twitter-v2');
const TwitterV1 = require('twitter');
const mergeImg = require('merge-img');
const emojis = require('./emoji-compact.json');
const twemoji = require('twemoji');
const sharp = require('sharp');
const TWITTER_HANDLE = '@tdinh_me';
const credentials = {
consumer_key: 'YOUR KEY HERE',
consumer_secret: 'YOUR KEY HERE',
access_token_key: 'YOUR KEY HERE',
access_token_secret: 'YOUR KEY HERE'
};
const clientV2 = new TwitterV2(credentials);
const clientV1 = new TwitterV1(credentials);
let lastTweetID = '';
let lastDrawImage = 0;
let emoijString = [];
let drawTimer;
async function pollIt() {
const params = {
max_results: 50,
query: TWITTER_HANDLE,
'tweet.fields': 'id,text,referenced_tweets'
};
if (lastTweetID) {
params.since_id = lastTweetID;
}
// get replies
const response = await clientV2.get(`tweets/search/recent`, params);
if (!response.data || !response.data.length) {
console.log(new Date(), 'no new replies');
return;
}
lastTweetID = response.data[0].id;
console.log('polled', response.data.length);
console.log('lastTweetID', lastTweetID);
const rows = response.data.slice();
rows.reverse();
// get all the emojis from the replies
rows
.filter(
(t) =>
t &&
t.referenced_tweets &&
t.referenced_tweets.length &&
t.referenced_tweets[0].type === 'replied_to'
)
.forEach((item) => {
console.log(item.text);
emoijString.unshift(...getEmojis(item.text));
});
// draw the emojis and update banner
function drawit() {
console.log('drawing');
lastDrawImage = Date.now();
drawImage(emoijString.slice(0, 20));
}
const remaining = Date.now() - lastDrawImage;
// Avoid hitting rate limit when update banner
// 30 requests per 15 mins meaning 1 request per 30 secs
if (remaining > 30000) {
drawit();
} else {
console.log('set timer', 30000 - remaining);
clearTimeout(drawTimer);
drawTimer = setTimeout(drawit, 30000 - remaining);
}
}
function getEmojis(input) {
return emojis
.filter((e) => input.indexOf(e) > -1)
.map((e) => twemoji.convert.toCodePoint(e));
}
async function drawImage(imageNames) {
var fileName = '1500x500.png';
try {
const img = await mergeImg(
imageNames
.map((name) => `./assets/72x72/${name}.png`)
.filter((path) => fs.existsSync(path))
);
const name = Math.random(); // avoid disk cache for same file names (weird)
img.write(`${name}-1.png`, async () => {
console.log(`${name}-1.png`);
await sharp(`${name}-1.png`).resize(800).toFile(`${name}-2.png`);
await sharp(fileName)
.composite([{ input: `${name}-2.png`, top: 450, left: 450 }])
.toFile(`${name}.png`);
const base64 = fs.readFileSync(`${name}.png`, { encoding: 'base64' });
clientV1.post(
'account/update_profile_banner',
{
banner: base64
},
(err, data, response) => {
console.log('err', err);
const json = response.toJSON();
console.log(json.statusCode, json.headers, json.body);
try {
console.log('removing', `${name}{,1,2}.png`);
fs.unlinkSync(`${name}.png`);
fs.unlinkSync(`${name}-1.png`);
fs.unlinkSync(`${name}-2.png`);
} catch (e) {
console.log(e);
}
}
);
});
} catch (e) {
console.error(e);
}
}
// start everything
pollIt();
setInterval(() => {
pollIt();
}, 6000);