AgentStack
SKILL verified MIT Self-run

Kelly Messenger

skill-mr-kelly-skills-kelly-messenger · by mr-kelly

Personal App-in-Skill unified chat inbox aggregating WhatsApp, Discord, Slack, and Telegram messages into one local app with a reply queue. Use when the user invokes $kelly-messenger or /kelly-messenger, wants a unified inbox, chat aggregation, to read WhatsApp/Discord/Slack/Telegram messages in one place, review unanswered conversations, queue or approve replies, run connector sync, or manage th…

No reviews yet
0 installs
1 views
0.0% view→install

Install

$ agentstack add skill-mr-kelly-skills-kelly-messenger

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Kelly Messenger? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Kelly Messenger

Overview

Use this skill as Kelly's unified chat inbox operator. It aggregates messages from WhatsApp, Discord, Slack, and Telegram (extensible to WeChat, iMessage, LINE, Messenger) into one file-backed App-in-Skill app: a command-desk overview, a unified inbox with chat transcripts and a reply composer, an outbox review queue for outgoing replies, and account/connector health.

Default interaction mode: App UI. Unless the user explicitly asks for chat-only handling, check onboarding/config, refresh or load the local message snapshot, start/reuse the local app with app/start.sh, and give the actual local URL. Use chat-only mode only when the user says "纯聊天", "chat only", "不要打开 UI", or similar.

App UI Screenshots

OverviewMessaging command desk with reply-decision counts, per-platform sync status, and oldest-waiting indicator. ConversationChat transcript with an agent-suggested reply prefilled in the composer, ready to edit and queue.

Unified inboxConversations across WhatsApp, Slack, Discord, and Telegram sorted by latest activity with waiting-time badges. Reply outboxApproval queue for outgoing replies: every message is reviewed before the agent sends it via platform connectors.

Boundary

  • The app reads and writes local files only and never touches any network beyond 127.0.0.1. It cannot send messages: the composer only queues drafts into the local outbox.
  • Every outgoing message is approval-required. The skill executes only replies whose outbox status is approved, via scripts/send_outbox.ts (dry-run by default) or, for browser_agent/manual connectors, by the agent performing the handoff after --send marks them handoff_to_agent.
  • Own accounts only: read and send exclusively through accounts the user owns and has configured. Respect each platform's terms of service and rate limits; prefer official APIs; keep sync read-only.
  • Never store passwords, QR-login payloads, or session tokens. For browser_agent collection the agent drives the user's own already-authenticated web session and stores only message text needed for review.
  • Treat all chat content as sensitive. Do not commit config.local.json, env files, app/.data/, exports, tokens, or customer PII.

First Run And Onboarding

On invocation, check app/.data/onboarding.json and private config readiness. If onboarding is absent/incomplete, guide setup before syncing real accounts.

Private config priority:

  1. KELLY_MESSENGER_CONFIG=/absolute/path/to/config.json
  2. skills/kelly-messenger/config.local.json
  3. ~/.config/kelly-messenger/config.json
  4. skills/kelly-messenger/config.example.json as template only

Env priority:

  1. Existing environment variables
  2. KELLY_MESSENGER_ENV_FILE=/absolute/path/to/.env
  3. Repository root .env
  4. skills/kelly-messenger/.env.local
  5. ~/.config/kelly-messenger/.env

Onboarding asks, turn by turn: which platforms to connect, which connector method per account, and which env var names hold the tokens. Ask for non-secret details only: platform, display name, workspace/server, channels or chats to watch, reply style, and env var names. Never ask the user to paste secret values into chat; secrets belong only in local env files.

Connector reality per platform (declare as "connector" on each account):

  • slack — official Web API (conversations.history to read, chat.postMessage to send) with a bot/user token from env (bot_token_env / user_token_env).
  • discord — official REST API with a bot token from env (bot_token_env); the bot must be in the servers/channels it should read.
  • telegram — Telegram Bot API (getUpdates to read, sendMessage to send) with a bot token from env (bot_token_env); the bot must share the chats.
  • whatsapp_cloud — WhatsApp Business Cloud API with access_token_env + phone_number_id_env. Inbound messages arrive via webhook only, so history is collected via ingest; sends use the Cloud API.
  • browser_agent — the agent drives the user's own web session (e.g. WhatsApp Web) with the browser skill, then writes a payload through scripts/ingest_messages.ts. No passwords or QR secrets are ever stored.
  • manual — the user or agent prepares an ingest payload by hand. Use for anything else (WeChat, iMessage, LINE, Messenger).

When setup is complete and the user confirms, write app/.data/onboarding.json:

{
  "completed": true,
  "completed_at": "ISO timestamp",
  "config_version": "1"
}

Local App

Start the app with:

skills/kelly-messenger/app/start.sh

The app uses local HTTP on 127.0.0.1, preferring ports 3000 through 4000, or KELLY_MESSENGER_UI_PORT when set. /api/state identifies the app as kelly-messenger.

Required app views (hash routes):

  • #/overview: messaging command desk. Human-attention numbers (conversations needing a reply decision, approved replies waiting for send, blocked), oldest-waiting indicator, per-platform account cards (unread, conversations, last sync, connector method), and recent activity.
  • #/inbox and #/inbox/: the unified inbox. Left: conversations across all platforms sorted by latest activity with platform badge, title, preview, unread dot, and waiting time. Right: chat transcript (incoming left, Kelly's outgoing right, sender names, timestamps, channel/workspace metadata) plus a reply composer with an agent-suggested_reply prefill when present, a note field, and a Queue reply button. Queued replies appear as dashed "queued" bubbles.
  • #/outbox: review queue over outgoing replies with workflow states needs_review / changes_requested / approved / done / blocked, stable refs (Reply #1), editable draft text, reason/context, and decision buttons (approve / request changes / save edit / block). done means sent, with the execution result shown.
  • #/accounts: connected accounts with platform, workspace, connector method, env readiness boolean, last sync, conversation/unread counts, and warnings.
  • #/settings: sanitized config summary (data provider, config path, onboarding state, reply style, accounts with env readiness booleans), sync log, and last execution report. Never secrets.

Demo mode:

  • ?demo=overview, ?demo=inbox, ?demo=chat (opens the featured conversation wa-lena-pricing with an agent-suggested reply prefilled), and ?demo=outbox select named deterministic mock scenes.
  • lang=en or lang=zh forces UI chrome language for screenshots. Deep links such as /?demo=chat&lang=en#/inbox/wa-lena-pricing work.
  • Demo mode never reads or writes app/.data/. Composer and outbox buttons still work but act on in-memory state only and show a demo notice.

UI language: English and Chinese chrome with Auto default following the browser language; explicit selector persisted locally. Keep message content, sender names, and chat titles in their original language.

File Contract

Read references/messenger-schema.md before editing the app, scripts, or any generated JSON.

  • app/.data/messages_snapshot.json: accounts, conversations with transcripts, metrics, sync log. Written only by scripts/sync_messages.ts and scripts/ingest_messages.ts.
  • app/.data/outbox.json: the decisions file — queued/decided outgoing replies keyed by reply id with conversation ref, text, status, decision, timestamps.
  • app/.data/agent_tasks.json: queued agent work; request_changes decisions land here as revise_reply tasks.
  • app/.data/execution_report.json: latest send run results.
  • app/.data/onboarding.json: onboarding completion marker.
  • app/.data/agent.lock: temporary lock while the skill syncs, ingests, or sends. While it exists the app rejects writes and renders the composer and outbox read-only.

Validate with node scripts/validate_ui_schema.ts before relying on a snapshot in the UI.

Sync Workflow

  1. Detect mode. Default to App UI.
  2. Load private config. If only config.example.json exists, enter onboarding.
  3. For API connectors (slack, discord, telegram, whatsapp_cloud), run node scripts/sync_messages.ts. It uses global fetch only, prints a clear friendly message when tokens are missing, refuses to run under an active lock, acquires the lock itself, merges into the snapshot by stable message ids, appends sync_log entries, and releases the lock.
  4. For browser_agent platforms, use the browser skill on the user's own session to read conversations, build an ingest payload (see the schema), and run node scripts/ingest_messages.ts payload.json — the single write-path for collected messages. Same for manual.
  5. Start/reuse the UI and report the URL. Surface connector problems as snapshot warnings, not silent failures.

Reply And Outbox Workflow

  1. Queue: the user writes or edits a reply in the composer (optionally starting from the agent's suggested_reply) and clicks Queue reply; the app writes it to outbox.json as needs_review. The agent may also queue drafts (suggested_by: "agent") with a reason.
  2. Review: in #/outbox the user approves, edits (Save edit), requests changes, or blocks each reply. request_changes enqueues a revise_reply task in agent_tasks.json.
  3. Agent revision loop: poll agent_tasks.json, redraft the reply text honoring the comment and the config reply_style, set the reply back to needs_review, and mark the task done.
  4. Send: only after the user asks to send, run node scripts/send_outbox.ts (dry-run) and show the plan. With explicit approval, run node scripts/send_outbox.ts --send: it re-checks the lock and each reply's approval immediately before sending, sends API-connector replies via the official APIs, marks browser_agent/manual replies as handoff_to_agent for the agent to deliver through the user's session, sets sent replies to done, and writes execution_report.json.
  5. Report per-reply results back to the user with the stable Reply #N refs.

Safety Defaults

  • Never send without an approved status recorded in the outbox, and never bypass the dry-run → --send sequence.
  • Prefer read-scoped tokens where the platform offers them; keep sync strictly read-only.
  • Redact tokens and token-like strings from logs, reports, and UI state; expose only env-var readiness booleans.
  • Keep sends idempotent: stable reply ids, execution results stored on the reply, and re-reading decisions before each send.
  • If a send target is missing (provider_conversation_id), block that reply and ask for configuration instead of guessing.
  • Honor platform rate limits; on 429s back off rather than retrying aggressively.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.