any-env-code / join.py
izuemon's picture
Update join.py
2db2628 verified
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import time
import requests
from typing import List, Dict, Any, Optional
# ===== 設定 =====
X_ACCOUNT = os.getenv("dmsendertoken")
if not X_ACCOUNT:
raise RuntimeError("環境変数 dmsendertoken が設定されていません")
BASE = "https://desk-api.channel.io/desk/channels/200605"
GROUP_ID = 463667
CHECK_PERSON_ID = "614601"
# accountIdベースのブラックリスト
BLACKLIST_ACCOUNT_IDS = ["476793", "486092", "471246"]
HEADERS = {
"accept": "application/json",
"accept-language": "ja",
"content-type": "application/json",
"x-account": X_ACCOUNT,
}
GET_PARAMS = {
"sortOrder": "desc",
"limit": 34,
"logFolded": "false",
}
WELCOME_TEMPLATE = """
こんにちは。ITRSAにようこそ。
自動でいくつかの部屋に招待しています。
<b>使い方:</b>
左側のメニューから、部屋(グループ)を開くことができます。
・「あいてぃーあーるえすえい」は本部で、雑談などをする部屋です。
・「Youtubeダウンローダー」は、URLを送ると自動でYoutubeをダウンロードしてくれる部屋です。
・「チャッピーくん」は、ChatGPTと話せる部屋です。
・「幹部と裁判所からの報告」はここを管理する幹部や裁判所から通知が来る部屋です。この部屋は基本的に抜けないでください。
"""
INVITE_GROUPS = [
519217,
536194,
534868,
521995,
530062,
517180,
524837
]
# ===== API =====
def get_messages() -> List[Dict[str, Any]]:
url = f"{BASE}/groups/{GROUP_ID}/messages"
r = requests.get(url, headers=HEADERS, params=GET_PARAMS, timeout=20)
r.raise_for_status()
return r.json().get("messages", [])
def get_group_titles() -> Dict[int, str]:
url = f"{BASE}/groups?limit=1000"
response = requests.get(url, headers=HEADERS, timeout=20)
response.raise_for_status()
groups = response.json().get("groups", [])
return {
group.get("id"): group.get("title")
for group in groups
if "id" in group and "title" in group
}
def get_manager_account_id(person_id: str) -> Optional[str]:
"""
personId を使って managers API を取得し、
managers[0].accountId を返す
"""
url = f"{BASE}/managers"
params = {
"limit": 1,
"since": person_id
}
r = requests.get(url, headers=HEADERS, params=params, timeout=20)
r.raise_for_status()
data = r.json()
managers = data.get("managers", [])
if not managers:
return None
return str(managers[0].get("accountId"))
def blacklist_manager(person_id: str) -> None:
"""
personId を使って manager を削除
"""
url = f"{BASE}/managers/{person_id}"
requests.delete(url, headers=HEADERS, timeout=20).raise_for_status()
payload = {
"requestId": f"desk-web-{int(time.time() * 1000)}",
"blocks": [
{"type": "text", "value": "さようなら。"}
]
}
url = f"{BASE}/groups/{GROUP_ID}/messages"
requests.post(url, headers=HEADERS, json=payload, timeout=20).raise_for_status()
print(f"[INFO] personId={person_id} を削除しました")
def post_welcome_message() -> None:
TITLES = get_group_titles()
welcome_text = WELCOME_TEMPLATE.format(
hq=TITLES.get(532214, "本部")
)
url = f"{BASE}/groups/{GROUP_ID}/messages"
payload = {
"requestId": f"desk-web-{int(time.time() * 1000)}",
"blocks": [
{"type": "text", "value": welcome_text}
]
}
requests.post(url, headers=HEADERS, json=payload, timeout=20).raise_for_status()
print("[INFO] 歓迎メッセージを送信しました")
def invite_person(group_id: int, person_id: str) -> None:
url = f"{BASE}/groups/{group_id}/invite"
params = {"managerIds": person_id}
requests.post(url, headers=HEADERS, params=params, timeout=20).raise_for_status()
print(f"[INFO] personId={person_id} を group {group_id} に招待しました")
# ===== ロジック =====
def process():
messages = get_messages()
# CHECK_PERSON_ID の最新発言時刻
latest_check_person = max(
(int(m.get("createdAt", 0))
for m in messages
if str(m.get("personId")) == CHECK_PERSON_ID),
default=0
)
join_targets = []
for m in messages:
log = m.get("log") or {}
if log.get("action") != "join":
continue
created_at = int(m.get("createdAt", 0))
person_id = str(m.get("personId", ""))
# ===== ここを追加 =====
# CHECK_PERSON_ID の最新発言より前なら無視
if created_at <= latest_check_person:
continue
# ===== ブラックリスト判定(accountIdベース)=====
try:
account_id = get_manager_account_id(person_id)
except Exception as e:
print(f"[ERROR] manager取得失敗 personId={person_id} : {e}")
continue
if account_id and account_id in BLACKLIST_ACCOUNT_IDS:
try:
blacklist_manager(person_id)
except Exception as e:
print(f"[ERROR] 削除失敗 personId={person_id} : {e}")
continue
# ===== 通常処理 =====
join_targets.append(person_id)
if not join_targets:
return
join_targets = list(set(join_targets))
# 歓迎メッセージは1回だけ
post_welcome_message()
# 招待処理
for pid in join_targets:
for gid in INVITE_GROUPS:
try:
invite_person(gid, pid)
except Exception as e:
print(f"[ERROR] 招待失敗 personId={pid} group={gid} : {e}")
def main():
print("[INFO] Bot 起動(10秒間隔)")
while True:
try:
process()
except Exception as e:
print(f"[ERROR] {e}")
time.sleep(10)
if __name__ == "__main__":
main()