feat: add telegram growth broadcast
All checks were successful
CI and Production Smoke / smoke (push) Successful in 6s
All checks were successful
CI and Production Smoke / smoke (push) Successful in 6s
This commit is contained in:
@@ -5,6 +5,22 @@ import { cronUnauthorizedResponse, isCronRequestAuthorized } from "@/lib/cron-au
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
const TELEGRAM_BOT_TOKEN = (
|
||||
process.env.TELEGRAM_BOT_TOKEN ||
|
||||
process.env.VIBEWORKAIAGENTBOT_TOKEN ||
|
||||
process.env.VIBEWORK_AI_BOT_TOKEN
|
||||
)?.trim();
|
||||
const TELEGRAM_CHAT_ID = (
|
||||
process.env.A2A_GROWTH_TELEGRAM_CHAT_ID ||
|
||||
process.env.TELEGRAM_CHAT_ID ||
|
||||
process.env.VIBEWORKAIAGENTBOT_CHAT_ID ||
|
||||
process.env.VIBEWORK_AI_BOT_CHAT_ID
|
||||
)?.trim();
|
||||
const TELEGRAM_BROADCAST_DEDUPE_MINUTES = Math.max(
|
||||
5,
|
||||
Number.parseInt(process.env.A2A_GROWTH_TELEGRAM_DEDUPE_MINUTES || "60", 10) || 60
|
||||
);
|
||||
|
||||
type ContactEndpoints = {
|
||||
webhook?: unknown;
|
||||
growth_webhook?: unknown;
|
||||
@@ -67,11 +83,116 @@ async function notifyExternalAgent(params: {
|
||||
};
|
||||
}
|
||||
|
||||
function wantsTelegramBroadcast(request: Request) {
|
||||
const url = new URL(request.url);
|
||||
return (
|
||||
url.searchParams.get("broadcast") === "telegram" ||
|
||||
process.env.A2A_GROWTH_ENABLE_TELEGRAM === "true"
|
||||
);
|
||||
}
|
||||
|
||||
async function sendTelegramMessage(text: string) {
|
||||
if (!TELEGRAM_BOT_TOKEN || !TELEGRAM_CHAT_ID) {
|
||||
return {
|
||||
attempted: false as const,
|
||||
reason: "telegram_not_configured",
|
||||
};
|
||||
}
|
||||
|
||||
const response = await fetch(`https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage`, {
|
||||
method: "POST",
|
||||
headers: { "content-type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
chat_id: TELEGRAM_CHAT_ID,
|
||||
text,
|
||||
disable_web_page_preview: false,
|
||||
}),
|
||||
});
|
||||
const data = await response.json().catch(() => ({}));
|
||||
|
||||
return {
|
||||
attempted: true as const,
|
||||
ok: response.ok,
|
||||
status: response.status,
|
||||
telegram_ok: Boolean((data as { ok?: unknown }).ok),
|
||||
};
|
||||
}
|
||||
|
||||
async function broadcastTelegramGrowthCampaign(request: Request) {
|
||||
if (!wantsTelegramBroadcast(request)) {
|
||||
return {
|
||||
attempted: false as const,
|
||||
reason: "not_requested",
|
||||
};
|
||||
}
|
||||
|
||||
const url = new URL(request.url);
|
||||
const force = url.searchParams.get("force") === "true";
|
||||
const since = new Date(Date.now() - TELEGRAM_BROADCAST_DEDUPE_MINUTES * 60 * 1000);
|
||||
const existing = force
|
||||
? null
|
||||
: await prisma.auditEvent.findFirst({
|
||||
where: {
|
||||
action: "A2A_INTERNAL_GROWTH_TELEGRAM_BROADCAST",
|
||||
createdAt: { gte: since },
|
||||
},
|
||||
orderBy: { createdAt: "desc" },
|
||||
select: { id: true, createdAt: true },
|
||||
});
|
||||
|
||||
if (existing) {
|
||||
return {
|
||||
attempted: false as const,
|
||||
reason: "deduped",
|
||||
last_broadcast_at: existing.createdAt.toISOString(),
|
||||
};
|
||||
}
|
||||
|
||||
const kit = buildAgentGrowthKit({
|
||||
agentId: "vibeaiagent-telegram",
|
||||
campaign: "a2a-agent-referral",
|
||||
source: "telegram",
|
||||
});
|
||||
const text = [
|
||||
"VibeWork A2A paid intake is live.",
|
||||
"任務:外部 AI Agent 請把有預算的人類需求方導到 VibeWork,不要自行收款或蒐集密碼/私鑰。",
|
||||
"預設 Scout Intake:29 USDC,Base USDC 直入 Treasury。",
|
||||
`Referral link: ${kit.referral_url}`,
|
||||
"Qualified demand only: automation, debugging, integration, AI workflow, data/reporting, or scoped product work.",
|
||||
].join("\n");
|
||||
|
||||
const delivery = await sendTelegramMessage(text);
|
||||
|
||||
await prisma.auditEvent.create({
|
||||
data: {
|
||||
actorType: "SYSTEM",
|
||||
actorId: "internal-a2a-growth-agent",
|
||||
action: "A2A_INTERNAL_GROWTH_TELEGRAM_BROADCAST",
|
||||
entityType: "SYSTEM",
|
||||
entityId: "vibeaiagent-telegram",
|
||||
metadata: {
|
||||
referral_url: kit.referral_url,
|
||||
campaign: "a2a-agent-referral",
|
||||
source: "telegram",
|
||||
force,
|
||||
dedupe_minutes: TELEGRAM_BROADCAST_DEDUPE_MINUTES,
|
||||
delivery,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
...delivery,
|
||||
referral_url: kit.referral_url,
|
||||
};
|
||||
}
|
||||
|
||||
export async function POST(request: Request) {
|
||||
if (!isCronRequestAuthorized(request)) {
|
||||
return cronUnauthorizedResponse("cron-a2a-growth");
|
||||
}
|
||||
|
||||
const telegramDelivery = await broadcastTelegramGrowthCampaign(request);
|
||||
const enableOutbound = process.env.A2A_GROWTH_ENABLE_OUTBOUND === "true";
|
||||
const agents = await prisma.agentProfile.findMany({
|
||||
where: {
|
||||
@@ -146,6 +267,7 @@ export async function POST(request: Request) {
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
outbound_enabled: enableOutbound,
|
||||
telegram_delivery: telegramDelivery,
|
||||
processed: results.length,
|
||||
results,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user