mirror of
https://github.com/syuilo/ai.git
synced 2025-03-25 21:12:56 +00:00
146 lines
6.3 KiB
TypeScript
146 lines
6.3 KiB
TypeScript
import autobind from 'autobind-decorator';
|
||
import Message from '@/message';
|
||
import Module from '@/module';
|
||
import serifs from '@/serifs';
|
||
import { genItem } from '@/vocabulary';
|
||
import config from '@/config';
|
||
import { Note } from '@/misskey/note';
|
||
|
||
export default class extends Module {
|
||
public readonly name = 'poll';
|
||
|
||
@autobind
|
||
public install() {
|
||
setInterval(() => {
|
||
if (Math.random() < 0.1) {
|
||
this.post();
|
||
}
|
||
}, 1000 * 60 * 120);
|
||
|
||
return {
|
||
mentionHook: this.mentionHook,
|
||
timeoutCallback: this.timeoutCallback,
|
||
};
|
||
}
|
||
|
||
@autobind
|
||
private async post() {
|
||
const duration = 1000 * 60 * 15;
|
||
|
||
const polls = [ // TODO: Extract serif
|
||
['珍しそうなもの', 'みなさんは、どれがいちばん珍しいと思いますか?'],
|
||
['美味しそうなもの', 'みなさんは、どれがいちばん美味しいと思いますか?'],
|
||
['重そうなもの', 'みなさんは、どれがいちばん重いと思いますか?'],
|
||
['欲しいもの', 'みなさんは、どれがいちばん欲しいですか?'],
|
||
['無人島に持っていきたいもの', 'みなさんは、無人島にひとつ持っていけるとしたらどれにしますか?'],
|
||
['家に飾りたいもの', 'みなさんは、家に飾るとしたらどれにしますか?'],
|
||
['売れそうなもの', 'みなさんは、どれがいちばん売れそうだと思いますか?'],
|
||
['降ってきてほしいもの', 'みなさんは、どれが空から降ってきてほしいですか?'],
|
||
['携帯したいもの', 'みなさんは、どれを携帯したいですか?'],
|
||
['商品化したいもの', 'みなさんは、商品化するとしたらどれにしますか?'],
|
||
['発掘されそうなもの', 'みなさんは、遺跡から発掘されそうなものはどれだと思いますか?'],
|
||
['良い香りがしそうなもの', 'みなさんは、どれがいちばんいい香りがすると思いますか?'],
|
||
['高値で取引されそうなもの', 'みなさんは、どれがいちばん高値で取引されると思いますか?'],
|
||
['地球周回軌道上にありそうなもの', 'みなさんは、どれが地球周回軌道上を漂っていそうだと思いますか?'],
|
||
['プレゼントしたいもの', 'みなさんは、私にプレゼントしてくれるとしたらどれにしますか?'],
|
||
['プレゼントされたいもの', 'みなさんは、プレゼントでもらうとしたらどれにしますか?'],
|
||
['私が持ってそうなもの', 'みなさんは、私が持ってそうなものはどれだと思いますか?'],
|
||
['流行りそうなもの', 'みなさんは、どれが流行りそうだと思いますか?'],
|
||
['朝ごはん', 'みなさんは、朝ごはんにどれが食べたいですか?'],
|
||
['お昼ごはん', 'みなさんは、お昼ごはんにどれが食べたいですか?'],
|
||
['お夕飯', 'みなさんは、お夕飯にどれが食べたいですか?'],
|
||
['体に良さそうなもの', 'みなさんは、どれが体に良さそうだと思いますか?'],
|
||
['後世に遺したいもの', 'みなさんは、どれを後世に遺したいですか?'],
|
||
['楽器になりそうなもの', 'みなさんは、どれが楽器になりそうだと思いますか?'],
|
||
['お味噌汁の具にしたいもの', 'みなさんは、お味噌汁の具にするとしたらどれがいいですか?'],
|
||
['ふりかけにしたいもの', 'みなさんは、どれをごはんにふりかけたいですか?'],
|
||
['よく見かけるもの', 'みなさんは、どれをよく見かけますか?'],
|
||
['道に落ちてそうなもの', 'みなさんは、道端に落ちてそうなものはどれだと思いますか?'],
|
||
['美術館に置いてそうなもの', 'みなさんは、この中で美術館に置いてありそうなものはどれだと思いますか?'],
|
||
['教室にありそうなもの', 'みなさんは、教室にありそうなものってどれだと思いますか?'],
|
||
['絵文字になってほしいもの', '絵文字になってほしいものはどれですか?'],
|
||
['Misskey本部にありそうなもの', 'みなさんは、Misskey本部にありそうなものはどれだと思いますか?'],
|
||
['燃えるゴミ', 'みなさんは、どれが燃えるゴミだと思いますか?'],
|
||
['好きなおにぎりの具', 'みなさんの好きなおにぎりの具はなんですか?'],
|
||
];
|
||
|
||
const poll = polls[Math.floor(Math.random() * polls.length)];
|
||
|
||
const choices = [
|
||
genItem(),
|
||
genItem(),
|
||
genItem(),
|
||
genItem(),
|
||
];
|
||
|
||
const note = await this.ai.post({
|
||
text: poll[1],
|
||
poll: {
|
||
choices,
|
||
expiredAfter: duration,
|
||
multiple: false,
|
||
}
|
||
});
|
||
|
||
// タイマーセット
|
||
this.setTimeoutWithPersistence(duration + 3000, {
|
||
title: poll[0],
|
||
noteId: note.id,
|
||
});
|
||
}
|
||
|
||
@autobind
|
||
private async mentionHook(msg: Message) {
|
||
if (!msg.or(['/poll']) || msg.user.username !== config.master) {
|
||
return false;
|
||
} else {
|
||
this.log('Manualy poll requested');
|
||
}
|
||
|
||
this.post();
|
||
|
||
return true;
|
||
}
|
||
|
||
@autobind
|
||
private async timeoutCallback({ title, noteId }) {
|
||
const note: Note = await this.ai.api('notes/show', { noteId });
|
||
|
||
const choices = note.poll!.choices;
|
||
|
||
let mostVotedChoice;
|
||
|
||
for (const choice of choices) {
|
||
if (mostVotedChoice == null) {
|
||
mostVotedChoice = choice;
|
||
continue;
|
||
}
|
||
|
||
if (choice.votes > mostVotedChoice.votes) {
|
||
mostVotedChoice = choice;
|
||
}
|
||
}
|
||
|
||
const mostVotedChoices = choices.filter(choice => choice.votes === mostVotedChoice.votes);
|
||
|
||
if (mostVotedChoice.votes === 0) {
|
||
this.ai.post({ // TODO: Extract serif
|
||
text: '投票はありませんでした',
|
||
renoteId: noteId,
|
||
});
|
||
} else if (mostVotedChoices.length === 1) {
|
||
this.ai.post({ // TODO: Extract serif
|
||
cw: `${title}アンケートの結果発表です!`,
|
||
text: `結果は${mostVotedChoice.votes}票の「${mostVotedChoice.text}」でした!`,
|
||
renoteId: noteId,
|
||
});
|
||
} else {
|
||
const choices = mostVotedChoices.map(choice => `「${choice.text}」`).join('と');
|
||
this.ai.post({ // TODO: Extract serif
|
||
cw: `${title}アンケートの結果発表です!`,
|
||
text: `結果は${mostVotedChoice.votes}票の${choices}でした!`,
|
||
renoteId: noteId,
|
||
});
|
||
}
|
||
}
|
||
}
|