File size: 4,432 Bytes
fb481fa
 
e3e1fb6
 
 
 
fb481fa
e3e1fb6
 
fb481fa
 
 
e3e1fb6
fb481fa
 
e3e1fb6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e4f6d97
 
fb481fa
e3e1fb6
 
 
 
 
 
 
 
 
 
 
 
228ce2f
e3e1fb6
228ce2f
e3e1fb6
 
 
 
 
 
fb481fa
e3e1fb6
 
 
 
e4f6d97
e3e1fb6
 
 
fb481fa
e3e1fb6
 
 
 
 
 
 
 
 
 
 
 
fb481fa
e3e1fb6
 
fb481fa
e4f6d97
e3e1fb6
 
 
e4f6d97
 
e3e1fb6
 
 
e4f6d97
e3e1fb6
 
 
 
 
 
 
2bcf4f9
fb481fa
e3e1fb6
 
 
 
 
 
 
 
 
 
 
e4f6d97
e3e1fb6
e4f6d97
e3e1fb6
 
 
228ce2f
e3e1fb6
e4f6d97
e3e1fb6
 
 
 
 
 
228ce2f
e3e1fb6
 
228ce2f
e3e1fb6
 
 
 
 
228ce2f
e3e1fb6
 
 
 
 
 
 
 
 
 
 
 
 
e4f6d97
e3e1fb6
 
 
 
fb481fa
 
e3e1fb6
 
 
 
 
 
 
 
 
 
 
 
 
 
fb481fa
e3e1fb6
 
fb481fa
 
 
e3e1fb6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
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"<b>時報</b>\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 = ["<b>☀️ 本日の天気予報(7時以降・1時間ごと)</b>"]

    for idx, pref in enumerate(todoufuken):
        hourly = data[idx]["hourly"]
        times = hourly["time"]

        lines.append(f"\n<b>{pref['name']}:</b>")

        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()