This commit is contained in:
syuilo 2018-08-11 15:26:25 +09:00
parent d5120ca0b0
commit 6160d0f825
10 changed files with 192 additions and 127 deletions

32
package-lock.json generated
View file

@ -13,6 +13,19 @@
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.0.5.tgz",
"integrity": "sha512-he3QlF+xnGlmsnL1H8/CiM6r25kk0STky6U5yIqNh4Nnp9KlJBSdMMIiCzDYtAFLw2rWnJ4XKc1xB2/u/anYow=="
},
"@types/promise-retry": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@types/promise-retry/-/promise-retry-1.1.2.tgz",
"integrity": "sha512-rnfMx3T3mJBd1T4Jd4EouFTSXivbOIDmamTKPXx9KuwEzYxqPW7SuPAnQ7KmHq52GjKYzQFWz++ICuWa092deQ==",
"requires": {
"@types/retry": "*"
}
},
"@types/retry": {
"version": "0.10.2",
"resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.10.2.tgz",
"integrity": "sha512-LqJkY4VQ7S09XhI7kA3ON71AxauROhSv74639VsNXC9ish4IWHnIi98if+nP1MxQV3RMPqXSCYgpPsDHjlg9UQ=="
},
"@types/ws": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-5.1.2.tgz",
@ -167,6 +180,11 @@
"safer-buffer": "^2.1.0"
}
},
"err-code": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz",
"integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA="
},
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
@ -344,6 +362,15 @@
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
},
"promise-retry": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-1.1.1.tgz",
"integrity": "sha1-ZznpaOMFHaIM5kl/srUPaRHfPW0=",
"requires": {
"err-code": "^1.0.0",
"retry": "^0.10.0"
}
},
"psl": {
"version": "1.1.29",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz",
@ -419,6 +446,11 @@
"tough-cookie": ">=2.3.3"
}
},
"retry": {
"version": "0.10.1",
"resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz",
"integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q="
},
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",

View file

@ -1,13 +1,15 @@
{
"name": "ai",
"main": "./built/front.js",
"main": "./built/index.js",
"scripts": {
"build": "tsc"
},
"dependencies": {
"@types/node": "10.0.5",
"@types/promise-retry": "1.1.2",
"@types/ws": "5.1.2",
"misskey-reversi": "0.0.5",
"promise-retry": "1.1.1",
"reconnecting-websocket": "4.0.0-rc5",
"request": "2.87.0",
"request-promise-native": "1.0.5",

122
src/ai.ts Normal file
View file

@ -0,0 +1,122 @@
// 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';
const ReconnectingWebSocket = require('../node_modules/reconnecting-websocket/dist/reconnecting-websocket-cjs.js');
/**
*
*/
export default class {
private account: any;
/**
*
*/
private connection: any;
private modules: IModule[] = [];
constructor(account: any) {
this.account = account;
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');
});
this.connection.addEventListener('message', message => {
const msg = JSON.parse(message.data);
this.onMessage(msg);
});
if (config.reversiEnabled) {
}
}
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;
}
}
private onMention = (msg: MessageLike) => {
console.log(`mention received: ${msg.id}`);
// リアクションする
if (!msg.isMessage) {
setTimeout(() => {
request.post(`${config.apiUrl}/notes/reactions/create`, {
json: {
i: config.i,
noteId: msg.id,
reaction: 'love'
}
});
}, 1000);
}
this.modules.filter(m => m.hasOwnProperty('onMention')).some(m => {
return m.onMention(msg);
});
}
public post = (param: any) => {
this.api('notes/create', param);
}
public sendMessage = (userId: any, param: any) => {
this.api('messaging/messages/create', Object.assign({
userId: userId,
}, param));
}
public api = (endpoint: string, param) => {
return request.post(`${config.apiUrl}/${endpoint}`, {
json: Object.assign({
i: config.i
}, param)
});
};
}

View file

@ -1,7 +1,6 @@
type Config = {
host: string;
i: string;
id: string;
wsUrl: string;
apiUrl: string;
reversiEnabled: boolean;

View file

@ -1,127 +1,21 @@
// AI CORE
import * as WebSocket from 'ws';
import * as request from 'request-promise-native';
import serifs from './serifs';
import from './ai';
import config from './config';
import IModule from './module';
import MessageLike from './message-like';
import ReversiModule from './modules/reversi';
import ServerModule from './modules/server';
const ReconnectingWebSocket = require('../node_modules/reconnecting-websocket/dist/reconnecting-websocket-cjs.js');
import PingModule from './modules/ping';
import * as request from 'request-promise-native';
const promiseRetry = require('promise-retry');
/**
*
*/
export default class {
/**
*
*/
private connection: any;
private modules: IModule[] = [];
constructor() {
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');
});
this.connection.addEventListener('message', message => {
const msg = JSON.parse(message.data);
this.onMessage(msg);
});
if (config.reversiEnabled) {
promiseRetry(retry => {
return request.post(`${config.apiUrl}/i`, {
json: {
i: config.i
}
}
}).catch(retry);
}).then(account => {
const ai = new (account);
public install = (module: IModule) => {
module.install(this);
this.modules.push(module);
}
private onMessage = (msg: any) => {
switch (msg.type) {
// メンションされたとき
case 'mention': {
if (msg.body.userId == config.id) return; // 自分は弾く
this.onMention(new MessageLike(this, msg.body, false));
break;
}
// 返信されたとき
case 'reply': {
if (msg.body.userId == config.id) return; // 自分は弾く
this.onMention(new MessageLike(this, msg.body, false));
break;
}
// メッセージ
case 'messaging_message': {
if (msg.body.userId == config.id) return; // 自分は弾く
this.onMention(new MessageLike(this, msg.body, true));
break;
}
default:
break;
}
}
private onMention = (msg: MessageLike) => {
console.log(`mention received: ${msg.id}`);
// リアクションする
if (!msg.isMessage) {
setTimeout(() => {
request.post(`${config.apiUrl}/notes/reactions/create`, {
json: {
i: config.i,
noteId: msg.id,
reaction: 'love'
}
});
}, 1000);
}
this.modules.filter(m => m.hasOwnProperty('onMention')).some(m => {
return m.onMention(msg);
});
}
public post = (param: any) => {
this.api('notes/create', param);
}
public sendMessage = (userId: any, param: any) => {
this.api('messaging/messages/create', Object.assign({
userId: userId,
}, param));
}
public api = (endpoint: string, param) => {
return request.post(`${config.apiUrl}/${endpoint}`, {
json: Object.assign({
i: config.i
}, param)
});
};
}
const ai = new ();
const serverModule = new ServerModule();
ai.install(serverModule);
const reversiModule = new ReversiModule();
ai.install(reversiModule);
ai.install(new PingModule());
ai.install(new ServerModule());
ai.install(new ReversiModule());
});

View file

@ -1,4 +1,4 @@
import from '.';
import from './ai';
export default class MessageLike {
private ai: ;

View file

@ -1,4 +1,4 @@
import from '.';
import from './ai';
import MessageLike from './message-like';
export default interface IModule {

16
src/modules/ping/index.ts Normal file
View file

@ -0,0 +1,16 @@
import from '../../ai';
import IModule from '../../module';
import MessageLike from '../../message-like';
export default class PingModule implements IModule {
public install = (ai: ) => { }
public onMention = (msg: MessageLike) => {
if (msg.text && msg.text.indexOf('ping') > -1) {
msg.reply('PONG!');
return true;
} else {
return false;
}
}
}

View file

@ -1,6 +1,6 @@
import * as childProcess from 'child_process';
const ReconnectingWebSocket = require('../../../node_modules/reconnecting-websocket/dist/reconnecting-websocket-cjs.js');
import from '../..';
import from '../../ai';
import IModule from '../../module';
import serifs from '../../serifs';
import config from '../../config';

View file

@ -1,6 +1,6 @@
import * as childProcess from 'child_process';
import * as WebSocket from 'ws';
import from '../..';
import from '../../ai';
import IModule from '../../module';
import serifs from '../../serifs';
import config from '../../config';