跳到文档正文

推文元数据、更新与生命周期

(platform, tweetId) 替换实时元数据快照并合并更新,再应用生命周期操作,不要替换已存内容。

运行五分钟快速开始
在聊天中打开
按产品代码校对:2026年9月2日

tweet/meta

实时元数据 payload 是对应帖子的最新快照。请替换之前的元数据,以清除省略的字段。History 返回对应记录中保存的富化数据。恢复时,它只能填充空的本地元数据,不能覆盖实时快照。

推文元数据类型

typescript
type TweetMeta = {
  tweetId: string;
  // Pair with tweetId when merging enrichment. Omitted means twitter on legacy frames.
  platform?: 'twitter' | 'truth_social' | 'binance_square';
  ocr?: {
    text: string;
  };
  detected?: {
    tokens?: Array<{
      symbol?: string;
      name?: string;
      contract?: string;
      chain?: string;
      networkId?: number;
      priceUsd?: number;
      sources: Array<'text' | 'ocr'>;
    }>;
    cex?: Array<{
      exchange: 'bybit' | 'binance' | 'hyperliquid';
      symbol?: string;
      priceUsd?: number;
      url?: string;
      baseAsset?: string;
      quoteAsset?: string;
      sources: Array<'text' | 'ocr'>;
    }>;
    prediction?: Array<{
      exchange: 'polymarket' | 'kalshi';
      marketId?: string;
      title?: string;
      priceUsd?: number;
      url?: string;
      sources: Array<'text' | 'ocr'>;
    }>;
  };
};

推文元数据事件

json
{
  "v": 1,
  "t": "tweet",
  "op": "meta",
  "id": "1234567890",
  "ts": 1702500001000,
  "d": {
    "tweetId": "1234567890",
    "platform": "twitter",
    "ocr": {
      "text": "Chart showing SOL breakout at $100"
    },
    "detected": {
      "tokens": [
        {
          "symbol": "SOL",
          "name": "Solana",
          "priceUsd": 98.50,
          "sources": ["text", "ocr"]
        }
      ]
    }
  }
}

tweet/update

将存在的字段应用到已存帖子。更新中的引用会替换已存引用快照。

推文更新类型

typescript
type VerifiedType = 'blue' | 'business' | 'government' | 'verified' | 'none';
type TweetVerifiedLabel = {
  badge: string | null;
  description: string;
  url: string | null;
};
 
type TweetAuthor = {
  banner?: string;
  bio?: string;
  followersCount?: number;
  followingCount?: number;
  id?: string;
  joinedAt?: number;
  location?: string;
  metrics?: {
    likes?: number;
    tweets?: number;
  };
  // Includes a leading @ when present, for example "@elonmusk".
  handle?: string;
  name?: string;
  platform?: 'twitter' | 'truth_social' | 'binance_square';
  profileImage?: string;
  url?: string;
  verifiedLabel?: TweetVerifiedLabel;
  verifiedType?: VerifiedType;
};
 
type Media = {
  url: string;
} & (
  | {
      type: 'video';
      // Every video is a progressive MP4. A public still poster is included when available.
      thumbnail?: string;
    }
  | {
      type?: 'image' | 'gif';
      thumbnail?: string;
    }
);
 
type TweetUrl = {
  url: string;
  name?: string;
  tco?: string;
};
 
type TweetMention = {
  handle?: string;
  id?: string;
  name?: string;
};
 
type TweetArticle = {
  description?: string;
  id?: string;
  publishedAt?: number;
  text?: string;
  thumbnail?: string;
  title: string;
  updatedAt?: number;
  url: string;
};
 
type TweetPollChoice = {
  id?: string;
  image?: string;
  label: string;
  votes?: number;
};
 
type TweetPoll = {
  choices: TweetPollChoice[];
  endsAt?: number;
  totalVotes?: number;
  updatedAt?: number;
};
 
type TweetContentKind = 'post' | 'reply' | 'quote' | 'retweet';
 
type TweetReference = {
  article?: TweetArticle;
  type: 'reply' | 'quote' | 'retweet';
  tweetId: string;
  text?: string;
  translatedText?: string;
  author?: TweetAuthor;
  media?: Media[];
  poll?: TweetPoll;
  quoted?: TweetReference;
  subtweet?: TweetReference;
};
 
type TweetContent = {
  tweetId: string;
  kind: TweetContentKind;
  // Original tweet text when the event includes both original and translated text.
  text: string;
  // Translation, present only when available.
  translatedText?: string;
  createdAt: number;
  author: TweetAuthor;
  article?: TweetArticle;
  link?: string;
  media?: Media[];
  mentions?: TweetMention[];
  poll?: TweetPoll;
  receivedAt?: number;
  urls?: TweetUrl[];
  ref?: TweetReference;
};
 
type TweetUpdate = {
  tweetId: string;
  // Pair with tweetId. On legacy frames, fall back to author.platform, then twitter.
  platform?: 'twitter' | 'truth_social' | 'binance_square';
  article?: TweetArticle;
  kind?: TweetContentKind;
  translatedText?: string;
  author?: TweetAuthor;
  media?: Media[];
  mentions?: TweetMention[];
  poll?: TweetPoll;
  receivedAt?: number;
  urls?: TweetUrl[];
  ref?: TweetReference;
} & (
  | {
      text?: string;
      textUpdateType?: never;
    }
  | {
      text: string;
      // Completes an earlier truncated rendering. This is not an edit signal.
      textUpdateType: 'completion';
    }
);

推文更新事件

json
{
  "v": 1,
  "t": "tweet",
  "op": "update",
  "id": "1234567890",
  "ts": 1702500000180,
  "d": {
    "tweetId": "1234567890",
    "platform": "twitter",
    "ref": {
      "type": "reply",
      "tweetId": "1234567880",
      "text": "Mainnet is ready for launch."
    }
  }
}

递归引用更新

json
{
  "v": 1,
  "t": "tweet",
  "op": "update",
  "id": "1234567890",
  "ts": 1702500000240,
  "d": {
    "tweetId": "1234567890",
    "platform": "twitter",
    "ref": {
      "type": "reply",
      "tweetId": "1234567880",
      "text": "Mainnet is ready for launch.",
      "author": {
        "handle": "@projectteam",
        "name": "Project Team"
      },
      "subtweet": {
        "type": "quote",
        "tweetId": "1234567800",
        "text": "Launch proposal and contract details.",
        "author": {
          "handle": "@projectteam",
          "name": "Project Team"
        }
      }
    }
  }
}

生命周期事件

生命周期操作会更新已知帖子,不会替换已存内容。

推文生命周期类型

typescript
type VerifiedType = 'blue' | 'business' | 'government' | 'verified' | 'none';
type TweetVerifiedLabel = {
  badge: string | null;
  description: string;
  url: string | null;
};
 
type TweetAuthor = {
  banner?: string;
  bio?: string;
  followersCount?: number;
  followingCount?: number;
  id?: string;
  joinedAt?: number;
  location?: string;
  metrics?: {
    likes?: number;
    tweets?: number;
  };
  // Includes a leading @ when present, for example "@elonmusk".
  handle?: string;
  name?: string;
  platform?: 'twitter' | 'truth_social' | 'binance_square';
  profileImage?: string;
  url?: string;
  verifiedLabel?: TweetVerifiedLabel;
  verifiedType?: VerifiedType;
};
 
type Media = {
  url: string;
} & (
  | {
      type: 'video';
      // Every video is a progressive MP4. A public still poster is included when available.
      thumbnail?: string;
    }
  | {
      type?: 'image' | 'gif';
      thumbnail?: string;
    }
);
 
type TweetUrl = {
  url: string;
  name?: string;
  tco?: string;
};
 
type TweetMention = {
  handle?: string;
  id?: string;
  name?: string;
};
 
type TweetArticle = {
  description?: string;
  id?: string;
  publishedAt?: number;
  text?: string;
  thumbnail?: string;
  title: string;
  updatedAt?: number;
  url: string;
};
 
type TweetPollChoice = {
  id?: string;
  image?: string;
  label: string;
  votes?: number;
};
 
type TweetPoll = {
  choices: TweetPollChoice[];
  endsAt?: number;
  totalVotes?: number;
  updatedAt?: number;
};
 
type TweetContentKind = 'post' | 'reply' | 'quote' | 'retweet';
 
type TweetReference = {
  article?: TweetArticle;
  type: 'reply' | 'quote' | 'retweet';
  tweetId: string;
  text?: string;
  translatedText?: string;
  author?: TweetAuthor;
  media?: Media[];
  poll?: TweetPoll;
  quoted?: TweetReference;
  subtweet?: TweetReference;
};
 
type TweetContent = {
  tweetId: string;
  kind: TweetContentKind;
  // Original tweet text when the event includes both original and translated text.
  text: string;
  // Translation, present only when available.
  translatedText?: string;
  createdAt: number;
  author: TweetAuthor;
  article?: TweetArticle;
  link?: string;
  media?: Media[];
  mentions?: TweetMention[];
  poll?: TweetPoll;
  receivedAt?: number;
  urls?: TweetUrl[];
  ref?: TweetReference;
};
 
type TweetDeleteEvent = {
  tweetId: string;
  // On legacy frames, fall back to author.platform, then twitter.
  platform?: 'twitter' | 'truth_social' | 'binance_square';
  eventId?: string;
  deletedAt?: number;
  receivedAt?: number;
  author?: TweetAuthor;
  text?: string;
};
 
type TweetPinEvent = {
  tweetId: string;
  // On legacy frames, fall back to tweet.author.platform or author.platform, then twitter.
  platform?: 'twitter' | 'truth_social' | 'binance_square';
  eventId: string;
  observedAt: number;
  receivedAt?: number;
  action: 'pin';
  author: TweetAuthor;
  text?: string;
  tweet?: TweetContent;
};
 
type TweetUnpinEvent = {
  tweetId: string;
  // On legacy frames, fall back to tweet.author.platform or author.platform, then twitter.
  platform?: 'twitter' | 'truth_social' | 'binance_square';
  eventId: string;
  observedAt: number;
  receivedAt?: number;
  action: 'unpin';
  author: TweetAuthor;
  text?: string;
  tweet?: TweetContent;
};

tweet/delete

观察到此事件时,将帖子标记为已删除。

推文删除事件

json
{
  "v": 1,
  "t": "tweet",
  "op": "delete",
  "id": "tweet-delete",
  "ts": 1772000001060,
  "d": {
    "eventId": "delete-1",
    "tweetId": "tweet-delete",
    "platform": "twitter",
    "author": {
      "id": "10228272",
      "handle": "@TeamYouTube"
    },
    "deletedAt": 1772000001040,
    "receivedAt": 1772000001050,
    "text": "deleted"
  }
}

tweet/pin

将帖子标记为已置顶,并保留附带的帖子快照。

推文置顶事件

json
{
  "v": 1,
  "t": "tweet",
  "op": "pin",
  "id": "tweet-pin",
  "ts": 1772000001060,
  "d": {
    "action": "pin",
    "author": {
      "id": "10228272",
      "handle": "@TeamYouTube"
    },
    "eventId": "pin-1",
    "observedAt": 1772000001060,
    "tweetId": "tweet-pin",
    "platform": "twitter",
    "receivedAt": 1772000001050,
    "text": "pinned"
  }
}

tweet/unpin

移除对应帖子的置顶状态。

推文取消置顶事件

json
{
  "v": 1,
  "t": "tweet",
  "op": "unpin",
  "id": "tweet-unpin",
  "ts": 1772000001060,
  "d": {
    "action": "unpin",
    "author": {
      "id": "10228272",
      "handle": "@TeamYouTube"
    },
    "eventId": "unpin-1",
    "observedAt": 1772000001060,
    "tweetId": "tweet-unpin",
    "platform": "twitter",
    "receivedAt": 1772000001050,
    "text": "unpinned"
  }
}