izuemon commited on
Commit
4de97a6
·
verified ·
1 Parent(s): 2db2628

Create orion-server/join.py

Browse files
Files changed (1) hide show
  1. orion-server/join.py +205 -0
orion-server/join.py ADDED
@@ -0,0 +1,205 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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, Optional
8
+
9
+ # ===== 設定 =====
10
+ X_ACCOUNT = os.getenv("orionchanneltalktoken")
11
+ if not X_ACCOUNT:
12
+ raise RuntimeError("環境変数 orionchanneltalktoken が設定されていません")
13
+
14
+ BASE = "https://desk-api.channel.io/desk/channels/232082"
15
+ GROUP_ID = 548829
16
+ CHECK_PERSON_ID = "619110"
17
+
18
+ # accountIdベースのブラックリスト
19
+ BLACKLIST_ACCOUNT_IDS = []
20
+
21
+ HEADERS = {
22
+ "accept": "application/json",
23
+ "accept-language": "ja",
24
+ "content-type": "application/json",
25
+ "x-account": X_ACCOUNT,
26
+ }
27
+
28
+ GET_PARAMS = {
29
+ "sortOrder": "desc",
30
+ "limit": 34,
31
+ "logFolded": "false",
32
+ }
33
+
34
+ WELCOME_TEMPLATE = """
35
+ こんにちは。おりおんるーむにようこそ。
36
+ 自動でいくつかの部屋に招待しています。
37
+ """
38
+
39
+ INVITE_GROUPS = [
40
+ 548834,
41
+ 548832,
42
+ 548833
43
+ ]
44
+
45
+ # ===== API =====
46
+
47
+ def get_messages() -> List[Dict[str, Any]]:
48
+ url = f"{BASE}/groups/{GROUP_ID}/messages"
49
+ r = requests.get(url, headers=HEADERS, params=GET_PARAMS, timeout=20)
50
+ r.raise_for_status()
51
+ return r.json().get("messages", [])
52
+
53
+
54
+ def get_group_titles() -> Dict[int, str]:
55
+ url = f"{BASE}/groups?limit=1000"
56
+ response = requests.get(url, headers=HEADERS, timeout=20)
57
+ response.raise_for_status()
58
+
59
+ groups = response.json().get("groups", [])
60
+ return {
61
+ group.get("id"): group.get("title")
62
+ for group in groups
63
+ if "id" in group and "title" in group
64
+ }
65
+
66
+
67
+ def get_manager_account_id(person_id: str) -> Optional[str]:
68
+ """
69
+ personId を使って managers API を取得し、
70
+ managers[0].accountId を返す
71
+ """
72
+ url = f"{BASE}/managers"
73
+ params = {
74
+ "limit": 1,
75
+ "since": person_id
76
+ }
77
+
78
+ r = requests.get(url, headers=HEADERS, params=params, timeout=20)
79
+ r.raise_for_status()
80
+
81
+ data = r.json()
82
+ managers = data.get("managers", [])
83
+
84
+ if not managers:
85
+ return None
86
+
87
+ return str(managers[0].get("accountId"))
88
+
89
+
90
+ def blacklist_manager(person_id: str) -> None:
91
+ """
92
+ personId を使って manager を削除
93
+ """
94
+ url = f"{BASE}/managers/{person_id}"
95
+ requests.delete(url, headers=HEADERS, timeout=20).raise_for_status()
96
+ payload = {
97
+ "requestId": f"desk-web-{int(time.time() * 1000)}",
98
+ "blocks": [
99
+ {"type": "text", "value": "さようなら。"}
100
+ ]
101
+ }
102
+ url = f"{BASE}/groups/{GROUP_ID}/messages"
103
+ requests.post(url, headers=HEADERS, json=payload, timeout=20).raise_for_status()
104
+ print(f"[INFO] personId={person_id} を削除しました")
105
+
106
+
107
+ def post_welcome_message() -> None:
108
+ TITLES = get_group_titles()
109
+
110
+ welcome_text = WELCOME_TEMPLATE.format(
111
+ hq=TITLES.get(532214, "本部")
112
+ )
113
+
114
+ url = f"{BASE}/groups/{GROUP_ID}/messages"
115
+ payload = {
116
+ "requestId": f"desk-web-{int(time.time() * 1000)}",
117
+ "blocks": [
118
+ {"type": "text", "value": welcome_text}
119
+ ]
120
+ }
121
+
122
+ requests.post(url, headers=HEADERS, json=payload, timeout=20).raise_for_status()
123
+ print("[INFO] 歓迎メッセージを送信しました")
124
+
125
+
126
+ def invite_person(group_id: int, person_id: str) -> None:
127
+ url = f"{BASE}/groups/{group_id}/invite"
128
+ params = {"managerIds": person_id}
129
+ requests.post(url, headers=HEADERS, params=params, timeout=20).raise_for_status()
130
+ print(f"[INFO] personId={person_id} を group {group_id} に招待しました")
131
+
132
+
133
+ # ===== ロジック =====
134
+
135
+ def process():
136
+ messages = get_messages()
137
+
138
+ # CHECK_PERSON_ID の最新発言時刻
139
+ latest_check_person = max(
140
+ (int(m.get("createdAt", 0))
141
+ for m in messages
142
+ if str(m.get("personId")) == CHECK_PERSON_ID),
143
+ default=0
144
+ )
145
+
146
+ join_targets = []
147
+
148
+ for m in messages:
149
+ log = m.get("log") or {}
150
+ if log.get("action") != "join":
151
+ continue
152
+
153
+ created_at = int(m.get("createdAt", 0))
154
+ person_id = str(m.get("personId", ""))
155
+
156
+ # ===== ここを追加 =====
157
+ # CHECK_PERSON_ID の最新発言より前なら無視
158
+ if created_at <= latest_check_person:
159
+ continue
160
+
161
+ # ===== ブラックリスト判定(accountIdベース)=====
162
+ try:
163
+ account_id = get_manager_account_id(person_id)
164
+ except Exception as e:
165
+ print(f"[ERROR] manager取得失敗 personId={person_id} : {e}")
166
+ continue
167
+
168
+ if account_id and account_id in BLACKLIST_ACCOUNT_IDS:
169
+ try:
170
+ blacklist_manager(person_id)
171
+ except Exception as e:
172
+ print(f"[ERROR] 削除失敗 personId={person_id} : {e}")
173
+ continue
174
+
175
+ # ===== 通常処理 =====
176
+ join_targets.append(person_id)
177
+ if not join_targets:
178
+ return
179
+
180
+ join_targets = list(set(join_targets))
181
+
182
+ # 歓迎メッセージは1回���け
183
+ post_welcome_message()
184
+
185
+ # 招待処理
186
+ for pid in join_targets:
187
+ for gid in INVITE_GROUPS:
188
+ try:
189
+ invite_person(gid, pid)
190
+ except Exception as e:
191
+ print(f"[ERROR] 招待失敗 personId={pid} group={gid} : {e}")
192
+
193
+
194
+ def main():
195
+ print("[INFO] Bot 起動(10秒間隔)")
196
+ while True:
197
+ try:
198
+ process()
199
+ except Exception as e:
200
+ print(f"[ERROR] {e}")
201
+ time.sleep(10)
202
+
203
+
204
+ if __name__ == "__main__":
205
+ main()