Merge remote-tracking branch 'cffnpwr/nodev18' into dev

This commit is contained in:
nullnyat 2023-02-15 21:25:15 +09:00
commit d0fc7f7f0b
26 changed files with 4808 additions and 130 deletions

2
.npmrc
View File

@ -1,2 +0,0 @@
save-exact = true
package-lock = false

6
.swcrc
View File

@ -11,10 +11,14 @@
"transform": {
"legacyDecorator": false,
"decoratorMetadata": false
},
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
},
"module": {
"type": "commonjs",
"noInterop": true
"noInterop": false
}
}

View File

@ -1,19 +1,19 @@
FROM node:16 AS module
FROM node:18 AS module
WORKDIR /app
RUN apt-get update
RUN apt-get install -y build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev
COPY package.json .
COPY package.json ./
RUN corepack enable
RUN pnpm install --prod
RUN pnpm i --frozen-lockfile --prod
FROM module AS build
RUN pnpm install
RUN pnpm i --frozen-lockfile
COPY . .
@ -37,7 +37,7 @@ RUN apk add tini-static
RUN mv /sbin/tini-static /tini
FROM node:16-slim
FROM node:18-slim
ENV NODE_ENV="production"

View File

@ -1,5 +1,7 @@
## これってなに?
Misskey用の[Aiベース](https://github.com/syuilo/ai)のBotです。
```
_ __ ____ __ ________ __
/ | / /_ __/ / /________ _/ /_/ ____/ /_ ____ _____ / /
@ -9,6 +11,7 @@ Misskey用の[Aiベース](https://github.com/syuilo/ai)のBotです。
```
## 大きな変更点
- 自動投稿の内容
- 自動返信の内容
- ゴママヨに反応
@ -23,10 +26,21 @@ Misskey用の[Aiベース](https://github.com/syuilo/ai)のBotです。
- アニメ予想機能
## 導入方法
> Node.js と pnpm と MeCab がインストールされている必要があります。
まず適当なディレクトリに `git clone` します。
次にそのディレクトリに `config.json` を作成します。中身は次のようにします:
### Dockerを使わずに動かす
#### 必要要件
- [Node.js](https://nodejs.org/) v18
- [pnpm](https://pnpm.io/) v7
- [MeCab](https://taku910.github.io/mecab/)
#### インストール
まず適当なディレクトリにこのリポジトリをクローンします。
次にそのディレクトリに`config.json`を作成します。中身は次のようにします。
``` json
{
"host": "https:// + あなたのインスタンスのURL (末尾の / は除く)",
@ -48,12 +62,22 @@ Misskey用の[Aiベース](https://github.com/syuilo/ai)のBotです。
"ti": "ちの意味をを表す絵文字を入れる(デフォルトだと:_ti:)"
}
```
`pnpm install` して `pnpm run build` して `pnpm start` すれば起動できます。
`pnpm fetch`して`pnpm build`して`pnpm start`すれば起動できます。
### Dockerで動かす
まず適当なディレクトリに `git clone` します。<br>
次にそのディレクトリに `config.json` を作成します。中身は次のようにします:
#### 必要要件
- [Docker](https://www.docker.com/)
- [Docker Compose](https://docs.docker.com/compose/) v2
#### インストール
まず適当なディレクトリにこのリポジトリをクローンします。
次にそのディレクトリに`config.json`を作成します。中身は次のようにします。
MeCabの設定、memoryDirについては触らないでください
``` json
{
"host": "https:// + あなたのインスタンスのURL (末尾の / は除く)",
@ -62,7 +86,7 @@ Misskey用の[Aiベース](https://github.com/syuilo/ai)のBotです。
"notingEnabled": "ランダムにートを投稿する機能。true(on) or false(off)",
"keywordEnabled": "キーワードを覚える機能 (MeCab が必要) true or false",
"mecab": "/usr/bin/mecab",
"mecabDic": "/usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologd/",
"mecabDic": "/min",
"memoryDir": "data",
"shellgeiUrl": "シェル芸BotのAPIのURLです(オプション、デフォルトではhttps://websh.jiro4989.com/api/shellgei)",
"love": "いいねやloveの意味をを表す絵文字を入れる(デフォルトだと:love_nullcatchan:)",
@ -74,12 +98,8 @@ Misskey用の[Aiベース](https://github.com/syuilo/ai)のBotです。
"ti": "ちの意味をを表す絵文字を入れる(デフォルトだと:_ti:)"
}
```
`pnpm install` して `pnpm run docker` すれば起動できます。<br>
`docker-compose.yml``enable_mecab``0` にすると、MeCabをインストールしないようにもできます。メモリが少ない環境など
#### dockerimageを配布しています
[ここ](https://hub.docker.com/r/nullnyat/nullcatchan)にある
`docker compose up -d`すれば起動できます。
#### 一部の機能にはフォントが必要です。NullcatChan!にはフォントは同梱されていないので、ご自身でフォントをインストールしてそのフォントを`font.ttf`という名前でインストールディレクトリに設置してください。
#### NullcatChan!は記憶の保持にインメモリデータベースを使用しており、nullcatchanのインストールディレクトリに `memory.json` という名前で永続化されます。

View File

@ -1,74 +1,69 @@
{
"version": "2.2.0",
"version": "2.3.0",
"main": "./built/index.js",
"packageManager": "pnpm@7.26.3",
"scripts": {
"docker:dev": "cross-env DOCKER_ENV=development docker-compose -f docker-compose.yml -f docker-compose_development.yml up -d --build && docker-compose logs -f",
"docker": "cross-env DOCKER_ENV=production docker-compose up -d --build && docker-compose logs -f",
"dev": "cross-env NODE_ENV=development node ./built",
"dev": "cross-env NODE_ENV=development nodemon --exec ts-node -r tsconfig-paths/register src",
"start": "cross-env NODE_ENV=production node ./built",
"lint": "prettier --write ./src/",
"build": "swc src -d built",
"test": "jest"
},
"dependencies": {
"accurate-interval": "1.0.9",
"autobind-decorator": "2.4.0",
"canvas": "2.8.0",
"chalk": "4.1.1",
"cjp": "1.2.3",
"cross-env": "7.0.3",
"gomamayo-js": "0.2.1",
"humanize-duration": "3.27.1",
"koa": "2.13.1",
"koa-json-body": "5.3.0",
"lokijs": "1.5.12",
"memory-streams": "0.1.3",
"misskey-reversi": "0.0.5",
"module-alias": "2.2.2",
"moji": "0.5.1",
"node-fetch": "2.6.7",
"accurate-interval": "^1.0.9",
"autobind-decorator": "^2.4.0",
"canvas": "^2.11.0",
"chalk": "^4.1.1",
"cjp": "^2.3.0",
"cross-env": "^7.0.3",
"gomamayo-js": "^0.2.1",
"humanize-duration": "^3.28.0",
"koa": "^2.14.1",
"koa-json-body": "^5.3.0",
"lokijs": "^1.5.12",
"memory-streams": "^0.1.3",
"misskey-reversi": "^0.0.5",
"module-alias": "^2.2.2",
"moji": "^0.5.1",
"promise-retry": "2.0.1",
"random-seed": "0.3.0",
"random-seed": "^0.3.0",
"reconnecting-websocket": "4.4.0",
"request": "2.88.2",
"request-promise-native": "1.0.9",
"seedrandom": "3.0.5",
"timeout-as-promise": "1.0.0",
"twemoji-parser": "13.1.0",
"uuid": "8.3.2",
"ws": "7.5.2",
"zod": "3.11.6"
"seedrandom": "^3.0.5",
"timeout-as-promise": "^1.0.0",
"twemoji-parser": "^14.0.0",
"uuid": "^9.0.0",
"websocket": "^1.0.34",
"ws": "8.12.0",
"zod": "^3.20.2"
},
"devDependencies": {
"@koa/router": "9.4.0",
"@swc/cli": "0.1.59",
"@swc/core": "1.3.30",
"@types/accurate-interval": "1.0.0",
"@types/chalk": "2.2.0",
"@types/humanize-duration": "3.27.1",
"@types/jest": "26.0.23",
"@types/koa": "2.13.1",
"@types/koa__router": "8.0.4",
"@types/lokijs": "1.5.4",
"@types/moji": "0.5.0",
"@types/node": "16.0.1",
"@types/promise-retry": "1.1.3",
"@types/random-seed": "0.3.3",
"@types/request-promise-native": "1.0.18",
"@types/seedrandom": "2.4.28",
"@types/twemoji-parser": "13.1.1",
"@types/uuid": "8.3.1",
"@types/websocket": "1.0.2",
"@types/ws": "7.4.6",
"jest": "26.6.3",
"prettier": "2.5.1",
"ts-jest": "26.5.6",
"ts-node": "10.0.0",
"typescript": "4.5.5",
"websocket": "1.0.34"
},
"_moduleAliases": {
"@": "built"
"@koa/router": "^12.0.0",
"@swc/cli": "^0.1.60",
"@swc/core": "^1.3.32",
"@swc/helpers": "0.4.14",
"@types/accurate-interval": "^1.0.0",
"@types/humanize-duration": "^3.27.1",
"@types/jest": "^29.4.0",
"@types/koa": "^2.13.5",
"@types/koa__router": "^12.0.0",
"@types/lokijs": "^1.5.7",
"@types/moji": "^0.5.0",
"@types/node": "^18.11.18",
"@types/promise-retry": "^1.1.3",
"@types/random-seed": "^0.3.3",
"@types/seedrandom": "^3.0.4",
"@types/twemoji-parser": "^13.1.1",
"@types/uuid": "^9.0.0",
"@types/websocket": "^1.0.5",
"@types/ws": "^8.5.4",
"jest": "^29.4.1",
"nodemon": "2.0.20",
"prettier": "^2.8.3",
"regenerator-runtime": "0.13.11",
"ts-jest": "^29.0.5",
"ts-node": "^10.9.1",
"tsconfig-paths": "4.1.2",
"typescript": "^4.9.5"
},
"jest": {
"testRegex": "/test/.*",

4654
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -2,11 +2,10 @@
import * as fs from 'fs';
import autobind from 'autobind-decorator';
import * as loki from 'lokijs';
import * as request from 'request-promise-native';
import * as chalk from 'chalk';
import loki from 'lokijs';
import chalk from 'chalk';
import { v4 as uuid } from 'uuid';
const delay = require('timeout-as-promise');
import delay from 'timeout-as-promise';
import config from '@/config';
import Module from '@/module';
@ -363,16 +362,18 @@ export default class 藍 {
*/
@autobind
public async upload(file: Buffer | fs.ReadStream, meta: any) {
const res = await request.post({
url: `${config.apiUrl}/drive/files/create`,
formData: {
const res = await fetch(`${config.apiUrl}/drive/files/create`, {
method: "POST",
body: JSON.stringify({
i: config.i,
file: {
value: file,
options: meta
}
},
json: true
}),
headers: {
"Content-Type": "application/json",
}
});
return res;
}
@ -418,13 +419,21 @@ export default class 藍 {
*/
@autobind
public api(endpoint: string, param?: any) {
return request.post(`${config.apiUrl}/${endpoint}`, {
json: Object.assign(
{
i: config.i
},
param
)
return fetch(`${config.apiUrl}/${endpoint}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
...{ i: config.i }, ...param
}),
}).then(res => {
if(res.status != 204)
return res.json();
return new Promise((resolve, reject) => {
resolve(JSON.parse("{}"));
})
});
}

View File

@ -2,9 +2,8 @@
import 'module-alias/register';
import * as chalk from 'chalk';
import * as request from 'request-promise-native';
const promiseRetry = require('promise-retry');
import chalk from 'chalk';
import Retry from 'promise-retry';
import from './ai';
import config from './config';
@ -53,23 +52,26 @@ function log(msg: string): void {
log(chalk.bold(`Nullcat chan! v${pkg.version}`));
promiseRetry(
Retry(
retry => {
log(`Account fetching... ${chalk.gray(config.host)}`);
// アカウントをフェッチ
return request
.post(`${config.apiUrl}/i`, {
json: {
i: config.i
}
})
.catch(retry);
return fetch(`${config.apiUrl}/i`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
i: config.i,
})
}).catch(retry);
},
{
retries: 3
}
)
.then(res => res.json())
.then(account => {
const acct = `@${account.username}`;
log(chalk.green(`Account fetched successfully: ${chalk.underline(acct)}`));

View File

@ -1,6 +1,6 @@
import autobind from 'autobind-decorator';
import * as chalk from 'chalk';
const delay = require('timeout-as-promise');
import chalk from 'chalk';
import delay from 'timeout-as-promise';
import from '@/ai';
import Friend from '@/friend';

View File

@ -2,7 +2,6 @@ import config from '@/config';
import Message from '@/message';
import Module from '@/module';
import autobind from 'autobind-decorator';
import fetch from 'node-fetch';
import { z } from 'zod';
export default class extends Module {

View File

@ -1,7 +1,6 @@
import autobind from 'autobind-decorator';
import { parse } from 'twemoji-parser';
import delay from 'timeout-as-promise';
import config from '@/config';
const delay = require('timeout-as-promise');
import { Note } from '@/misskey/note';
import Module from '@/module';
import Stream from '@/stream';

View File

@ -1,7 +1,7 @@
import Message from '@/message';
import Module from '@/module';
import autobind from 'autobind-decorator';
import * as seedrandom from 'seedrandom';
import seedrandom from 'seedrandom';
export const feelings = ['つらい', 'ねむい', 'るんるん', '虚無'];

View File

@ -2,7 +2,7 @@ import autobind from 'autobind-decorator';
import Module from '@/module';
import Message from '@/message';
import serifs from '@/serifs';
import * as seedrandom from 'seedrandom';
import seedrandom from 'seedrandom';
import { genItem } from '@/vocabulary';
export const blessing = ['にゃん吉🐈', 'みゃ~吉🐾', 'ぬるきゃっと吉💙', 'なんかすごい吉✨', '特大吉✨', '大大吉🎊', '大吉🎊', '吉🎉', '中吉🎉', '小吉🎉', '凶🗿', '大凶🗿'];

View File

@ -2,7 +2,6 @@ import config from '@/config';
import Message from '@/message';
import Module from '@/module';
import autobind from 'autobind-decorator';
import fetch from 'node-fetch';
import { z } from 'zod';
export default class extends Module {

View File

@ -1,7 +1,7 @@
import Module from '@/module';
import autobind from 'autobind-decorator';
const accurateInterval = require('accurate-interval');
import accurateInterval from 'accurate-interval';
export default class extends Module {
public readonly name = 'jihou';

View File

@ -1,5 +1,5 @@
import autobind from 'autobind-decorator';
import * as loki from 'lokijs';
import loki from 'lokijs';
import Message from '@/message';
import Module from '@/module';
import NGWord from '@/ng-words';

View File

@ -1,7 +1,6 @@
import Message from '@/message';
import Module from '@/module';
import autobind from 'autobind-decorator';
import fetch from 'node-fetch';
import { z } from 'zod';
export default class extends Module {

View File

@ -2,7 +2,7 @@ import Module from '@/module';
import serifs from '@/serifs';
import autobind from 'autobind-decorator';
const accurateInterval = require('accurate-interval');
import accurateInterval from 'accurate-interval';
export default class extends Module {
public readonly name = 'rogubo';

View File

@ -2,7 +2,6 @@ import autobind from 'autobind-decorator';
import Module from '@/module';
import Message from '@/message';
import config from '@/config';
import fetch from 'node-fetch';
export default class extends Module {
public readonly name = 'shellgei';

View File

@ -1,9 +1,8 @@
import Message from '@/message';
import Module from '@/module';
import autobind from 'autobind-decorator';
import fetch from 'node-fetch';
import { z } from 'zod';
import humanizeDuration = require('humanize-duration');
import humanizeDuration from 'humanize-duration';
export default class extends Module {
public readonly name = 'trace-moe';

View File

@ -48,8 +48,6 @@ export default class extends Module {
this.log(`Version changed: ${v}`);
this.ai.post({ text: `ぼくのおうちが${v}にリフォームされたよ!!` });
} else {
// 変更なし
}
}

View File

@ -1,7 +1,7 @@
import toHiragana from './utils/to-hiragana';
const fs = require('fs');
const readline = require('readline');
import fs from 'fs';
import readline from 'readline';
export default class NGWord {
private excludedWords: string[] = [];

View File

@ -1,7 +1,7 @@
import autobind from 'autobind-decorator';
import { EventEmitter } from 'events';
import * as WebSocket from 'ws';
const ReconnectingWebsocket = require('reconnecting-websocket');
import WebSocket from 'ws';
import ReconnectingWebsocket from 'reconnecting-websocket';
import config from './config';
/**

View File

@ -1,4 +1,4 @@
import * as chalk from 'chalk';
import chalk from 'chalk';
export default function (msg: string) {
const now = new Date();

View File

@ -1,4 +1,4 @@
import * as seedrandom from 'seedrandom';
import seedrandom from 'seedrandom';
export const itemPrefixes = [
'そこらへんの',

View File

@ -8,6 +8,7 @@
"noFallthroughCasesInSwitch": true,
"strictNullChecks": true,
"experimentalDecorators": true,
"esModuleInterop": true,
"sourceMap": false,
"target": "es2020",
"module": "commonjs",
@ -23,5 +24,8 @@
"compileOnSave": false,
"include": [
"./src/**/*.ts"
]
],
"ts-node": {
"swc": true
}
}