tweet-rl-tracker

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

What I Do

功能介绍

Set up a Notion database to track tweet performance and enable a feedback loop for improving tweet quality over time. This is "poor man's reinforcement learning" - manually logging outcomes to discover what works.
NEW: Screenshot Capture - Automatically capture screenshots from tweet links (including video frames at 10 seconds) using Chrome DevTools MCP.
搭建一个Notion数据库来跟踪推文表现,形成反馈循环,长期提升推文质量。这就是「平民版强化学习」——手动记录结果来摸索有效的内容方向。
新增功能:截图捕获 - 使用Chrome DevTools MCP自动捕获推文链接的截图(包括视频第10秒的帧画面)。

The RL Loop

强化学习循环

1. WRITE   -> Draft tweet with a hypothesis (hook type, topic, etc.)
2. POST    -> Publish to Twitter/X
3. LOG     -> Record in Notion after 24-48hrs with metrics
4. SCORE   -> Mark "Worked?" based on engagement rate
5. REVIEW  -> Weekly: compare winners vs losers, extract patterns
6. REPEAT  -> Apply learnings to step 1
1. WRITE   -> 撰写带假设的推文草稿(钩子类型、主题等)
2. POST    -> 发布到Twitter/X
3. LOG     -> 24-48小时后将数据记录到Notion
4. SCORE   -> 根据互动率标记「是否有效?」
5. REVIEW  -> 每周对比高/低表现内容,提炼规律
6. REPEAT  -> 将经验应用到第一步的创作中

Database Schema

数据库结构

Core Fields (Outcomes)

核心字段(结果数据)

PropertyTypePurpose
TweettitleThe tweet text
LikesnumberPrimary engagement signal
ImpressionsnumberReach/views
Scoreformula
Likes / Impressions * 100
(engagement %)
Worked?checkboxBinary gut-check - was this a win?
属性类型用途
Tweettitle推文正文
Likesnumber核心互动指标
Impressionsnumber触达/浏览量
Scoreformula
点赞数 / 触达量 * 100
(互动率百分比)
Worked?checkbox二元判断:这条推文是否达到预期?

Input Features (What You Controlled)

输入特征(可控变量)

PropertyTypeOptions
HookselectQuestion, Bold Claim, Story, List, How-To, Contrarian, Data/Stats
Topicselect(customize to your niche)
PosteddateWhen you posted
属性类型可选值
Hookselect提问式, 大胆断言, 故事型, 清单式, 教程型, 反常识观点, 数据/统计
Topicselect(可自定义为你的垂直领域主题)
Posteddate发布时间

Optional Extensions

可选扩展字段

PropertyTypePurpose
RepliesnumberConversation signal
RetweetsnumberAmplification signal
LinkurlLink to original tweet
Notesrich_textWhy did it work/fail?
属性类型用途
Repliesnumber对话互动指标
Retweetsnumber传播扩散指标
Linkurl原推文链接
Notesrich_text效果好坏的原因分析

Setup Instructions

搭建指南

Step 1: Create the Page and Database

步骤1:创建页面和数据库

Use the Notion MCP tools to create:
notion_notion-create-pages with:
- title: "Tweet Lab" (or your preferred name)
- content: Brief intro about the system

Then inside that page, create a database with:
notion_notion-create-database with the schema above
使用Notion MCP工具创建:
notion_notion-create-pages with:
- title: "Tweet Lab"(或你偏好的名称)
- content: 系统的简要介绍

然后在该页面内,用以下命令创建数据库:
notion_notion-create-database with the schema above

Step 2: Example Notion Tool Calls

步骤2:Notion工具调用示例

Create the container page:
json
{
  "pages": [
    {
      "properties": { "title": "Tweet Lab" },
      "content": "## Tweet Performance Tracker\n\nA simple system to track what works and improve over time.\n\n### The Loop\n1. Post tweet\n2. Log metrics after 24-48hrs\n3. Mark if it \"Worked\"\n4. Weekly: review patterns\n\n<database>Tweets</database>"
    }
  ]
}
Create the database (after getting page_id):
json
{
  "parent": { "page_id": "<page-id-from-above>" },
  "title": [{ "type": "text", "text": { "content": "Tweets" } }],
  "properties": {
    "Tweet": { "type": "title", "title": {} },
    "Likes": { "type": "number", "number": { "format": "number" } },
    "Impressions": { "type": "number", "number": { "format": "number" } },
    "Score": {
      "type": "formula",
      "formula": {
        "expression": "if(prop(\"Impressions\") > 0, prop(\"Likes\") / prop(\"Impressions\") * 100, 0)"
      }
    },
    "Worked?": { "type": "checkbox", "checkbox": {} },
    "Hook": {
      "type": "select",
      "select": {
        "options": [
          { "name": "Question", "color": "blue" },
          { "name": "Bold Claim", "color": "red" },
          { "name": "Story", "color": "green" },
          { "name": "List", "color": "yellow" },
          { "name": "How-To", "color": "purple" },
          { "name": "Contrarian", "color": "orange" },
          { "name": "Data/Stats", "color": "pink" }
        ]
      }
    },
    "Topic": {
      "type": "select",
      "select": { "options": [] }
    },
    "Posted": { "type": "date", "date": {} }
  }
}
创建容器页面:
json
{
  "pages": [
    {
      "properties": { "title": "Tweet Lab" },
      "content": "## 推文表现跟踪器\n\n一个简单的系统,用于跟踪有效内容、长期提升创作效果。\n\n### 循环流程\n1. 发布推文\n2. 24-48小时后记录数据\n3. 标记是否达到预期\n4. 每周复盘规律\n\n<database>Tweets</database>"
    }
  ]
}
创建数据库(获取page_id后执行):
json
{
  "parent": { "page_id": "<page-id-from-above>" },
  "title": [{ "type": "text", "text": { "content": "Tweets" } }],
  "properties": {
    "Tweet": { "type": "title", "title": {} },
    "Likes": { "type": "number", "number": { "format": "number" } },
    "Impressions": { "type": "number", "number": { "format": "number" } },
    "Score": {
      "type": "formula",
      "formula": {
        "expression": "if(prop(\"Impressions\") > 0, prop(\"Likes\") / prop(\"Impressions\") * 100, 0)"
      }
    },
    "Worked?": { "type": "checkbox", "checkbox": {} },
    "Hook": {
      "type": "select",
      "select": {
        "options": [
          { "name": "Question", "color": "blue" },
          { "name": "Bold Claim", "color": "red" },
          { "name": "Story", "color": "green" },
          { "name": "List", "color": "yellow" },
          { "name": "How-To", "color": "purple" },
          { "name": "Contrarian", "color": "orange" },
          { "name": "Data/Stats", "color": "pink" }
        ]
      }
    },
    "Topic": {
      "type": "select",
      "select": { "options": [] }
    },
    "Posted": { "type": "date", "date": {} }
  }
}

Using the System

系统使用方法

Daily: Log Tweets

日常:记录推文数据

After 24-48 hours, add a row:
  • Copy tweet text
  • Pull Likes and Impressions from Twitter analytics
  • Select the Hook type you used
  • Select or create a Topic tag
发布24-48小时后,添加一条新数据行:
  • 复制推文正文
  • 从Twitter后台导出点赞和触达数据
  • 选择你使用的钩子类型
  • 选择或创建对应的主题标签

Weekly: Review Session

每周:复盘会议

  1. Sort by Score (descending) - what performed best?
  2. Filter by "Worked?" = true - what patterns emerge?
  3. Group by Hook - which hook types win?
  4. Group by Topic - which topics resonate?
  1. 按得分降序排序 - 哪些内容表现最好?
  2. 筛选「是否有效?= 是」的内容 - 出现了哪些共同规律?
  3. 按钩子类型分组 - 哪种钩子效果最好?
  4. 按主题分组 - 哪些主题用户更感兴趣?

Monthly: Form Hypotheses

每月:提出假设

Based on patterns, create hypotheses to test:
  • "Questions about [topic] get 2x engagement"
  • "Bold claims underperform for my audience"
  • "Threads outperform single tweets"
Then deliberately test these in the next month.
基于复盘的规律,提出可测试的假设:
  • 「关于[主题]的提问式内容互动率是其他类型的2倍」
  • 「大胆断言类内容对我的受众效果不好」
  • 「线程推文比单条推文表现更好」
然后在下个月刻意测试这些假设。

Key Insights

核心要点

What Makes This Work

系统有效的原因

  1. Track inputs, not just outputs - Without knowing what you tried (hook, topic), you can't learn what caused success
  2. Binary "Worked?" is powerful - Forces a clear decision, easier to analyze than continuous scores
  3. Review regularly - Data without reflection is useless
  4. Test hypotheses deliberately - Don't just observe, experiment
  1. 同时跟踪输入和输出 - 如果不知道你尝试过什么(钩子、主题),就无法知道成功的原因
  2. 二元「是否有效?」判断非常高效 - 强制做出清晰判断,比连续得分更容易分析
  3. 定期复盘 - 没有反思的数据毫无价值
  4. 刻意测试假设 - 不要只观察,要做实验

Common Pitfalls

常见误区

  • Logging inconsistently (do it same time each day/week)
  • Not tracking input features (hook, topic)
  • Never reviewing the data
  • Optimizing for wrong metric (likes vs. replies vs. followers)
  • 记录不连贯(固定每天/每周的同一时间处理)
  • 不跟踪输入特征(钩子、主题)
  • 从不复盘数据
  • 优化错误的指标(点赞 vs 评论 vs 粉丝增长)

Customization

自定义配置

Different Goals = Different Metrics

不同目标对应不同指标

GoalPrimary MetricFormula
ViralityRetweets / ImpressionsAmplification rate
Engagement(Likes + Replies) / ImpressionsInteraction rate
GrowthProfile clicks / ImpressionsCuriosity rate
CommunityReplies / ImpressionsConversation rate
目标核心指标计算公式
传播度转发数 / 触达量扩散率
互动率(点赞数 + 评论数) / 触达量交互率
涨粉量主页点击量 / 触达量好奇率
社区活跃度评论数 / 触达量对话率

Add Your Topics

添加你的专属主题

Update the Topic select options based on your niche. Examples:
  • Tech founder: Product, Fundraising, Hiring, Lessons, Industry
  • Creator: Process, Tools, Mindset, Results, Behind-the-scenes
根据你的垂直领域更新主题选项,示例:
  • 科技创业者:产品、融资、招聘、经验教训、行业动态
  • 内容创作者:创作过程、工具、思维方式、成果、幕后故事

Troubleshooting

问题排查

"I forget to log tweets"

「我忘记记录推文数据」

  • Set a daily/weekly calendar reminder
  • Add a "Logged?" checkbox to your posting workflow
  • Batch log once per week instead of daily
  • 设置每日/每周日历提醒
  • 在你的发布流程里添加「已记录?」检查项
  • 改成每周批量记录一次,不用每日处理

"I don't know what hook I used"

「我不记得用了什么钩子类型」

  • Decide BEFORE posting, not after
  • Add hook type to your tweet drafting process
  • When in doubt, pick the closest match
  • 发布前就确定钩子类型,不要发布后回溯
  • 把钩子类型选择加入你的推文草稿流程
  • 不确定的时候选最接近的类型即可

"My Score is always low"

「我的得分一直很低」

  • Engagement rates are typically 1-5% - this is normal
  • Compare relative performance, not absolute numbers
  • Consider using a different base metric for "Worked?"

  • 正常的互动率通常在1-5%之间,这是普遍情况
  • 对比相对表现,不要纠结绝对数值
  • 可以考虑换其他基础指标来判断「是否有效?」

Screenshot Capture with Chrome MCP

使用Chrome MCP捕获截图

Prerequisites

前置要求

  • Chrome DevTools MCP configured in your MCP client
  • Logged into Twitter/X in the Chrome profile
  • 在你的MCP客户端中配置了Chrome DevTools MCP
  • Chrome配置文件中已经登录了Twitter/X账号

Database Field

数据库字段

The Tweets database includes a
Screenshot
field (type: files) to store captured images.
Data Source ID:
a6913492-bfdc-4f6a-b539-ea98b57a2738
推文数据库包含
Screenshot
字段(类型:files)用于存储捕获的图片。
数据源ID:
a6913492-bfdc-4f6a-b539-ea98b57a2738

Workflow: Capture Tweet Screenshot

工作流:捕获推文截图

Given a tweet URL like
https://x.com/username/status/1234567890
:
对于类似
https://x.com/username/status/1234567890
的推文链接:

Step 1: Navigate to Tweet

步骤1:打开推文页面

javascript
// Open new page with the tweet
new_page({ url: 'https://x.com/username/status/1234567890' });

// Wait for tweet to load
wait_for({ text: 'Reply' }); // or wait for specific tweet content
javascript
// 打开推文的新页面
new_page({ url: 'https://x.com/username/status/1234567890' });

// 等待推文加载完成
wait_for({ text: 'Reply' }); // 或者等待特定推文内容出现

Step 2: Take Screenshot of Tweet

步骤2:截取推文截图

javascript
// Take full page screenshot
take_screenshot({ fullPage: false });

// Or screenshot specific element (the tweet article)
take_snapshot(); // Get element uids first
take_screenshot({ uid: 'tweet-article-uid' });
javascript
// 截取当前页面可见区域
take_screenshot({ fullPage: false });

// 或者截取特定元素(推文article节点)
take_snapshot(); // 先获取元素uid
take_screenshot({ uid: 'tweet-article-uid' });

Step 3: For Video Tweets - Capture Frame at 10 Seconds

步骤3:视频推文:捕获第10秒的帧画面

javascript
// 1. Find and click the video to start playing
take_snapshot();
click({ uid: 'video-player-uid' });

// 2. Wait 10 seconds for video to play
// (Use evaluate_script to seek if possible)
evaluate_script({
  function: `() => {
    const video = document.querySelector('video');
    if (video) {
      video.currentTime = 10;
      video.pause();
      return { success: true, duration: video.duration };
    }
    return { success: false };
  }`,
});

// 3. Take screenshot of the video frame
take_screenshot({ fullPage: false });
javascript
// 1. 找到视频并点击播放
take_snapshot();
click({ uid: 'video-player-uid' });

// 2. 等待10秒视频播放
// (如果支持的话可以用evaluate_script直接跳转到指定时间点)
evaluate_script({
  function: `() => {
    const video = document.querySelector('video');
    if (video) {
      video.currentTime = 10;
      video.pause();
      return { success: true, duration: video.duration };
    }
    return { success: false };
  }`,
});

// 3. 截取视频帧画面
take_screenshot({ fullPage: false });

Step 4: Extract Tweet Metadata

步骤4:提取推文元数据

javascript
evaluate_script({
  function: `() => {
    // Extract tweet text
    const tweetText = document.querySelector('[data-testid="tweetText"]')?.textContent || '';
    
    // Extract author
    const author = document.querySelector('[data-testid="User-Name"]')?.textContent || '';
    
    // Extract metrics (likes, retweets, etc.)
    const metrics = {};
    document.querySelectorAll('[data-testid="like"], [data-testid="retweet"]').forEach(el => {
      const label = el.getAttribute('aria-label') || '';
      if (label.includes('like')) metrics.likes = parseInt(label) || 0;
      if (label.includes('repost')) metrics.retweets = parseInt(label) || 0;
    });
    
    // Check if video exists
    const hasVideo = !!document.querySelector('video');
    const hasImage = !!document.querySelector('[data-testid="tweetPhoto"]');
    
    return {
      text: tweetText,
      author,
      metrics,
      mediaType: hasVideo ? 'Video' : hasImage ? 'Image' : 'None'
    };
  }`,
});
javascript
evaluate_script({
  function: `() => {
    // 提取推文正文
    const tweetText = document.querySelector('[data-testid="tweetText"]')?.textContent || '';
    
    // 提取作者信息
    const author = document.querySelector('[data-testid="User-Name"]')?.textContent || '';
    
    // 提取指标(点赞、转发等)
    const metrics = {};
    document.querySelectorAll('[data-testid="like"], [data-testid="retweet"]').forEach(el => {
      const label = el.getAttribute('aria-label') || '';
      if (label.includes('like')) metrics.likes = parseInt(label) || 0;
      if (label.includes('repost')) metrics.retweets = parseInt(label) || 0;
    });
    
    // 检查是否有媒体内容
    const hasVideo = !!document.querySelector('video');
    const hasImage = !!document.querySelector('[data-testid="tweetPhoto"]');
    
    return {
      text: tweetText,
      author,
      metrics,
      mediaType: hasVideo ? 'Video' : hasImage ? 'Image' : 'None'
    };
  }`,
});

Complete Example: Add Tweet with Screenshot

完整示例:添加带截图的推文到跟踪器

User: Add this tweet to the tracker: https://x.com/unvalley_/status/2005899617775542298

Agent workflow:
1. new_page({ url: 'https://x.com/unvalley_/status/2005899617775542298' })
2. wait_for({ text: 'Reply' })
3. take_snapshot() - to see page structure
4. evaluate_script() - extract tweet text, author, media type
5. If video: seek to 10s and pause
6. take_screenshot() - capture the visual
7. Save screenshot to local file (screenshot is returned as base64)
8. Create Notion page with extracted data + screenshot file
用户:把这条推文添加到跟踪器:https://x.com/unvalley_/status/2005899617775542298

Agent工作流:
1. new_page({ url: 'https://x.com/unvalley_/status/2005899617775542298' })
2. wait_for({ text: 'Reply' })
3. take_snapshot() - 分析页面结构
4. evaluate_script() - 提取推文正文、作者、媒体类型
5. 如果是视频:跳转到10秒并暂停
6. take_screenshot() - 捕获画面
7. 把截图保存到本地文件(截图返回格式为base64)
8. 用提取到的数据+截图文件创建Notion页面

Saving Screenshot to Notion

保存截图到Notion

Important: Notion's files property requires external URLs. The workflow is:
  1. Take screenshot with Chrome MCP (returns base64)
  2. Save to a publicly accessible location (e.g., upload to S3, Cloudinary, or use a temp file host)
  3. Add the URL to the Notion page's Screenshot field
javascript
// After taking screenshot, you'll get base64 data
// Save it locally first:
const fs = require('fs');
const screenshotPath = `/tmp/tweet-${Date.now()}.png`;
fs.writeFileSync(screenshotPath, Buffer.from(base64Data, 'base64'));

// Then upload to your preferred hosting and get URL
// Finally, create Notion page with the screenshot URL
重要提示:Notion的文件属性需要外部可访问的URL,工作流如下:
  1. 用Chrome MCP截取截图(返回base64格式)
  2. 上传到公开可访问的存储服务(例如S3、Cloudinary,或者临时文件托管服务)
  3. 把URL添加到Notion页面的Screenshot字段
javascript
// 拿到截图的base64数据后
// 先保存到本地:
const fs = require('fs');
const screenshotPath = `/tmp/tweet-${Date.now()}.png`;
fs.writeFileSync(screenshotPath, Buffer.from(base64Data, 'base64'));

// 然后上传到你选择的托管服务获取URL
// 最后用截图URL创建Notion页面

Quick Reference: Chrome MCP Tools for Tweet Capture

快速参考:用于推文捕获的Chrome MCP工具

ToolPurpose
new_page
Navigate to tweet URL
wait_for
Wait for tweet to load
take_snapshot
Get accessibility tree (find element uids)
take_screenshot
Capture visual screenshot
evaluate_script
Extract tweet data, control video playback
click
Click play button on video
工具用途
new_page
跳转到推文URL
wait_for
等待推文加载完成
take_snapshot
获取无障碍树(查找元素uid)
take_screenshot
捕获截图
evaluate_script
提取推文数据、控制视频播放
click
点击视频播放按钮

Troubleshooting Screenshots

截图问题排查

"Tweet not loading"
  • Check if logged into Twitter in Chrome profile
  • Twitter may require login for some content
  • Try
    wait_for
    with longer timeout
"Video won't seek"
  • Some videos are streaming and don't support seeking
  • Try clicking play first, then waiting 10 seconds naturally
  • Use
    setTimeout
    in evaluate_script if needed
"Screenshot is blank"
  • Wait longer for content to render
  • Check if page has overlay/modal blocking content
  • Try
    fullPage: true
    to capture everything
"Can't upload to Notion"
  • Notion files require external URLs
  • Use a file hosting service (S3, Cloudinary, imgur)
  • Or embed screenshot as image in page content instead
「推文加载不出来」
  • 检查Chrome配置文件中是否登录了Twitter账号
  • 部分Twitter内容需要登录才能查看
  • 尝试给
    wait_for
    设置更长的超时时间
「视频无法跳转到指定时间点」
  • 部分流视频不支持进度跳转
  • 尝试先点击播放,然后自然等待10秒
  • 需要的话可以在evaluate_script里用
    setTimeout
    处理
「截图是空白的」
  • 等待更长时间让内容渲染
  • 检查页面是否有覆盖内容的弹窗/遮罩层
  • 尝试设置
    fullPage: true
    捕获整个页面
「无法上传到Notion」
  • Notion文件字段需要外部可访问的URL
  • 使用文件托管服务(S3、Cloudinary、imgur)
  • 或者把截图作为图片嵌入到页面内容中