Add keyword module

This commit is contained in:
syuilo 2018-08-13 17:54:56 +09:00
parent cca9c7bc03
commit 6e2c87cdfc
7 changed files with 113 additions and 1 deletions

41
package-lock.json generated
View file

@ -3,11 +3,24 @@
"requires": true, "requires": true,
"lockfileVersion": 1, "lockfileVersion": 1,
"dependencies": { "dependencies": {
"@types/doublearray": {
"version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/doublearray/-/doublearray-0.0.29.tgz",
"integrity": "sha1-PL5rthavUkZI1EC733hOnB40AJ0="
},
"@types/events": { "@types/events": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/@types/events/-/events-1.2.0.tgz", "resolved": "https://registry.npmjs.org/@types/events/-/events-1.2.0.tgz",
"integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==" "integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA=="
}, },
"@types/kuromoji": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@types/kuromoji/-/kuromoji-0.1.0.tgz",
"integrity": "sha512-gEAkIk4qxsK5ry64fCYFGjb3a+NQVOiNOT6fz0OyXizob+yewF4GFVX23GG4YNwKM2hB0J6fnMPMffFK+cYHnw==",
"requires": {
"@types/doublearray": "*"
}
},
"@types/lokijs": { "@types/lokijs": {
"version": "1.5.2", "version": "1.5.2",
"resolved": "https://registry.npmjs.org/@types/lokijs/-/lokijs-1.5.2.tgz", "resolved": "https://registry.npmjs.org/@types/lokijs/-/lokijs-1.5.2.tgz",
@ -82,6 +95,14 @@
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
}, },
"async": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz",
"integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==",
"requires": {
"lodash": "^4.17.10"
}
},
"async-limiter": { "async-limiter": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
@ -180,6 +201,11 @@
"resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
"integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA=="
}, },
"doublearray": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/doublearray/-/doublearray-0.0.2.tgz",
"integrity": "sha1-Yxhv6NNEEydtNiH2qg7F954ifvk="
},
"ecc-jsbn": { "ecc-jsbn": {
"version": "0.1.2", "version": "0.1.2",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
@ -314,6 +340,16 @@
"verror": "1.10.0" "verror": "1.10.0"
} }
}, },
"kuromoji": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/kuromoji/-/kuromoji-0.1.2.tgz",
"integrity": "sha512-V0dUf+C2LpcPEXhoHLMAop/bOht16Dyr+mDiIE39yX3vqau7p80De/koFqpiTcL1zzdZlc3xuHZ8u5gjYRfFaQ==",
"requires": {
"async": "^2.0.1",
"doublearray": "0.0.2",
"zlibjs": "^0.3.1"
}
},
"lodash": { "lodash": {
"version": "4.17.10", "version": "4.17.10",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
@ -599,6 +635,11 @@
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz",
"integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=" "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo="
},
"zlibjs": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/zlibjs/-/zlibjs-0.3.1.tgz",
"integrity": "sha1-UBl+2yihxCymWcyLTmqd3W1ERVQ="
} }
} }
} }

View file

@ -5,11 +5,13 @@
"build": "tsc" "build": "tsc"
}, },
"dependencies": { "dependencies": {
"@types/kuromoji": "0.1.0",
"@types/lokijs": "1.5.2", "@types/lokijs": "1.5.2",
"@types/node": "10.0.5", "@types/node": "10.0.5",
"@types/promise-retry": "1.1.2", "@types/promise-retry": "1.1.2",
"@types/seedrandom": "2.4.27", "@types/seedrandom": "2.4.27",
"@types/ws": "5.1.2", "@types/ws": "5.1.2",
"kuromoji": "0.1.2",
"lokijs": "1.5.5", "lokijs": "1.5.5",
"misskey-reversi": "0.0.5", "misskey-reversi": "0.0.5",
"promise-retry": "1.1.1", "promise-retry": "1.1.1",

View file

@ -129,7 +129,7 @@ export default class 藍 {
}, param)); }, param));
} }
public api = (endpoint: string, param) => { public api = (endpoint: string, param?: any) => {
return request.post(`${config.apiUrl}/${endpoint}`, { return request.post(`${config.apiUrl}/${endpoint}`, {
json: Object.assign({ json: Object.assign({
i: config.i i: config.i

View file

@ -3,7 +3,9 @@ type Config = {
i: string; i: string;
wsUrl: string; wsUrl: string;
apiUrl: string; apiUrl: string;
keywordEnabled: boolean;
reversiEnabled: boolean; reversiEnabled: boolean;
mecabDic?: string;
}; };
const config = require('../config.json'); const config = require('../config.json');

View file

@ -6,6 +6,7 @@ import PingModule from './modules/ping';
import EmojiModule from './modules/emoji'; import EmojiModule from './modules/emoji';
import FortuneModule from './modules/fortune'; import FortuneModule from './modules/fortune';
import GuessingGameModule from './modules/guessing-game'; import GuessingGameModule from './modules/guessing-game';
import KeywordModule from './modules/keyword';
import * as request from 'request-promise-native'; import * as request from 'request-promise-native';
const promiseRetry = require('promise-retry'); const promiseRetry = require('promise-retry');
@ -24,4 +25,5 @@ promiseRetry(retry => {
ai.install(new GuessingGameModule()); ai.install(new GuessingGameModule());
ai.install(new ServerModule()); ai.install(new ServerModule());
ai.install(new ReversiModule()); ai.install(new ReversiModule());
if (config.keywordEnabled) ai.install(new KeywordModule());
}); });

View file

@ -0,0 +1,60 @@
import from '../../ai';
import IModule from '../../module';
import config from '../../config';
import * as kuromoji from 'kuromoji';
import MessageLike from '../../message-like';
import serifs from '../../serifs';
export default class KeywordModule implements IModule {
public name = 'keyword';
private ai: ;
private tokenizer: kuromoji.Tokenizer<kuromoji.IpadicFeatures>;
public install = (ai: ) => {
this.ai = ai;
kuromoji.builder({
dicPath: config.mecabDic
}).build((err, tokenizer) => {
if (err) {
console.error(err);
} else {
this.tokenizer = tokenizer;
setTimeout(this.say, 1000 * 60 * 60);
}
});
}
private say = async () => {
const tl = await this.ai.api('notes/local-timeline');
const interestedNotes = tl.filter(note => note.userId !== this.ai.account.id && note.text != null);
let keywords: kuromoji.IpadicFeatures[] = [];
interestedNotes.forEach(note => {
const tokens = this.tokenizer.tokenize(note.text);
const keywordsInThisNote = tokens.filter(token => token.pos_detail_1 == '固有名詞');
keywords = keywords.concat(keywordsInThisNote);
});
console.log(keywords);
const keyword = keywords[Math.floor(Math.random() * keywords.length)];
this.ai.post(serifs.KEYWORD
.replace('{word}', keyword.surface_form)
.replace('{reading}', keyword.reading));
}
public onMention = (msg: MessageLike) => {
if (msg.user.isAdmin && msg.text && msg.text.includes('なんか言って')) {
this.say();
return true;
} else {
return false;
}
}
}

View file

@ -86,4 +86,9 @@ export default {
* *
*/ */
GUESSINGGAME_CONGRATS: '正解です🎉 ({tries}回目で当てました)', GUESSINGGAME_CONGRATS: '正解です🎉 ({tries}回目で当てました)',
/**
*
*/
KEYWORD: '({word}... {reading}...)',
}; };