mirror of
https://github.com/domfelipe/mika-agent-assist.git
synced 2026-08-07 11:36:42 +00:00
140 lines
4.5 KiB
TypeScript
140 lines
4.5 KiB
TypeScript
// configure-telegram-webhook
|
|
// Mantém compatibilidade com o wizard: garante que o webhook do Telegram fique desligado,
|
|
// pois o Hermes responde via polling/runtime.
|
|
|
|
import { createClient } from "https://esm.sh/@supabase/supabase-js@2.57.4";
|
|
import { corsHeaders } from "../_shared/cors.ts";
|
|
import { telegramApi } from "../_shared/telegram.ts";
|
|
|
|
function jsonResponse(body: unknown, status = 200): Response {
|
|
return new Response(JSON.stringify(body), {
|
|
status,
|
|
headers: { ...corsHeaders, "Content-Type": "application/json" },
|
|
});
|
|
}
|
|
|
|
// deno-lint-ignore no-explicit-any
|
|
async function getDecryptedSecret(
|
|
admin: any,
|
|
secretId: string,
|
|
): Promise<string | null> {
|
|
const { data, error } = await admin
|
|
.rpc("vault_decrypt_secret", { secret_id: secretId })
|
|
.single();
|
|
if (!error && data) {
|
|
// deno-lint-ignore no-explicit-any
|
|
return (data as any).decrypted_secret ?? (data as unknown as string);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
Deno.serve(async (req) => {
|
|
if (req.method === "OPTIONS") {
|
|
return new Response(null, { headers: corsHeaders });
|
|
}
|
|
|
|
try {
|
|
const supabaseUrl = Deno.env.get("SUPABASE_URL")!;
|
|
const serviceKey = Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!;
|
|
const anonKey = Deno.env.get("SUPABASE_ANON_KEY")!;
|
|
|
|
const authHeader = req.headers.get("Authorization") ?? "";
|
|
const userClient = createClient(supabaseUrl, anonKey, {
|
|
global: { headers: { Authorization: authHeader } },
|
|
});
|
|
const { data: userData, error: userErr } = await userClient.auth.getUser();
|
|
if (userErr || !userData.user) {
|
|
return jsonResponse({ error: "Não autenticado" }, 401);
|
|
}
|
|
const userId = userData.user.id;
|
|
|
|
const admin = createClient(supabaseUrl, serviceKey);
|
|
|
|
const { data: agent, error: agentErr } = await admin
|
|
.from("agent_instances")
|
|
.select("id, uuid_tenant, telegram_bot_token_vault_id, status")
|
|
.eq("user_id", userId)
|
|
.maybeSingle();
|
|
|
|
if (agentErr || !agent) {
|
|
return jsonResponse({ error: "Agente não encontrado." }, 404);
|
|
}
|
|
if (!agent.telegram_bot_token_vault_id) {
|
|
return jsonResponse(
|
|
{ error: "Conecte um bot antes de configurar o webhook." },
|
|
400,
|
|
);
|
|
}
|
|
|
|
const token = await getDecryptedSecret(admin, agent.telegram_bot_token_vault_id);
|
|
if (!token) {
|
|
return jsonResponse(
|
|
{ error: "Token corrompido. Desconecte e reconecte o bot." },
|
|
500,
|
|
);
|
|
}
|
|
|
|
const deleteRes = await telegramApi(token, "deleteWebhook", {
|
|
drop_pending_updates: false,
|
|
});
|
|
|
|
if (!deleteRes.ok) {
|
|
console.error("deleteWebhook failed", deleteRes);
|
|
return jsonResponse(
|
|
{ error: "Falha ao liberar o Telegram para o runtime do agente." },
|
|
500,
|
|
);
|
|
}
|
|
|
|
const { error: updErr } = await admin
|
|
.from("agent_instances")
|
|
.update({
|
|
telegram_webhook_secret: null,
|
|
telegram_webhook_configured: false,
|
|
updated_at: new Date().toISOString(),
|
|
})
|
|
.eq("id", agent.id);
|
|
|
|
if (updErr) {
|
|
console.error("agent update error", updErr);
|
|
return jsonResponse({ error: "Webhook configurado, mas falha ao salvar." }, 500);
|
|
}
|
|
|
|
// Auto-provisionamento: agora que temos token + webhook, disparamos provision-agent
|
|
// de forma assíncrona. Não bloqueamos a resposta — falhas são tratadas via retry/admin.
|
|
if (agent.status === "provisioning") {
|
|
try {
|
|
const provisionUrl = `${supabaseUrl}/functions/v1/provision-agent`;
|
|
console.log(
|
|
`auto-provision: disparando para agent ${agent.id} (user ${userId})`,
|
|
);
|
|
// Fire-and-forget: não fazemos await para não bloquear o cliente
|
|
fetch(provisionUrl, {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
Authorization: `Bearer ${serviceKey}`,
|
|
"X-Internal-Secret": Deno.env.get("INTERNAL_FUNCTION_SECRET") ?? "",
|
|
},
|
|
body: JSON.stringify({
|
|
agent_instance_id: agent.id,
|
|
user_id: userId,
|
|
}),
|
|
}).catch((err) =>
|
|
console.error("auto-provision fetch error:", err)
|
|
);
|
|
} catch (err) {
|
|
console.error("auto-provision trigger error:", err);
|
|
// Não re-throw — wizard do Telegram deve retornar sucesso mesmo se provision falhar
|
|
}
|
|
}
|
|
|
|
return jsonResponse({ success: true });
|
|
} catch (err) {
|
|
console.error("configure-telegram-webhook fatal", err);
|
|
return jsonResponse(
|
|
{ error: err instanceof Error ? err.message : "Erro inesperado" },
|
|
500,
|
|
);
|
|
}
|
|
});
|