AgentSkillsCN

x-integration

为Guardian Core集成X(Twitter)。发布推文、点赞、回复、转发,以及引用推文。可用于X功能的设置、测试或故障排除。可通过“设置X”、“X集成”、“Twitter”、“发布推文”、“推文”等语句触发。

SKILL.md
--- frontmatter
name: x-integration
description: X (Twitter) integration for Guardian Core. Post tweets, like, reply, retweet, and quote. Use for setup, testing, or troubleshooting X functionality. Triggers on "setup x", "x integration", "twitter", "post tweet", "tweet".

X (Twitter) Integration

Browser automation for X interactions via WhatsApp.

Compatibility: Guardian Core v1.0.0. Directory structure may change in future versions.

Features

ActionToolDescription
Postx_postPublish new tweets
Likex_likeLike any tweet
Replyx_replyReply to tweets
Retweetx_retweetRetweet without comment
Quotex_quoteQuote tweet with comment

Prerequisites

Before using this skill, ensure:

  1. Guardian Core is installed and running - WhatsApp connected, service active
  2. Dependencies installed:
    bash
    bun pm ls playwright dotenv-cli || bun install playwright dotenv-cli
    
  3. CHROME_PATH configured in .env (if Chromium is not at default location):
    bash
    # Find your Chromium path
    which chromium || which google-chrome
    # Add to .env if needed
    CHROME_PATH=/usr/bin/chromium
    

Quick Start

bash
# 1. Setup authentication (interactive)
bunx dotenv -e .env -- bun .claude/skills/x-integration/scripts/setup.ts
# Verify: data/x-auth.json should exist after successful login

# 2. Rebuild container to include skill
./container/build.sh
# Verify: Output shows "COPY .claude/skills/x-integration/agent.ts"

# 3. Rebuild host and restart service
cd platform && mix compile
systemctl --user restart guardian-core
# Verify: systemctl --user status guardian-core shows active

Configuration

Environment Variables

VariableDefaultDescription
CHROME_PATH/usr/bin/chromiumChromium executable path
GUARDIAN_CORE_ROOTprocess.cwd()Project root directory
LOG_LEVELinfoLogging level (debug, info, warn, error)

Set in .env file (loaded via dotenv-cli at runtime):

bash
# .env
CHROME_PATH=/usr/bin/chromium

Configuration File

Edit lib/config.ts to modify defaults:

typescript
export const config = {
    // Browser viewport
    viewport: { width: 1280, height: 800 },

    // Timeouts (milliseconds)
    timeouts: {
        navigation: 30000,    // Page navigation
        elementWait: 5000,    // Wait for element
        afterClick: 1000,     // Delay after click
        afterFill: 1000,      // Delay after form fill
        afterSubmit: 3000,    // Delay after submit
        pageLoad: 3000,       // Initial page load
    },

    // Tweet limits
    limits: {
        tweetMaxLength: 280,
    },
};

Data Directories

Paths relative to project root:

PathPurposeGit
data/x-browser-profile/Chrome profile with X sessionIgnored
data/x-auth.jsonAuth state markerIgnored
logs/guardian-core.logService logs (contains X operation logs)Ignored

Architecture

code
┌─────────────────────────────────────────────────────────────┐
│  Container (Docker)                                         │
│  └── agent.ts → MCP tool definitions (x_post, etc.)    │
│      └── Writes IPC request to /workspace/ipc/tasks/       │
└──────────────────────┬──────────────────────────────────────┘
                       │ IPC (file system)
                       ▼
┌─────────────────────────────────────────────────────────────┐
│  Host (Linux)                                               │
│  └── src/index.ts → processTaskIpc()                       │
│      └── host.ts → handleXIpc()                         │
│          └── spawn subprocess → scripts/*.ts               │
│              └── Playwright → Chrome → X Website           │
└─────────────────────────────────────────────────────────────┘

Why This Design?

  • API is expensive - X official API requires paid subscription ($100+/month) for posting
  • Bot browsers get blocked - X detects and bans headless browsers and common automation fingerprints
  • Must use user's real browser - Reuses the user's actual Chrome on Host with real browser fingerprint to avoid detection
  • One-time authorization - User logs in manually once, session persists in Chrome profile for future use

File Structure

code
.claude/skills/x-integration/
├── SKILL.md          # This documentation
├── host.ts           # Host-side IPC handler
├── agent.ts          # Container-side MCP tool definitions
├── lib/
│   ├── config.ts     # Centralized configuration
│   └── browser.ts    # Playwright utilities
└── scripts/
    ├── setup.ts      # Interactive login
    ├── post.ts       # Post tweet
    ├── like.ts       # Like tweet
    ├── reply.ts      # Reply to tweet
    ├── retweet.ts    # Retweet
    └── quote.ts      # Quote tweet

Integration Points

To integrate this skill into Guardian Core, make the following modifications:


1. Host side: src/index.ts

Add import after other local imports (look for import { loadJson, saveJson, acquirePidLock } from './utils.js';):

typescript
import { handleXIpc } from '../.claude/skills/x-integration/host.js';

Modify processTaskIpc function's switch statement default case:

typescript
// Find:
default:
logger.warn({ type: data.type }, 'Unknown IPC task type');

// Replace with:
default:
const handled = await handleXIpc(data, sourceGroup, isMain, DATA_DIR);
if (!handled) {
    logger.warn({ type: data.type }, 'Unknown IPC task type');
}

2. Container side: container/agent-runner/src/ipc-mcp.ts

Add import after cron-parser import:

typescript
// @ts-ignore - Copied during Docker build from .claude/skills/x-integration/
import { createXTools } from './skills/x-integration/agent.js';

Add to the end of tools array (before the closing ]):

typescript
    ...createXTools({ groupFolder, isMain })

3. Build script: container/build.sh

Change build context from container/ to project root (required to access .claude/skills/):

bash
# Find:
container build -t "${IMAGE_NAME}:${TAG}" .

# Replace with:
cd "$SCRIPT_DIR/.."
container build -t "${IMAGE_NAME}:${TAG}" -f container/Dockerfile .

4. Dockerfile: container/Dockerfile

First, update the build context paths (required to access .claude/skills/ from project root):

dockerfile
# Find:
COPY agent-runner/package*.json ./
...
COPY agent-runner/ ./

# Replace with:
COPY container/agent-runner/package*.json ./
...
COPY container/agent-runner/ ./

Then add COPY line after COPY container/agent-runner/ ./ and before RUN bun run build:

dockerfile
# Copy skill MCP tools
COPY .claude/skills/x-integration/agent.ts ./src/skills/x-integration/

Setup

All paths below are relative to project root (GUARDIAN_CORE_ROOT).

1. Check Chrome Path

bash
# Check if Chrome exists at configured path
cat .env | grep CHROME_PATH
ls -la "$(grep CHROME_PATH .env | cut -d= -f2)" 2>/dev/null || \
echo "Chrome not found - update CHROME_PATH in .env"

2. Run Authentication

bash
bunx dotenv -e .env -- bun .claude/skills/x-integration/scripts/setup.ts

This opens Chrome for manual X login. Session saved to data/x-browser-profile/.

Verify success:

bash
cat data/x-auth.json  # Should show {"authenticated": true, ...}

3. Rebuild Container

bash
./container/build.sh

Verify success:

bash
./container/build.sh 2>&1 | grep -i "agent.ts"  # Should show COPY line

4. Restart Service

bash
cd platform && mix compile
systemctl --user restart guardian-core

Verify success:

bash
systemctl --user status guardian-core  # Should show active (running)

Usage via WhatsApp

Replace @Assistant with your configured trigger name (ASSISTANT_NAME in .env):

code
@Assistant post a tweet: Hello world!

@Assistant like this tweet https://x.com/user/status/123

@Assistant reply to https://x.com/user/status/123 with: Great post!

@Assistant retweet https://x.com/user/status/123

@Assistant quote https://x.com/user/status/123 with comment: Interesting

Note: Only the main group can use X tools. Other groups will receive an error.

Testing

Scripts require environment variables from .env. Use dotenv-cli to load them:

Check Authentication Status

bash
# Check if auth file exists and is valid
cat data/x-auth.json 2>/dev/null && echo "Auth configured" || echo "Auth not configured"

# Check if browser profile exists
ls -la data/x-browser-profile/ 2>/dev/null | head -5

Re-authenticate (if expired)

bash
bunx dotenv -e .env -- bun .claude/skills/x-integration/scripts/setup.ts

Test Post (will actually post)

bash
echo '{"content":"Test tweet - please ignore"}' | bunx dotenv -e .env -- bun .claude/skills/x-integration/scripts/post.ts

Test Like

bash
echo '{"tweetUrl":"https://x.com/user/status/123"}' | bunx dotenv -e .env -- bun .claude/skills/x-integration/scripts/like.ts

Or export CHROME_PATH manually before running:

bash
export CHROME_PATH="/path/to/chrome"
echo '{"content":"Test"}' | bun .claude/skills/x-integration/scripts/post.ts

Troubleshooting

Authentication Expired

bash
bunx dotenv -e .env -- bun .claude/skills/x-integration/scripts/setup.ts
systemctl --user restart guardian-core

Browser Lock Files

If Chrome fails to launch:

bash
rm -f data/x-browser-profile/SingletonLock
rm -f data/x-browser-profile/SingletonSocket
rm -f data/x-browser-profile/SingletonCookie

Check Logs

bash
# Host logs (relative to project root)
grep -i "x_post\|x_like\|x_reply\|handleXIpc" logs/guardian-core.log | tail -20

# Script errors
grep -i "error\|failed" logs/guardian-core.log | tail -20

Script Timeout

Default timeout is 2 minutes (120s). Increase in host.ts:

typescript
const timer = setTimeout(() => {
  proc.kill('SIGTERM');
  resolve({ success: false, message: 'Script timed out (120s)' });
}, 120000);  // ← Increase this value

X UI Selector Changes

If X updates their UI, selectors in scripts may break. Current selectors:

ElementSelector
Tweet input[data-testid="tweetTextarea_0"]
Post button[data-testid="tweetButtonInline"]
Reply button[data-testid="reply"]
Like[data-testid="like"]
Unlike[data-testid="unlike"]
Retweet[data-testid="retweet"]
Unretweet[data-testid="unretweet"]
Confirm retweet[data-testid="retweetConfirm"]
Modal dialog[role="dialog"][aria-modal="true"]
Modal submit[data-testid="tweetButton"]

Container Build Issues

If MCP tools not found in container:

bash
# Verify build copies skill
./container/build.sh 2>&1 | grep -i skill

# Check container has the file
docker run --rm --entrypoint /bin/bash guardian-core-agent:latest -c 'ls -la /app/src/skills/'

Security

  • data/x-browser-profile/ - Contains X session cookies (in .gitignore)
  • data/x-auth.json - Auth state marker (in .gitignore)
  • Only main group can use X tools (enforced in agent.ts and host.ts)
  • Scripts run as subprocesses with limited environment