ai/src/modules/emoji-react/index.ts
2022-08-10 16:58:29 +09:00

111 lines
3.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)]);
}
}
}