mirror of
https://github.com/syuilo/ai.git
synced 2024-12-22 08:21:08 +00:00
Refactor
This commit is contained in:
parent
cac1badb98
commit
2f916de51c
62
src/ai.ts
62
src/ai.ts
|
@ -4,17 +4,19 @@ import autobind from 'autobind-decorator';
|
|||
import * as loki from 'lokijs';
|
||||
import * as request from 'request-promise-native';
|
||||
import chalk from 'chalk';
|
||||
const delay = require('timeout-as-promise');
|
||||
|
||||
import config from './config';
|
||||
import Module from './module';
|
||||
import MessageLike from './message-like';
|
||||
import Message from './message';
|
||||
import { FriendDoc } from './friend';
|
||||
import { User } from './misskey/user';
|
||||
import getCollection from './utils/get-collection';
|
||||
import Stream from './stream';
|
||||
import log from './log';
|
||||
|
||||
type MentionHook = (msg: MessageLike) => boolean | HandlerResult;
|
||||
type ContextHook = (msg: MessageLike, data?: any) => void | HandlerResult;
|
||||
type MentionHook = (msg: Message) => boolean | HandlerResult;
|
||||
type ContextHook = (msg: Message, data?: any) => void | HandlerResult;
|
||||
|
||||
export type HandlerResult = {
|
||||
reaction: string;
|
||||
|
@ -37,7 +39,7 @@ export default class 藍 {
|
|||
public db: loki;
|
||||
|
||||
private contexts: loki.Collection<{
|
||||
isMessage: boolean;
|
||||
isDm: boolean;
|
||||
noteId?: string;
|
||||
userId?: string;
|
||||
module: string;
|
||||
|
@ -94,20 +96,20 @@ export default class 藍 {
|
|||
mainStream.on('mention', data => {
|
||||
if (data.userId == this.account.id) return; // 自分は弾く
|
||||
if (data.text && data.text.startsWith('@' + this.account.username)) {
|
||||
this.onMention(new MessageLike(this, data, false));
|
||||
this.onReceiveMessage(new Message(this, data, false));
|
||||
}
|
||||
});
|
||||
|
||||
// 返信されたとき
|
||||
mainStream.on('reply', data => {
|
||||
if (data.userId == this.account.id) return; // 自分は弾く
|
||||
this.onMention(new MessageLike(this, data, false));
|
||||
this.onReceiveMessage(new Message(this, data, false));
|
||||
});
|
||||
|
||||
// メッセージ
|
||||
mainStream.on('messagingMessage', data => {
|
||||
if (data.userId == this.account.id) return; // 自分は弾く
|
||||
this.onMention(new MessageLike(this, data, true));
|
||||
this.onReceiveMessage(new Message(this, data, true));
|
||||
});
|
||||
//#endregion
|
||||
|
||||
|
@ -125,17 +127,17 @@ export default class 藍 {
|
|||
}
|
||||
|
||||
@autobind
|
||||
private onMention(msg: MessageLike) {
|
||||
private async onReceiveMessage(msg: Message): Promise<void> {
|
||||
this.log(chalk.gray(`<<< An message received: ${chalk.underline(msg.id)}`));
|
||||
|
||||
const isNoContext = !msg.isMessage && msg.replyId == null;
|
||||
const isNoContext = !msg.isDm && msg.replyId == null;
|
||||
|
||||
// Look up the context
|
||||
const context = isNoContext ? null : this.contexts.findOne(msg.isMessage ? {
|
||||
isMessage: true,
|
||||
const context = isNoContext ? null : this.contexts.findOne(msg.isDm ? {
|
||||
isDm: true,
|
||||
userId: msg.userId
|
||||
} : {
|
||||
isMessage: false,
|
||||
isDm: false,
|
||||
noteId: msg.replyId
|
||||
});
|
||||
|
||||
|
@ -161,22 +163,22 @@ export default class 藍 {
|
|||
}
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
if (msg.isMessage) {
|
||||
// 既読にする
|
||||
this.api('messaging/messages/read', {
|
||||
messageId: msg.id,
|
||||
await delay(1000);
|
||||
|
||||
if (msg.isDm) {
|
||||
// 既読にする
|
||||
this.api('messaging/messages/read', {
|
||||
messageId: msg.id,
|
||||
});
|
||||
} else {
|
||||
// リアクションする
|
||||
if (reaction) {
|
||||
this.api('notes/reactions/create', {
|
||||
noteId: msg.id,
|
||||
reaction: reaction
|
||||
});
|
||||
} else {
|
||||
// リアクションする
|
||||
if (reaction) {
|
||||
this.api('notes/reactions/create', {
|
||||
noteId: msg.id,
|
||||
reaction: reaction
|
||||
});
|
||||
}
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
@autobind
|
||||
|
@ -202,15 +204,15 @@ export default class 藍 {
|
|||
};
|
||||
|
||||
@autobind
|
||||
public subscribeReply(module: Module, key: string, isMessage: boolean, id: string, data?: any) {
|
||||
this.contexts.insertOne(isMessage ? {
|
||||
isMessage: true,
|
||||
public subscribeReply(module: Module, key: string, isDm: boolean, id: string, data?: any) {
|
||||
this.contexts.insertOne(isDm ? {
|
||||
isDm: true,
|
||||
userId: id,
|
||||
module: module.name,
|
||||
key: key,
|
||||
data: data
|
||||
} : {
|
||||
isMessage: false,
|
||||
isDm: false,
|
||||
noteId: id,
|
||||
module: module.name,
|
||||
key: key,
|
||||
|
|
|
@ -7,10 +7,10 @@ import or from './utils/or';
|
|||
import chalk from 'chalk';
|
||||
const delay = require('timeout-as-promise');
|
||||
|
||||
export default class MessageLike {
|
||||
export default class Message {
|
||||
private ai: 藍;
|
||||
private messageOrNote: any;
|
||||
public isMessage: boolean;
|
||||
public isDm: boolean;
|
||||
|
||||
public get id(): string {
|
||||
return this.messageOrNote.id;
|
||||
|
@ -34,10 +34,10 @@ export default class MessageLike {
|
|||
|
||||
public friend: Friend;
|
||||
|
||||
constructor(ai: 藍, messageOrNote: any, isMessage: boolean) {
|
||||
constructor(ai: 藍, messageOrNote: any, isDm: boolean) {
|
||||
this.ai = ai;
|
||||
this.messageOrNote = messageOrNote;
|
||||
this.isMessage = isMessage;
|
||||
this.isDm = isDm;
|
||||
|
||||
this.friend = new Friend(ai, { user: this.user });
|
||||
|
||||
|
@ -57,7 +57,7 @@ export default class MessageLike {
|
|||
|
||||
await delay(2000);
|
||||
|
||||
if (this.isMessage) {
|
||||
if (this.isDm) {
|
||||
return await this.ai.sendMessage(this.messageOrNote.userId, {
|
||||
text: text
|
||||
});
|
|
@ -19,8 +19,8 @@ export default abstract class Module {
|
|||
}
|
||||
|
||||
@autobind
|
||||
protected subscribeReply(key: string, isMessage: boolean, id: string, data?: any) {
|
||||
this.ai.subscribeReply(this, key, isMessage, id, data);
|
||||
protected subscribeReply(key: string, isDm: boolean, id: string, data?: any) {
|
||||
this.ai.subscribeReply(this, key, isDm, id, data);
|
||||
}
|
||||
|
||||
@autobind
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import autobind from 'autobind-decorator';
|
||||
import { HandlerResult } from '../../ai';
|
||||
import Module from '../../module';
|
||||
import MessageLike from '../../message-like';
|
||||
import Message from '../../message';
|
||||
import serifs, { getSerif } from '../../serifs';
|
||||
import getDate from '../../utils/get-date';
|
||||
|
||||
|
@ -21,7 +21,7 @@ export default class CoreModule extends Module {
|
|||
}
|
||||
|
||||
@autobind
|
||||
private mentionHook(msg: MessageLike) {
|
||||
private mentionHook(msg: Message) {
|
||||
if (!msg.text) return false;
|
||||
|
||||
return (
|
||||
|
@ -40,13 +40,13 @@ export default class CoreModule extends Module {
|
|||
}
|
||||
|
||||
@autobind
|
||||
private setName(msg: MessageLike): boolean {
|
||||
private setName(msg: Message): boolean {
|
||||
if (!msg.text) return false;
|
||||
if (!msg.text.includes('って呼んで')) return false;
|
||||
if (msg.text.startsWith('って呼んで')) return false;
|
||||
|
||||
// メッセージのみ
|
||||
if (!msg.isMessage) return true;
|
||||
if (!msg.isDm) return true;
|
||||
|
||||
if (msg.friend.love < 5) {
|
||||
msg.reply(serifs.core.requireMoreLove);
|
||||
|
@ -72,7 +72,7 @@ export default class CoreModule extends Module {
|
|||
msg.reply(serifs.core.setNameOk(name));
|
||||
} else {
|
||||
msg.reply(serifs.core.san).then(reply => {
|
||||
this.subscribeReply(msg.userId, msg.isMessage, msg.isMessage ? msg.userId : reply.id, {
|
||||
this.subscribeReply(msg.userId, msg.isDm, msg.isDm ? msg.userId : reply.id, {
|
||||
name: name
|
||||
});
|
||||
});
|
||||
|
@ -82,7 +82,7 @@ export default class CoreModule extends Module {
|
|||
}
|
||||
|
||||
@autobind
|
||||
private greet(msg: MessageLike): boolean {
|
||||
private greet(msg: Message): boolean {
|
||||
if (msg.text == null) return false;
|
||||
|
||||
const incLove = () => {
|
||||
|
@ -151,11 +151,11 @@ export default class CoreModule extends Module {
|
|||
}
|
||||
|
||||
@autobind
|
||||
private nadenade(msg: MessageLike): boolean {
|
||||
private nadenade(msg: Message): boolean {
|
||||
if (!msg.includes(['なでなで'])) return false;
|
||||
|
||||
// メッセージのみ
|
||||
if (!msg.isMessage) return true;
|
||||
if (!msg.isDm) return true;
|
||||
|
||||
//#region 1日に1回だけ親愛度を上げる(嫌われてない場合のみ)
|
||||
if (msg.friend.love >= 0) {
|
||||
|
@ -186,11 +186,11 @@ export default class CoreModule extends Module {
|
|||
}
|
||||
|
||||
@autobind
|
||||
private kawaii(msg: MessageLike): boolean {
|
||||
private kawaii(msg: Message): boolean {
|
||||
if (!msg.includes(['かわいい', '可愛い'])) return false;
|
||||
|
||||
// メッセージのみ
|
||||
if (!msg.isMessage) return true;
|
||||
if (!msg.isDm) return true;
|
||||
|
||||
msg.reply(
|
||||
msg.friend.love >= 5 ? serifs.core.kawaii.love :
|
||||
|
@ -201,11 +201,11 @@ export default class CoreModule extends Module {
|
|||
}
|
||||
|
||||
@autobind
|
||||
private suki(msg: MessageLike): boolean {
|
||||
private suki(msg: Message): boolean {
|
||||
if (!msg.or(['好き', 'すき'])) return false;
|
||||
|
||||
// メッセージのみ
|
||||
if (!msg.isMessage) return true;
|
||||
if (!msg.isDm) return true;
|
||||
|
||||
msg.reply(
|
||||
msg.friend.love >= 5 ? (msg.friend.name ? serifs.core.suki.love(msg.friend.name) : serifs.core.suki.normal) :
|
||||
|
@ -216,11 +216,11 @@ export default class CoreModule extends Module {
|
|||
}
|
||||
|
||||
@autobind
|
||||
private hug(msg: MessageLike): boolean {
|
||||
private hug(msg: Message): boolean {
|
||||
if (!msg.or(['ぎゅ', 'むぎゅ', /^はぐ(し(て|よ|よう)?)?$/])) return false;
|
||||
|
||||
// メッセージのみ
|
||||
if (!msg.isMessage) return true;
|
||||
if (!msg.isDm) return true;
|
||||
|
||||
//#region 前のハグから1分経ってない場合は返信しない
|
||||
// これは、「ハグ」と言って「ぎゅー」と返信したとき、相手が
|
||||
|
@ -250,11 +250,11 @@ export default class CoreModule extends Module {
|
|||
}
|
||||
|
||||
@autobind
|
||||
private humu(msg: MessageLike): boolean {
|
||||
private humu(msg: Message): boolean {
|
||||
if (!msg.includes(['踏んで'])) return false;
|
||||
|
||||
// メッセージのみ
|
||||
if (!msg.isMessage) return true;
|
||||
if (!msg.isDm) return true;
|
||||
|
||||
msg.reply(
|
||||
msg.friend.love >= 5 ? serifs.core.humu.love :
|
||||
|
@ -265,11 +265,11 @@ export default class CoreModule extends Module {
|
|||
}
|
||||
|
||||
@autobind
|
||||
private batou(msg: MessageLike): boolean {
|
||||
private batou(msg: Message): boolean {
|
||||
if (!msg.includes(['罵倒して', '罵って'])) return false;
|
||||
|
||||
// メッセージのみ
|
||||
if (!msg.isMessage) return true;
|
||||
if (!msg.isDm) return true;
|
||||
|
||||
msg.reply(
|
||||
msg.friend.love >= 5 ? serifs.core.batou.love :
|
||||
|
@ -280,7 +280,7 @@ export default class CoreModule extends Module {
|
|||
}
|
||||
|
||||
@autobind
|
||||
private ponkotu(msg: MessageLike): boolean | HandlerResult {
|
||||
private ponkotu(msg: Message): boolean | HandlerResult {
|
||||
if (!msg.includes(['ぽんこつ'])) return false;
|
||||
|
||||
msg.friend.decLove();
|
||||
|
@ -291,7 +291,7 @@ export default class CoreModule extends Module {
|
|||
}
|
||||
|
||||
@autobind
|
||||
private rmrf(msg: MessageLike): boolean | HandlerResult {
|
||||
private rmrf(msg: Message): boolean | HandlerResult {
|
||||
if (!msg.includes(['rm -rf'])) return false;
|
||||
|
||||
msg.friend.decLove();
|
||||
|
@ -302,7 +302,7 @@ export default class CoreModule extends Module {
|
|||
}
|
||||
|
||||
@autobind
|
||||
private shutdown(msg: MessageLike): boolean | HandlerResult {
|
||||
private shutdown(msg: Message): boolean | HandlerResult {
|
||||
if (!msg.includes(['shutdown'])) return false;
|
||||
|
||||
msg.reply(serifs.core.shutdown);
|
||||
|
@ -313,7 +313,7 @@ export default class CoreModule extends Module {
|
|||
}
|
||||
|
||||
@autobind
|
||||
private contextHook(msg: MessageLike, data: any) {
|
||||
private contextHook(msg: Message, data: any) {
|
||||
if (msg.text == null) return;
|
||||
|
||||
const done = () => {
|
||||
|
@ -329,7 +329,7 @@ export default class CoreModule extends Module {
|
|||
done();
|
||||
} else {
|
||||
msg.reply(serifs.core.yesOrNo).then(reply => {
|
||||
this.subscribeReply(msg.userId, msg.isMessage, reply.id, data);
|
||||
this.subscribeReply(msg.userId, msg.isDm, reply.id, data);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import autobind from 'autobind-decorator';
|
||||
import Module from '../../module';
|
||||
import MessageLike from '../../message-like';
|
||||
import Message from '../../message';
|
||||
import serifs from '../../serifs';
|
||||
|
||||
export default class DiceModule extends Module {
|
||||
|
@ -14,7 +14,7 @@ export default class DiceModule extends Module {
|
|||
}
|
||||
|
||||
@autobind
|
||||
private mentionHook(msg: MessageLike) {
|
||||
private mentionHook(msg: Message) {
|
||||
if (msg.text == null) return false;
|
||||
|
||||
const query = msg.text.match(/([0-9]+)[dD]([0-9]+)/);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import autobind from 'autobind-decorator';
|
||||
import Module from '../../module';
|
||||
import MessageLike from '../../message-like';
|
||||
import Message from '../../message';
|
||||
import serifs from '../../serifs';
|
||||
|
||||
const hands = [
|
||||
|
@ -137,7 +137,7 @@ export default class EmojiModule extends Module {
|
|||
}
|
||||
|
||||
@autobind
|
||||
private mentionHook(msg: MessageLike) {
|
||||
private mentionHook(msg: Message) {
|
||||
if (msg.includes(['顔文字', '絵文字', 'emoji', '福笑い'])) {
|
||||
const hand = hands[Math.floor(Math.random() * hands.length)];
|
||||
const face = faces[Math.floor(Math.random() * faces.length)];
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import autobind from 'autobind-decorator';
|
||||
import Module from '../../module';
|
||||
import MessageLike from '../../message-like';
|
||||
import Message from '../../message';
|
||||
|
||||
export default class FollowModule extends Module {
|
||||
public readonly name = 'follow';
|
||||
|
@ -13,7 +13,7 @@ export default class FollowModule extends Module {
|
|||
}
|
||||
|
||||
@autobind
|
||||
private mentionHook(msg: MessageLike) {
|
||||
private mentionHook(msg: Message) {
|
||||
if (msg.text && msg.includes(['フォロー', 'フォロバ', 'follow me'])) {
|
||||
if (!msg.user.isFollowing) {
|
||||
this.ai.api('following/create', {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import autobind from 'autobind-decorator';
|
||||
import Module from '../../module';
|
||||
import MessageLike from '../../message-like';
|
||||
import Message from '../../message';
|
||||
import serifs from '../../serifs';
|
||||
import * as seedrandom from 'seedrandom';
|
||||
import { blessing, itemPrefixes, items } from './vocabulary';
|
||||
|
@ -16,7 +16,7 @@ export default class FortuneModule extends Module {
|
|||
}
|
||||
|
||||
@autobind
|
||||
private mentionHook(msg: MessageLike) {
|
||||
private mentionHook(msg: Message) {
|
||||
if (msg.includes(['占', 'うらな', '運勢', 'おみくじ'])) {
|
||||
const date = new Date();
|
||||
const seed = `${date.getFullYear()}/${date.getMonth()}/${date.getDate()}@${msg.userId}`;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import autobind from 'autobind-decorator';
|
||||
import * as loki from 'lokijs';
|
||||
import Module from '../../module';
|
||||
import MessageLike from '../../message-like';
|
||||
import Message from '../../message';
|
||||
import serifs from '../../serifs';
|
||||
import getCollection from '../../utils/get-collection';
|
||||
|
||||
|
@ -32,7 +32,7 @@ export default class GuessingGameModule extends Module {
|
|||
}
|
||||
|
||||
@autobind
|
||||
private mentionHook(msg: MessageLike) {
|
||||
private mentionHook(msg: Message) {
|
||||
if (!msg.includes(['数当て', '数あて'])) return false;
|
||||
|
||||
const exist = this.guesses.findOne({
|
||||
|
@ -40,7 +40,7 @@ export default class GuessingGameModule extends Module {
|
|||
isEnded: false
|
||||
});
|
||||
|
||||
if (!msg.isMessage) {
|
||||
if (!msg.isDm) {
|
||||
if (exist != null) {
|
||||
msg.reply(serifs.guessingGame.arleadyStarted);
|
||||
} else {
|
||||
|
@ -62,14 +62,14 @@ export default class GuessingGameModule extends Module {
|
|||
});
|
||||
|
||||
msg.reply(serifs.guessingGame.started).then(reply => {
|
||||
this.subscribeReply(msg.userId, msg.isMessage, msg.isMessage ? msg.userId : reply.id);
|
||||
this.subscribeReply(msg.userId, msg.isDm, msg.isDm ? msg.userId : reply.id);
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@autobind
|
||||
private contextHook(msg: MessageLike) {
|
||||
private contextHook(msg: Message) {
|
||||
if (msg.text == null) return;
|
||||
|
||||
const exist = this.guesses.findOne({
|
||||
|
@ -90,7 +90,7 @@ export default class GuessingGameModule extends Module {
|
|||
|
||||
if (guess == null) {
|
||||
msg.reply(serifs.guessingGame.nan).then(reply => {
|
||||
this.subscribeReply(msg.userId, msg.isMessage, reply.id);
|
||||
this.subscribeReply(msg.userId, msg.isDm, reply.id);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ export default class GuessingGameModule extends Module {
|
|||
|
||||
msg.reply(text).then(reply => {
|
||||
if (!end) {
|
||||
this.subscribeReply(msg.userId, msg.isMessage, reply.id);
|
||||
this.subscribeReply(msg.userId, msg.isDm, reply.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import autobind from 'autobind-decorator';
|
||||
import Module from '../../module';
|
||||
import MessageLike from '../../message-like';
|
||||
import Message from '../../message';
|
||||
|
||||
export default class PingModule extends Module {
|
||||
public readonly name = 'ping';
|
||||
|
@ -13,7 +13,7 @@ export default class PingModule extends Module {
|
|||
}
|
||||
|
||||
@autobind
|
||||
private mentionHook(msg: MessageLike) {
|
||||
private mentionHook(msg: Message) {
|
||||
if (msg.text && msg.text.includes('ping')) {
|
||||
msg.reply('PONG!');
|
||||
return true;
|
||||
|
|
|
@ -3,7 +3,7 @@ import autobind from 'autobind-decorator';
|
|||
import Module from '../../module';
|
||||
import serifs from '../../serifs';
|
||||
import config from '../../config';
|
||||
import MessageLike from '../../message-like';
|
||||
import Message from '../../message';
|
||||
import Friend from '../../friend';
|
||||
import getDate from '../../utils/get-date';
|
||||
|
||||
|
@ -33,7 +33,7 @@ export default class ReversiModule extends Module {
|
|||
}
|
||||
|
||||
@autobind
|
||||
private mentionHook(msg: MessageLike) {
|
||||
private mentionHook(msg: Message) {
|
||||
if (msg.includes(['リバーシ', 'オセロ', 'reversi', 'othello'])) {
|
||||
if (config.reversiEnabled) {
|
||||
msg.reply(serifs.reversi.ok);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import autobind from 'autobind-decorator';
|
||||
import Module from '../../module';
|
||||
import MessageLike from '../../message-like';
|
||||
import Message from '../../message';
|
||||
import serifs from '../../serifs';
|
||||
|
||||
export default class TimerModule extends Module {
|
||||
|
@ -14,7 +14,7 @@ export default class TimerModule extends Module {
|
|||
}
|
||||
|
||||
@autobind
|
||||
private mentionHook(msg: MessageLike) {
|
||||
private mentionHook(msg: Message) {
|
||||
const secondsQuery = (msg.text || '').match(/([0-9]+)秒/);
|
||||
const minutesQuery = (msg.text || '').match(/([0-9]+)分/);
|
||||
const hoursQuery = (msg.text || '').match(/([0-9]+)時間/);
|
||||
|
|
Loading…
Reference in a new issue