mirror of
https://github.com/syuilo/ai.git
synced 2025-03-25 21:12:56 +00:00
111 lines
3.2 KiB
TypeScript
111 lines
3.2 KiB
TypeScript
import autobind from 'autobind-decorator';
|
||
import {parse} from 'twemoji-parser';
|
||
const delay = require('timeout-as-promise');
|
||
|
||
import {Note} from '@/misskey/note';
|
||
import Module from '@/module';
|
||
import Stream from '@/stream';
|
||
import includes from '@/utils/includes';
|
||
|
||
export default class extends Module {
|
||
public readonly name = 'emoji-react';
|
||
|
||
private htl: ReturnType<Stream['useSharedConnection']>;
|
||
|
||
@autobind
|
||
public install() {
|
||
this.htl = this.ai.connection.useSharedConnection('homeTimeline');
|
||
this.htl.on('note', this.onNote);
|
||
|
||
return {};
|
||
}
|
||
|
||
@autobind
|
||
private async onNote(note: Note) {
|
||
if (note.reply != null) return;
|
||
if (note.text == null) return;
|
||
if (note.text.includes('@')) return; // (自分または他人問わず)メンションっぽかったらreject
|
||
|
||
const react = async (reaction: string, immediate = false) => {
|
||
if (!immediate) {
|
||
await delay(2500);
|
||
}
|
||
this.ai.api('notes/reactions/create', {
|
||
noteId: note.id,
|
||
reaction: reaction,
|
||
});
|
||
};
|
||
|
||
// /う[〜|ー]*んこ/g]にマッチしたときの処理
|
||
if (note.text.match(/う[〜|ー]*んこ/g) || includes(note.text, ['unko'])) {
|
||
return await react(':anataima_unkotte_iimashitane:');
|
||
}
|
||
|
||
if (note.text.match(/う[〜|ー]*んち/g)) {
|
||
return await react(':erait:');
|
||
}
|
||
|
||
if (includes(note.text, ['いい']) && (includes(note.text, ['?']) || includes(note.text, ['?']))) {
|
||
// 50%の確率で":dame:"または":yattare:"を返す
|
||
if (Math.random() < 0.5) {
|
||
return react(':dame:');
|
||
} else {
|
||
return react(':yattare:');
|
||
}
|
||
}
|
||
|
||
if (includes(note.text, ['どこ'])) {
|
||
return await react(':t_ofuton:');
|
||
}
|
||
|
||
const customEmojis = note.text.match(/:([^\n:]+?):/g);
|
||
if (customEmojis) {
|
||
// カスタム絵文字が複数種類ある場合はキャンセル
|
||
if (!customEmojis.every((val, i, arr) => val === arr[0])) return;
|
||
|
||
this.log(`Custom emoji detected - ${customEmojis[0]}`);
|
||
|
||
return react(customEmojis[0]);
|
||
}
|
||
|
||
const emojis = parse(note.text).map((x) => x.text);
|
||
if (emojis.length > 0) {
|
||
// 絵文字が複数種類ある場合はキャンセル
|
||
if (!emojis.every((val, i, arr) => val === arr[0])) return;
|
||
|
||
this.log(`Emoji detected - ${emojis[0]}`);
|
||
|
||
const reaction = emojis[0];
|
||
|
||
switch (reaction) {
|
||
case '✊': return react('🖐', true);
|
||
case '✌': return react('✊', true);
|
||
case '🖐': case '✋': return react('✌', true);
|
||
}
|
||
|
||
return react(reaction);
|
||
}
|
||
|
||
if (includes(note.text, ['ぴざ'])) return react('🍕');
|
||
if (includes(note.text, ['ぷりん'])) return react('🍮');
|
||
if (includes(note.text, ['寿司', 'sushi']) || note.text === 'すし') return react('🍣');
|
||
|
||
if (includes(note.text, ['ずなず']) || includes(note.text, ['ずにゃず'])) return react('🙌');
|
||
if (includes(note.text, ['なず']) || includes(note.text, ['にゃず'])) {
|
||
if (this.ai.isMaster(note.userId)) {
|
||
return react(':google_hart:');
|
||
}
|
||
return react(':oltu:');
|
||
};
|
||
|
||
const gameReact = [
|
||
':ysvi:',
|
||
':ysf:',
|
||
':yso:',
|
||
];
|
||
if (includes(note.text, ['おゲームするかしら'])) {
|
||
// gameReactの中からランダムに選択
|
||
return react(gameReact[Math.floor(Math.random() * gameReact.length)]);
|
||
}
|
||
}
|
||
}
|