-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.ts
141 lines (130 loc) · 4.42 KB
/
main.ts
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
import * as uuid from "uuid";
import { DiscordWebhookClient, sleep, SpotifyApiClient } from "./lib";
import { discordConfig, spotifyConfig } from "./config";
import jsonData, { TrackModel } from "./data";
import fs from "fs";
let isShuttingDown = false;
let isProcessing = false;
const PROCESS_ID = uuid.v4();
console.log(`[${PROCESS_ID}] Batch Process ID is ${PROCESS_ID}`);
let MODE = process.env.MODE || "NO-INIT";
const main = async () => {
const spotifyApiClient = SpotifyApiClient();
const discordWebhookClient = DiscordWebhookClient();
// while (!isShuttingDown) {
isProcessing = true;
const credentialData = await spotifyApiClient.clientCredentialsGrant();
spotifyApiClient.setAccessToken(credentialData.body["access_token"]);
try {
const beforeTracks = jsonData;
// [業] 既存トラックの削除を考慮して-50で取り始める
let offset = beforeTracks.length >50 ? beforeTracks.length - 50 : 0;
const playlist = await spotifyApiClient.getPlaylist(
spotifyConfig.playlistId
);
let playlistData = await spotifyApiClient.getPlaylistTracks(
spotifyConfig.playlistId,
{ limit: 100, offset }
);
let trackDataList: TrackModel[] = [];
while (true && playlistData.body.items) {
const users = Array.from(
new Set(playlistData.body.items.map((item) => item.added_by.id))
);
let userMap: { [key: string]: any } = {};
for (const userId of users) {
userMap[userId] = (await spotifyApiClient.getUser(userId)).body;
}
// なぜかtrackがnullになる場合がある
for (const track of playlistData.body.items.filter(item => item.track)) {
const trackData: TrackModel = {
id: track.track.id,
name: track.track.name,
external_url: track.track.external_urls.spotify,
add_info: {
added_at: track.added_at,
add_user_id: track.added_by.id,
add_user_name: userMap[track.added_by.id].display_name || "--",
add_user_external_url:
userMap[track.added_by.id].external_urls.spotify || "--",
},
artists: track.track.artists.map((artist) => artist.name),
};
trackDataList.push(trackData);
}
if (playlistData.body.items.length < 100) {
break;
}
offset = offset + 100;
playlistData = await spotifyApiClient.getPlaylistTracks(
spotifyConfig.playlistId,
{ limit: 100, offset }
);
}
const newTracks = trackDataList.filter(
(newTrack) =>
!beforeTracks.map((oldTrack) => oldTrack.id).includes(newTrack.id)
);
if (newTracks.length !== 0 && MODE !== "INIT") {
for (const track of newTracks) {
const embed = {
color: 0x0099ff,
title: discordConfig.message.title.replace(
"${playlistName}",
playlist.body.name
),
url: playlist.body.external_urls.spotify,
fields: [
{
name: "投稿者",
value: `${track.add_info.add_user_name}`,
},
{
name: "曲名",
value: `[${track.name}](${track.external_url})`,
inline: true,
},
{
name: "アーティスト",
value: track.artists,
inline: true,
},
],
};
await discordWebhookClient.send("", {
username: discordConfig.message.botName,
embeds: [embed],
});
}
} else {
MODE = "NoInit";
console.log("nothing to do now...");
}
fs.writeFileSync(
"./data/data.json",
JSON.stringify(beforeTracks.concat(newTracks), null, 2)
);
isProcessing = false;
process.exit(0);
} catch (error) {
console.log(`[${PROCESS_ID}] ${error.name}`);
console.log(JSON.stringify(error));
isProcessing = false;
await sleep(5000);
}
}
// };
const shutdownGracefully = async () => {
if (isShuttingDown) {
return;
}
isShuttingDown = true;
console.log(`[${PROCESS_ID}] Shutting down...`);
while (isProcessing) {
await sleep(10);
}
process.exit(0);
};
process.on("SIGINT", shutdownGracefully);
process.on("SIGTERM", shutdownGracefully);
main();