6.7 KiB
Ajouter un nouveau bot
Trois cas selon ce que tu veux faire.
Cas 1 — Envoi seul (Cowork → Telegram, pas d'interaction)
Le gateway n'est pas nécessaire. Une session Cowork qui envoie juste des notifications appelle directement la Bot API.
Setup une fois (humain) :
- @BotFather →
/newbot→ noter le token - Trouver ton chat_id via @userinfobot ou en messageant le bot et en regardant
getUpdates
Prompt à donner à la session Cowork :
Tu peux envoyer une notification Telegram via :
curl -sS -X POST "https://api.telegram.org/bot$BOT_TOKEN/sendMessage" \
-H 'Content-Type: application/json' \
-d '{"chat_id":<CHAT_ID>,"text":"<message>"}'
Variables :
BOT_TOKEN=<token-botfather> # à fournir en env ou en clair
CHAT_ID=<ton-chat-id-numerique>
Pas besoin du gateway pour de l'envoi pur. Préfère cette voie quand
la session n'a rien à recevoir en retour.
Cas 2 — Bot echo simple via le gateway (Phase 1, gated par auth)
Utile pour valider la chaîne, créer un canal de log conversationnel, etc.
Auth (Phase 1.5, ADR 20260509) : par défaut,
requireAuth: trues'applique → tout user qui DM ce bot doit d'abord ouvrir une session via/auth <code>chez@arcodange_factory_bot. VoirAUTH.md. Pour rendre un bot public, ajouter explicitementrequireAuth: false.
Steps (humain ou session Claude avec accès au cluster + au repo) :
-
@BotFather crée le bot, noter le TOKEN.
TOKEN='1234:AAA...' SLUG='monbot' # kebab-case, [a-z0-9-]+ ENV_SLUG=$(echo "$SLUG" | tr 'a-z-' 'A-Z_') # ex: monbot → MONBOT SECRET=$(openssl rand -hex 32) -
Patcher le Secret cluster (ajoute les 2 clés sans toucher aux existantes) :
kubectl -n telegram-gateway patch secret telegram-gateway-bots --type=json -p="[ {\"op\":\"add\",\"path\":\"/data/BOT_${ENV_SLUG}_TOKEN\",\"value\":\"$(echo -n "$TOKEN" | base64)\"}, {\"op\":\"add\",\"path\":\"/data/BOT_${ENV_SLUG}_SECRET\",\"value\":\"$(echo -n "$SECRET" | base64)\"} ]" -
Déclarer le bot dans
chart/values.yamlsousbots::bots: monbot: handler: echo # requireAuth: true (implicite — défaut sécurisé)Pour un bot public (notifications status, etc.), opt-out explicite :
bots: statusbot: handler: echo requireAuth: false -
Push + rollout :
cd /Users/gabrielradureau/Work/Vibe/telegram-gateway git add chart/values.yaml git commit -m "bots: add $SLUG" git push kubectl -n telegram-gateway rollout restart deploy/telegram-gateway kubectl -n telegram-gateway rollout status deploy/telegram-gateway -
Enregistrer le webhook côté Telegram :
export BOT_${ENV_SLUG}_TOKEN="$TOKEN" export BOT_${ENV_SLUG}_SECRET="$SECRET" make setwebhook SLUG="$SLUG" BASE_URL=https://tg.arcodange.fr -
Test :
- Si
requireAuthest laissé à true : envoie un message → réponse🔒 /auth chez @arcodange_factory_bot; fais/auth <code>chez factory ; renvoie un message → echo en < 2 s. - Si
requireAuth: false: echo direct en < 2 s.
- Si
Limite handler echo : tous les bots echo répondent toujours pareil. Pour de la logique métier, voir Cas 2.5 (HTTP forward) ou Cas 3 (agent async).
Cas 2.5 — Bot piloté par un service interne via HTTP forward (Phase 2a, livré)
Cible : un service du cluster (par ex. webapp, ou un mini-service Go/Python dédié) reçoit l'Update Telegram complet en POST JSON, traite sa logique, renvoie {"text": "<reply>"}. Le gateway envoie text au user.
Sync : le webhook ack attend la réponse (timeout par défaut 5 s, plafond 30 s — Telegram coupe vers 60 s). Pour des backends lents, voir Cas 3.
Setup côté gateway (suit Cas 2 pour le bot Telegram + le Secret) puis :
-
Déclarer le bot avec
handler: httpdanschart/values.yaml:bots: webappbot: handler: http http: url: http://webapp.webapp.svc.cluster.local:8080/telegram/update timeout: 5s # requireAuth: true (implicite — défaut sécurisé) -
Côté service interne, exposer un endpoint qui :
- Accepte
POST <url>avec un body = JSON TelegramUpdate(champs :update_id,message.text,message.from.id,message.chat.id, etc.) - Lit le header
X-Bot-Slug: <slug>pour distinguer plusieurs bots qui forwarderaient au même service - Renvoie
200 {"text": "réponse au user"}(ou200body vide si pas de réponse à envoyer) - Respecte le timeout configuré (le gateway coupe à
timeout)
- Accepte
-
Push values.yaml + rollout comme dans Cas 2.
Exemple minimal de upstream service (Go) :
http.HandleFunc("/telegram/update", func(w http.ResponseWriter, r *http.Request) {
var u struct {
Message struct {
Text string `json:"text"`
From struct{ ID int64 `json:"id"` } `json:"from"`
} `json:"message"`
}
json.NewDecoder(r.Body).Decode(&u)
reply := fmt.Sprintf("hello user %d, you said: %s", u.Message.From.ID, u.Message.Text)
json.NewEncoder(w).Encode(map[string]string{"text": reply})
})
Cas 3 — Bot interactif piloté par un agent async (Phase 3, pas encore livré)
Cible : utilisateur DM le bot → gateway enqueue le job → worker async exécute un wrapper shell (ex. claude --print, mistral-vibe, ou un script Python qui appelle Ollama) → la réponse est renvoyée via Telegram, même si le backend (Macbook Ollama) dort au moment du DM (retry exponentiel jusqu'à 1 h).
Pour l'instant non supporté. Requiert :
- Phase 2b (queue Postgres + worker — fondation async)
- Phase 3 (handlers
shell/script/ollama+ WoL Macbook optionnel)
Quand Phase 3 sera up, l'ajout d'un tel bot sera : steps Cas 2 + handler shell/script/ollama au lieu d'echo, plus la commande/script à exécuter.
Plan complet : ~/.claude/plans/pour-les-notifications-on-inherited-seal.md.
Récap : quel cas choisir ?
| Besoin | Cas | État | Gateway impliqué ? |
|---|---|---|---|
| Notifs sortantes one-way (Cowork → user) | Cas 1 | livré | non, Bot API directe |
| Bot qui répond toujours pareil (echo, ack, ping) | Cas 2 | livré (Phase 1) | oui |
| Bot piloté par un service interne du cluster (webapp, mini-service custom) | Cas 2.5 | livré (Phase 2a) | oui |
| Bot conversationnel piloté par agent async (Claude / Mistral / Ollama / script, retry si backend dort) | Cas 3 | futur (Phase 3) | oui |