/install badgebot
Slack Lead Scanner
Monitor #leadscanner for new images/text, process as leads via Apollo + HubSpot, reply in-thread. Also check Slack DM replies to update HubSpot contacts.
Setup
- SLACK_TOKEN in ~/.openclaw/credentials/slack-bot-token (xoxb- token)
- Apollo key in ~/.openclaw/credentials/apollo-api-key
- HubSpot token in ~/.openclaw/credentials/hubspot-api-key
- State file: ~/clawd/memory/slack-lead-scanner-state.json
- Portal ID: 43856876
- Channel: #leadscanner (C0AQAJ8VD8A)
State File Schema
{
"last_ts": 1234567890,
"processed_ids": ["msg_ts_1", "msg_ts_2"],
"channel_id": "C0AQAJ8VD8A",
"pending_dm_replies": [
{
"dm_ts": "1234567890.123456",
"hubspot_contact_id": "12345",
"contact_name": "John Doe"
}
]
}
Polling Workflow
Part 1: Process New #leadscanner Messages
- Load state from ~/clawd/memory/slack-lead-scanner-state.json
- Fetch messages:
curl -H "Authorization: Bearer $SLACK_TOKEN" "https://slack.com/api/conversations.history?channel=C0AQAJ8VD8A&oldest=[last_ts]&limit=50" - Filter: ts > last_ts, not in processed_ids, has files or non-empty text
- For each new message:
a. Download image:
curl -H "Authorization: Bearer $SLACK_TOKEN" "[file.url_private_download]" -o /tmp/lead-[ts].jpgb. Analyze with image tool: "Extract structured data from this badge or business card. Return JSON: {first_name, last_name, company, title, email, phone, notes}" c. Append message.text to notes d. Dedup: Search HubSpot first by firstname+lastname+company — if exists, skip enrich, go to step (g) e. Enrich via Apollo:curl -X POST -H "Content-Type: application/json" -d '{"api_key":"[KEY]","first_name":"[f]","last_name":"[l]","organization_name":"[co]","title":"[t]","reveal_personal_emails":true,"reveal_phone_number":true}' https://api.apollo.io/api/v1/people/matchf. Sleep 10s, then search HubSpot for new contact (sort by createdate DESC, filter name+company) g. Get contact id, build link:https://app.hubspot.com/contacts/43856876/contact/[id]h. Send DM to Mark (user:U03H7C6HW5B) with formatted message (see Reply Format below) i. Track DM timestamp from response, add to pending_dm_replies in state j. React ✅ on original #leadscanner message k. Add msg ts to processed_ids, update last_ts l. Cleanup:rm /tmp/lead-[ts].jpg
Part 2: Check DM Replies for HubSpot Updates
-
For each entry in pending_dm_replies: a. Fetch thread replies:
curl -H "Authorization: Bearer $SLACK_TOKEN" "https://slack.com/api/conversations.replies?channel=[DM_CHANNEL_ID]&ts=[dm_ts]"b. Filter replies that are from the user (not the bot itself) and not yet processed c. Parse reply text as a natural-language HubSpot update instruction, e.g.:- "update title to VP of Sales" → jobtitle
- "wrong email, it's [email protected]" → email
- "company is Acme Corp" → company
- "phone is 415-555-1234" → phone
- "add note: met at SaaStr" → note (create HubSpot note via /crm/v3/objects/notes)
d. Apply update via HubSpot PATCH:
curl -X PATCH -H "Authorization: Bearer $HUBSPOT_TOKEN" -H "Content-Type: application/json" -d '{"properties":{"[field]":"[value]"}}' "https://api.hubapi.com/crm/v3/objects/contacts/[hubspot_contact_id]"e. Reply in thread: "✅ Updated [field] to [value] for [contact_name]." f. If unrecognized instruction, reply: "❓ I didn't understand that. Try: 'update title to [value]' or 'email is [value]'"
-
Write updated state back to ~/clawd/memory/slack-lead-scanner-state.json
-
Log to memory/YYYY-MM-DD.md
Reply Format (DM to Mark)
Use Slack line breaks (
) between fields:
*[Full Name]*
[Title]
[Company]
📧 [Email]
📞 [Phone]
🔗 \x3Chttps://app.hubspot.com/contacts/43856876/contact/[id]|View in HubSpot>
_Reply to this message to update any field in HubSpot._
HubSpot Field Mappings
| Natural language | HubSpot property |
|---|---|
| name / first name / last name | firstname / lastname |
| title / job title / role | jobtitle |
| company / org | company |
| phone | phone |
| note / notes | create note object |
Error Handling
- No Apollo match: send DM anyway with extracted data, note "No enrichment match"
- No HubSpot match after sleep: send DM with "Sync pending - check HubSpot later", omit link
- API errors: Log and DM "Error processing: [msg]" with ❌ react
- Unknown DM reply: Reply with ❓ and guidance
Notes
- Use haiku model for cost efficiency
- Rate limits: Slack ~1 call/sec, Apollo per plan, HubSpot 100 req/10s
- Never log or output tokens
- Get DM channel ID for direct messages: it's a conversations.open response for user U03H7C6HW5B
- 确保已安装 OpenClaw(本地或 Docker 部署)
- 在对话框中输入安装命令:
/install badgebot - 安装完成后,直接呼叫该 Skill 的名称或使用
/badgebot触发 - 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
badgebot 是什么?
Monitor a Slack channel for images/text of leads (badges, business cards), extract data, enrich with Apollo.io API, let Apollo auto-sync to HubSpot, search H... 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 87 次。
如何安装 badgebot?
在 OpenClaw 或 Claude Code 对话框中运行命令「/install badgebot」即可一键安装,无需额外配置。
badgebot 是免费的吗?
是的,badgebot 完全免费,采用 MIT-0 许可证,可自由下载、安装和使用。
badgebot 支持哪些平台?
badgebot 跨平台运行,可在任意部署了 OpenClaw / Claude Code 的环境中使用(cross-platform)。
谁开发了 badgebot?
由 Mark Chen(@mchensf)开发并维护,当前版本 v1.0.0。