"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.
Set both to save (or rotate); leave both blank and save to clear.