AGENT SKILL

community-manager

暂无简介

License 许可
MIT
所属仓库
aeonfun/aeon
最近更新
2026-11-14
Stars
★ 792
Forks
308

03 SKILL.md 正文

${var} — Optional. Override the channel name. If empty, summarises [REPLACE: CHANNEL_NAME].

Today is ${today}. Read the last 24h of activity in [REPLACE: CHANNEL_PLATFORM] channel [REPLACE: CHANNEL_NAME] and produce a community digest.

Required secrets per platform

Platform Secrets Notes
discord DISCORD_BOT_TOKEN, DISCORD_CHANNEL_ID Bot must be in the server with View Channel + Read Message History.
telegram TELEGRAM_BOT_TOKEN, TELEGRAM_CHAT_ID Bot must have been added to the chat (private chats and groups both work).
slack SLACK_BOT_TOKEN, SLACK_CHANNEL_ID Bot needs channels:history (public) or groups:history (private) scope.

Read the "Keys set for this run" line in your run notes, never a shell test (those are refused and cost a turn). If the secrets for [REPLACE: CHANNEL_PLATFORM] are not on it, log COMMUNITY_NO_TOKEN and exit cleanly.

Steps

  1. Resolve channel - the channel is ${var} if set, else [REPLACE: CHANNEL_NAME]. A channel or chat ID is not a credential, so ./secretcurl does not fill a {DISCORD_CHANNEL_ID} style placeholder: print the ID with its own call, node -e 'console.log(process.env.DISCORD_CHANNEL_ID)' (or SLACK_CHANNEL_ID), and write the printed value into the call literally (the <CHANNEL_ID> below). The exact API call depends on [REPLACE: CHANNEL_PLATFORM], one call each:

    • discord:
      ./secretcurl -s -o /tmp/community-messages.json -w 'discord http=%{http_code}\n' -H "Authorization: Bot {DISCORD_BOT_TOKEN}" "https://discord.com/api/v10/channels/<CHANNEL_ID>/messages?limit=100"
      
    • telegram - getUpdates polling has limits; better to read the bot's stored offset state from memory/topics/[REPLACE: SKILL_NAME]-tg-offset.json (Read it, then write the offset in literally):
      ./secretcurl -s -o /tmp/community-messages.json -w 'telegram http=%{http_code}\n' "https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/getUpdates?offset=<OFFSET>&limit=100"
      
    • slack - get the window start with its own call, date -u -d '24 hours ago' +%s, and write it in as <OLDEST>:
      ./secretcurl -s -o /tmp/community-messages.json -w 'slack http=%{http_code}\n' -H "Authorization: Bearer {SLACK_BOT_TOKEN}" -G "https://slack.com/api/conversations.history" -d channel=<CHANNEL_ID> -d oldest=<OLDEST> -d limit=200
      
  2. Filter to the last 24h — drop messages older than now - 24h. Drop bot messages (most platforms expose is_bot / bot_id). Keep replies.

  3. Cluster into threads — Discord and Slack expose explicit thread/parent IDs; Telegram doesn't. For Telegram, cluster by reply-chain hops.

  4. Score threads — for each thread:

    • Reach — unique participants × log(message count).
    • Question pressure — does the parent message end with ? or contain words like "how", "why", "anyone", "stuck"? +5.
    • Recency — within the last 12h gets full marks.

    Pick the top [REPLACE: TOP_N_THREADS] threads.

  5. Detect open questions — scan all parent-level messages. If a message ends with ? and has zero replies after 6 hours, mark it as OPEN_QUESTION. List them separately so the operator can chase.

  6. Write output/articles/[REPLACE: SKILL_NAME]-${today}.md:

    # [REPLACE: CHANNEL_NAME] — ${today}
    
    **Volume**: N messages from M participants (vs 7d avg of K).
    
    ## Top [REPLACE: TOP_N_THREADS] threads
    1. [Author · timestamp] "Parent message excerpt..."
       → N replies, M reactions
       → Permalink
    
    ...
    
    ## Open questions (no reply > 6h)
    - [Author] "Question text..." → permalink
    
    ## Volume sparkline (last 7 days)
    ▁▂▃▅▇▆▄
    
  7. Notify via ./notify with a 3-line summary:

    *[REPLACE: CHANNEL_NAME] — ${today}*
    N messages · M participants · K open questions · top thread: <one-line>
    Full digest: <url>
    

    Skip the notification on quiet days (volume < 25% of 7d avg AND zero OPEN_QUESTIONs).

  8. Log — append to memory/logs/${today}.md:

    ## [REPLACE: SKILL_NAME]
    - **Channel**: [REPLACE: CHANNEL_PLATFORM]/[REPLACE: CHANNEL_NAME]
    - **Volume**: messages=N, participants=M, vs_7d_avg=Δ%
    - **Threads picked**: [REPLACE: TOP_N_THREADS] (of K candidates)
    - **Open questions**: N
    - **Status**: COMMUNITY_OK | COMMUNITY_QUIET | COMMUNITY_DEGRADED (api errors)
    

Network note

Discord and Slack need their bot token in the Authorization header; Telegram puts it in the URL path (/bot{TELEGRAM_BOT_TOKEN}/). A bare $TOKEN on a curl line is refused by the Bash permission analyzer - so call ./secretcurl with a {ENV_NAME} placeholder instead. The token (injected via the skill's requires:) is substituted inside the helper and never appears on the command line, as in the step 1 calls.

Shell shape. Each Bash call is one allowed command (pipes are fine). The run refuses a call that sets a variable (CHANNEL=...), uses if / for, tests a key, joins commands with ;, && or ||, redirects into a file, or puts a shell variable on a ./secretcurl line ($DISCORD_CHANNEL_ID), and each refusal costs a model turn. So write IDs, offsets and dates into each call literally, save replies with -o /tmp/<file>, and write the offset file, the article and the log with Write/Edit.

Constraints

  • Privacy. Don't quote DMs or anything from a private channel verbatim into a public notification — paraphrase, attribute by display name only, never include user IDs.
  • The "open questions" section is the most useful output. Even on a quiet day, if there's an unanswered question, surface it. That's the operator-action signal.
  • Avoid bot-on-bot loops. If this skill notifies into the same channel it reads from, filter your own bot's messages out before scoring.

04 同仓库更多 Skills

aeonfun
aeonfun/aeon

sns-digest

Digest Internet Computer governance - new and open NNS proposals and SNS DAO proposals - so the operator sees what is up for a vote without watching the dashboard. Fully public, no secret; fires only when there is something new to report.

★ 792
aeonfun
aeonfun/aeon

icp-deploy-check

Pre-deploy safety checklist for an Internet Computer Rust canister - read a local/cloned canister repo and verify the deploy-time footguns from the canister-security checklist (controller backup, anonymous-principal rejection, no mainnet fetch_root_key, upgrade safety) before it ships. Static, read-only, no network and no mainnet action.

运维与部署
★ 792
aeonfun
aeonfun/aeon

canister-status

Monitor Internet Computer canisters for control-plane changes - a new controller, a module-hash change (upgrade), or a canister going missing from the public index - and alert the moment one happens. Uses only the public IC dashboard API.

开发工程师后端与接口
★ 792
aeonfun
aeonfun/aeon

you-web-search

Web search using You.com Search API with high-quality, cited results — runs keyless out of the box; YDC_API_KEY unlocks higher limits and real-time web crawling

开发工程师后端与接口
★ 792
aeonfun
aeonfun/aeon

write-tweet

Multi-format tweet studio - standalone drafts (10 across 5 size tiers), a 5-10 tweet thread, or 10 remixes of past tweets, selected via ${var}

★ 792
aeonfun
aeonfun/aeon

weekly-aeoncard

Build a weekly token-consumption recap image from memory/token-usage.csv - this week + all-time totals, top skills, rendered as a shareable SVG card.

图像与多媒体
★ 792