From 644ba912b15ebfa9d980d1dd3af60a05aa2b50c7 Mon Sep 17 00:00:00 2001 From: Last2014 Date: Wed, 6 Aug 2025 21:27:29 +0900 Subject: [PATCH] v8.0 --- checks/api.ts | 3 +- examples/config.ts | 14 +++- main.ts | 6 ++ package.json | 8 +- panel/main.ts | 52 +++++++++++++ panel/public/index.html | 36 +++++++++ panel/public/script.js | 88 +++++++++++++++++++++ panel/route/api.ts | 35 +++++++++ panel/route/command.ts | 25 ++++++ panel/route/ueuse.ts | 40 ++++++++++ panel/route/weather.ts | 25 ++++++ scripts/commands/birthday.ts | 2 +- scripts/commands/follow.ts | 2 +- scripts/commands/help.ts | 2 +- scripts/commands/info.ts | 7 +- scripts/commands/legal/privacy.ts | 2 +- scripts/commands/legal/terms.ts | 2 +- scripts/commands/main.ts | 122 +++++++++++++++--------------- scripts/commands/report.ts | 17 ++++- scripts/commands/unfollow.ts | 2 +- scripts/commands/weather.ts | 2 +- scripts/earthquakeNotice.ts | 4 +- scripts/successExit.ts | 4 +- scripts/weatherNotice.ts | 2 +- src/mailer.ts | 74 ++++++++++-------- tsconfig.json | 2 +- types/config.d.ts | 38 ++++++++-- types/types.d.ts | 6 ++ 28 files changed, 498 insertions(+), 124 deletions(-) create mode 100644 panel/main.ts create mode 100644 panel/public/index.html create mode 100644 panel/public/script.js create mode 100644 panel/route/api.ts create mode 100644 panel/route/command.ts create mode 100644 panel/route/ueuse.ts create mode 100644 panel/route/weather.ts diff --git a/checks/api.ts b/checks/api.ts index 8e5e2b9..0990a43 100644 --- a/checks/api.ts +++ b/checks/api.ts @@ -7,7 +7,8 @@ export default async function APICheck() { method: "POST", body: JSON.stringify({ token: config.uwuzu.apiToken, - }) + }), + cache: "no-store", }); const res = await req.json(); diff --git a/examples/config.ts b/examples/config.ts index e052582..3d08cc9 100644 --- a/examples/config.ts +++ b/examples/config.ts @@ -24,10 +24,9 @@ const config: configTypes = { // 緊急時設定 emergency: { - function: true, // 緊急時のコンソール表示 - report: false, // reportコマンド + isEnabled: true, // 緊急時のコンソール表示 mail: { - function: true, // 緊急時のメール送信 + isEnabled: true, // 緊急時のメール送信 host: "smtp.example.com", // SMTPサーバー port: 465, // SMTPポート user: "mailUser@example.com", // BOTメール送信元 @@ -47,6 +46,15 @@ const config: configTypes = { admin: { name: "あどみん", // BOT管理者名 showMail: false, // メールアドレスを公開するか(false:非公開/文字列:メールアドレス) + panel: { // 管理パネル + isEnabled: true, // 有効/無効 + port: 74919, // 配信ポート + }, + }, + // /report設定 + report: { + isEnabled: true, // 有効/無効 + message: "", // 報告者へのメッセージ }, // uwuzuサーバー設定 uwuzu: { diff --git a/main.ts b/main.ts index b6bb2eb..7f99c64 100644 --- a/main.ts +++ b/main.ts @@ -43,5 +43,11 @@ cron.schedule("0 7 * * *", () => { }, 100); }); +// 管理パネル +import AdminPanel from "./panel/main.js"; +(async () => { + await AdminPanel(); +})(); + // 起動表示 console.log("BOTサーバーが起動しました"); diff --git a/package.json b/package.json index 9f3ca17..6627bde 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "notice-uwuzu", - "version": "v7.5@uwuzu1.5.4", - "tag": "v7.5", + "version": "v8.0@uwuzu1.6.1", + "tag": "v8.0", "description": "Notice Bot for uwuzu", "main": "dist/main.js", "scripts": { @@ -38,16 +38,18 @@ "dependencies": { "@types/date-fns": "^2.5.3", "@types/dotenv": "^6.1.1", + "@types/express": "^5.0.3", "@types/node": "^24.0.7", "@types/node-cron": "^3.0.11", "@types/nodemailer": "^6.4.17", "@types/ws": "^8.18.1", "child_process": "^1.0.2", "date-fns": "^4.1.0", + "express": "^5.1.0", "fs": "^0.0.1-security", "node-cron": "^4.1.1", "nodemailer": "^7.0.4", - "typescript": "^5.8.3", + "typescript": "^5.9.2", "ws": "^8.18.3" }, "devDependencies": { diff --git a/panel/main.ts b/panel/main.ts new file mode 100644 index 0000000..fa0c7d6 --- /dev/null +++ b/panel/main.ts @@ -0,0 +1,52 @@ +import express from "express"; +import * as os from "os"; +import config from "../config.js"; +import { NetworkInterfaceDetails } from "types/types"; + +// バックエンドルーティング +import CommandExecute from "./route/command.js"; +import ueusePost from "./route/ueuse.js"; +import WeatherUeuse from "./route/weather.js"; +import API from "./route/api.js"; + +AdminPanel(); + +export default async function AdminPanel() { + // 無効 + if (!config.admin.panel.isEnabled) { + return; + } + + // 管理パネル + const app = express(); + const port = config.admin.panel.port; + + // ルーティング + app.use(ueusePost); + app.use(CommandExecute); + app.use(WeatherUeuse); + app.use(API); + app.use(express.static("panel/public")); + + app.listen(port, () => { + console.log(`http://${LocalIP()}:${port} で管理パネルを起動しました`); + }); +} + +function LocalIP() { + const interfaces = os.networkInterfaces(); + + for (const name in interfaces) { + const iface: any = interfaces[name]; + + for (const i of iface) { + const details: NetworkInterfaceDetails = i; + + if (details.family === 'IPv4' && details.internal !== true) { + return details.address; + } + } + } + + return "localhost"; +} diff --git a/panel/public/index.html b/panel/public/index.html new file mode 100644 index 0000000..e9d9a4e --- /dev/null +++ b/panel/public/index.html @@ -0,0 +1,36 @@ + + + + + + 管理パネル + + + + + + + +

noticeUwuzu管理パネル

+ + + + + + + + + + + + diff --git a/panel/public/script.js b/panel/public/script.js new file mode 100644 index 0000000..a4243ab --- /dev/null +++ b/panel/public/script.js @@ -0,0 +1,88 @@ +document.getElementById("commandExec").addEventListener("click", async () => { + const req = await fetch("/actions/command-execute", { + method: "POST", + }); + + const res = await req.text(); + + if (res === "Accepted") { + alert("コマンド実行を受け付けました"); + } else { + alert(`コマンド実行の要求にエラーが発生しました:${res}`); + } +}); + +document.getElementById("weatherUeuse").addEventListener("click", async () => { + const req = await fetch("/actions/weatherUeuse", { + method: "POST", + }); + + const res = await req.text(); + + if (res === "Accepted") { + alert("天気お知らせを受け付けました"); + } else { + alert(`天気お知らせの要求にエラーが発生しました:${res}`); + } +}); + +document.getElementById("ueuse").addEventListener("click", async () => { + const text = prompt("ユーズ内容").toLowerCase(); + + if (text === "") { + alert("ユーズ内容がありません。"); + return; + } + + const nsfw = confirm("NSFWにしますか?"); + + const req = await fetch("/actions/ueuse", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + text, text, + nsfw: nsfw, + }), + }); + + const res = await req.text(); + + if (res === "Success") { + alert("ユーズ投稿を受け付けました"); + } else { + alert(`ユーズ投稿の要求にエラーが発生しました:${res}`); + } +}); + +document.getElementById("api").addEventListener("click", async () => { + const endpoint = prompt("エンドポイント", "/serverinfo-api").toLowerCase(); + + if (endpoint === "") { + alert("エンドポイントが設定されていません。"); + return; + } + + const body = prompt("body(JSON)", `{"key": "value"}`).toLowerCase(); + + if (body === "") { + alert("bodyが設定されていません。"); + return; + } + + const req = await fetch("/actions/api", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + endpoint: endpoint, + body: JSON.parse(body), + }), + }); + + const res = await req.text(); + + alert(res); +}); diff --git a/panel/route/api.ts b/panel/route/api.ts new file mode 100644 index 0000000..f298f95 --- /dev/null +++ b/panel/route/api.ts @@ -0,0 +1,35 @@ +import express from "express"; +const API = express.Router(); + +import config from "../../config.js"; + +API.use(express.json()); +API.use(express.urlencoded({ extended: true })); + +API.post("/actions/api", async (req, res, next) => { + const endpoint = req.body.endpoint; + let body = req.body.body + body["token"] = config.uwuzu.apiToken; + + try { + const apiReq = await fetch(`https://${config.uwuzu.host}/api${endpoint}`, { + method: "POST", + body: JSON.stringify(body), + }); + + const apiRes = await apiReq.json(); + + res.status(200) + .send(apiRes); + } catch(err) { + res.status(500) + .send(`Error: ${err}`); + } +}); + +API.get("/actions/api", (req, res) => { + res.status(501) + .send("POST Only"); +}); + +export default API; diff --git a/panel/route/command.ts b/panel/route/command.ts new file mode 100644 index 0000000..44b89c8 --- /dev/null +++ b/panel/route/command.ts @@ -0,0 +1,25 @@ +import express from "express"; +const CommandExecute = express.Router(); + +import Commands from "../../scripts/commands/main.js"; + +CommandExecute.post("/actions/command-execute", (req, res) => { + try { + (async () => { + await Commands(); + })(); + + res.status(202) + .send("Accepted"); + } catch(err) { + res.status(500) + .send(`Error: ${err}`); + } +}); + +CommandExecute.get("/actions/command-execute", (req, res) => { + res.status(501) + .send("POST Only"); +}); + +export default CommandExecute; diff --git a/panel/route/ueuse.ts b/panel/route/ueuse.ts new file mode 100644 index 0000000..1bc0424 --- /dev/null +++ b/panel/route/ueuse.ts @@ -0,0 +1,40 @@ +import express from "express"; +const ueusePost = express.Router(); + +import config from "../../config.js"; + +ueusePost.use(express.json()); +ueusePost.use(express.urlencoded({ extended: true })); + +ueusePost.post("/actions/ueuse", async (req, res, next) => { + const text = req.body.text; + const nsfw = req.body.nsfw; + + try { + const ueuseReq = await fetch(`https://${config.uwuzu.host}/api/ueuse/create`, { + method: "POST", + body: JSON.stringify({ + token: config.uwuzu.apiToken, + text: text, + nsfw: nsfw, + }), + }); + + const ueuseRes = await ueuseReq.json(); + + console.log(`ユーズ(管理パネル):${ueuseRes}`); + + res.status(200) + .send("Success"); + } catch(err) { + res.status(500) + .send(`Error: ${err}`); + } +}); + +ueusePost.get("/actions/ueuse", (req, res) => { + res.status(501) + .send("POST Only"); +}); + +export default ueusePost; diff --git a/panel/route/weather.ts b/panel/route/weather.ts new file mode 100644 index 0000000..36cc4a2 --- /dev/null +++ b/panel/route/weather.ts @@ -0,0 +1,25 @@ +import express from "express"; +const WeatherUeuse = express.Router(); + +import { weatherNotice } from "../../scripts/weatherNotice.js"; + +WeatherUeuse.post("/actions/command-execute", (req, res) => { + try { + (async () => { + await weatherNotice(); + })(); + + res.status(202) + .send("Accepted"); + } catch(err) { + res.status(500) + .send(`Error: ${err}`); + } +}); + +WeatherUeuse.get("/actions/command-execute", (req, res) => { + res.status(501) + .send("POST Only"); +}); + +export default WeatherUeuse; diff --git a/scripts/commands/birthday.ts b/scripts/commands/birthday.ts index 5989fa6..c8befb2 100644 --- a/scripts/commands/birthday.ts +++ b/scripts/commands/birthday.ts @@ -1,4 +1,4 @@ -import { ueuse } from "types/types.js"; +import { ueuse } from "types/types"; import { readFileSync, writeFileSync, existsSync } from "fs"; import { parse, isValid } from 'date-fns/fp'; import { Reply } from "./main.js"; diff --git a/scripts/commands/follow.ts b/scripts/commands/follow.ts index 2acc9e2..c9d9626 100644 --- a/scripts/commands/follow.ts +++ b/scripts/commands/follow.ts @@ -1,4 +1,4 @@ -import { ueuse } from "types/types.js"; +import { ueuse } from "types/types"; import config from "../../config.js"; import { Reply } from "./main.js"; diff --git a/scripts/commands/help.ts b/scripts/commands/help.ts index fb249ba..321be1e 100644 --- a/scripts/commands/help.ts +++ b/scripts/commands/help.ts @@ -1,4 +1,4 @@ -import { ueuse } from "types/types.js"; +import { ueuse } from "types/types"; import { readFileSync } from "fs"; import { Reply } from "./main.js"; diff --git a/scripts/commands/info.ts b/scripts/commands/info.ts index 3993fb2..6b9851a 100644 --- a/scripts/commands/info.ts +++ b/scripts/commands/info.ts @@ -1,4 +1,4 @@ -import { ueuse } from "types/types.js"; +import { ueuse } from "types/types"; import { readFileSync } from "fs"; import { Reply } from "./main.js"; import config from "../../config.js"; @@ -23,7 +23,7 @@ export default async function Info(data: ueuse) { let isReport; - if (config.emergency.report) { + if (config.report.isEnabled) { isReport = "有効"; } else { isReport = "無効"; @@ -50,6 +50,9 @@ export default async function Info(data: ueuse) { 運営者へ報告が必要ですか? \`/report\`をご利用ください。 + 利用規約をお探しですか? + \`/legal terms\`をご利用ください。 + プライバシーポリシーをお探しですか? \`/legal privacy\`をご利用ください。 diff --git a/scripts/commands/legal/privacy.ts b/scripts/commands/legal/privacy.ts index a6d7d48..123d337 100644 --- a/scripts/commands/legal/privacy.ts +++ b/scripts/commands/legal/privacy.ts @@ -1,4 +1,4 @@ -import { ueuse } from "types/types.js"; +import { ueuse } from "types/types"; import { Reply } from "../main.js"; import config from "../../../config.js"; diff --git a/scripts/commands/legal/terms.ts b/scripts/commands/legal/terms.ts index 1406d28..71ec9c7 100644 --- a/scripts/commands/legal/terms.ts +++ b/scripts/commands/legal/terms.ts @@ -1,4 +1,4 @@ -import { ueuse } from "types/types.js"; +import { ueuse } from "types/types"; import { Reply } from "../main.js"; import config from "../../../config.js"; diff --git a/scripts/commands/main.ts b/scripts/commands/main.ts index 11ba9d6..1186ef8 100644 --- a/scripts/commands/main.ts +++ b/scripts/commands/main.ts @@ -1,6 +1,6 @@ import * as fs from "fs"; import config from "../../config.js"; -import type { ueuse } from "types/types.js"; +import type { ueuse } from "types/types"; const initialFile: Array = []; @@ -16,16 +16,16 @@ import Terms from "./legal/terms.js" import PrivacyPolicy from "./legal/privacy.js"; // 初期化 -if (!fs.existsSync("logs/alreadyCommands.json")) { +if (!fs.existsSync("data/alreadyCommands.json")) { fs.writeFileSync( - "logs/alreadyCommands.json", + "data/alreadyCommands.json", JSON.stringify(initialFile), "utf-8", ); } // 対応済みユーズ一覧 -const alreadyCommands: Array = JSON.parse(fs.readFileSync("logs/alreadyCommands.json", "utf-8")); +const alreadyCommands: Array = JSON.parse(fs.readFileSync("data/alreadyCommands.json", "utf-8")); function cutAfterChar(str: string, char: string) { const index = str.indexOf(char); @@ -57,7 +57,7 @@ function alreadyAdd(data: string) { alreadyCommands[alreadyCommands.length] = data; fs.writeFileSync( - "logs/alreadyCommands.json", + "data/alreadyCommands.json", JSON.stringify(alreadyCommands), "utf-8", ); @@ -74,72 +74,74 @@ export default async function Commands() { } ); - const mentions: Array = await mentionsReq.json(); + const mentions: { [key: string]: ueuse } = await mentionsReq.json(); console.log("----------------"); console.log("コマンド処理"); - for (let i = 0; i < mentions.length; i++) { - const data = mentions[i]; + for (const key in mentions) { + if (mentions.hasOwnProperty(key)) { + const data = mentions[key]; - // 除外ユーズ - if (alreadyCommands.indexOf(data.uniqid) !== -1) { - break; - } + // 除外ユーズ + if (alreadyCommands.indexOf(data.uniqid) !== -1) { + break; + } - if ( - data.text.charAt(0) === "!" || - data.text.charAt(0) === "!" || - data.abi === "ignore" - ) { - break; - } + if ( + data.text.charAt(0) === "!" || + data.text.charAt(0) === "!" || + data.abi === "ignore" + ) { + break; + } - // コマンド処理 - console.log("--------"); + // コマンド処理 + console.log("--------"); - const commandName = cutAfterChar(data.text, "/"); + const commandName = cutAfterChar(data.text, "/"); - alreadyAdd(data.uniqid); + alreadyAdd(data.uniqid); - switch (commandName) { - case "": - break; - case "info": - Info(data); - break; - case "help": - Help(data); - break; - case "legal terms": - Terms(data); - break; - case "legal privacy": - PrivacyPolicy(data); - break; - case "report": - Report(data); - break; - case "follow": - Follow(data); - break; - case "unfollow": - UnFollow(data); - break; - case "weather": - Weather(data); - break; - case "birthday": - Birthday(data); - break; - default: - const reply = await Reply(` - 不明なコマンドです。 - コマンド実行を除外する場合は1文字目に\`!\`を入れてください。 - `, data.uniqid); + switch (commandName) { + case "": + break; + case "info": + Info(data); + break; + case "help": + Help(data); + break; + case "legal terms": + Terms(data); + break; + case "legal privacy": + PrivacyPolicy(data); + break; + case "report": + Report(data); + break; + case "follow": + Follow(data); + break; + case "unfollow": + UnFollow(data); + break; + case "weather": + Weather(data); + break; + case "birthday": + Birthday(data); + break; + default: + const reply = await Reply(` + 不明なコマンドです。 + コマンド実行を除外する場合は1文字目に\`!\`を入れてください。 + `, data.uniqid); - console.log("未対応コマンド: ", reply); - break; + console.log("未対応コマンド: ", reply); + break; + } } } } diff --git a/scripts/commands/report.ts b/scripts/commands/report.ts index 5463ffe..4c0735c 100644 --- a/scripts/commands/report.ts +++ b/scripts/commands/report.ts @@ -1,4 +1,4 @@ -import { ueuse } from "types/types.js"; +import { ueuse } from "types/types"; import { Reply } from "./main.js"; import config from "../../config.js"; import sendMail from "../../src/mailer.js"; @@ -15,7 +15,15 @@ export default async function Report(data: ueuse) { return; } - if (!config.emergency.mail.function) { + if (!config.emergency.isEnabled) { + console.log("報告(重要通知オフ):", await Reply(` + BOTの運営者によって重要通知が無効化されています。 + そのため報告機能はご利用いただけません。 + `, data.uniqid)); + return; + } + + if (!config.emergency.mail.isEnabled) { console.log("報告(メールオフ):", await Reply(` BOTの運営者によってメール送信機能が無効化されています。 そのため報告機能はご利用いただけません。 @@ -23,7 +31,7 @@ export default async function Report(data: ueuse) { return; } - if (!config.emergency.report) { + if (!config.report.isEnabled) { console.log("報告(機能オフ):", await Reply(` BOTの運営者によって報告機能が無効化されています。 そのため報告機能はご利用いただけません。 @@ -49,7 +57,8 @@ export default async function Report(data: ueuse) { console.log("報告(完了):", await Reply(` 報告が完了しました。 運営者は報告者、ユーズのURL、内容を確認できます。 - 場合によっては運営者、BOTからブロックされる可能性があります。 + --運営者からのメッセージ-- + ${config.report.message} `, data.uniqid)); return; diff --git a/scripts/commands/unfollow.ts b/scripts/commands/unfollow.ts index 25120bc..65c68c5 100644 --- a/scripts/commands/unfollow.ts +++ b/scripts/commands/unfollow.ts @@ -1,4 +1,4 @@ -import { ueuse } from "types/types.js"; +import { ueuse } from "types/types"; import config from "../../config.js"; import { Reply } from "./main.js"; diff --git a/scripts/commands/weather.ts b/scripts/commands/weather.ts index 71b081b..60bc831 100644 --- a/scripts/commands/weather.ts +++ b/scripts/commands/weather.ts @@ -1,5 +1,5 @@ import { weatherReply } from "../weatherNotice.js"; -import { ueuse } from "types/types.js"; +import { ueuse } from "types/types"; export default function Weather(data: ueuse) { weatherReply(data.uniqid); diff --git a/scripts/earthquakeNotice.ts b/scripts/earthquakeNotice.ts index 019890e..7d13d4f 100644 --- a/scripts/earthquakeNotice.ts +++ b/scripts/earthquakeNotice.ts @@ -276,7 +276,7 @@ async function event(earthquakeInfo: any): Promise { if ( earthquakeInfo.earthquake.maxScale !== undefined && earthquakeInfo.earthquake.maxScale >= 60 && - config.emergency.function + config.emergency.isEnabled ) { console.log("----------------"); @@ -284,7 +284,7 @@ async function event(earthquakeInfo: any): Promise { console.log("サーバーがダウンする可能性があります"); // メール送信 - if (config.emergency.function) { + if (config.emergency.isEnabled) { sendMail({ to: config.emergency.mail.to, subject: "【警告】震度6強以上の地震を受信しました", diff --git a/scripts/successExit.ts b/scripts/successExit.ts index b85f575..0a4f178 100644 --- a/scripts/successExit.ts +++ b/scripts/successExit.ts @@ -15,7 +15,7 @@ export default function successExit() { const iolog = JSON.parse(fs.readFileSync("logs/boot.json", "utf-8")); - if (config.emergency.function) { + if (config.emergency.isEnabled) { // 前回の終了確認 const start = iolog.start; const stop = iolog.stop; @@ -23,7 +23,7 @@ export default function successExit() { if (isAfter(start, stop)) { console.log("前回の終了が適切でない可能性があります"); - if (config.emergency.mail.function) { + if (config.emergency.mail.isEnabled) { sendMail({ to: config.emergency.mail.to, subject: "【警告】前回終了が不適切な可能性", diff --git a/scripts/weatherNotice.ts b/scripts/weatherNotice.ts index eae8b76..6431635 100644 --- a/scripts/weatherNotice.ts +++ b/scripts/weatherNotice.ts @@ -1,6 +1,6 @@ import { cityList } from "../src/weatherId.js"; -import type * as types from "types/types.js"; +import type * as types from "types/types"; import config from "../config.js"; diff --git a/src/mailer.ts b/src/mailer.ts index 2dbcb70..8fc4f6a 100644 --- a/src/mailer.ts +++ b/src/mailer.ts @@ -11,42 +11,54 @@ export interface EmailMessage { } async function createTransporter() { - const transporter = nodemailer.createTransport({ - host: config.emergency.mail.host, - port: config.emergency.mail.port, - secure: config.emergency.mail.secure, - auth: { - user: config.emergency.mail.user, - pass: config.emergency.mail.password, - }, - } as SMTPTransport.Options); + if ( + config.emergency.isEnabled && + config.emergency.mail.isEnabled + ) { + const transporter = nodemailer.createTransport({ + host: config.emergency.mail.host, + port: config.emergency.mail.port, + secure: config.emergency.mail.secure, + auth: { + user: config.emergency.mail.user, + pass: config.emergency.mail.password, + }, + } as SMTPTransport.Options); - // 接続テスト - try { - await transporter.verify(); - console.log("SMTPサーバーに接続できました"); - } catch (error) { - console.error("SMTP接続テストに失敗:", error); - throw error; + // 接続テスト + try { + await transporter.verify(); + console.log("SMTPサーバーに接続できました"); + } catch (error) { + console.error("SMTP接続テストに失敗:", error); + throw error; + } + + return transporter; } - - return transporter; } export default async function sendMail(message: EmailMessage): Promise { - try { - const transporter = await createTransporter(); + if ( + config.emergency.isEnabled && + config.emergency.mail.isEnabled + ) { + try { + const transporter: any = await createTransporter(); - await transporter.sendMail({ - from: config.emergency.mail.user, - to: Array.isArray(message.to) ? message.to.join(",") : message.to, - subject: message.subject, - text: message.text, - html: message.html, - }); - console.log("メール送信成功"); - } catch (error) { - console.error("メール送信に失敗しました:", error); - throw error; + await transporter.sendMail({ + from: config.emergency.mail.user, + to: Array.isArray(message.to) ? message.to.join(",") : message.to, + subject: message.subject, + text: message.text, + html: message.html, + }); + console.log("メール送信成功"); + } catch (error) { + console.error("メール送信に失敗しました:", error); + throw error; + } + } else { + return; } } diff --git a/tsconfig.json b/tsconfig.json index ca0c613..44d57b8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "target": "ES2024", "module": "ESNext", - "moduleResolution": "bundler", + "moduleResolution": "node", "outDir": "./dist", "esModuleInterop": true, "allowSyntheticDefaultImports": true, diff --git a/types/config.d.ts b/types/config.d.ts index e65b698..20b2c39 100644 --- a/types/config.d.ts +++ b/types/config.d.ts @@ -18,8 +18,8 @@ interface timeTypes { stopTimes: stopsTypes; } -interface emergencyMailTypes { - function: boolean; +interface emergencyMailFullTypes { + isEnabled: true; host: string; port: number; user: string; @@ -28,10 +28,18 @@ interface emergencyMailTypes { to: string | string[]; } -interface emergencyTypes { - function: boolean; - mail: emergencyMailTypes; - report: boolean; +interface emergencyMailMinTypes { + isEnabled: false; + mail: undefined; +} + +interface emergencyFullTypes { + isEnabled: true; + mail: emergencyMailFullTypes | emergemcyMailMinTypes; +} + +interface emergencyMinTypes { + isEnabled: false; } interface legalTypes { @@ -39,9 +47,24 @@ interface legalTypes { privacy: string; } +interface PanelFullTypes { + isEnabled: true; + port: number; +} + +interface PanelMinTypes { + isEnabled: false; +} + interface adminTypes { name: string; showMail: string | false; + panel: PanelFullTypes | PanelMinTypes; +} + +interface reportTypes { + isEnabled: boolean; + message: string; } interface uwuzuTypes { @@ -55,8 +78,9 @@ export interface configTypes { earthquake: earthquakeTypes; weather: weatherTypes; - emergency: emergencyTypes; + emergency: emergencyFullTypes | emergencyMinTypes; legal: legalTypes; admin: adminTypes; + report: reportTypes; uwuzu: uwuzuTypes; } diff --git a/types/types.d.ts b/types/types.d.ts index c7f6c5a..85b7e6e 100644 --- a/types/types.d.ts +++ b/types/types.d.ts @@ -56,3 +56,9 @@ export interface ueuseCreateApi { export interface followApi { userid: string; } + +export interface NetworkInterfaceDetails { + family: string; + internal: boolean; + address: string; +}