← 返回
数据分析 中文

Birdfolio

Bird identification, life list tracking, and trading card generation. Use this skill when the user: sends a bird photo to identify, says "set up my Birdfolio...
鸟类识别、终身观察记录追踪和交易卡生成。当用户发送鸟照进行识别或说“设置我的Birdfolio...”时,使用此技能。
tonbistudio
数据分析 clawhub v1.0.0 1 版本 99822.5 Key: 无需
★ 0
Stars
📥 1,125
下载
💾 12
安装
1
版本
#latest

概述

Birdfolio

Birdfolio turns bird photos into a personal life list. Users photograph birds in the wild, send the photo to you, and you identify the species with Vision. You.com provides real-time rarity and regional data. Each sighting is logged to a life list with a Pokémon-inspired rarity tier (Common / Rare / Super Rare) and gets a visual trading card sent back via Telegram.

Data lives in: Railway PostgreSQL (via API) + local birdfolio/ folder (cards, birds, config)

Scripts live in: {baseDir}/scripts/

API: https://api-production-d0e2.up.railway.app (also saved to birdfolio/config.json after init)

Schema reference: {baseDir}/references/data-schema.md

Search queries: {baseDir}/references/you-search-queries.md

> Note on --workspace & --api-url: Every data script accepts --workspace (absolute path to birdfolio/) and --api-url (API base URL). After init_birdfolio.py runs, both the API URL and Telegram ID are saved to birdfolio/config.json and read automatically — subsequent scripts only need --workspace.

>

> Telegram ID: Read from the inbound message metadata (sender_id). Pass as --telegram-id to init_birdfolio.py on first setup.


1. Setup Flow

Trigger: User says "Set up my Birdfolio", "set my region", or sends a photo before setup exists.

Check first: If birdfolio/config.json exists in your workspace, setup is already done — skip to the relevant flow.

Steps:

  1. Ask: "What's your home region? (e.g. California, Texas, United Kingdom)"
  1. Run to create the workspace folder structure and register the user in the API:

```

exec: python {baseDir}/scripts/init_birdfolio.py \

--telegram-id {senderTelegramId} \

--region "{region}" \

--api-url "https://api-production-d0e2.up.railway.app" \

--workspace

```

  1. Search You.com (run all three):

```

"{region} most common backyard birds eBird species list"

"{region} uncommon seasonal rare birds eBird checklist"

"{region} rare vagrant endangered birds eBird"

```

  1. From results, build a checklist with 10 common, 5 rare, 1 super rare species. Use classification signals from {baseDir}/references/you-search-queries.md.
  1. Write the populated checklist to birdfolio/checklist.json in your workspace:

```json

{

"{region}": {

"common": [

{ "species": "American Robin", "slug": "american-robin", "found": false, "dateFound": null }

],

"rare": [...],

"superRare": [...]

}

}

```

  1. Reply with a welcome message and checklist preview:

```

🦅 Birdfolio is set up for {region}!

Your checklist:

Common (10): American Robin, House Sparrow, ...

Rare (5): Great Blue Heron, ...

Super Rare: California Condor

Send me a bird photo to start collecting!

```


2. Bird Identification Flow

Trigger: User sends a photo.

> Getting the photo file path: When a user sends a photo via Telegram, OpenClaw downloads it and makes the local file path available in the message attachment metadata. Capture this path — you'll need it for card generation in Step 5. If OpenClaw provides the image inline without a path, use exec to find the most recently downloaded file in OpenClaw's temp/media folder, or check %APPDATA%\openclaw\media\ on Windows. Save the photo to birdfolio/birds/{slug}-{timestamp}.jpg for permanent storage:

> ```

> exec: copy "" "birdfolio/birds/-.jpg"

> ```

Step 1 — Identify with Vision

The submitted photo is directly visible in your context. Analyze it (or use the image tool if it's not inline):

Identify the bird species in this photo. Return JSON only:
{
  "commonName": "...",
  "scientificName": "...",
  "confidence": "high|medium|low",
  "features": ["visible feature 1", "visible feature 2"]
}

Rarity rules:

  • Bird IS on the checklist → use its tier: common, rare, or superRare
  • Bird is NOT on the checklist → use bonus (shows a neutral "Bonus Find" badge, no rarity assigned)

Confidence rules:

  • "high" → proceed automatically, no confirmation needed
  • "medium" → ask: "I think this might be a [species] — based on [features]. Does that look right to you?" → wait for confirmation before continuing
  • "low" → reply: "This photo isn't clear enough for me to be confident. Could you send a clearer shot?" → stop, do not log anything

Step 2 — Rarity lookup

Search You.com:

"{commonName} {homeRegion} eBird frequency how common rare"

Classify using these signals:

TierScript valueSignals
----------------------------
Common 🟢common"abundant", "widespread", "year-round resident", >50% of checklists
Rare 🟡rare"uncommon", "seasonal", "migratory", "occasional", 5–50% of checklists
Super Rare 🔴superRare"rare", "vagrant", "accidental", "endangered", <5% of checklists

When unsure → default to rare. Always use the script value (e.g. superRare, not Super Rare) when passing --rarity to any script.

Step 3 — Get a fun fact

Search You.com:

"{commonName} bird interesting facts habitat behavior"

Extract one punchy fact (1–2 sentences).

Step 4 — Log the sighting

Save the sighting to birdfolio/lifeList.json in your workspace:

exec: python {baseDir}/scripts/log_sighting.py \
  --species "{commonName}" \
  --scientific-name "{scientificName}" \
  --rarity "{rarity}" \
  --region "{homeRegion}" \
  --notes "" \
  --workspace <absolute path to birdfolio/ in your workspace>

Capture from output: isLifer, totalSightings, totalSpecies.

Step 5 — Update checklist

Mark the species as found in birdfolio/checklist.json:

exec: python {baseDir}/scripts/update_checklist.py \
  --species "{commonName}" \
  --region "{homeRegion}" \
  --workspace <absolute path to birdfolio/ in your workspace>

Step 6 — Generate trading card

The card is a two-column design: the user's photo fills the left panel (280px), a solid dark info panel sits on the right. Always use the user's actual submitted photo — not a stock image.

Step 6a — Detect bird position with Vision:

Use the image tool on the submitted photo:

> "Where is the bird positioned horizontally in this photo? Give me approximately what percentage from the left edge the bird's center is (0–100)."

Convert the answer to a CSS value: "40% center", "60% center", "center center", etc. Use this as --object-position.

Step 6b — Generate the card HTML with the embedded photo:

exec: python {baseDir}/scripts/generate_card.py \
  --species "{commonName}" \
  --scientific-name "{scientificName}" \
  --rarity "{rarity}" \
  --region "{homeRegion}" \
  --date "{YYYY-MM-DD}" \
  --fun-fact "{funFact}" \
  --image-path "<absolute path to submitted photo>" \
  --object-position "{objectPosition}" \
  --life-count {totalSpecies} \
  --workspace <absolute path to birdfolio/ in your workspace>

--image-path embeds the user's actual photo as base64 directly into the HTML. No separate embed step needed.

Fallback if photo path is unavailable: omit --image-path and pass --image-url "" instead (find a URL via You.com: "{commonName} bird photo wildlife").

Capture cardPath from output.

Step 6c — Screenshot, save, upload, and send:

Run the screenshot script to render the card at 600×400 and save a PNG:

exec: node {baseDir}/scripts/screenshot_card.js "<cardPath>"

Capture pngPath from output.

Upload to Cloudflare R2 and get a public URL:

exec: python {baseDir}/scripts/upload_card.py "<pngPath>"

Capture url from output.

Update the sighting's card URL in the API (use the id from the log_sighting output):

PATCH /users/{telegram_id}/sightings/{sighting_id}/card
Body: {"card_png_url": "<url>"}

Send the PNG via Telegram:

message(action="send", media="<pngPath>")

Step 7 — Reply

  • If isLifer is true:

"🎉 New lifer! That's your first ever [commonName]! Bird #[totalSpecies] in your Birdfolio."

If totalSpecies == 1 (this is their very first bird ever): also send their personal PWA link:

*"🦅 Your Birdfolio is live! Bookmark this link to see your life list:

https://birdfolio.tonbistudio.com/app/[telegram_id]"*

The telegram_id is the sender's Telegram ID from the inbound message metadata (sender_id). This is also stored in birdfolio/config.json after init.

  • Otherwise:

"[commonName] spotted! You've now seen [N] species in your Birdfolio."

Include: rarity badge emoji, the fun fact, checklist status (if species was on checklist, mention it).

Fallback if screenshot fails: Send a formatted text card:

🦅 [RARITY_EMOJI] [Common Name]
Scientific: [Scientific Name]
Region: [Region] | Spotted: [Date]
Rarity: [Rarity]
💡 [Fun Fact]
Bird #[N] in your Birdfolio

3. Checklist & Stats

Trigger: "How's my checklist?", "Birdfolio progress", "How many birds have I found?"

exec: python {baseDir}/scripts/get_stats.py \
  --workspace <absolute path to birdfolio/ in your workspace>

Format response using checklistProgress from output:

📋 {region} Checklist

Common     ✅✅✅⬜⬜⬜⬜⬜⬜⬜  3/10
Rare       ✅⬜⬜⬜⬜              1/5
Super Rare ⬜                      0/1

🐦 {totalSpecies} species | {totalSightings} total sightings
📍 Last spotted: {mostRecentSighting.commonName} on {date}
🏆 Rarest find: {rarestBird.commonName} ({rarity})

Use ✅ for found, ⬜ for not found. One box per species.

Optional visual checklist card: Generate a visual HTML checklist card and screenshot it:

exec: python {baseDir}/scripts/generate_checklist_card.py \
  --workspace <absolute path to birdfolio/ in your workspace>

Then screenshot with screenshot_card.js and send the PNG.


4. Life List View

Trigger: "Show my Birdfolio", "Show my life list"

Read birdfolio/lifeList.json from your workspace.

Group lifers by rarity (Super Rare first, then Rare, then Common). Format as a text list or generate an HTML gallery, save it to birdfolio/my-birdfolio.html in your workspace, and screenshot it.


5. Species Lookup (no logging)

Trigger: "Tell me about [species]"

Search You.com:

"{species} bird facts habitat range behavior diet"
"{species} bird {homeRegion} eBird frequency resident or migratory"

Return a conversational summary. Do not log a sighting or generate a card.


6. Rarest Bird

Trigger: "What's my rarest bird?", "Show my best find"

exec: python {baseDir}/scripts/get_stats.py \
  --workspace <absolute path to birdfolio/ in your workspace>

Read rarestBird from output and reply with species name, rarity, date spotted, and region.


Quick Reference

ScriptKey argsReturns
---------------------------
init_birdfolio.py--telegram-id, --region, --api-url, --workspace{status, workspace, files_created, next}
log_sighting.py--species, --scientific-name, --rarity, --region, --date, --workspace{status, sighting, isLifer, totalSightings, totalSpecies}
update_checklist.py--species, --region, --workspace{status, tier, dateFound} or {status: not_on_checklist}
get_stats.py--workspace{totalSightings, totalSpecies, checklistProgress, mostRecentSighting, rarestBird}
generate_card.py--species, --scientific-name, --rarity, --region, --date, --fun-fact, --image-path (preferred) OR --image-url, --object-position, --life-count, --workspace{status, cardPath, filename}
generate_checklist_card.py--workspace{status, cardPath} — visual HTML checklist card
screenshot_card.js [outputPath]{status, pngPath} — saves PNG to birdfolio/cards/
upload_card.py [--secrets path]{status, url} — uploads to R2, returns public URL

All Python scripts output JSON to stdout. Always pass absolute --workspace path.

screenshot_card.js uses OpenClaw's bundled playwright-core + system Chrome/Edge (no separate install needed).

版本历史

共 1 个版本

  • v1.0.0 当前
    2026-03-29 08:24 安全 安全

安全检测

腾讯云安全 (Keen)

安全,无风险
查看报告

腾讯云安全 (Sanbu)

安全,无风险
查看报告

🔗 相关推荐

data-analysis

A股量化 AkShare

mbpz
A股量化数据分析工具,基于AkShare库获取A股行情、财务数据、板块信息等。用于回答关于A股股票查询、行情数据、财务分析、选股等问题。
★ 164 📥 59,865
data-analysis

Excel / XLSX

ivangdavila
创建、检查和编辑 Microsoft Excel 工作簿及 XLSX 文件,支持可靠的公式、日期、类型、格式、重算及模板保留功能。
★ 367 📥 140,256
productivity

Hackathon Manager

tonbistudio
追踪黑客松截止日期,管理提交清单,监控进度。适用于管理多个黑客松、查看即将到期任务、标记需求完成,或从URL自动提取信息填充截止日期和需求。
★ 0 📥 1,696