78 lines
2.8 KiB
TypeScript
78 lines
2.8 KiB
TypeScript
import { sendTrafficAlert } from "./traffic-alert";
|
|
import { TwitterApi } from "twitter-api-v2";
|
|
|
|
export type FomoEventType = "HIGH_VALUE_BOUNTY" | "SPEED_RUN" | "A2A_SUBCONTRACT" | "NEW_BOUNTY_CREATED";
|
|
|
|
export interface FomoEvent {
|
|
type: FomoEventType;
|
|
taskId: string;
|
|
amountFormatted: string; // e.g., "$500"
|
|
title?: string;
|
|
agentId?: string;
|
|
timeToSolveMinutes?: number;
|
|
}
|
|
|
|
const TARGET_AGENT_HANDLES = [
|
|
"@NousResearch", // Hermes
|
|
"@NvidiaAI", // Nemotron
|
|
"@OpenDevin", // OpenDevin
|
|
"@LangChainAI", // LangChain
|
|
"@Auto_GPT", // AutoGPT
|
|
"@Cognition_Labs", // Devin
|
|
"@openinterpreter" // OpenInterpreter
|
|
];
|
|
|
|
function generateTweetText(event: FomoEvent): string {
|
|
const url = `https://agent.wooo.work/tasks/${event.taskId}`;
|
|
const randomTarget = TARGET_AGENT_HANDLES[Math.floor(Math.random() * TARGET_AGENT_HANDLES.length)];
|
|
|
|
switch (event.type) {
|
|
case "HIGH_VALUE_BOUNTY":
|
|
return `🔥 A massive ${event.amountFormatted} AI Bounty just dropped on VibeWork! Hey ${randomTarget}, is your AI Agent smart enough to solve this before a human does? Prove it and take the cash: ${url}`;
|
|
|
|
case "SPEED_RUN":
|
|
return `⚡️ WOW! A ${event.amountFormatted} task was just solved by an AI in exactly ${event.timeToSolveMinutes} minutes! The Agent Economy is moving at lightspeed. Hey ${randomTarget}, can your agents keep up? Join the arena: ${url}`;
|
|
|
|
case "A2A_SUBCONTRACT":
|
|
return `🤯 An AI just hired another AI on VibeWork to solve a ${event.amountFormatted} bug! The autonomous economy is literally building itself. Hey ${randomTarget}, are your models ready for the A2A economy? Watch it happen live: ${url}`;
|
|
}
|
|
}
|
|
|
|
export async function broadcastFomoEvent(event: FomoEvent) {
|
|
const text = generateTweetText(event);
|
|
|
|
// Use App Key/Secret + Access Token/Secret for User Context Posting (OAuth 1.0a)
|
|
const appKey = process.env.TWITTER_API_KEY;
|
|
const appSecret = process.env.TWITTER_API_SECRET;
|
|
const accessToken = process.env.TWITTER_ACCESS_TOKEN;
|
|
const accessSecret = process.env.TWITTER_ACCESS_SECRET;
|
|
|
|
if (!appKey || !appSecret || !accessToken || !accessSecret) {
|
|
// Mock Mode: Log to console and send to internal traffic alert
|
|
console.log(`[X Broadcaster Mock] Would tweet: "${text}"`);
|
|
void sendTrafficAlert({
|
|
level: "info",
|
|
action: "FOMO_TWEET_MOCK",
|
|
surface: "x-broadcaster",
|
|
actorType: "SYSTEM",
|
|
actorId: "broadcaster",
|
|
message: `準備發布的 FOMO 推文: ${text}`,
|
|
});
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const client = new TwitterApi({
|
|
appKey,
|
|
appSecret,
|
|
accessToken,
|
|
accessSecret,
|
|
});
|
|
|
|
const response = await client.v2.tweet(text);
|
|
console.log("[X Broadcaster] Successfully posted tweet. Tweet ID:", response.data.id);
|
|
} catch (err) {
|
|
console.error("[X Broadcaster] Twitter API Error:", err);
|
|
}
|
|
}
|