This commit is contained in:
syuilo 2019-01-15 18:47:22 +09:00
parent cac1badb98
commit 2f916de51c
No known key found for this signature in database
GPG key ID: BDC4C49D06AB9D69
12 changed files with 83 additions and 81 deletions

View file

@ -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,

View file

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

View file

@ -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

View file

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

View file

@ -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]+)/);

View file

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

View file

@ -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', {

View file

@ -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}`;

View file

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

View file

@ -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;

View file

@ -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);

View file

@ -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]+)時間/);