izuemon commited on
Commit
e3e1fb6
·
verified ·
1 Parent(s): cb00740

Update jihou.py

Browse files
Files changed (1) hide show
  1. jihou.py +138 -77
jihou.py CHANGED
@@ -1,115 +1,176 @@
1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
-
4
- import os
5
  import time
6
  import requests
7
- from typing import List, Dict, Any
8
-
9
- # ===== 設定 =====
10
- X_ACCOUNT = os.getenv("dmsendertoken")
11
- if not X_ACCOUNT:
12
- raise RuntimeError("環境変数 dmsendertoken が設定されていません")
13
 
14
- BASE = "https://desk-api.channel.io/desk/channels/200605"
15
- GROUP_ID = 463667
16
- CHECK_PERSON_ID = "604730"
17
 
18
  HEADERS = {
19
- "accept": "application/json",
20
  "accept-language": "ja",
21
- "content-type": "application/json",
22
- "x-account": X_ACCOUNT,
23
  }
24
 
25
- GET_PARAMS = {
26
- "sortOrder": "desc",
27
- "limit": 34,
28
- "logFolded": "false",
 
 
 
 
 
 
 
 
 
 
 
29
  }
30
 
31
- WELCOME_TEXT = "こんにちは。ITRSAにようこそ。自動でいくつかの部屋に招待しています。"
32
 
33
- INVITE_GROUPS = [519217, 536194, 534868]
 
 
 
 
 
 
 
 
 
 
 
34
 
 
35
 
36
- # ===== API =====
37
- def get_messages() -> List[Dict[str, Any]]:
38
- url = f"{BASE}/groups/{GROUP_ID}/messages"
39
- r = requests.get(url, headers=HEADERS, params=GET_PARAMS, timeout=20)
 
 
40
  r.raise_for_status()
41
- return r.json().get("messages", [])
 
 
 
42
 
 
 
 
43
 
44
- def post_welcome_message() -> None:
45
- url = f"{BASE}/groups/{GROUP_ID}/messages"
46
- payload = {
47
- "requestId": f"desk-web-{int(time.time() * 1000)}",
48
- "blocks": [
49
- {"type": "text", "value": WELCOME_TEXT}
50
- ]
 
 
 
 
 
51
  }
52
- requests.post(url, headers=HEADERS, json=payload, timeout=20).raise_for_status()
53
- print("[INFO] 歓迎メッセージを送信しました")
54
 
55
 
56
- def invite_person(group_id: int, person_id: str) -> None:
57
- url = f"{BASE}/groups/{group_id}/invite"
58
- params = {"managerIds": person_id}
59
- requests.post(url, headers=HEADERS, params=params, timeout=20).raise_for_status()
60
- print(f"[INFO] personId={person_id} を group {group_id} に招待しました")
61
 
62
 
63
- # ===== ロジック =====
64
- def process():
65
- messages = get_messages()
66
 
67
- # personId=599642 の最新発言時刻
68
- latest_599642 = max(
69
- (int(m.get("createdAt", 0))
70
- for m in messages
71
- if str(m.get("personId")) == CHECK_PERSON_ID),
72
- default=0
 
73
  )
74
 
75
- # 条件を満たす join メッセージを抽出
76
- join_targets = []
77
- for m in messages:
78
- log = m.get("log") or {}
79
- if log.get("action") != "join":
80
- continue
 
 
 
 
 
81
 
82
- created_at = int(m.get("createdAt", 0))
83
- person_id = str(m.get("personId", ""))
84
 
85
- # join 以降に 599642 の発言が無い
86
- if created_at > latest_599642:
87
- join_targets.append(person_id)
88
 
89
- if not join_targets:
90
- return
91
 
92
- # 重複排除
93
- join_targets = list(set(join_targets))
 
 
 
 
94
 
95
- # 歓迎メッセージは1回だけ
96
- post_welcome_message()
97
 
98
- # 全員を各グループへ招待
99
- for pid in join_targets:
100
- for gid in INVITE_GROUPS:
101
- invite_person(gid, pid)
 
102
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
 
104
- def main():
105
- print("[INFO] Bot 起動(10秒間隔)")
 
 
106
  while True:
107
  try:
108
- process()
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  except Exception as e:
110
- print(f"[ERROR] {e}")
111
- time.sleep(10)
112
 
113
 
114
  if __name__ == "__main__":
115
- main()
 
 
 
 
 
1
  import time
2
  import requests
3
+ import os
4
+ import json
5
+ from datetime import datetime, timedelta
6
+ from zoneinfo import ZoneInfo
 
 
7
 
8
+ BASE_URL = "https://desk-api.channel.io/desk/channels/227312"
9
+ TARGET_GROUP_CHAT_ID = "536135"
 
10
 
11
  HEADERS = {
 
12
  "accept-language": "ja",
13
+ "x-account": os.getenv("dmsendertoken")
 
14
  }
15
 
16
+ JST = ZoneInfo("Asia/Tokyo")
17
+
18
+ # ---------------- 天気コード ----------------
19
+
20
+ WEATHER_CODE_MAP = {
21
+ 0: "☀️晴れ",
22
+ 1: "☁️曇り",
23
+ 2: "吹雪",
24
+ 3: "砂嵐",
25
+ 4: "🌫️霧",
26
+ 5: "🌫️霧雨",
27
+ 6: "🌧️雨",
28
+ 7: "🌨️雪",
29
+ 8: "🌦️シャワー",
30
+ 9: "⛈️雷雨",
31
  }
32
 
 
33
 
34
+ def format_weather_code(code: int) -> str:
35
+ if code < 10:
36
+ return WEATHER_CODE_MAP.get(code, str(code))
37
+
38
+ main = code // 10
39
+ sub = code % 10
40
+
41
+ main_str = WEATHER_CODE_MAP.get(main)
42
+ sub_str = WEATHER_CODE_MAP.get(sub)
43
+
44
+ if main_str and sub_str:
45
+ return f"{main_str}、{sub_str}"
46
 
47
+ return str(code)
48
 
49
+ # ---------------- Channel 投稿 ----------------
50
+
51
+
52
+ def post_group_message(chat_id, body):
53
+ url = f"{BASE_URL}/groups/{chat_id}/messages"
54
+ r = requests.post(url, headers=HEADERS, json=body)
55
  r.raise_for_status()
56
+ return r.json()
57
+
58
+ # ---------------- 時報 ----------------
59
+
60
 
61
+ def create_time_signal_body():
62
+ now = datetime.now(JST)
63
+ hour = now.hour
64
 
65
+ if hour < 12:
66
+ period = "午前"
67
+ display_hour = hour if hour != 0 else 12
68
+ else:
69
+ period = "午後"
70
+ display_hour = hour - 12 if hour > 12 else 12
71
+
72
+ message = f"<b>時報</b>\n{period}{display_hour}時をお知らせします。"
73
+
74
+ return {
75
+ "requestId": f"desk-web-time-signal-{int(time.time())}",
76
+ "blocks": [{"type": "text", "value": message}],
77
  }
78
+
79
+ # ---------------- 天気予報 ----------------
80
 
81
 
82
+ def load_todoufuken():
83
+ with open("todoufuken.json", encoding="utf-8") as f:
84
+ return json.load(f)
 
 
85
 
86
 
87
+ def fetch_weather(todoufuken):
88
+ lats = ",".join(str(p["lat"]) for p in todoufuken)
89
+ lons = ",".join(str(p["lon"]) for p in todoufuken)
90
 
91
+ url = (
92
+ "https://api.open-meteo.com/v1/forecast"
93
+ f"?latitude={lats}"
94
+ f"&longitude={lons}"
95
+ "&hourly=relative_humidity_2m,apparent_temperature,temperature_2m,"
96
+ "precipitation_probability,weather_code"
97
+ "&forecast_days=1"
98
  )
99
 
100
+ r = requests.get(url)
101
+ r.raise_for_status()
102
+ return r.json()
103
+
104
+
105
+ def create_weather_body():
106
+ now = datetime.now(JST)
107
+ today_7am = now.replace(hour=7, minute=0, second=0, microsecond=0)
108
+
109
+ todoufuken = load_todoufuken()
110
+ data = fetch_weather(todoufuken)
111
 
112
+ lines = ["<b>☀️ 本日の天気予報(7時以降・1時間ごと)</b>"]
 
113
 
114
+ for idx, pref in enumerate(todoufuken):
115
+ hourly = data[idx]["hourly"]
116
+ times = hourly["time"]
117
 
118
+ lines.append(f"\n<b>{pref['name']}:</b>")
 
119
 
120
+ for i, t in enumerate(times):
121
+ t_jst = (
122
+ datetime.fromisoformat(t)
123
+ .replace(tzinfo=ZoneInfo("UTC"))
124
+ .astimezone(JST)
125
+ )
126
 
127
+ if t_jst < today_7am:
128
+ continue
129
 
130
+ wc = hourly["weather_code"][i]
131
+ at = hourly["apparent_temperature"][i]
132
+ temp = hourly["temperature_2m"][i]
133
+ pop = hourly["precipitation_probability"][i]
134
+ rh = hourly["relative_humidity_2m"][i]
135
 
136
+ wc_str = format_weather_code(wc)
137
+
138
+ line = (
139
+ f" {t_jst.strftime('%H時')}:"
140
+ f"{wc_str} "
141
+ f"{at}℃ {temp}℃ {pop}% {rh}%"
142
+ )
143
+ lines.append(line)
144
+
145
+ return {
146
+ "requestId": f"desk-web-weather-{int(time.time())}",
147
+ "blocks": [{"type": "text", "value": "\n".join(lines)}],
148
+ }
149
 
150
+ # ---------------- メインループ ----------------
151
+
152
+
153
+ def main_loop():
154
  while True:
155
  try:
156
+ now = datetime.now(JST)
157
+
158
+ # 毎正時の時報
159
+ if now.minute == 0:
160
+ body = create_time_signal_body()
161
+ post_group_message(TARGET_GROUP_CHAT_ID, body)
162
+
163
+ # 午後2時9分に天気予報
164
+ if now.hour == 14 and now.minute == 20:
165
+ body = create_weather_body()
166
+ post_group_message(TARGET_GROUP_CHAT_ID, body)
167
+
168
+ time.sleep(60)
169
+
170
  except Exception as e:
171
+ print("Error:", e)
172
+ time.sleep(10)
173
 
174
 
175
  if __name__ == "__main__":
176
+ main_loop()