Connecter Claude à Telegram Business — réponses IA supervisées
Une architecture qui marche pour router votre inbox Telegram Business via Claude, avec l'utilisateur fermement dans la boucle. Code, prompts, coûts, et quoi faire quand Claude se trompe.
La killer feature de Telegram Business en 2026 ce n’est pas le widget heures d’ouverture ou le message d’absence. C’est le bot que vous connectez à votre compte personnel — et le moment où ce bot commence à drafter de bonnes réponses, vous tournez une opération solo qui scale comme une équipe de cinq.
Ce guide construit ce bot, proprement. Claude comme cerveau. Vous comme éditeur. Pas d’auto-send.
Ce que vous allez construire
Un bot connecté à votre compte Business qui :
- Surveille chaque message entrant à votre compte.
- Demande à Claude de drafter une réponse dans votre voix.
- Poste le draft dans un channel privé que vous contrôlez (“Drafts”).
- Vous laisse taper Send ou Edit dans ce channel ; le bot envoie ensuite depuis votre compte.
Claude ne parle jamais directement. Vous signez toujours.
Architecture
[DM client] → [Votre compte Telegram] → [Webhook Telegram Business]
↓
[Votre serveur bot]
↓ ↓
[API Claude] [DB historique conversations]
↓
[Channel Drafts] ← vous approuvez
↓
[Bot envoie comme vous] → [Client]
Trois composants : un webhook, un appel LLM avec contexte, et une boucle d’approbation. Construisons chacun.
Provisionner le bot et le connecter à votre compte
- Créez un bot via @BotFather (
/newbot). - Dans Telegram, Settings → Telegram Business → Chatbots. Collez le
@usernamede votre bot. Accordez Read incoming messages + Reply on your behalf. - Dans le code de votre bot, écoutez les updates
business_connectionpour savoir quand vous avez été connecté, et stockez lebusiness_connection_idrésultant — vous en aurez besoin sur chaque réponse sortante.
// pseudo-code; pickez votre framework préféré
bot.on("business_connection", async (update) => {
await db.businessConnection.upsert({
where: { userId: update.user.id },
update: { id: update.id, can_reply: update.can_reply },
create: { id: update.id, userId: update.user.id, can_reply: update.can_reply },
});
}); core.telegram.org Référence Business Connection ↗ Capturer les messages entrants
Telegram envoie un update business_message quand quelqu’un DM votre compte. La shape est identique à un message régulier, avec un business_connection_id extra.
bot.on("business_message", async (update) => {
const msg = update.business_message;
await db.message.create({
data: {
direction: "in",
chatId: msg.chat.id,
fromUserId: msg.from.id,
text: msg.text,
receivedAt: new Date(msg.date * 1000),
businessConnectionId: update.business_connection_id,
},
});
await draftReply(msg);
});Le chat.id est l’id user du client. Stocker le thread de conversation key sur ça est le modèle le plus simple.
Construire le prompt
Claude a besoin de trois choses pour bien drafter : qui vous êtes, ce que vous avez déjà dit, et ce qui vient d’arriver.
async function draftReply(incomingMsg) {
const history = await db.message.findMany({
where: { chatId: incomingMsg.chat.id },
orderBy: { receivedAt: "desc" },
take: 20,
});
const conversation = history.reverse().map((m) => ({
role: m.direction === "in" ? "user" : "assistant",
content: m.text,
}));
const draft = await anthropic.messages.create({
model: "claude-sonnet-4-6",
max_tokens: 600,
system: SYSTEM_PROMPT,
messages: [
...conversation,
{ role: "user", content: incomingMsg.text },
],
});
return draft.content[0].text;
}Le system prompt est où la majeure partie du travail se passe. Gardez-le court, spécifique, et fermement dans votre voix :
Vous draftez les réponses DM Telegram pour le compte de {your_name}, un {your_role}.
Voix : chaleureuse, concise, jamais gushing. "i" minuscule pour "I" seulement
quand l'humain à qui vous répondez le fait d'abord.
Règles :
- Répondre dans la même langue que le message entrant.
- Si le message demande un prix, liez vers /pricing plutôt que de quoter
(l'humain ajustera).
- Ne jamais promettre des heures de calendrier. Suggérer "plus tard cette semaine"
et laisser l'humain s'engager.
- Si le message est unclear, posez une question clarifiante.
- Si le message est hostile ou spam, draftez un one-liner poli
fermant le thread.
- Maximum 4 phrases sauf si l'utilisateur demande du détail.Itérez sur ce prompt deux semaines. C’est la différence entre des drafts que vous shippez 90% du temps vs 30%.
Poster le draft pour approbation
Créez un channel privé dans votre compte (“Drafts”). Ajoutez votre bot comme admin. Chaque draft poste là comme un message avec deux boutons inline : Send et Edit.
async function postDraftForApproval(incomingMsg, draftText) {
await bot.api.sendMessage(DRAFTS_CHANNEL_ID, formatPreview(incomingMsg, draftText), {
reply_markup: {
inline_keyboard: [[
{ text: "✓ Send", callback_data: `send:${incomingMsg.chat.id}:${draftId}` },
{ text: "✎ Edit", callback_data: `edit:${incomingMsg.chat.id}:${draftId}` },
]],
},
});
}
function formatPreview(incomingMsg, draftText) {
return `*De* ${incomingMsg.from.first_name} (@${incomingMsg.from.username || "—"})
> ${incomingMsg.text}
---
*Draft :*
${draftText}`;
}Le channel Drafts devient votre file matinale. Skim, tap Send sur ce qui est juste, Edit sur ce qui ne l’est pas.
Envoyer la réponse approuvée comme vous
Sur callback, votre bot utilise le business_connection_id stocké pour envoyer la réponse en votre nom :
bot.on("callback_query", async (cq) => {
const [action, chatId, draftId] = cq.data.split(":");
const draft = await db.draft.findUnique({ where: { id: draftId } });
const conn = await db.businessConnection.findFirst();
if (action === "send") {
await bot.api.sendMessage(Number(chatId), draft.text, {
business_connection_id: conn.id,
});
await db.message.create({
data: { direction: "out", chatId: Number(chatId), text: draft.text, sentAt: new Date() },
});
await bot.api.editMessageText(DRAFTS_CHANNEL_ID, cq.message.message_id, "✓ Sent: " + draft.text);
}
await bot.api.answerCallbackQuery(cq.id);
});business_connection_id est ce qui dit à Telegram “ce message vient du compte de l’utilisateur, pas du bot”. Sans ça, le client voit la réponse de votre bot, pas de vous — relation entièrement différente.
Gérer Edit gracefully
Tap Edit → bot envoie le draft text back dans le channel Drafts comme un message normal avec un force_reply pour que vous puissiez éditer et répondre. Votre réponse devient le nouveau draft. Tap Send sur la version éditée.
Un flow deux-taps pour le cas commun (c’est bien), trois taps pour le cas edit (c’est pas parfait, à fixer).
Économie des coûts
Par draft, avec Claude Sonnet 4.6 au pricing actuel :
- Input tokens : ~800 (system + 20-msg history + nouveau message) : 0,0024 $
- Output tokens : ~250 (le draft) : 0,0038 $
- Coût par draft : ~0,006 $
100 drafts par jour = 0,60 $/jour = 18 $/mois. Pour un business solo c’est ~30 minutes de typing économisé par jour.
Si vous restez sur Sonnet 4.6 pendant un an : 216 $. Si vous migrez vers Haiku 4.5 pour les drafts routiniers et n’invoquez Sonnet que sur messages flaggés, divisez par deux.
Ce qui foire
- Claude est trop verbeux. Ajoutez
Maximum 4 sentencesau system prompt. AjoutezSentences must average under 16 words.Itérez. - Claude invente des faits sur votre offering. Déplacez pricing/calendrier/policy dans une Quick Reply, pas dans le contexte de Claude. Faites Claude liker plutôt que quoter.
- Claude ne peut pas voir les attachments. Telegram livre média + caption. Passez la caption à Claude avec une note “[user sent image]”. Pour vraie compréhension d’image, routez via les endpoints vision de Claude.
- Deux clients vous DM la même chose simultanément. Lock per-chat dans votre handler. Sinon les deux drafts postent dans le channel en même temps et vous mis-tappez.
- Le channel Drafts devient bruyant. Ajoutez un filtre topic (“ne poster que les drafts pour messages de non-contacts” ou “seulement quand la conversation est plus vieille que 24h”) pour garder le volume sain.
Privacy : dites-le aux gens
Votre Quick Reply /welcome devrait disclose : “Un assistant draft mes réponses pour que je review avant l’envoi.” Certains apprécieront la transparence. Ceux qui ne l’apprécient pas n’allaient jamais convertir de toute façon.
Quand graduer vers auto-send
Trackez le taux d’approbation par catégorie (en utilisant Claude lui-même pour tag les messages : pricing, scheduling, support, sales, hostile, autre). Quand une catégorie est >95% approval rate sur 100 messages, vous pouvez flip auto-send pour cette catégorie — laissez un trigger de review manuelle pour les outliers.
Les deux catégories qui auto-sendent safely d’abord : acknowledgements de greeting et réponses link-only (“voici la page pricing : …”). Les deux qui ne le font quasi jamais : négociation de pricing et refunds.
À lire ensuite
Paiements bot, de bout en bout
Un guide sans raccourci pour accepter les paiements via un bot Telegram — Stars pour digital, fiat pour physique, refunds, webhooks, et les pièges que personne ne documente.
Channels vs groupes vs bots vs Mini Apps — quoi utiliser quand
Un guide de décision simple pour les nouveaux utilisateurs Telegram : les quatre surfaces principales, à quoi sert chacune, et comment picker la bonne en toute situation.
Les Mini Apps qui ont gagné (et celles qui gagnent encore) — T2 2026
Une tournée éditoriale opinionnée des Mini Apps Telegram qui méritent vraiment l'attention en 2026 — survivants post-airdrop, nouvelles catégories, et les boring-essentials dont personne ne parle.