diff --git a/miq/main.ts b/miq/main.ts index 3136efc..f4351e3 100644 --- a/miq/main.ts +++ b/miq/main.ts @@ -1,134 +1,3 @@ -import { createCanvas, loadImage, registerFont } from "canvas"; -import { writeFileSync } from "fs"; -import sharp from "sharp"; -import { MiQOptions } from "./miq"; - -function textReplace( - text: string -) { - let result = ""; - - // 改行削除 - text = text.replaceAll("\n", ""); - - // 10文字/1回で改行を追加 - let maxLength = 10; - if (text.length > maxLength) { - for (let i = 0; i < text.length; i += maxLength) { - result += text.substring(i, i + maxLength) + "\n"; - } - result = result.trimEnd(); - } - - // 80文字以上は「...」で省略 - maxLength = 80; - if (result.length > maxLength) { - result = result.substring(0, maxLength) - + "..."; - } - - return result; -} - -async function iconReplace( - color: boolean, - iconURL: string, -) { - let result = ""; - - const buffer = await(await fetch(iconURL, { - method: "GET", - cache: "no-store", - })).arrayBuffer(); - - if (color) { - const img = await sharp(Buffer.from(buffer)) - .png() - .toBuffer(); - - result = `data:image/png;base64,${img.toString("base64")}`; - } else { - const img = await sharp(Buffer.from(buffer)) - .png() - .grayscale() - .toBuffer(); - - result = `data:image/png;base64,${img.toString("base64")}`; - } - - return result; -} - -/** - * A function to generate - * Make it a quote on Node.js. -*/ -export default async function MiQ({ - type, - color, - text, - iconURL, - userName, - userID, -}: MiQOptions) { - // フォント読み込み - registerFont("miq/fonts/NotoSansJP.ttf", { family: "Noto Sans JP" }); - - // 初期化 - const canvas = createCanvas(1200, 630); - const ctx = canvas.getContext("2d"); - - // 背景描画 - ctx.fillStyle = "black"; - ctx.fillRect(0, 0, canvas.width, canvas.height); - - // アイコン描画 - const iconImg = await loadImage(await iconReplace( - color, - iconURL, - )); - const iconSize = canvas.height; - ctx.drawImage(iconImg, 0, 0, iconSize, iconSize); - - // ユーザー名描画 - ctx.font = "38px Noto Sans JP"; - ctx.fillStyle = "white"; - ctx.textAlign = "left"; - ctx.textBaseline = "middle"; - let x = 670; - let y = 480; - ctx.fillText("-", x, y); - ctx.fillText(userName, x+40, y, canvas.width-(x+40)); - - // ユーザーID描画 - ctx.font = "28px Noto Sans JP"; - ctx.fillStyle = "#3c3c3c"; - ctx.fillText(`@${userID}`, x+120, y+50, canvas.width-(x+120)); - - // 本文描画 - ctx.font = "48px Noto Sans JP"; - ctx.textAlign = "center"; - ctx.textBaseline = "middle"; - ctx.fillStyle = "white"; - text = textReplace(text); - x = 870; - y = 30; - ctx.fillText(text, x, y+50); - - // フェード描画 - const fadeColor = "black"; - const gradient = ctx.createLinearGradient(0, 0, canvas.width, 0); - gradient.addColorStop(0, "rgba(0, 0, 0, 0)"); - gradient.addColorStop(0.5, fadeColor); - ctx.fillStyle = gradient; - ctx.fillRect(0, 0, iconSize, canvas.height); - - // 返答 - if (type === "Buffer") { - return canvas.toBuffer(); - } else if (type === "Base64") { - return canvas.toDataURL(); - } else { - return "Error: The type property is invalid."; - } -} +version https://git-lfs.github.com/spec/v1 +oid sha256:0603619bda0ca36bf1cfe1b2d10e516f1a2d21f9626b5be60479c6a0c657613a +size 4319 diff --git a/miq/miq.d.ts b/miq/miq.d.ts index 04b297e..2d3f76a 100644 --- a/miq/miq.d.ts +++ b/miq/miq.d.ts @@ -1,12 +1,3 @@ -type MiQType = -"Buffer" | -"Base64" - -export interface MiQOptions { - type: MiQType; - color: boolean; - text: string; - iconURL: string; - userName: string; - userID: string; -} +version https://git-lfs.github.com/spec/v1 +oid sha256:5b1cb95596912cb34b14f8fbac141e247516421c1bacec932bcd855a05166212 +size 214 diff --git a/package.json b/package.json index 9301da0..8f82d6f 100644 --- a/package.json +++ b/package.json @@ -1,62 +1,3 @@ -{ - "name": "notice-uwuzu", - "version": "v25.8.5@uwuzu1.6.4", - "tag": "v25.8.5", - "description": "Notice Bot for uwuzu", - "main": "dist/main.js", - "scripts": { - "start": "node .", - "build": "tsc", - "main": "tsc && node .", - "dev": "tsx main.ts", - "clean": "tsc && node dist/scripts/clean/main.js" - }, - "repository": { - "type": "git", - "url": "https://gitea.last2014.com/last2014/noticeUwuzu" - }, - "keywords": [ - "uwuzu", - "bot", - "cron", - "notice", - "mail", - "weather", - "time", - "earthquake", - "command", - "commands" - ], - "author": { - "name": "Last2014", - "url": "https://last2014.com", - "email": "info@last2014.com" - }, - "contributors": [], - "license": "Apache-2.0", - "type": "module", - "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/sharp": "^0.31.1", - "@types/ws": "^8.18.1", - "canvas": "^3.2.0", - "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", - "sharp": "^0.34.3", - "timers": "^0.1.1", - "typescript": "^5.9.2", - "ws": "^8.18.3" - }, - "devDependencies": { - "tsx": "^4.20.3" - } -} +version https://git-lfs.github.com/spec/v1 +oid sha256:10efff1e335d1cef6d9823c21d5bc80f7ef39de2abedbe8a897cdd63b6d458cb +size 1380 diff --git a/scripts/commands/help.ts b/scripts/commands/help.ts index ff784f1..106c87b 100644 --- a/scripts/commands/help.ts +++ b/scripts/commands/help.ts @@ -1,79 +1,3 @@ -import { ueuse } from "types/types"; -import { readFileSync } from "fs"; -import { Reply } from "./main.js"; - -const helpsMin = { - "info": "このBOTについての概要を返信するコマンドです。", - "help": "コマンドの概要を返信します。追記に\`/\`抜きのコマンド名を入力することでそのコマンドの詳細(フル)を返信します。", - "follow": "コマンド送信者をフォローします。", - "unfollow": "コマンド送信者をフォロー解除します。", - "weather": "天気を返信します。", - "report": "運営者に不具合などを報告します。", - "legal terms": "利用規約を返信します。", - "legal privacy": "プライバシーポリシーを返信します。", -} as { [key: string]: string }; - -const helpsFull = { - "info": ` - このBOTについての概要を返信するコマンドです。 - バージョン、開発者などが確認できます。 - `, - "help": ` - このコマンドです。コマンドの概要を返信します。 - 追記に\`/\`抜きのコマンド名を入力することでそのコマンドの詳細(フル)を返信します。 - `, - "follow": ` - コマンドを送信したユーザーをフォローします。 - 既にフォローされているユーザーも使用できます。 - `, - "unfollow": ` - コマンドを送信したユーザーをフォロー解除します。 - 既にフォローされていないユーザーも使用できます。 - `, - "weather": ` - 天気を返信します。 - 毎日7:00の天気を再投稿するわけではなく、 - 再取得して返信します。 - `, - "report": ` - 不具合などを運営者にメールで報告できます。 - 運営者によって有効化されていないと使用できません。 - \`/report\`を使用してそのユーズの追記に内容を入力することで使用できます。 - `, - "legal terms": ` - 利用規約を返信します。 - `, - "legal privacy": ` - プライバシーポリシーを返信します。 - `, -} as { [key: string]: string }; - -export default async function Help(data: ueuse) { - const packageJson = JSON.parse(readFileSync("package.json", "utf-8")); - - if ( - data.abi === "none" || - data.abi === "" - ) { - const helpMsg = - Object.entries(helpsMin) - .map(([command, message]) => - `\`/${command}\`:${message}` - ).join('\n'); - - const ueuse = await Reply(` - ${helpMsg} - BOTの概要は\`/info\`をご利用ください。 - Wikiを見る:${packageJson.repository.url}/wiki - `, data.uniqid); - - console.log("ヘルプ:", ueuse); - } else { - const ueuse = await Reply(` - ${helpsFull[data.abi]} - 機能を見る:${packageJson.repository.url}/wiki - `, data.uniqid); - - console.log("ヘルプ:", ueuse); - } -} +version https://git-lfs.github.com/spec/v1 +oid sha256:af22354b1b58e7d17e094c97b89bfda2cf57caf12c353065c50414c97781d2f2 +size 3115 diff --git a/scripts/commands/main.ts b/scripts/commands/main.ts index b5124ca..476ab95 100644 --- a/scripts/commands/main.ts +++ b/scripts/commands/main.ts @@ -1,191 +1,3 @@ -import * as fs from "fs"; -import config from "../../config.js"; -import type { ueuse } from "types/types"; - -const initialFile: Array = []; - -// コマンド読み込み -import Info from "./info.js"; -import Help from "./help.js"; -import Follow from "./follow.js"; -import UnFollow from "./unfollow.js"; -import Weather from "./weather.js"; -import MakeItAQuote from "./miq.js"; -import Report from "./report.js"; -import Terms from "./legal/terms.js" -import PrivacyPolicy from "./legal/privacy.js"; - -// 初期化 -if (!fs.existsSync("data/alreadyCommands.json")) { - fs.writeFileSync( - "data/alreadyCommands.json", - JSON.stringify(initialFile), - "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); - - if (index === -1) { - return ""; - } - - return str.substring(index + 1); -} - -async function commandSearch(text: string) { - // /のある行を特定 - const lines = text.split(/\n/); - let slashLine: number = -1; - for (let i = 0; i < lines.length; i++) { - if (lines[i].indexOf("/") !== -1) { - slashLine = i; - } - } - - // /がない場合は無を返答 - if (slashLine === -1) { - return ""; - } - - // BOTのユーザーIDを取得 - const userid: string = (await (await fetch(`${config.uwuzu.host}/api/me/`, { - method: "POST", - cache: "no-store", - body: JSON.stringify({ - token: config.uwuzu.apiToken, - }), - })).json()).userid; - - // BOTへのメンションを削除 - let slashLineText = lines[slashLine]; - slashLineText = slashLineText.replace(`@${userid}`, ""); - - // /以降の文字を取得 - slashLineText = cutAfterChar(slashLineText, "/"); - - // 前後の空白を削除 - slashLineText = slashLineText.trimStart().trimEnd(); - - return slashLineText; -} - -export async function Reply(text: string, reply: string) { - const req = await fetch(`${config.uwuzu.host}/api/ueuse/create`, { - method: "POST", - body: JSON.stringify({ - token: config.uwuzu.apiToken, - text: text, - replyid: reply, - }), - cache: "no-store", - }); - - const res = await req.json(); - - return res; -} - -function alreadyAdd(data: string) { - alreadyCommands[alreadyCommands.length] = data; - - fs.writeFileSync( - "data/alreadyCommands.json", - JSON.stringify(alreadyCommands), - "utf-8", - ); -} - -export default async function Commands() { - const mentionsReq = await fetch( - `${config.uwuzu.host}/api/ueuse/mentions`, { - method: "POST", - body: JSON.stringify({ - token: config.uwuzu.apiToken, - }), - cache: "no-store", - } - ); - - const mentions: { [key: string]: ueuse } = await mentionsReq.json(); - - console.log("----------------"); - console.log("コマンド処理"); - - for (const key in mentions) { - if (mentions.hasOwnProperty(key)) { - const data = mentions[key]; - - // 除外ユーズ - if (data.text === undefined) { - break; - } - - if (alreadyCommands.indexOf(data.uniqid) !== -1) { - break; - } - - if ( - data.text.charAt(0) === "!" || - data.text.charAt(0) === "!" || - data.abi === "ignore" - ) { - break; - } - - if (data.text.indexOf("/") === -1) { - break; - } - - // コマンド処理 - console.log("--------"); - - const commandName = await commandSearch(data.text); - console.log(commandName); - - alreadyAdd(data.uniqid); - - switch (commandName) { - 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 "miq": - MakeItAQuote(data); - break; - default: - const reply = await Reply(` - 不明なコマンドです。 - コマンド実行を除外する場合は1文字目に\`!\`を入れてください。 - `, data.uniqid); - - console.log("未対応コマンド: ", reply); - break; - } - } - } -} +version https://git-lfs.github.com/spec/v1 +oid sha256:15d284a3557c79cf4fe5c5c4b6fc4c71748dfe9e6e6a9d011e4a77b670ec0290 +size 4653 diff --git a/scripts/commands/miq.ts b/scripts/commands/miq.ts index 2b5f2df..6d3ea79 100644 --- a/scripts/commands/miq.ts +++ b/scripts/commands/miq.ts @@ -1,56 +1,3 @@ -import { ueuse } from "../../types/types"; -import MiQ from "../../miq/main.js"; -import config from "../../config.js"; - -export default async function MakeItAQuote(data: ueuse) { - let color: boolean; - let msg: string; - - if (data.abi === "color: true") { - msg = "カラーモードでMake it a quoteを生成しました。"; - color = true; - } else if (data.abi === "color: false") { - msg = "モノクロモードでMake it a quoteを生成しました。"; - color = false; - } else { - msg = "ご指定がないためモノクロモードでMake it a quoteを生成しました。"; - color = false; - } - - const ueuseData: ueuse = (await ( - await fetch(`${config.uwuzu.host}/api/ueuse/get`, { - method: "POST", - cache: "no-store", - body: JSON.stringify({ - token: config.uwuzu.apiToken, - uniqid: data.replyid, - }), - }) - ).json())["0"]; - - console.log(ueuseData) - - const img = await MiQ({ - type: "Base64", - color: color, - text: ueuseData.text, - iconURL: ueuseData.account.user_icon, - userName: ueuseData.account.username, - userID: ueuseData.account.userid, - }); - - const req = await fetch(`${config.uwuzu.host}/api/ueuse/create`, { - method: "POST", - body: JSON.stringify({ - token: config.uwuzu.apiToken, - text: msg, - image1: img, - replyid: data.uniqid, - }), - cache: "no-store", - }); - - const res = await req.json(); - - console.log("MiQ:", res); -} +version https://git-lfs.github.com/spec/v1 +oid sha256:b6b7ff552250c4119533d850a21057e0f4f01472b1f206449863644b4153aeb6 +size 1519