diff --git a/CHANGELOG.md b/CHANGELOG.md index 733a69e..0455877 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,33 @@ +# 2026.4.0 +- Breaking: noticeUwuzuを0から作り直しました +- Breaking: 25.12.0-alpha.1までの方針を全て廃止しました +- Chg: パッケージマネージャーをnpmからpnpmへ変更しました +- Chg: 全コードをsrcへ移動しました +- Chg: ユーズのメッセージをyamlとi18nextで管理することで先頭と末尾の改行のある問題などに対策しました +- Chg: 全ての保存データをmemory.jsonとして保管し、memory.tsを実装しました +- Note: 以下のログは全て実装として記録しています +- Feat: ユーザーは以下のコマンドを使用することができます。 + - `/weather`: 天気予報を取得できます。 + - `/help`: コマンドの利用方法などを取得できます。 + - `/miq`: Make it a Quoteを操作できます。 + - `/follow`: Botからフォローされます。 + - `/unfollow`: Botからフォロー解除されます。 +- Feat: 地震情報が利用できます。以下の情報を投稿します。 + - 地震発生情報 + - 津波予報 + - 緊急地震速報(警報) +- Feat: 時報が利用できます。毎時0分に投稿します。 +- Feat: 天気予報を利用できます。毎日7:00に投稿します。 +- Feat: 新年迎春の投稿を行います。遅延が最低限になるように出来ています。 +- Feat: worker_threadsによる並列処理 +- Feat: ユーズの再試行 +- Feat: ユーズの文字数制限回避 +- Feat: コマンドを並列処理 +- Feat: 地震情報のWebSocket再接続 +- Feat: 最大震度の要求を設定できる機能 +- Feat: 最大震度が不明な場合に投稿するかどうかを設定できる機能 +- Feat: デバッグ用とで過去の地震情報を読み込み10秒おきに投稿する機能 + # 2026.4.0-beta.0 - Feat: 地震発生情報の地域を都道府県でグループ化する機能 - Feat: ユーズの再試行 @@ -31,7 +61,7 @@ - Del: 各地震情報の情報源の信頼できるかどうかの内容を削除 - Chg: 津波予報情報の各時刻情報を実際に取得できる値まで削減(例: 2:03:00 > 2:03) - Fix: フォロー・フォロー解除に失敗した際にreturnできていない問題 -- Feat: デバッグ用とで過去の地震情報を読み込み10秒おきに投稿する機能 +- Feat: デバッグ用で過去の地震情報を読み込み10秒おきに投稿する機能 # 2026.4.0-alpha.0 - Breaking: noticeUwuzuを0から作り直しました diff --git a/config/example.yaml b/config/example.yaml index ab1c040..5059566 100644 --- a/config/example.yaml +++ b/config/example.yaml @@ -33,5 +33,11 @@ ueuse: # 再試行の間隔(ミリ秒) number # 正数のみが有効です。 retryInterval: 1000 + # 公開されたユーズの自主規制文字数 number + # 返信ではない(公開された)ユーズで使用する自主的な文字数制限です。 + # 返信では、サーバーの設定に従います。 + # 0にすると、返信ではないユーズでもサーバーの設定に従います。 + # 0以上の整数が有効です。 + maxLengthWithPublic: 512 # デバッグモードにするかどうか boolean debug: false \ No newline at end of file diff --git a/package.json b/package.json index aa3946b..b46e989 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "notice-uwuzu", - "version": "26.4.0-beta.0", + "version": "2026.4.0", "type": "module", "main": "dist/index.js", "scripts": { diff --git a/src/feature/earthquakeNotice.ts b/src/feature/earthquakeNotice.ts index e9572a4..9ad8767 100644 --- a/src/feature/earthquakeNotice.ts +++ b/src/feature/earthquakeNotice.ts @@ -116,7 +116,7 @@ const processMessage = async (message: any) => { message.earthquake.maxScale !== -1 && message.earthquake.maxScale < config.earthquake.requireMaxScale ) { - console.log("投稿に必要な最大震度に満たないため、スキップします"); + console.log(`最大震度(${scaleMessages[message.earthquake.maxScale]})が投稿に必要な値(${scaleMessages[config.earthquake.requireMaxScale]})に満たないため、スキップします`); break; } @@ -143,7 +143,7 @@ const processMessage = async (message: any) => { } const grouped: Record }> = {}; - + for (const point of message.points) { const { addr, scale, pref } = point; const label = scaleMessages[String(scale)] ?? "不明"; @@ -163,7 +163,7 @@ const processMessage = async (message: any) => { .sort((a, b) => b[1].scale - a[1].scale) .map(([label, { prefs }]) => { const prefLines = Object.entries(prefs) - .map(([pref, addrs]) => `${pref}: ${addrs.join("・")}`) + .map(([pref, addrs]) => `**${pref}:** ${addrs.join("・")}`) .join(EOL); return `【${label}】${EOL}${prefLines}`; @@ -281,7 +281,7 @@ const processMessage = async (message: any) => { ? `から${scaleMessages[String(Math.floor(area.scaleTo))]}` : ""), kind: kindMessages[area.kindCode] ?? "😕主要動の***到達予想は***ありません。", - arrivalTime: area.arrivalTime !== undefined + arrivalTime: typeof area.arrivalTime === "string" && area.arrivalTime !== "" ? format(new Date(area.arrivalTime), "yyyy年M月d日 H:mm:ss") : "不明", }) + EOL.repeat(2); @@ -306,7 +306,7 @@ const processMessage = async (message: any) => { magnitude: message.earthquake.hypocenter.magnitude === undefined || message.earthquake.hypocenter.magnitude === -1 ? "不明" - : `M${message.earthquake.hypocenter.magnitude}`, + : `M${message.earthquake.hypocenter.magnitude.toFixed(1)}`, areas: areasMsg !== "" ? EOL.repeat(2) + areasMsg.trim() : "", diff --git a/src/lib/client.ts b/src/lib/client.ts index 0024124..a038d99 100644 --- a/src/lib/client.ts +++ b/src/lib/client.ts @@ -15,7 +15,6 @@ export default client; export const createUeuse = async (data: ApiMap["ueuse/create"]["body"], title: string) => { const mem = Memory.memory; - const maxLength = mem.max_length; const excessedMessage = "👉返信に続きがあります。"; let lines = data.text.split(EOL); @@ -26,7 +25,13 @@ export const createUeuse = async (data: ApiMap["ueuse/create"]["body"], title: s count++; let currentText = ""; - const limit = maxLength - (excessedMessage.length + EOL.length * 2); + const currentMaxLength = (data.replyid !== undefined || firstUniqid !== "") + ? mem.max_length + : config.ueuse.maxLengthWithPublic === 0 + ? mem.max_length + : config.ueuse.maxLengthWithPublic; + + const limit = currentMaxLength - (excessedMessage.length + EOL.length * 2); while (lines.length > 0) { const nextLine = lines[0]; @@ -50,6 +55,8 @@ export const createUeuse = async (data: ApiMap["ueuse/create"]["body"], title: s } } + currentText = currentText.trimEnd(); + if (lines.length > 0) { currentText += EOL.repeat(2) + excessedMessage; } @@ -87,5 +94,9 @@ export const createUeuse = async (data: ApiMap["ueuse/create"]["body"], title: s firstUniqid = postedUniqid; console.log(`${title}を投稿(${count}):`, postedUniqid); + + while (lines.length > 0 && lines[0]?.trim() === "") { + lines.shift(); + } } } \ No newline at end of file diff --git a/src/lib/config.ts b/src/lib/config.ts index 76c9c64..960c708 100644 --- a/src/lib/config.ts +++ b/src/lib/config.ts @@ -37,6 +37,7 @@ const schema = z.object({ ueuse: z.object({ maxRetries: z.number().int().positive(), retryInterval: z.number().positive(), + maxLengthWithPublic: z.number().int().nonnegative(), }), debug: z.boolean().optional(), });