diff --git a/README.md b/README.md index 4750cd5..c49f00b 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,12 @@ -# uwuzu時報BOT +# uwuzuお知らせBOT -# なにこれ +# uwuzuお知らせBOTについて -uwuzuの時報BOT。 -1時間おきに投稿する。 -タイムゾーンはサーバー依存。 +uwuzuで動作するお知らせBOTです。 -# .envは? +# .env形式 -.env.example見て +`.env.example`をご覧ください。 # サーバー起動 @@ -17,3 +15,5 @@ npm install npm run build npm run start ``` + +※Node.js・npmがインストールされている必要があります。 diff --git a/main.ts b/main.ts index f41f181..4805953 100644 --- a/main.ts +++ b/main.ts @@ -1,64 +1,19 @@ import * as cron from "node-cron"; -import * as dotenv from "dotenv"; -import { format } from "date-fns"; -import type * as type from "./types"; +import timeNotice from "./scripts/timeNotice.js"; +import weatherNotice from "./scripts/weatherNotice.js"; -dotenv.config(); - -async function ueuse() { - const now = format(new Date(), "HH:mm"); - - const resUeuse = await fetch( - `https://${process.env.SERVER}/api/ueuse/create`, - { - method: "POST", - body: JSON.stringify({ - token: process.env.TOKEN, - text: `${now}になりました`, - }), - }, - ); - - const ueuseData: type.ueuseCreateApi = await resUeuse.json(); - - console.log(JSON.stringify(ueuseData)); -} - -async function follow() { - const resMe = await fetch(`https://${process.env.SERVER}/api/me`, { - method: "POST", - body: JSON.stringify({ - token: process.env.TOKEN, - }), - }); - - const meData: type.meApi = await resMe.json(); - - const followers: Array = meData.follower; - - for (let i = 0; i < followers.length; i++) { - const followerItem = followers[i]; - - const resFollow = await fetch( - `https://${process.env.SERVER}/api/users/follow`, - { - method: "POST", - body: JSON.stringify({ - token: process.env.TOKEN, - userid: followerItem, - }), - }, - ); - - const followData: type.followApi = await resFollow.json(); - - console.log(JSON.stringify(followData)); - } -} +import followBack from "./scripts/followBack.js"; +// 時報・フォローバック(毎時) cron.schedule("0 * * * *", () => { - ueuse(); + timeNotice(); + followBack(); +}); + +// 天気お知らせ(毎日7:00) +cron.schedule("0 7 * * *", () => { + weatherNotice(); }); console.log("サーバーが起動しました"); diff --git a/package.json b/package.json index ebc6bc4..5052a97 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { - "name": "timenoticeuwuzu", - "version": "v1.1@uwuzu1.5.4", - "description": "@TimeNotice@uwuzu.netの中身", + "name": "noticeuwuzu", + "version": "v2.0@uwuzu1.5.4", + "description": "uwuzu Notice Bot", "main": "dist/main.js", "scripts": { "start": "node .", diff --git a/scripts/followBack.ts b/scripts/followBack.ts new file mode 100644 index 0000000..7508b6e --- /dev/null +++ b/scripts/followBack.ts @@ -0,0 +1,40 @@ +import * as dotenv from "dotenv"; + +import type * as types from "../types"; + +dotenv.config(); + +export default async function followBack() { + // uwuzu.netで/api/meのPOSTが死んでいるため簡易的にGET + const resMe = await fetch( + `https://${process.env.SERVER}/api/me?token=${process.env.TOKEN}`, + { + method: "GET", + }, + ); + + const meData: types.meApi = await resMe.json(); + + console.log(meData); + + const followers: Array = meData.follower; + + for (let i = 0; i < followers.length; i++) { + const followerItem = followers[i]; + + const resFollow = await fetch( + `https://${process.env.SERVER}/api/users/follow`, + { + method: "POST", + body: JSON.stringify({ + token: process.env.TOKEN, + userid: followerItem, + }), + }, + ); + + const followData: types.followApi = await resFollow.json(); + + console.log(JSON.stringify(followData)); + } +} diff --git a/scripts/timeNotice.ts b/scripts/timeNotice.ts new file mode 100644 index 0000000..cca91ac --- /dev/null +++ b/scripts/timeNotice.ts @@ -0,0 +1,25 @@ +import * as dotenv from "dotenv"; +import { format } from "date-fns"; + +import type * as types from "../types"; + +dotenv.config(); + +export default async function timeNotice() { + const now = format(new Date(), "HH:mm"); + + const resUeuse = await fetch( + `https://${process.env.SERVER}/api/ueuse/create`, + { + method: "POST", + body: JSON.stringify({ + token: process.env.TOKEN, + text: `${now}になりました`, + }), + }, + ); + + const ueuseData: types.ueuseCreateApi = await resUeuse.json(); + + console.log(JSON.stringify(ueuseData)); +} diff --git a/scripts/weatherNotice.ts b/scripts/weatherNotice.ts new file mode 100644 index 0000000..8456c78 --- /dev/null +++ b/scripts/weatherNotice.ts @@ -0,0 +1,50 @@ +import * as dotenv from "dotenv"; +import { cityList } from "../src/weatherId.js"; + +import type * as types from "../types"; + +dotenv.config(); + +export default async function weatherNotice() { + let weatherResults: string = ""; + + for (const [cityId, cityName] of Object.entries(cityList)) { + const res = await fetch( + `https://weather.tsukumijima.net/api/forecast/city/${cityId}`, + ); + const data = await res.json(); + + const today = data.forecasts[0]; + const weather = today.telop ?? "取得できませんでした"; + const maxTemp = today.temperature.max?.celsius ?? "取得できませんでした"; + const minTemp = today.temperature.min?.celsius ?? "取得できませんでした"; + const chanceOfRain = data.chanceOfRain?.["T06_12"] ?? "取得できませんでした"; + + weatherResults = weatherResults + + `【${cityName}】\n + 天気:${weather}\n + 最高気温:${maxTemp}℃\n + 最低気温:${minTemp}℃\n + 降水確率:${chanceOfRain} + `; + } + + // 返信用ユーズ + const resUeuse = await fetch( + `https://${process.env.SERVER}/api/ueuse/create`, + { + method: "POST", + body: JSON.stringify({ + token: process.env.TOKEN, + text: ` + # 本日の天気\n + ${weatherResults} + `, + }), + }, + ); + + const ueuseData: types.ueuseCreateApi = await resUeuse.json(); + + console.log(JSON.stringify(ueuseData)); +} diff --git a/src/weatherId.ts b/src/weatherId.ts new file mode 100644 index 0000000..af72a7b --- /dev/null +++ b/src/weatherId.ts @@ -0,0 +1,49 @@ +export const cityList: { [cityId: string]: string } = { + "016010": "札幌", + "020010": "青森", + "030010": "盛岡", + "040010": "仙台", + "050010": "秋田", + "060010": "山形", + "070010": "福島", + "080010": "水戸", + "090010": "宇都宮", + "100010": "前橋", + "110010": "さいたま", + "120010": "千葉", + "130010": "東京", + "140010": "横浜", + "150010": "新潟", + "160010": "富山", + "170010": "金沢", + "180010": "福井", + "190010": "甲府", + "200010": "長野", + "210010": "岐阜", + "220010": "静岡", + "230010": "名古屋", + "240010": "津", + "250010": "大津", + "260010": "京都", + "270000": "大阪", + "280010": "神戸", + "290010": "奈良", + "300010": "和歌山", + "310010": "鳥取", + "320010": "松江", + "330010": "岡山", + "340010": "広島", + "350010": "山口", + "360010": "徳島", + "370000": "高松", + "380010": "松山", + "390010": "高知", + "400010": "福岡", + "410010": "佐賀", + "420010": "長崎", + "430010": "熊本", + "440010": "大分", + "450010": "宮崎", + "460010": "鹿児島", + "471010": "那覇", +};