izuemon commited on
Commit
af09506
·
verified ·
1 Parent(s): 8adbc35

Update jihou.py

Browse files
Files changed (1) hide show
  1. jihou.py +77 -138
jihou.py CHANGED
@@ -1,176 +1,115 @@
 
 
 
 
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()
 
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()