import time import requests import os import json from datetime import datetime, timedelta from zoneinfo import ZoneInfo BASE_URL = "https://desk-api.channel.io/desk/channels/227312" TARGET_GROUP_CHAT_ID = "536135" HEADERS = { "accept-language": "ja", "x-account": os.getenv("dmsendertoken") } JST = ZoneInfo("Asia/Tokyo") # ---------------- 天気コード ---------------- WEATHER_CODE_MAP = { 0: "☀️晴れ", 1: "☁️曇り", 2: "吹雪", 3: "砂嵐", 4: "🌫️霧", 5: "🌫️霧雨", 6: "🌧️雨", 7: "🌨️雪", 8: "🌦️シャワー", 9: "⛈️雷雨", } def format_weather_code(code: int) -> str: if code < 10: return WEATHER_CODE_MAP.get(code, str(code)) main = code // 10 sub = code % 10 main_str = WEATHER_CODE_MAP.get(main) sub_str = WEATHER_CODE_MAP.get(sub) if main_str and sub_str: return f"{main_str}、{sub_str}" return str(code) # ---------------- Channel 投稿 ---------------- def post_group_message(chat_id, body): url = f"{BASE_URL}/groups/{chat_id}/messages" r = requests.post(url, headers=HEADERS, json=body) r.raise_for_status() return r.json() # ---------------- 時報 ---------------- def create_time_signal_body(): now = datetime.now(JST) hour = now.hour if hour < 12: period = "午前" display_hour = hour if hour != 0 else 12 else: period = "午後" display_hour = hour - 12 if hour > 12 else 12 message = f"時報\n{period}{display_hour}時をお知らせします。" return { "requestId": f"desk-web-time-signal-{int(time.time())}", "blocks": [{"type": "text", "value": message}], } # ---------------- 天気予報 ---------------- def load_todoufuken(): with open("todoufuken.json", encoding="utf-8") as f: return json.load(f) def fetch_weather(todoufuken): lats = ",".join(str(p["lat"]) for p in todoufuken) lons = ",".join(str(p["lon"]) for p in todoufuken) url = ( "https://api.open-meteo.com/v1/forecast" f"?latitude={lats}" f"&longitude={lons}" "&hourly=relative_humidity_2m,apparent_temperature,temperature_2m," "precipitation_probability,weather_code" "&forecast_days=1" ) r = requests.get(url) r.raise_for_status() return r.json() def create_weather_body(): now = datetime.now(JST) today_7am = now.replace(hour=7, minute=0, second=0, microsecond=0) todoufuken = load_todoufuken() data = fetch_weather(todoufuken) lines = ["☀️ 本日の天気予報(7時以降・1時間ごと)"] for idx, pref in enumerate(todoufuken): hourly = data[idx]["hourly"] times = hourly["time"] lines.append(f"\n{pref['name']}:") for i, t in enumerate(times): t_jst = ( datetime.fromisoformat(t) .replace(tzinfo=ZoneInfo("UTC")) .astimezone(JST) ) if t_jst < today_7am: continue wc = hourly["weather_code"][i] at = hourly["apparent_temperature"][i] temp = hourly["temperature_2m"][i] pop = hourly["precipitation_probability"][i] rh = hourly["relative_humidity_2m"][i] wc_str = format_weather_code(wc) line = ( f" {t_jst.strftime('%H時')}:" f"{wc_str} " f"{at}℃ {temp}℃ {pop}% {rh}%" ) lines.append(line) return { "requestId": f"desk-web-weather-{int(time.time())}", "blocks": [{"type": "text", "value": "\n".join(lines)}], } # ---------------- メインループ ---------------- def main_loop(): while True: try: now = datetime.now(JST) # 毎正時の時報 if now.minute == 0: body = create_time_signal_body() post_group_message(TARGET_GROUP_CHAT_ID, body) # 午後2時9分に天気予報 if now.hour == 14 and now.minute == 20: body = create_weather_body() post_group_message(TARGET_GROUP_CHAT_ID, body) time.sleep(60) except Exception as e: print("Error:", e) time.sleep(10) if __name__ == "__main__": main_loop()