-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathindex.js
More file actions
93 lines (79 loc) · 2.42 KB
/
index.js
File metadata and controls
93 lines (79 loc) · 2.42 KB
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
const Twit = require('twit');
const Lyricist = require('lyricist/node6');
const MarkovChain = require('markovchain');
// Uncomment these 2 lines if running locally (see readme for more details)
// const config = require('./config.js');
// process.env = config;
const T = new Twit({
consumer_key: process.env.consumer_key,
consumer_secret: process.env.consumer_secret,
access_token: process.env.access_token,
access_token_secret: process.env.access_token_secret
});
const lyricist = new Lyricist(process.env.GENIUS_ACCESS_TOKEN);
const getLyrics = async () => {
let allLyrics = '';
// Set your artist ID as an environment variable.
// Make a first call to retrieve the first 50 songs of the artist
const songList = await lyricist.songsByArtist(process.env.artist_id, {
page: 1,
perPage: 50
});
// For each song, we have to scrape the lyrics (as they are not available through the API)
const songs = await Promise.all(
Array.from(songList)
.map(song => {
return lyricist.song(song.id, { fetchLyrics: true }).catch(() => {
return false;
});
})
// Filter out rejected promises
// @TODO improve the way rejected promises are handled
.filter(song => {
if (!!song) {
return song;
}
})
);
// For convenience, we add lyrics from all the songs into a single string
Array.from(songs).forEach(song => {
const songArray = song.lyrics.split('\n');
songArray.forEach(songLine => {
if (songLine && songLine[0] !== '[') {
allLyrics += songLine + '\n';
}
});
});
generateMarkov(allLyrics);
return;
};
const generateMarkov = string => {
const markov = new MarkovChain(string);
let newLyrics = markov.end(30).process(); // Set the word limit to 30
// If the new lyrics are too short or are over Twitter's 280 characters limit, we just generate some new ones
if (newLyrics.length < 20 || newLyrics.length > 280) {
generateMarkov(string);
}
// Prettify the output
newLyrics = newLyrics.charAt(0).toUpperCase() + newLyrics.slice(1);
newLyrics = newLyrics.replace(/([,!] )(\w)/g, (match, $1, $2) => {
return $1 + '\n' + $2.toUpperCase();
});
postTweet(newLyrics);
return;
};
// Publish the tweet
const postTweet = tweetContent => {
T.post('statuses/update', { status: tweetContent }, (err, data, resp) => {
if (err) {
console.log('error: ', err);
process.exit(1);
return;
} else {
console.log('successfully posted');
process.exit(0);
return;
}
});
};
getLyrics();