ai/src/ai.ts

193 lines
4.4 KiB
TypeScript
Raw Normal View History

2018-08-11 06:26:25 +00:00
// AI CORE
import * as WebSocket from 'ws';
import * as request from 'request-promise-native';
import serifs from './serifs';
import config from './config';
import IModule from './module';
import MessageLike from './message-like';
import { contexts } from './memory';
2018-08-11 06:26:25 +00:00
const ReconnectingWebSocket = require('../node_modules/reconnecting-websocket/dist/reconnecting-websocket-cjs.js');
/**
*
*/
export default class {
public account: any;
2018-08-11 06:26:25 +00:00
/**
*
*/
private connection: any;
2018-08-13 21:14:47 +00:00
/**
*
*/
private localTimelineConnection: any;
2018-08-11 06:26:25 +00:00
private modules: IModule[] = [];
constructor(account: any) {
this.account = account;
2018-08-13 21:14:47 +00:00
//#region Home stream
2018-08-11 06:26:25 +00:00
this.connection = new ReconnectingWebSocket(`${config.wsUrl}/?i=${config.i}`, [], {
WebSocket: WebSocket
});
this.connection.addEventListener('open', () => {
console.log('home stream opened');
});
this.connection.addEventListener('close', () => {
console.log('home stream closed');
2018-08-25 05:18:16 +00:00
this.connection.reconnect();
2018-08-11 06:26:25 +00:00
});
this.connection.addEventListener('message', message => {
const msg = JSON.parse(message.data);
this.onMessage(msg);
});
2018-08-13 21:14:47 +00:00
//#endregion
2018-08-11 06:26:25 +00:00
2018-08-13 21:14:47 +00:00
//#region Local timeline stream
this.localTimelineConnection = new ReconnectingWebSocket(`${config.wsUrl}/local-timeline?i=${config.i}`, [], {
WebSocket: WebSocket
});
this.localTimelineConnection.addEventListener('open', () => {
console.log('local-timeline stream opened');
});
this.localTimelineConnection.addEventListener('close', () => {
console.log('local-timeline stream closed');
});
this.localTimelineConnection.addEventListener('message', message => {
const msg = JSON.parse(message.data);
this.onLocalNote(msg.body);
});
//#endregion
2018-08-11 06:26:25 +00:00
}
public install = (module: IModule) => {
module.install(this);
this.modules.push(module);
}
private onMessage = (msg: any) => {
switch (msg.type) {
// メンションされたとき
case 'mention': {
if (msg.body.userId == this.account.id) return; // 自分は弾く
if (msg.body.text.startsWith('@' + this.account.username)) {
this.onMention(new MessageLike(this, msg.body, false));
}
break;
}
// 返信されたとき
case 'reply': {
if (msg.body.userId == this.account.id) return; // 自分は弾く
this.onMention(new MessageLike(this, msg.body, false));
break;
}
// メッセージ
case 'messaging_message': {
if (msg.body.userId == this.account.id) return; // 自分は弾く
this.onMention(new MessageLike(this, msg.body, true));
break;
}
default:
break;
}
}
2018-08-13 21:14:47 +00:00
private onLocalNote = (note: any) => {
this.modules.filter(m => m.hasOwnProperty('onLocalNote')).forEach(m => {
return m.onLocalNote(note);
});
}
2018-08-11 06:26:25 +00:00
private onMention = (msg: MessageLike) => {
console.log(`mention received: ${msg.id}`);
setTimeout(() => {
if (msg.isMessage) {
// 既読にする
2018-08-11 12:43:55 +00:00
this.api('messaging/messages/read', {
messageId: msg.id,
2018-08-11 06:26:25 +00:00
});
} else {
// リアクションする
2018-08-11 12:43:55 +00:00
this.api('notes/reactions/create', {
noteId: msg.id,
reaction: 'love'
});
}
}, 1000);
2018-08-11 06:26:25 +00:00
const context = !msg.isMessage && msg.replyId == null ? null : contexts.findOne(msg.isMessage ? {
isMessage: true,
userId: msg.userId
} : {
isMessage: false,
noteId: msg.replyId
2018-08-11 06:26:25 +00:00
});
if (context != null) {
const module = this.modules.find(m => m.name == context.module);
module.onReplyThisModule(msg);
} else {
this.modules.filter(m => m.hasOwnProperty('onMention')).some(m => {
return m.onMention(msg);
});
}
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)
});
};
public subscribeReply = (module: IModule, key: string, isMessage: boolean, id: string) => {
contexts.insertOne(isMessage ? {
isMessage: true,
userId: id,
module: module.name,
key: key,
} : {
isMessage: false,
noteId: id,
module: module.name,
key: key,
});
}
public unsubscribeReply = (module: IModule, key: string) => {
contexts.findAndRemove({
key: key,
module: module.name
});
}
2018-08-11 06:26:25 +00:00
}