88 lines
3.7 KiB
Python
Executable File
88 lines
3.7 KiB
Python
Executable File
#!/usr/bin/env python3
|
||
|
||
"""Войти в комнату вайбграма по коду приглашения и получить токен агента.
|
||
|
||
Обычный путь - CLI `vibegram join <code> --nick <ник> --no-hooks` из клона
|
||
репы комнаты. Сторожевой комнате клон не нужен (в ней только строки `hb` и
|
||
`ack`), поэтому здесь тот же вызов хаба напрямую: `POST /api/rooms/join`
|
||
с `joinCode` и `nick`. Ответ печатается целиком - токен из него едет в
|
||
`.env` как `VIBEGRAM_HB_TOKEN`, после чего gateway надо перезапустить.
|
||
|
||
python3 scripts/vibegram_join.py <join-code> --nick <ник>
|
||
python3 scripts/vibegram_join.py <join-code> --hub https://vibegram.example
|
||
|
||
Хаб по умолчанию берётся из `VIBEGRAM_HUB` в окружении или в соседнем `.env`.
|
||
Токен печатается в терминал - не вставляй вывод в чаты и в задачи.
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import argparse
|
||
import json
|
||
import os
|
||
import sys
|
||
import urllib.error
|
||
import urllib.request
|
||
from pathlib import Path
|
||
|
||
ENV = Path(__file__).resolve().parent.parent / ".env"
|
||
USER_AGENT = "beaver-agent/0.1 (+vibegram)"
|
||
|
||
|
||
def hub_from_env() -> str | None:
|
||
if os.environ.get("VIBEGRAM_HUB"):
|
||
return os.environ["VIBEGRAM_HUB"]
|
||
if not ENV.exists():
|
||
return None
|
||
for line in ENV.read_text(encoding="utf-8").splitlines():
|
||
key, _, value = line.partition("=")
|
||
if key.strip() == "VIBEGRAM_HUB" and value.strip():
|
||
return value.strip()
|
||
return None
|
||
|
||
|
||
def main() -> int:
|
||
parser = argparse.ArgumentParser(description=__doc__)
|
||
parser.add_argument("code", help="код приглашения из комнаты")
|
||
parser.add_argument("--nick", help="ник агента в этой комнате")
|
||
parser.add_argument("--hub", default=hub_from_env(), help="адрес хаба вайбграма")
|
||
args = parser.parse_args()
|
||
if not args.hub:
|
||
print("не знаю адрес хаба: задай --hub или VIBEGRAM_HUB", file=sys.stderr)
|
||
return 2
|
||
|
||
body: dict[str, str] = {"joinCode": args.code}
|
||
if args.nick:
|
||
body["nick"] = args.nick
|
||
request = urllib.request.Request( # noqa: S310 - адрес хаба задаёт оператор
|
||
f"{args.hub.rstrip('/')}/api/rooms/join",
|
||
data=json.dumps(body).encode(),
|
||
# Перед хабом Cloudflare: безымянный `Python-urllib` он отбивает 1010.
|
||
# Тот же user-agent, что у клиента в `beaver_agent/hands/vibegram.py`.
|
||
headers={"content-type": "application/json", "user-agent": USER_AGENT},
|
||
method="POST",
|
||
)
|
||
try:
|
||
with urllib.request.urlopen(request, timeout=20) as response: # noqa: S310
|
||
data = json.loads(response.read())
|
||
except urllib.error.HTTPError as exc:
|
||
print(f"хаб отказал: {exc.code} {exc.read().decode()[:400]}", file=sys.stderr)
|
||
return 1
|
||
except OSError as exc:
|
||
print(f"хаб не отвечает: {exc}", file=sys.stderr)
|
||
return 1
|
||
|
||
print(json.dumps(data, ensure_ascii=False, indent=2))
|
||
token = next(
|
||
(data[k] for k in ("token", "agentToken", "apiToken") if data.get(k)), None
|
||
)
|
||
if token:
|
||
print(f"\nVIBEGRAM_HB_TOKEN={token}\n\nдальше: строку в .env, затем рестарт")
|
||
else:
|
||
print("\nтокена в ответе не видно - смотри поля выше", file=sys.stderr)
|
||
return 0
|
||
|
||
|
||
if __name__ == "__main__":
|
||
raise SystemExit(main())
|