ai/src/ai.ts

180 lines
4.1 KiB
TypeScript
Raw Normal View History

2018-08-11 06:26:25 +00:00
// AI CORE
2018-08-26 21:16:56 +00:00
import * as loki from 'lokijs';
2018-08-11 06:26:25 +00:00
import * as request from 'request-promise-native';
import config from './config';
import IModule from './module';
import MessageLike from './message-like';
2018-08-27 11:22:59 +00:00
import { FriendDoc } from './friend';
2018-08-28 21:30:48 +00:00
import { User } from './misskey/user';
2018-08-29 07:26:33 +00:00
import getCollection from './utils/get-collection';
2018-10-09 15:47:03 +00:00
import Stream from './stream';
2018-08-11 06:26:25 +00:00
/**
*
*/
export default class {
2018-08-28 21:30:48 +00:00
public account: User;
2018-10-09 15:47:03 +00:00
public connection: Stream;
2018-08-11 06:26:25 +00:00
private modules: IModule[] = [];
2018-08-26 21:16:56 +00:00
public db: loki;
private contexts: loki.Collection<{
isMessage: boolean;
noteId?: string;
userId?: string;
module: string;
key: string;
2018-08-26 21:59:18 +00:00
data?: any;
}>;
2018-08-27 11:22:59 +00:00
public friends: loki.Collection<FriendDoc>;
2018-08-26 21:16:56 +00:00
2018-08-28 21:30:48 +00:00
constructor(account: User, modules: IModule[]) {
2018-08-11 06:26:25 +00:00
this.account = account;
2018-08-28 07:02:20 +00:00
this.modules = modules;
2018-08-11 06:26:25 +00:00
2018-08-26 21:16:56 +00:00
this.db = new loki('memory.json', {
autoload: true,
autosave: true,
autosaveInterval: 1000,
autoloadCallback: this.init
});
}
private init = () => {
//#region Init DB
2018-08-29 07:26:33 +00:00
this.contexts = getCollection(this.db, 'contexts', {
indices: ['key']
});
this.friends = getCollection(this.db, 'friends', {
indices: ['userId']
});
2018-08-26 21:16:56 +00:00
//#endregion
2018-10-09 15:47:03 +00:00
// Init stream
this.connection = new Stream();
2018-08-11 06:26:25 +00:00
2018-10-09 15:47:03 +00:00
//#region Main stream
const mainStream = this.connection.useSharedConnection('main');
2018-08-11 06:26:25 +00:00
2018-10-09 15:47:03 +00:00
// メンションされたとき
mainStream.on('mention', data => {
if (data.userId == this.account.id) return; // 自分は弾く
if (data.text.startsWith('@' + this.account.username)) {
this.onMention(new MessageLike(this, data, false));
}
2018-08-13 21:14:47 +00:00
});
2018-10-09 15:47:03 +00:00
// 返信されたとき
mainStream.on('reply', data => {
if (data.userId == this.account.id) return; // 自分は弾く
this.onMention(new MessageLike(this, data, false));
2018-08-13 21:14:47 +00:00
});
2018-10-09 15:47:03 +00:00
// メッセージ
mainStream.on('messagingMessage', data => {
if (data.userId == this.account.id) return; // 自分は弾く
this.onMention(new MessageLike(this, data, true));
2018-08-13 21:14:47 +00:00
});
//#endregion
2018-08-11 06:26:25 +00:00
2018-10-09 15:47:03 +00:00
// Install modules
this.modules.forEach(m => m.install(this));
2018-08-13 21:14:47 +00:00
}
2018-08-11 06:26:25 +00:00
private onMention = (msg: MessageLike) => {
console.log(`mention received: ${msg.id}`);
2018-08-26 21:16:56 +00:00
const context = !msg.isMessage && msg.replyId == null ? null : this.contexts.findOne(msg.isMessage ? {
isMessage: true,
userId: msg.userId
} : {
isMessage: false,
noteId: msg.replyId
2018-08-11 06:26:25 +00:00
});
let reaction = 'love';
if (context != null) {
const module = this.modules.find(m => m.name == context.module);
const res = module.onReplyThisModule(msg, context.data);
if (res != null && typeof res === 'object') {
reaction = res.reaction;
}
} else {
let res: ReturnType<IModule['onMention']>;
this.modules.filter(m => m.hasOwnProperty('onMention')).some(m => {
res = m.onMention(msg);
return res === true || typeof res === 'object';
});
if (res != null && typeof res === 'object') {
reaction = res.reaction;
}
}
setTimeout(() => {
if (msg.isMessage) {
// 既読にする
this.api('messaging/messages/read', {
messageId: msg.id,
});
} else {
// リアクションする
2018-12-03 08:20:15 +00:00
if (reaction) {
this.api('notes/reactions/create', {
noteId: msg.id,
reaction: reaction
});
}
}
}, 1000);
2018-08-11 06:26:25 +00:00
}
public post = async (param: any) => {
const res = await this.api('notes/create', param);
return res.createdNote;
2018-08-11 06:26:25 +00:00
}
public sendMessage = (userId: any, param: any) => {
return this.api('messaging/messages/create', Object.assign({
2018-08-11 06:26:25 +00:00
userId: userId,
}, param));
}
2018-08-13 08:54:56 +00:00
public api = (endpoint: string, param?: any) => {
2018-08-11 06:26:25 +00:00
return request.post(`${config.apiUrl}/${endpoint}`, {
json: Object.assign({
i: config.i
}, param)
});
};
2018-08-26 21:59:18 +00:00
public subscribeReply = (module: IModule, key: string, isMessage: boolean, id: string, data?: any) => {
2018-08-26 21:16:56 +00:00
this.contexts.insertOne(isMessage ? {
isMessage: true,
userId: id,
module: module.name,
key: key,
2018-08-26 21:59:18 +00:00
data: data
} : {
isMessage: false,
noteId: id,
module: module.name,
key: key,
2018-08-26 21:59:18 +00:00
data: data
});
}
public unsubscribeReply = (module: IModule, key: string) => {
2018-08-26 21:16:56 +00:00
this.contexts.findAndRemove({
key: key,
module: module.name
});
}
2018-08-11 06:26:25 +00:00
}