Del: tsxの開発環境 / Chg: typescriptを5.9.3にダウングレード / Feat: 緊急地震速報の最大予測震度の上限に99(〜程度以上)を実装 / Chg: 緊急地震速報の最大予測震度で上限と下限が一致する場合に"から〜"を投稿内容に含めない / Feat: worker_threadsによる並列処理 / Del: 各地震情報の情報源の信頼できるかどうかの内容を削除 / Chg: 津波予報情報の各時刻情報を実際に取得できる値まで削減(例: 2:03:00 > 2:03) / Fix: フォロー・フォロー解除に失敗した際にreturnできていない問題 / Feat: デバッグ用とで過去の地震情報を読み込み10秒おきに投稿する機能
This commit is contained in:
@@ -21,6 +21,7 @@ export default async function followCommand(ueuse: ueuseModule) {
|
||||
|
||||
if (!notice.success) {
|
||||
console.warn("フォロー通知に失敗:", notice.error_code);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("フォロー通知:", notice.uniqid);
|
||||
|
||||
@@ -6,9 +6,13 @@ import weatherCommand from "@/feature/command/weather";
|
||||
import helpCommand from "@/feature/command/help";
|
||||
import followCommand from "@/feature/command/follow";
|
||||
import unfollowCommand from "@/feature/command/unfollow";
|
||||
import miqCommand from "./miq";
|
||||
import miqCommand from "@/feature/command/miq";
|
||||
import initI18n from "@/lib/i18n";
|
||||
|
||||
export default async function commandExecute() {
|
||||
await initI18n();
|
||||
console.log("コマンドの処理を行います");
|
||||
|
||||
try {
|
||||
let ueuses: ueuseModule[] = [];
|
||||
|
||||
{
|
||||
@@ -124,4 +128,11 @@ export default async function commandExecute() {
|
||||
Memory.memory = mem;
|
||||
}
|
||||
}
|
||||
|
||||
process.exit(0);
|
||||
} catch (err: any) {
|
||||
console.error("message" in err
|
||||
? err.message
|
||||
: err);
|
||||
process.exit(1);
|
||||
}
|
||||
@@ -21,6 +21,7 @@ export default async function unfollowCommand(ueuse: ueuseModule) {
|
||||
|
||||
if (!notice.success) {
|
||||
console.warn("フォロー解除通知に失敗:", notice.error_code);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("フォロー解除通知:", notice.uniqid);
|
||||
|
||||
+258
-239
@@ -1,15 +1,29 @@
|
||||
import client from "@/lib/client";
|
||||
import config from "@/lib/config";
|
||||
import initI18n from "@/lib/i18n";
|
||||
import { format } from "date-fns";
|
||||
import i18next from "i18next";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { EOL } from "node:os";
|
||||
import { WebSocket } from "ws";
|
||||
|
||||
const WEBSOCKET_URL = config.debug
|
||||
? "wss://api-realtime-sandbox.p2pquake.net/v2/ws"
|
||||
: "wss://api.p2pquake.net/v2/ws";
|
||||
await initI18n();
|
||||
|
||||
if (config.earthquake?.useHistoryData) {
|
||||
console.log("過去の地震情報を配信します");
|
||||
const history = JSON.parse(readFileSync(`${import.meta.dirname}/../../260420.json`, "utf-8"));
|
||||
history.reverse();
|
||||
|
||||
let i = 0;
|
||||
setInterval(() => {
|
||||
processMessage(history[i]);
|
||||
i++;
|
||||
}, 10 * 1000);
|
||||
} else {
|
||||
const WEBSOCKET_URL = config.debug
|
||||
? "wss://api-realtime-sandbox.p2pquake.net/v2/ws"
|
||||
: "wss://api.p2pquake.net/v2/ws";
|
||||
|
||||
const P2PEarthquakeClient = () => {
|
||||
console.log("P2P地震情報のWebSocketに接続します");
|
||||
const socket = new WebSocket(WEBSOCKET_URL);
|
||||
|
||||
@@ -29,241 +43,246 @@ const P2PEarthquakeClient = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const scaleMessages: Record<string, string> = {
|
||||
"-1": "不明",
|
||||
"10": "震度1",
|
||||
"20": "震度2",
|
||||
"30": "震度3",
|
||||
"40": "震度4",
|
||||
"45": "震度5弱",
|
||||
"46": "**推定**震度5弱以上***(正確には不明)***",
|
||||
"50": "震度5強",
|
||||
"55": "震度6弱",
|
||||
"60": "震度6強",
|
||||
"70": "震度7",
|
||||
}
|
||||
|
||||
switch (message.code) {
|
||||
case 551:
|
||||
{
|
||||
console.log("地震発生情報を受信しました");
|
||||
|
||||
const domesticTsunamiMessages: Record<string, string> = {
|
||||
"None": "😌この地震による**国内**の津波の心配はありません。",
|
||||
"Unknown": "😕この地震による**国内**の***津波情報は***不明です。",
|
||||
"Checking": "🧐この地震による**国内**の津波情報を**調査中です。**",
|
||||
"NonEffective": "😌この地震による**国内**の**海面変動が予想されますが**、被害の心配はありません。",
|
||||
"Watch": "⚠️この地震により**国内**で津波注意報が発令しています。",
|
||||
"Warning": "🚨この地震による**国内**の津波予報があります。",
|
||||
}
|
||||
|
||||
const foreignTsunamiMessages: Record<string, string> = {
|
||||
"None": "😌この地震による**国外**の津波の心配はありません。",
|
||||
"Unknown": "😕この地震による**国外**の***津波情報は***不明です。",
|
||||
"Checking": "🧐この地震による**国外**の津波情報を**調査中です。**",
|
||||
"NonEffectiveNearby": "😌この地震によって**国外**にて震源の近傍で**小さな津波の可能性はありますが**、被害の心配はありません。",
|
||||
"WarningNearby": "⚠️この地震によって**国外**にて震源の近傍で**津波の可能性**があります。",
|
||||
"WarningPacific": "⚠️この地震によって**太平洋**にて**津波の可能性**があります。",
|
||||
"WarningPacificWide": "🚨この地震によって**太平洋の広域**にて**津波の可能性**があります。",
|
||||
"WarningIndian": "⚠️この地震によって**インド洋**にて**津波の可能性**があります。",
|
||||
"WarningIndianWide": "🚨この地震によって**インド洋の広域**にて**津波の可能性**があります。",
|
||||
"Potential": "🚨この地震によって**一般的に**この規模では津波の可能性があると考えられています。",
|
||||
}
|
||||
|
||||
let points: Record<string, any[]> = {};
|
||||
for (const point of message.points) {
|
||||
const scaleMsg = scaleMessages[String(point.scale)];
|
||||
if (!scaleMsg)
|
||||
break;
|
||||
|
||||
points[scaleMsg]?.push(point);
|
||||
}
|
||||
|
||||
const grouped: Record<string, { scale: number; addrs: string[] }> = {};
|
||||
for (const point of message.points) {
|
||||
const { addr, scale } = point;
|
||||
const label = scaleMessages[String(scale)] ?? "不明";
|
||||
|
||||
if (!grouped[label]) {
|
||||
grouped[label] = { scale, addrs: [] };
|
||||
}
|
||||
|
||||
grouped[label].addrs.push(addr);
|
||||
}
|
||||
|
||||
const pointsMsg = Object.entries(grouped)
|
||||
.sort((a, b) => b[1].scale - a[1].scale)
|
||||
.map(([label, { addrs }]) =>
|
||||
`【${label}】${EOL}${addrs.join("・")}`)
|
||||
.join(EOL.repeat(2)).trim();
|
||||
|
||||
const response = await client.request("ueuse/create", {
|
||||
text: i18next.t("earthquakeNotice", {
|
||||
occuredTime: format(new Date(message.earthquake.time), "yyyy年M月d日 H:mm"),
|
||||
maxScale: scaleMessages[String(message.earthquake.maxScale)],
|
||||
epicenter: message.earthquake.hypocenter.name === ""
|
||||
? "不明"
|
||||
: message.earthquake.hypocenter.name,
|
||||
magnitude: message.earthquake.hypocenter.magnitude === -1
|
||||
? "不明"
|
||||
: `M${message.earthquake.hypocenter.magnitude.toFixed(1)}`,
|
||||
depth: message.earthquake.hypocenter.depth === 0
|
||||
? "ごく浅い"
|
||||
: (message.earthquake.hypocenter.depth === -1
|
||||
? "不明"
|
||||
: `${message.earthquake.hypocenter.depth}km`),
|
||||
domesticTsunami: domesticTsunamiMessages[(message.earthquake.domesticTsunami ?? "Unknown")],
|
||||
foreignTsunami: foreignTsunamiMessages[(message.earthquake.foreignTsunami ?? "Unknown")],
|
||||
points: pointsMsg === ""
|
||||
? ""
|
||||
: EOL.repeat(2) + pointsMsg,
|
||||
source: message.issue.source ?? "不明",
|
||||
comment: message.comments.freeFormComment === ""
|
||||
? ""
|
||||
: EOL + message.comments.freeFormComment + EOL,
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.success) {
|
||||
console.warn("ユーズの作成に失敗しました:", response.error_code);
|
||||
break;
|
||||
}
|
||||
|
||||
console.log("地震発生情報を投稿:", response.uniqid);
|
||||
}
|
||||
break;
|
||||
case 552:
|
||||
{
|
||||
console.log("津波予報情報を受信しました");
|
||||
|
||||
if (message.cancelled) {
|
||||
const response = await client.request("ueuse/create", {
|
||||
text: i18next.t("tsunamiCancelNotice", {
|
||||
announceTime: format(new Date(message.issue.time), "yyyy年M月d日 H:mm:ss.SSS"),
|
||||
source: (message.issue.source ?? "不明") + (message.issue.source === "気象庁"
|
||||
? "(✅信頼できます)"
|
||||
: "(😕信頼できない可能性があります)"),
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.success) {
|
||||
console.warn("ユーズの作成に失敗しました:", response.error_code);
|
||||
break;
|
||||
}
|
||||
|
||||
console.log("津波予報解除情報を投稿:", response.uniqid);
|
||||
break;
|
||||
}
|
||||
|
||||
const gradeMessages: Record<string, string> = {
|
||||
"Unknown": "不明",
|
||||
"Watch": "津波注意報",
|
||||
"Warning": "津波警報",
|
||||
"MajorWarning": "大津波警報",
|
||||
}
|
||||
|
||||
let areasMsg = "";
|
||||
for (const area of message.areas) {
|
||||
areasMsg += i18next.t("tsunamiAreaMsg", {
|
||||
name: area.name,
|
||||
immediate: area.immediate
|
||||
? EOL + "🚨***直ちに津波が来襲すると予想されています。***"
|
||||
: "",
|
||||
grade: gradeMessages[area.grade],
|
||||
arrivalTime: area.firstHeight.arrivalTime,
|
||||
condition: area.firstHeight.condition
|
||||
? `${area.firstHeight.condition}されています`
|
||||
: "不明",
|
||||
maxHeight: area.maxHeight.value === 0.2
|
||||
? "0.2m未満"
|
||||
: (area.maxHeight.value
|
||||
? `${area.maxHeight.value}m`
|
||||
: area.maxHeight.description),
|
||||
}) + EOL.repeat(2);
|
||||
}
|
||||
|
||||
const response = await client.request("ueuse/create", {
|
||||
text: i18next.t("tsunamiForecastNotice", {
|
||||
announceTime: format(new Date(message.issue.time), "yyyy年M月d日 H:mm:ss.SSS"),
|
||||
areasMsg: areasMsg.trim(),
|
||||
source: message.issue.source ?? "不明",
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.success) {
|
||||
console.warn("ユーズの作成に失敗しました:", response.error_code);
|
||||
break;
|
||||
}
|
||||
|
||||
console.log("津波予報情報を投稿:", response.uniqid);
|
||||
}
|
||||
break;
|
||||
case 556:
|
||||
{
|
||||
console.log("緊急地震速報(警報)を受信しました");
|
||||
|
||||
const kindMessages: Record<string, string> = {
|
||||
"10": "⏳主要動は、**未到達と予測**されています。",
|
||||
"11": "🫨主要動が、**既に到達していると予測**されています。",
|
||||
"19": "🧐PLUM法によると、主要動の***到達予想は***ありません。",
|
||||
}
|
||||
|
||||
let areasMsg = "";
|
||||
for (const area of message.areas) {
|
||||
areasMsg += i18next.t("eewAreaMsg", {
|
||||
name: area.name,
|
||||
scaleFrom: scaleMessages[String(Math.floor(area.scaleFrom))],
|
||||
scaleTo: scaleMessages[String(Math.floor(area.scaleTo))],
|
||||
kind: kindMessages[area.kindCode] ?? "😕主要動の***到達予想は***ありません。",
|
||||
arrivalTime: area.arrivalTime !== undefined
|
||||
? format(new Date(area.arrivalTime), "yyyy年M月d日 H:mm:ss.SSS")
|
||||
: "不明",
|
||||
}) + EOL.repeat(2);
|
||||
}
|
||||
|
||||
const response = await client.request("ueuse/create", {
|
||||
text: i18next.t("eewNotice", {
|
||||
isTest: message.test
|
||||
? "⚒️これは**テストです。**"
|
||||
: "🚨これは**テストではありません。**",
|
||||
announceTime: format(new Date(message.issue.time), "yyyy年M月d日 H:mm:ss.SSS"),
|
||||
occuredTime: format(new Date(message.earthquake.originTime), "yyyy年M月d日 H:mm:ss.SSS"),
|
||||
arrivalTime: format(new Date(message.earthquake.arrivalTime), "yyyy年M月d日 H:mm:ss.SSS"),
|
||||
isAssume: message.earthquake.condition === "仮定震源要素"
|
||||
? `${EOL}❓これは、仮定震源要素です。そのため、震源に関する情報が保証できません。`
|
||||
: "",
|
||||
epicenter: message.earthquake.hypocenter.name ?? "不明",
|
||||
depth: message.earthquake.hypocenter.depth === undefined ||
|
||||
message.earthquake.hypocenter.depth === -1
|
||||
? "不明"
|
||||
: `${Math.floor(message.earthquake.hypocenter.depth)}km`,
|
||||
magnitude: message.earthquake.hypocenter.magnitude === undefined ||
|
||||
message.earthquake.hypocenter.magnitude === -1
|
||||
? "不明"
|
||||
: `M${message.earthquake.hypocenter.magnitude}`,
|
||||
areas: areasMsg !== ""
|
||||
? EOL.repeat(2) + areasMsg.trim()
|
||||
: "",
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.success) {
|
||||
console.warn("ユーズの作成に失敗しました:", response.error_code);
|
||||
break;
|
||||
}
|
||||
|
||||
console.log("緊急地震速報(警報)情報を投稿:", response.uniqid);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
console.log("未対応の情報:", message);
|
||||
break;
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn("メッセージの処理に失敗しました:", err);
|
||||
}
|
||||
processMessage(message);
|
||||
});
|
||||
}
|
||||
|
||||
export default P2PEarthquakeClient;
|
||||
const processMessage = async (message: any) => {
|
||||
try {
|
||||
const scaleMessages: Record<string, string> = {
|
||||
"-1": "不明",
|
||||
"10": "震度1",
|
||||
"20": "震度2",
|
||||
"30": "震度3",
|
||||
"40": "震度4",
|
||||
"45": "震度5弱",
|
||||
"46": "**推定**震度5弱以上***(正確には不明)***",
|
||||
"50": "震度5強",
|
||||
"55": "震度6弱",
|
||||
"60": "震度6強",
|
||||
"70": "震度7",
|
||||
"99": "程度以上",
|
||||
}
|
||||
|
||||
switch (message.code) {
|
||||
case 551:
|
||||
{
|
||||
console.log("地震発生情報を受信しました");
|
||||
|
||||
const domesticTsunamiMessages: Record<string, string> = {
|
||||
"None": "😌この地震による**国内**の津波の心配はありません。",
|
||||
"Unknown": "😕この地震による**国内**の***津波情報は***不明です。",
|
||||
"Checking": "🧐この地震による**国内**の津波情報を**調査中です。**",
|
||||
"NonEffective": "😌この地震による**国内**の**海面変動が予想されますが**、被害の心配はありません。",
|
||||
"Watch": "⚠️この地震により**国内**で津波注意報が発令しています。",
|
||||
"Warning": "🚨この地震による**国内**の津波予報があります。",
|
||||
}
|
||||
|
||||
const foreignTsunamiMessages: Record<string, string> = {
|
||||
"None": "😌この地震による**国外**の津波の心配はありません。",
|
||||
"Unknown": "😕この地震による**国外**の***津波情報は***不明です。",
|
||||
"Checking": "🧐この地震による**国外**の津波情報を**調査中です。**",
|
||||
"NonEffectiveNearby": "😌この地震によって**国外**にて震源の近傍で**小さな津波の可能性はありますが**、被害の心配はありません。",
|
||||
"WarningNearby": "⚠️この地震によって**国外**にて震源の近傍で**津波の可能性**があります。",
|
||||
"WarningPacific": "⚠️この地震によって**太平洋**にて**津波の可能性**があります。",
|
||||
"WarningPacificWide": "🚨この地震によって**太平洋の広域**にて**津波の可能性**があります。",
|
||||
"WarningIndian": "⚠️この地震によって**インド洋**にて**津波の可能性**があります。",
|
||||
"WarningIndianWide": "🚨この地震によって**インド洋の広域**にて**津波の可能性**があります。",
|
||||
"Potential": "🚨この地震によって**一般的に**この規模では津波の可能性があると考えられています。",
|
||||
}
|
||||
|
||||
let points: Record<string, any[]> = {};
|
||||
for (const point of message.points) {
|
||||
const scaleMsg = scaleMessages[String(point.scale)];
|
||||
if (!scaleMsg)
|
||||
break;
|
||||
|
||||
points[scaleMsg]?.push(point);
|
||||
}
|
||||
|
||||
const grouped: Record<string, { scale: number; addrs: string[] }> = {};
|
||||
for (const point of message.points) {
|
||||
const { addr, scale } = point;
|
||||
const label = scaleMessages[String(scale)] ?? "不明";
|
||||
|
||||
if (!grouped[label]) {
|
||||
grouped[label] = { scale, addrs: [] };
|
||||
}
|
||||
|
||||
grouped[label].addrs.push(addr);
|
||||
}
|
||||
|
||||
const pointsMsg = Object.entries(grouped)
|
||||
.sort((a, b) => b[1].scale - a[1].scale)
|
||||
.map(([label, { addrs }]) =>
|
||||
`【${label}】${EOL}${addrs.join("・")}`)
|
||||
.join(EOL.repeat(2)).trim();
|
||||
|
||||
const response = await client.request("ueuse/create", {
|
||||
text: i18next.t("earthquakeNotice", {
|
||||
occuredTime: format(new Date(message.earthquake.time), "yyyy年M月d日 H:mm"),
|
||||
maxScale: scaleMessages[String(message.earthquake.maxScale)],
|
||||
epicenter: message.earthquake.hypocenter.name === ""
|
||||
? "不明"
|
||||
: message.earthquake.hypocenter.name,
|
||||
magnitude: message.earthquake.hypocenter.magnitude === -1
|
||||
? "不明"
|
||||
: `M${message.earthquake.hypocenter.magnitude.toFixed(1)}`,
|
||||
depth: message.earthquake.hypocenter.depth === 0
|
||||
? "ごく浅い"
|
||||
: (message.earthquake.hypocenter.depth === -1
|
||||
? "不明"
|
||||
: `${message.earthquake.hypocenter.depth}km`),
|
||||
domesticTsunami: domesticTsunamiMessages[(message.earthquake.domesticTsunami ?? "Unknown")],
|
||||
foreignTsunami: foreignTsunamiMessages[(message.earthquake.foreignTsunami ?? "Unknown")],
|
||||
points: pointsMsg === ""
|
||||
? ""
|
||||
: EOL.repeat(2) + pointsMsg,
|
||||
source: message.issue.source ?? "不明",
|
||||
comment: message.comments.freeFormComment === ""
|
||||
? ""
|
||||
: EOL + message.comments.freeFormComment + EOL,
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.success) {
|
||||
console.warn("ユーズの作成に失敗しました:", response.error_code);
|
||||
break;
|
||||
}
|
||||
|
||||
console.log("地震発生情報を投稿:", response.uniqid);
|
||||
}
|
||||
break;
|
||||
case 552:
|
||||
{
|
||||
console.log("津波予報情報を受信しました");
|
||||
|
||||
if (message.cancelled) {
|
||||
const response = await client.request("ueuse/create", {
|
||||
text: i18next.t("tsunamiCancelNotice", {
|
||||
announceTime: format(new Date(message.issue.time), "yyyy年M月d日 H:mm:ss"),
|
||||
source: message.issue.source ?? "不明",
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.success) {
|
||||
console.warn("ユーズの作成に失敗しました:", response.error_code);
|
||||
break;
|
||||
}
|
||||
|
||||
console.log("津波予報解除情報を投稿:", response.uniqid);
|
||||
break;
|
||||
}
|
||||
|
||||
const gradeMessages: Record<string, string> = {
|
||||
"Unknown": "不明",
|
||||
"Watch": "津波注意報",
|
||||
"Warning": "津波警報",
|
||||
"MajorWarning": "大津波警報",
|
||||
}
|
||||
|
||||
let areasMsg = "";
|
||||
for (const area of message.areas) {
|
||||
areasMsg += i18next.t("tsunamiAreaMsg", {
|
||||
name: area.name,
|
||||
immediate: area.immediate
|
||||
? EOL + "🚨***直ちに津波が来襲すると予想されています。***"
|
||||
: "",
|
||||
grade: gradeMessages[area.grade],
|
||||
arrivalTime: format(new Date(area.firstHeight.arrivalTime), "yyyy年M月d日 H:mm"),
|
||||
condition: area.firstHeight.condition
|
||||
? `${area.firstHeight.condition}されています`
|
||||
: "不明",
|
||||
maxHeight: area.maxHeight.value === 0.2
|
||||
? "0.2m未満"
|
||||
: (area.maxHeight.value
|
||||
? `${area.maxHeight.value}m`
|
||||
: area.maxHeight.description),
|
||||
}) + EOL.repeat(2);
|
||||
}
|
||||
|
||||
const response = await client.request("ueuse/create", {
|
||||
text: i18next.t("tsunamiForecastNotice", {
|
||||
announceTime: format(new Date(message.issue.time), "yyyy年M月d日 H:mm:ss"),
|
||||
areasMsg: areasMsg.trim(),
|
||||
source: message.issue.source ?? "不明",
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.success) {
|
||||
console.warn("ユーズの作成に失敗しました:", response.error_code);
|
||||
break;
|
||||
}
|
||||
|
||||
console.log("津波予報情報を投稿:", response.uniqid);
|
||||
}
|
||||
break;
|
||||
case 556:
|
||||
{
|
||||
console.log("緊急地震速報(警報)を受信しました");
|
||||
|
||||
const kindMessages: Record<string, string> = {
|
||||
"10": "⏳主要動は、**未到達と予測**されています。",
|
||||
"11": "🫨主要動が、**既に到達していると予測**されています。",
|
||||
"19": "🧐PLUM法によると、主要動の***到達予想は***ありません。",
|
||||
}
|
||||
|
||||
let areasMsg = "";
|
||||
for (const area of message.areas) {
|
||||
areasMsg += i18next.t("eewAreaMsg", {
|
||||
name: area.name,
|
||||
maxScale: scaleMessages[String(Math.floor(area.scaleFrom))] +
|
||||
(area.scaleTo === 99
|
||||
? "程度以上"
|
||||
: area.scaleFrom !== area.scaleTo
|
||||
? `から${scaleMessages[String(Math.floor(area.scaleTo))]}`
|
||||
: ""),
|
||||
kind: kindMessages[area.kindCode] ?? "😕主要動の***到達予想は***ありません。",
|
||||
arrivalTime: area.arrivalTime !== undefined
|
||||
? format(new Date(area.arrivalTime), "yyyy年M月d日 H:mm:ss")
|
||||
: "不明",
|
||||
}) + EOL.repeat(2);
|
||||
}
|
||||
|
||||
const response = await client.request("ueuse/create", {
|
||||
text: i18next.t("eewNotice", {
|
||||
isTest: message.test
|
||||
? "⚒️これは**テストです。**"
|
||||
: "🚨これは**テストではありません。**",
|
||||
announceTime: format(new Date(message.issue.time), "yyyy年M月d日 H:mm:ss"),
|
||||
occuredTime: format(new Date(message.earthquake.originTime), "yyyy年M月d日 H:mm:ss"),
|
||||
arrivalTime: format(new Date(message.earthquake.arrivalTime), "yyyy年M月d日 H:mm:ss"),
|
||||
isAssume: message.earthquake.condition === "仮定震源要素"
|
||||
? `${EOL}❓これは、仮定震源要素です。そのため、震源に関する情報が保証できません。`
|
||||
: "",
|
||||
epicenter: message.earthquake.hypocenter.name ?? "不明",
|
||||
depth: message.earthquake.hypocenter.depth === undefined ||
|
||||
message.earthquake.hypocenter.depth === -1
|
||||
? "不明"
|
||||
: `${Math.floor(message.earthquake.hypocenter.depth)}km`,
|
||||
magnitude: message.earthquake.hypocenter.magnitude === undefined ||
|
||||
message.earthquake.hypocenter.magnitude === -1
|
||||
? "不明"
|
||||
: `M${message.earthquake.hypocenter.magnitude}`,
|
||||
areas: areasMsg !== ""
|
||||
? EOL.repeat(2) + areasMsg.trim()
|
||||
: "",
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.success) {
|
||||
console.warn("ユーズの作成に失敗しました:", response.error_code);
|
||||
break;
|
||||
}
|
||||
|
||||
console.log("緊急地震速報(警報)情報を投稿:", response.uniqid);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
console.log("未対応の情報:", message);
|
||||
break;
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn("メッセージの処理に失敗しました:", err);
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,26 @@
|
||||
import client from "@/lib/client";
|
||||
import initI18n from "@/lib/i18n";
|
||||
import { format } from "date-fns";
|
||||
import i18next from "i18next";
|
||||
|
||||
export default async function timeNotice() {
|
||||
await initI18n();
|
||||
console.log("時報の投稿を行います");
|
||||
|
||||
try {
|
||||
const response = await client.request("ueuse/create", {
|
||||
text: i18next.t("timeNotice", { time: format(new Date(), "HH:mm") }),
|
||||
});
|
||||
|
||||
if (!response.success) {
|
||||
console.warn("時報投稿に失敗しました:", response.error_code);
|
||||
return;
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log("時報投稿:", response.uniqid);
|
||||
process.exit(0);
|
||||
} catch (err: any) {
|
||||
console.error("message" in err
|
||||
? err.message
|
||||
: err);
|
||||
process.exit(1);
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
import client from "@/lib/client";
|
||||
import config from "@/lib/config";
|
||||
import initI18n from "@/lib/i18n";
|
||||
import i18next from "i18next";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { EOL } from "node:os";
|
||||
import { isMainThread, workerData } from "node:worker_threads";
|
||||
|
||||
const cityList = [
|
||||
"016010",
|
||||
@@ -54,19 +56,30 @@ const cityList = [
|
||||
"471010",
|
||||
];
|
||||
|
||||
export async function weatherNotice() {
|
||||
const provisionalUeuse = await client.request("ueuse/create", {
|
||||
text: i18next.t("weatherProvisional"),
|
||||
});
|
||||
if (!isMainThread && workerData === "scheduledWeatherNotice") {
|
||||
await initI18n();
|
||||
console.log("天気予報の投稿を行います");
|
||||
|
||||
if (!provisionalUeuse.success) {
|
||||
console.error("天気仮投稿に失敗しました:", provisionalUeuse.error_code);
|
||||
return;
|
||||
try {
|
||||
const provisionalUeuse = await client.request("ueuse/create", {
|
||||
text: i18next.t("weatherProvisional"),
|
||||
});
|
||||
|
||||
if (!provisionalUeuse.success) {
|
||||
console.error("天気仮投稿に失敗しました:", provisionalUeuse.error_code);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log("天気仮投稿:", provisionalUeuse.uniqid);
|
||||
|
||||
weatherReply(provisionalUeuse.uniqid);
|
||||
process.exit(0);
|
||||
} catch (err: any) {
|
||||
console.error("message" in err
|
||||
? err.message
|
||||
: err);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log("天気仮投稿:", provisionalUeuse.uniqid);
|
||||
|
||||
weatherReply(provisionalUeuse.uniqid);
|
||||
}
|
||||
|
||||
export async function weatherReply(uniqid: string) {
|
||||
|
||||
+5
-31
@@ -1,13 +1,9 @@
|
||||
import { schedule } from "node-cron";
|
||||
import { readFileSync } from "node:fs";
|
||||
import config from "@/lib/config";
|
||||
import initI18n from "@/lib/i18n";
|
||||
import { initUserID } from "@/lib/memory";
|
||||
import { styleText } from "node:util";
|
||||
import timeNotice from "@/feature/timeNotice";
|
||||
import { weatherNotice } from "@/feature/weatherNotice";
|
||||
import commandExecute from "@/feature/command";
|
||||
import P2PEarthquakeClient from "@/feature/earthquakeNotice";
|
||||
import { Worker } from "node:worker_threads";
|
||||
|
||||
try {
|
||||
console.log(readFileSync(`${import.meta.dirname}/../asciiart.txt`, "utf-8"));
|
||||
@@ -22,10 +18,9 @@ try {
|
||||
}
|
||||
console.log();
|
||||
|
||||
await initI18n();
|
||||
await initUserID();
|
||||
|
||||
P2PEarthquakeClient();
|
||||
new Worker(`${import.meta.dirname}/feature/earthquakeNotice.js`);
|
||||
|
||||
console.log("Botが起動しました");
|
||||
} catch (err: any) {
|
||||
@@ -36,34 +31,13 @@ try {
|
||||
}
|
||||
|
||||
schedule("0 * * * *", async () => {
|
||||
console.log("時報の投稿を行います");
|
||||
try {
|
||||
await timeNotice();
|
||||
} catch (err: any) {
|
||||
console.error("message" in err
|
||||
? err.message
|
||||
: err);
|
||||
}
|
||||
new Worker(`${import.meta.dirname}/feature/timeNotice.js`);
|
||||
});
|
||||
|
||||
schedule("0 7 * * *", async () => {
|
||||
console.log("天気予報の投稿を行います");
|
||||
try {
|
||||
await weatherNotice();
|
||||
} catch (err: any) {
|
||||
console.error("message" in err
|
||||
? err.message
|
||||
: err);
|
||||
}
|
||||
new Worker(`${import.meta.dirname}/feature/weatherNotice.js`);
|
||||
});
|
||||
|
||||
schedule(`*/${config.command.interval} * * * *`, async () => {
|
||||
console.log("コマンドの処理を行います");
|
||||
try {
|
||||
await commandExecute();
|
||||
} catch (err: any) {
|
||||
console.error("message" in err
|
||||
? err.message
|
||||
: err);
|
||||
}
|
||||
new Worker(`${import.meta.dirname}/feature/command/index.js`);
|
||||
});
|
||||
@@ -10,6 +10,9 @@ const schema = z.object({
|
||||
weather: z.object({
|
||||
splits: z.number().int().positive(),
|
||||
}),
|
||||
earthquake: z.object({
|
||||
useHistoryData: z.boolean(),
|
||||
}).optional(),
|
||||
uwuzu: z.object({
|
||||
token: z.string().length(64),
|
||||
origin: z.string().refine(data => {
|
||||
|
||||
Reference in New Issue
Block a user