integrations

star 1

Technical details for external platform integrations (APIs, credentials, rate limits). Use when posting, debugging issues, or adding new integrations.

AICMO By AICMO schedule Updated 3/24/2026

name: integrations description: Technical details for external platform integrations (APIs, credentials, rate limits). Use when posting, debugging issues, or adding new integrations. user-invocable: false

Integrations Technical Skill

How Posting Works

  1. Agent creates files in agent/outputs/{platform}/
  2. process-outputs.yml workflow runs on schedule
  3. Calls platform integration script for each file
  4. Success → file moves to posted/
  5. Failure → file stays for next run

X (Twitter) Integration

Credentials (OAuth 1.0a - preferred)

Stable tokens that don't expire.

Name Type Description
X_API_KEY var Consumer API Key
X_API_KEY_SECRET secret Consumer API Secret
X_ACCESS_TOKEN secret Access Token
X_ACCESS_TOKEN_SECRET secret Access Token Secret

Credentials (OAuth 2.0 - fallback)

Warning: Refresh token rotates on each use - not recommended.

Name Type Description
X_CLIENT_ID var OAuth 2.0 Client ID
X_CLIENT_SECRET secret OAuth 2.0 Client Secret
X_REFRESH_TOKEN secret Refresh token (rotates!)

Reply File Format

Reply files use REPLY_TO: header with the numeric tweet ID (NOT a handle or URL).

REPLY_TO: 1893847362910283745

Your reply text here...

NEVER use handles like @SomeUser — the API requires numeric IDs matching ^[0-9]{10,}$. To find a tweet ID: it's the number at the end of the tweet URL (e.g., https://x.com/user/status/1893847362910283745).

Invalid reply targets are auto-skipped to skipped/.

Rate Limits

  • Premium tier: API limits are higher, but workflow drain rate governs in practice
  • Observed drain rate: ~3 tweets/run, ~4 runs/day = ~12 tweets/day posted via workflow
  • Queue hard limit: 15 pending files max (publishing skill rule, not API limit)
  • Workflow adds 5s delay between posts
  • On 429 error, stops processing remaining files
  • Free tier limit: 17 tweets per 24-hour rolling window

Bluesky Integration

Credentials

App password authentication (no OAuth complexity).

Name Type Description
BLUESKY_HANDLE var Bluesky handle (e.g., user.bsky.social)
BLUESKY_APP_PASSWORD secret App password (Settings > App Passwords)

Rate Limits

  • 300 grapheme limit per post (not characters — emoji/CJK may count differently)
  • ~11,666 createRecord calls per day (1,667/hour for repo writes)
  • Login: 30 per 5 minutes, 300 per day per handle
  • Script adds 0.5s delay between posts

Reply File Format

Reply files use REPLY_TO: header with an AT URI (NOT a handle or URL).

REPLY_TO: at://did:plc:nphpplr7dcdi4wyjuizmz2wg/app.bsky.feed.post/3mfhgscgm4h2o

Your reply text here...

NEVER use handles like @someone.com — the API requires AT URIs starting with at://. Script resolves URI → CID automatically for strong refs. Invalid reply targets are auto-skipped to skipped/.

Thread Support

Same --- separator as X. Each part must be under 300 graphemes. Thread replies chain via reply.root (first post) + reply.parent (previous post).

Diagnostics

Check credentials configured

gh variable list | grep X_

If variables exist, presume secrets are also configured.

Check posting runs

gh run list --workflow=process-outputs.yml --limit 5
gh run view <run-id> --log

Get tweet IDs of recently posted tweets (for reply-to-own)

# Step 1: Get latest run ID
gh run list --workflow=process-outputs.yml --limit 1 --json databaseId,createdAt

# Step 2: Extract tweet IDs from that run's logs
gh run view <run_id> --log 2>/dev/null | grep 'INFO Response:' | head -5

Log format: INFO Response: {"data": {"id": "2033632169034125426", "text": "..."}}

Extract the numeric ID from "id": "XXXXXXXXXX" — use this as REPLY_TO: value.

Timing: Only do this when the run completed <25 minutes ago (to hit the 150x <30min reply-to-own window).

Common Issues

Symptom Cause Fix
429 errors Rate limit Wait 15+ min
Files in posted/ but not posted Bad exit code Check integration script logs
Files in skipped/ Invalid content (bad reply target, duplicate, etc.) Check reply format — must use numeric ID (X) or AT URI (Bluesky), not handles
Auth errors Missing credentials Check gh variable list

Adding New Platforms

  1. Create agent/integrations/{platform}/post.sh
    • Takes content as arg: post.sh "content"
    • Returns 0 on success, 1 on failure
  2. Create agent/outputs/{platform}/
  3. Add credentials to process-outputs.yml env section
Install via CLI
npx skills add https://github.com/AICMO/Autonomous-Agent-X-Bluesky-TEMPLATE --skill integrations
Repository Details
star Stars 1
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator