"use client"; import { useState } from "react"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { telegramApi } from "@/lib/api"; import { Label } from "@/components/ui/label"; import { Input } from "@/components/ui/input"; import { Button } from "@/components/ui/button"; import { HelpTip } from "@/components/ui/help-tip"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "@/components/ui/alert-dialog"; import { Key, KeyRound, Save } from "lucide-react"; import { toast } from "sonner"; const FIELDS: Array<{ key: "bot_token" | "chat_id"; label: string }> = [ { key: "bot_token", label: "Bot token (from @BotFather)" }, { key: "chat_id", label: "Chat id (destination)" }, ]; // The CEO's one-time entry of the Telegram bot token + destination chat id. // Write-only — the stored values are never displayed back, only whether // they're set (mirrors the X / git-token cards). Both are required together: // a token alone can't target a DM. Rendered chrome-less so it can nest inside // the Telegram feature-flag row. export function TelegramCredentialsForm() { const queryClient = useQueryClient(); const [values, setValues] = useState({ bot_token: "", chat_id: "" }); const { data: status, isLoading } = useQuery({ queryKey: ["telegram", "credentials"], queryFn: () => telegramApi.getCredentialsStatus(), }); const saveMutation = useMutation({ mutationFn: () => telegramApi.setCredentials(values), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["telegram", "credentials"] }); setValues({ bot_token: "", chat_id: "" }); toast.success("Telegram credentials saved"); }, onError: (error) => { toast.error( `Failed to save: ${error instanceof Error ? error.message : "Unknown error"}`, ); }, }); const allFilled = FIELDS.every((f) => values[f.key].trim().length > 0); const noneFilled = FIELDS.every((f) => values[f.key].trim().length === 0); const canSave = allFilled || (noneFilled && !!status?.has_credentials); const isClearing = noneFilled && !!status?.has_credentials; const [confirmClear, setConfirmClear] = useState(false); return (

The bot token from @BotFather and the chat id to DM (your user/channel id). Stored encrypted server-side; agents never see them and this panel never displays them again once saved.

{status?.has_credentials ? ( ) : ( )} {status?.has_credentials ? ( Credentials are set ) : ( {isLoading ? "Checking..." : "No credentials configured"} )}
{FIELDS.map((field) => (
setValues((prev) => ({ ...prev, [field.key]: e.target.value })) } placeholder="••••••••••••" />
))}

Set both to save (or rotate); leave both blank and save to clear.

{ if (!open) setConfirmClear(false); }} > Clear Telegram credentials? This will clear the stored bot token and chat id. This cannot be undone. Cancel { setConfirmClear(false); saveMutation.mutate(); }} > Clear
); }