-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathslack_emoji_analytics.gs
256 lines (200 loc) · 7.54 KB
/
slack_emoji_analytics.gs
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
/**
* Slack 絵文字解析
*/
function slackEmojiAnalytics() {
// Slack の API トークン
let token = '';
// 絵文字解析インスタンスを定義
let emojiAnalyzer = new SlackEmojiAnalyze(token);
// 解析開始日・終了日の定義
let start = '2021-04-01T00:00:00+09:00';
let end = '2022-03-31T23:59:59+09:00';
// 絵文字解析の実施
emojiAnalyzer.analyze(start, end);
}
/**
* Slack絵文字解析クラス
*/
class SlackEmojiAnalyze {
// コンストラクタ
constructor(token) {
// Slack の API トークン有無チェック
if (token == null)
throw new Error("API トークンが未定義もしくは null です");
// スクリプトプロパティ "SLACK_TOKEN" に API トークンを設定
PropertiesService.getScriptProperties().setProperty('SLACK_TOKEN', token);
}
// 解析の実施
analyze(startDay, endDay) {
// 対象となるパブリックチャンネル一覧を取得
let channels = this.getChannels();
// 対象期間のメッセージデータを取得
let messages = this.getMessages(channels, startDay, endDay);
// カスタム絵文字一覧を取得
let emoji = this.getEmojiData();
// 期間内で絵文字が使われた頻度をカウント
let emojiUsage = this.getEmojiCount(messages, emoji);
// 絵文字が使われた頻度をスプレッドシートへ出力
this.putSpreadSheet(emoji, emojiUsage);
}
// パブリックチャンネル一覧取得
getChannels() {
// リクエスト先 URL
let requestURL = 'https://slack.com/api/conversations.list';
// API トークン取得
let token = PropertiesService.getScriptProperties().getProperty('SLACK_TOKEN');
// 必要パラメータの定義
let headers = {
'Authorization' : 'Bearer ' + token,
};
let requestOptions = {
'method' : 'get',
'contentType' : 'application/x-www-form-urlencoded',
'headers' : headers
};
// HTTP GET 用パラメータの定義
let requestParams = {
'exclude_archived' : true,
'type' : 'public_channel'
}
// HTTP GET 用パラメータを文字列化
let paramStr = Object.entries(requestParams).map(([key, val]) => `${key}=${val}`).join('&');
// HTTP レスポンス取得
let response = UrlFetchApp.fetch(requestURL + '?' + paramStr, requestOptions);
// HTTP レスポンスチェック
if (response.getResponseCode() != 200)
throw new Error(response.getContentText());
// JSON パース
let json = JSON.parse(response.getContentText());
// Slack API のレスポンスチェック
if (!json['ok'])
throw new Error(json['error']);
// チャンネルの ID をリスト化
let channelIdList = [];
for(let channel of json['channels'])
channelIdList.push(channel['id']);
// チャンネルの ID 一覧を返却
return channelIdList;
}
// メッセージ一覧取得
getMessages(channels, start, end) {
// リクエスト先 URL
let requestURL = 'https://slack.com/api/conversations.history';
// メッセージ一覧をまとめたリスト
let messageList = [];
// 開始、終了時を UNIX タイムに変換 (帰ってくる数値がミリ秒なので 1000 で割る)
let oldest = Date.parse(start) / 1000;
let latest = Date.parse(end) / 1000;
// API トークン取得
let token = PropertiesService.getScriptProperties().getProperty('SLACK_TOKEN');
// UrlFetchApp.fetch 用パラメータの定義
let headers = {
'Authorization' : 'Bearer ' + token,
}
let requestOptions = {
'method' : 'get',
'contentType' : 'application/x-www-form-urlencoded',
'headers' : headers
};
// HTTP GET用パラメータの定義
// limit の数値は API ドキュメントで指定されている最大値 (1000) を指定
let requestParams = {
'channel' : '',
'latest' : latest,
'oldest' : oldest,
'limit' : 1000
}
for (let channel of channels) {
// チャンネル名を最新のものに書き換え
requestParams['channel'] = channel;
// HTTP GET パラメータを文字列化
let paramStr = Object.entries(requestParams).map(([key, val]) => `${key}=${val}`).join('&');
// HTTP レスポンス取得
let response = UrlFetchApp.fetch(
requestURL + '?' + paramStr,
requestOptions
);
// HTTP レスポンスチェック
if (response.getResponseCode() != 200)
throw new Error(response.getContentText());
// JSON パース
let json = JSON.parse(response.getContentText());
// Slack API のレスポンスチェック
if (!json['ok'])
throw new Error(json['error']);
// メッセージ群をリストに連結
messageList = messageList.concat(json['messages']);
}
// メッセージ一覧を返却
return messageList;
}
// カスタム絵文字一覧を取得
getEmojiData() {
// リクエスト先 URL
let requestURL = 'https://slack.com/api/emoji.list';
// API トークン取得
let token = PropertiesService.getScriptProperties().getProperty('SLACK_TOKEN');
// 必要パラメータの定義
let headers = {
'Authorization' : 'Bearer ' + token,
};
let requestOptions = {
'method' : 'get',
'contentType' : 'application/x-www-form-urlencoded',
'headers' : headers
};
// HTTP レスポンス取得
let response = UrlFetchApp.fetch(requestURL, requestOptions);
// HTTP レスポンスチェック
if (response.getResponseCode() != 200)
throw new Error(response.getContentText());
// JSON パース
let json = JSON.parse(response.getContentText());
// Slack API のレスポンスチェック
if (!json['ok'])
throw new Error(json['error']);
// 絵文字一覧を返却
return json['emoji'];
}
// 絵文字が使われた頻度を取得
getEmojiCount (messages, emoji) {
// 絵文字カウンター
let emojiCounter = {};
// 絵文字 ID リスト抽出
let emojiKeys = Object.keys(emoji);
// 取得したメッセージを走査
for (let message of messages)
// リアクションがある場合のみ、中身をみる
if (message.hasOwnProperty('reactions'))
for (let reaction of message['reactions']) {
// 絵文字ID
let name = reaction['name'];
// カスタム絵文字の場合のみ、カウンターへの追加処理を行う
if (emojiKeys.includes(name))
if (emojiCounter[name])
emojiCounter[name] += reaction['count'];
else
emojiCounter[name] = reaction['count'];
}
// 絵文字カウンターを返却
return emojiCounter;
}
// スプレッドシートへの出力
putSpreadSheet(emoji, usage) {
// アクティブになっているスプレッドシートのインスタンス確保
let sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シート1');
// 一行目を書き込み
let firstRow = ['ID', '絵文字', '利用回数'];
sheet.appendRow(firstRow);
// 絵文字ごとに利用状況をセルに書き出し
for (let key in emoji) {
// 絵文字の利用回数取得
let emojiCount = 0;
if (usage[key])
emojiCount = usage[key];
// 新規行の追加
let newRow = [key, '=image("' + emoji[key] + '")', emojiCount];
sheet.appendRow(newRow);
}
}
}