From 371c083d6ae08daf4065270063e447508dc7f42b Mon Sep 17 00:00:00 2001
From: tetsuya-k <64536338+tetsuya-ki@users.noreply.github.com>
Date: Wed, 25 Oct 2023 18:56:28 +0900
Subject: [PATCH] =?UTF-8?q?=E3=82=AB=E3=82=B9=E3=82=BF=E3=83=A0=E7=B5=B5?=
 =?UTF-8?q?=E6=96=87=E5=AD=97=E3=83=81=E3=82=A7=E3=83=83=E3=82=AF=E3=83=A2?=
 =?UTF-8?q?=E3=82=B8=E3=83=A5=E3=83=BC=E3=83=AB=E3=81=AE=E8=BF=BD=E5=8A=A0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/config.ts                            |   2 +
 src/index.ts                             |   2 +
 src/modules/check-custom-emojis/index.ts | 146 +++++++++++++++++++++++
 src/serifs.ts                            |   5 +
 4 files changed, 155 insertions(+)
 create mode 100644 src/modules/check-custom-emojis/index.ts

diff --git a/src/config.ts b/src/config.ts
index 1918b4f..a404782 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -1,5 +1,6 @@
 type Config = {
 	host: string;
+	serverName: string;
 	i: string;
 	master?: string;
 	wsUrl: string;
@@ -9,6 +10,7 @@ type Config = {
 	notingEnabled: boolean;
 	chartEnabled: boolean;
 	serverMonitoring: boolean;
+	checkEmojisEnabled: boolean;
 	mecab?: string;
 	mecabDic?: string;
 	memoryDir?: string;
diff --git a/src/index.ts b/src/index.ts
index dca5703..c6c2fa8 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -34,6 +34,7 @@ import SleepReportModule from './modules/sleep-report';
 import NotingModule from './modules/noting';
 import PollModule from './modules/poll';
 import ReminderModule from './modules/reminder';
+import CheckCustomEmojisModule from './modules/check-custom-emojis';
 
 console.log('   __    ____  _____  ___ ');
 console.log('  /__\\  (_  _)(  _  )/ __)');
@@ -88,6 +89,7 @@ promiseRetry(retry => {
 		new NotingModule(),
 		new PollModule(),
 		new ReminderModule(),
+		new CheckCustomEmojisModule(),
 	]);
 }).catch(e => {
 	log(chalk.red('Failed to fetch the account'));
diff --git a/src/modules/check-custom-emojis/index.ts b/src/modules/check-custom-emojis/index.ts
new file mode 100644
index 0000000..70653be
--- /dev/null
+++ b/src/modules/check-custom-emojis/index.ts
@@ -0,0 +1,146 @@
+import autobind from 'autobind-decorator';
+import * as loki from 'lokijs';
+import Module from '@/module';
+import serifs from '@/serifs';
+import config from '@/config';
+import Message from '@/message';
+
+export default class extends Module {
+	public readonly name = 'checkCustomEmojis';
+
+	private lastEmoji: loki.Collection<{
+		id: string;
+		updatedAt: number;
+	}>;
+
+	@autobind
+	public install() {
+		if (config.checkEmojisEnabled === false) return {};
+		this.lastEmoji = this.ai.getCollection('lastEmoji', {
+			indices: ['id']
+		});
+
+		this.timeCheck();
+		setInterval(this.timeCheck, 1000 * 60 * 3);
+
+		return {
+			mentionHook: this.mentionHook
+		};
+	}
+
+	@autobind
+	private timeCheck() {
+		const now = new Date();
+		if (now.getHours() !== 23) return;
+		const date = `${now.getFullYear()}-${now.getMonth()}-${now.getDate()}`;
+		const data = this.getData();
+		if (data.lastPosted == date) return;
+		data.lastPosted = date;
+		this.setData(data);
+
+		this.log('Time to check custom emojis!');
+		this.post();
+	}
+
+	@autobind
+	private async post() {
+		this.log('Start to check custom emojis.');
+		const lastEmoji = this.lastEmoji.find({});
+		// this.log('lastEmoji');
+		// this.log(JSON.stringify(lastEmoji,null,'\t'));
+
+		const lastId = lastEmoji.length != 0 ? lastEmoji[0].id : null;
+		const emojisData = await this.checkCumstomEmojis(lastId);
+		if (emojisData.length == 0) return;
+
+		// 絵文字データが取得された場合、元々のデータを削除しておく
+		const emojiSize = emojisData.length;
+		this.lastEmoji.remove(lastEmoji);
+
+		// 概要について投稿
+		const server_name = config.serverName ? config.serverName : 'このサーバー';
+		this.log('Posting...');
+		this.log(serifs.checkCustomEmojis.post(server_name, emojiSize));
+		await this.ai.post({
+			text: serifs.checkCustomEmojis.post(server_name, emojiSize)
+		});
+
+		// 各絵文字について投稿
+		for (const emoji of emojisData){
+			await this.ai.post({
+				text: serifs.checkCustomEmojis.emojiPost(emoji.name)
+			});
+			this.log(serifs.checkCustomEmojis.emojiPost(emoji.name));
+		}
+
+		// データの保存
+		this.log('Last custom emoji data saving...');
+		this.log(JSON.stringify(emojisData[emojiSize-1],null,'\t'));
+		this.lastEmoji.insertOne({
+			id: emojisData[emojiSize-1].id,
+			updatedAt: Date.now()
+		});
+		this.log('Check custom emojis finished!');
+	}
+
+	@autobind
+	private async checkCumstomEmojis(lastId : any) {
+		this.log('CustomEmojis fetching...');
+		let emojisData;
+		if(lastId != null){
+			this.log('lastId is **not** null');
+			emojisData = await this.ai.api('admin/emoji/list', {
+				sinceId: lastId,
+				limit: 30
+			});
+		} else {
+			this.log('lastId is null');
+			emojisData = await this.ai.api('admin/emoji/list', {
+				limit: 100
+			});
+
+			// 最後まで取得
+			let beforeEmoji = null;
+			let afterEmoji = emojisData.length > 1 ? emojisData[0] : null;
+			while(emojisData.length == 100 && beforeEmoji != afterEmoji){
+				const lastId = emojisData[emojisData.length-1].id;
+				// sinceIdを指定して再度取り直す
+				emojisData = await this.ai.api('admin/emoji/list', {
+					limit: 100,
+					sinceId: lastId
+				});
+				beforeEmoji = afterEmoji;
+				afterEmoji = emojisData.length > 1 ? emojisData[0] : null;
+				await this.sleep(50);
+			}
+
+			// sinceIdが未指定の場合、末尾から5件程度にしておく
+			let newJson: any[] = [];
+			for (let i = emojisData.length - 5; i < emojisData.length; i++) {
+				newJson.push(emojisData[i]);
+			}
+			emojisData = newJson;
+		}
+		return emojisData;
+	}
+
+	@autobind
+	private async mentionHook(msg: Message) {
+		if (!msg.includes(['カスタムえもじチェック'])) {
+			return false;
+		} else {
+			this.log('Check custom emojis requested');
+		}
+
+		await this.post();
+
+		return {
+			reaction: 'like'
+		};
+	}
+
+	@autobind
+	private async sleep(ms: number) {
+		return new Promise((res) => setTimeout(res, ms));
+	}
+}
diff --git a/src/serifs.ts b/src/serifs.ts
index 15ae16e..32515d5 100644
--- a/src/serifs.ts
+++ b/src/serifs.ts
@@ -381,6 +381,11 @@ export default {
 		foryou: '描きました!'
 	},
 
+	checkCustomEmojis: {
+		post: (server_name, num) => `${server_name}に${num}件の絵文字が追加されました!`,
+		emojiPost: emoji => `:${emoji}:\n(\`${emoji}\`) #AddCustomEmojis`
+	},
+
 	sleepReport: {
 		report: hours => `んぅ、${hours}時間くらい寝ちゃってたみたいです`,
 		reportUtatane: 'ん... うたた寝しちゃってました',