Steps 0–10 of the v2 plan, 194 tests passing. Core infrastructure - Shared Redis client (src/redis.ts); all four Redis consumers migrated - Vitest test harness with vitest.config.ts and npm test/test:watch scripts Billing & invoicing (Steps 1–2) - Monthly invoice generation with idempotency (MySQL uq_customer_period unique key) - Cron job with Redis distributed lock (Lua compare-delete, 1-hr TTL) - Invoice emailer via nodemailer (FETCHERPAY SMTP) - Billing middleware: checkLimit gate in handleToolCall; platform attribution fix Email multi-tenancy (Step 3) - EmailCtx = Account | EmailCredentials; imap.ts + smtp.ts accept both - resolveEmailCtx helper in tools.ts; all email tools use customer credentials Analytics + platform health (Steps 4–5) - Chart.js bar charts for platform breakdown and daily activity - Token expiry check in getCredential with dynamic import refresh - platform-health.ts: per-platform health probe with 10-min Redis cache - GET /api/health/platforms; "Token expired" amber badge in dashboard Tool schema filtering (Step 6) - stripAccountParam deep-clones tool schemas; multi-tenant sessions never see the internal account enum OAuth hardening (Step 7) - Atomic auth code consumption: UPDATE SET used=TRUE, check affectedRows - customer_id threaded through oauth_auth_codes → oauth_tokens - getTokenCustomer(); requireAuth resolves req.customer from Bearer token - Consent page requires authenticated session; redirect_uri validated against registered URIs; http://localhost:* loopback wildcard DCR browser flow (Step 8) - ensureOAuthAppRegistered() upserts pre-registered SquareMCP OAuth app on startup with redirect URIs for mcp-callback, localhost:*, claude-desktop, opencode - GET /oauth/connect-mcp → server-side redirect (client_id off frontend) - GET /oauth/mcp-callback → exchanges code, renders config snippet page with copy buttons for Claude Desktop and Codex CLI Webhooks (Step 9) - webhook_url + webhook_secret columns on customers - deliverWebhook(): HMAC-SHA256 signing, 3× exponential retry (1s/4s/16s), Redis DLQ with 7-day TTL on total failure - isValidWebhookUrl(): SSRF protection (blocks RFC-1918, localhost, .local) - POST /api/webhooks/config (secret returned once), GET, DELETE - GET /api/admin/webhooks/dlq/:customerId - WhatsApp POST route uses express.raw() for raw body preservation - Dashboard Webhooks tab with secret-once display and copy button Developer docs (Step 10) - docs/ static HTML site (GitHub Pages, no build pipeline) - index.html: landing page with client + platform overview - getting-started.html: tabbed MCP config for Claude Desktop, Codex CLI, opencode - platforms.html: LinkedIn, TikTok, WhatsApp, Instagram, Twitter, Telegram guides - agent-tutorial.html: complete Node.js agent (Anthropic SDK + MCP SDK), LinkedIn posting loop, extensions for multi-platform + inbound webhook reaction Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
289 lines
13 KiB
HTML
289 lines
13 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Platform Guides — SquareMCP Docs</title>
|
||
<link rel="stylesheet" href="styles.css">
|
||
</head>
|
||
<body>
|
||
|
||
<nav class="site-nav">
|
||
<div class="nav-inner">
|
||
<a href="index.html" class="nav-logo"><span class="nav-logo-mark">S</span> SquareMCP</a>
|
||
<div class="nav-links">
|
||
<a href="getting-started.html">Getting started</a>
|
||
<a href="platforms.html" class="active">Platform guides</a>
|
||
<a href="agent-tutorial.html">Agent tutorial</a>
|
||
<a href="https://hermes.squaremcp.com/openapi-social.json" target="_blank">API reference ↗</a>
|
||
</div>
|
||
<a href="https://squaremcp.com" class="nav-cta" target="_blank">Open app</a>
|
||
</div>
|
||
</nav>
|
||
|
||
<div class="page">
|
||
<div class="hero">
|
||
<h1>Platform guides</h1>
|
||
<p>Step-by-step instructions for connecting each platform. Click a platform to jump to its guide.</p>
|
||
</div>
|
||
|
||
<div class="card-grid">
|
||
<a href="#linkedin" class="card" style="text-decoration:none;color:inherit;"><h4><span class="icon" style="background:#0a66c2;color:#fff;">in</span> LinkedIn</h4><p>OAuth access token, post text and video.</p></a>
|
||
<a href="#tiktok" class="card" style="text-decoration:none;color:inherit;"><h4><span class="icon" style="background:#000;color:#fff;">🎵</span> TikTok</h4><p>Login Kit OAuth flow, upload video.</p></a>
|
||
<a href="#whatsapp" class="card" style="text-decoration:none;color:inherit;"><h4><span class="icon" style="background:#25d366;color:#fff;">💬</span> WhatsApp</h4><p>Business API, templates, inbound webhooks.</p></a>
|
||
<a href="#instagram" class="card" style="text-decoration:none;color:inherit;"><h4><span class="icon" style="background:linear-gradient(45deg,#f09433,#dc2743,#bc1888);color:#fff;">📷</span> Instagram</h4><p>Business account, Graph API token.</p></a>
|
||
<a href="#twitter" class="card" style="text-decoration:none;color:inherit;"><h4><span class="icon" style="background:#000;color:#fff;">𝕏</span> Twitter / X</h4><p>API v2 credentials, tweet with media.</p></a>
|
||
<a href="#telegram" class="card" style="text-decoration:none;color:inherit;"><h4><span class="icon" style="background:#0088cc;color:#fff;">✈️</span> Telegram</h4><p>Bot token from BotFather.</p></a>
|
||
</div>
|
||
|
||
<!-- ── LinkedIn ──────────────────────────────────────────────────── -->
|
||
<h2 id="linkedin"><span class="icon" style="background:#0a66c2;color:#fff;margin-right:8px;">in</span> LinkedIn</h2>
|
||
|
||
<h3>What you can do</h3>
|
||
<ul>
|
||
<li>Post text updates, articles, images, and videos</li>
|
||
<li>Search connections and send direct messages</li>
|
||
<li>Retrieve your profile and network info</li>
|
||
</ul>
|
||
|
||
<h3>Connecting LinkedIn</h3>
|
||
<ol class="steps">
|
||
<li>
|
||
<div>
|
||
<strong>Create a LinkedIn app</strong>
|
||
Go to <a href="https://developer.linkedin.com/apps" target="_blank">developer.linkedin.com/apps</a> and create a new app. Add your company page and request the <code>w_member_social</code> and <code>r_liteprofile</code> products.
|
||
</div>
|
||
</li>
|
||
<li>
|
||
<div>
|
||
<strong>Generate an access token</strong>
|
||
Use the LinkedIn OAuth 2.0 token generator in your app dashboard, or use the 3-legged OAuth flow. Copy the access token (valid 60 days; refresh tokens extend to ~12 months).
|
||
</div>
|
||
</li>
|
||
<li>
|
||
<div>
|
||
<strong>Paste into SquareMCP dashboard</strong>
|
||
Open the SquareMCP dashboard → LinkedIn → Connect → paste your access token → Save.
|
||
</div>
|
||
</li>
|
||
</ol>
|
||
|
||
<h3>Available tools</h3>
|
||
<p class="code-label">Example prompts</p>
|
||
<pre><code>Post a LinkedIn update: "Excited to announce our new product launch!"
|
||
|
||
Post a LinkedIn video from /tmp/demo.mp4 with caption "Watch our product demo"
|
||
|
||
Search my LinkedIn connections for people at Anthropic
|
||
|
||
Send a LinkedIn message to John Smith saying "Great meeting you at the conference"</code></pre>
|
||
|
||
<div class="callout">
|
||
<strong>Token refresh</strong>
|
||
LinkedIn access tokens expire after 60 days. SquareMCP will automatically attempt a refresh using the refresh token. If refresh fails (e.g., the user revokes access), reconnect from the dashboard.
|
||
</div>
|
||
|
||
<!-- ── TikTok ──────────────────────────────────────────────────────── -->
|
||
<h2 id="tiktok"><span class="icon" style="background:#000;color:#fff;margin-right:8px;">🎵</span> TikTok</h2>
|
||
|
||
<h3>What you can do</h3>
|
||
<ul>
|
||
<li>Upload and publish videos with captions</li>
|
||
<li>Set privacy level (public, friends, private)</li>
|
||
<li>View creator info and video status</li>
|
||
</ul>
|
||
|
||
<h3>Connecting TikTok</h3>
|
||
<ol class="steps">
|
||
<li>
|
||
<div>
|
||
<strong>OAuth via SquareMCP dashboard</strong>
|
||
Open the SquareMCP dashboard → TikTok → Connect. You'll be redirected to TikTok to authorise the app. SquareMCP uses TikTok Login Kit with <code>video.publish</code> and <code>user.info.basic</code> scopes.
|
||
</div>
|
||
</li>
|
||
<li>
|
||
<div>
|
||
<strong>Allow the requested permissions</strong>
|
||
TikTok shows the requested scopes. Click <strong>Authorize</strong>. You'll be redirected back to the dashboard with a "Connected" badge.
|
||
</div>
|
||
</li>
|
||
</ol>
|
||
|
||
<h3>Uploading a video</h3>
|
||
<p>Videos must be hosted at a publicly accessible URL. The tool uploads the video to TikTok's servers asynchronously — use <code>tiktok_get_video_status</code> to poll for completion.</p>
|
||
|
||
<p class="code-label">Example prompts</p>
|
||
<pre><code>Upload the video at https://cdn.example.com/demo.mp4 to TikTok
|
||
with caption "Check out our new feature! #AI #productlaunch"
|
||
and set privacy to PUBLIC_TO_EVERYONE
|
||
|
||
Check the status of my last TikTok upload</code></pre>
|
||
|
||
<div class="callout callout-warn">
|
||
<strong>TikTok sandbox vs. production</strong>
|
||
TikTok's Content Posting API requires app approval for production use. New apps start in sandbox mode (videos published to a test account only). Apply for production access through the TikTok developer portal.
|
||
</div>
|
||
|
||
<!-- ── WhatsApp ──────────────────────────────────────────────────── -->
|
||
<h2 id="whatsapp"><span class="icon" style="background:#25d366;color:#fff;margin-right:8px;">💬</span> WhatsApp</h2>
|
||
|
||
<h3>What you can do</h3>
|
||
<ul>
|
||
<li>Send freeform messages and approved template messages</li>
|
||
<li>Send images, documents, and media</li>
|
||
<li>Receive inbound messages via webhook and forward to your AI agent</li>
|
||
<li>List all approved message templates</li>
|
||
</ul>
|
||
|
||
<h3>Prerequisites</h3>
|
||
<p>You need a <strong>WhatsApp Business Account</strong> and a phone number registered through the <a href="https://business.facebook.com/settings/whatsapp-business-accounts" target="_blank">Meta Business Manager</a>.</p>
|
||
|
||
<h3>Connecting WhatsApp</h3>
|
||
<ol class="steps">
|
||
<li>
|
||
<div>
|
||
<strong>Get your credentials from Meta</strong>
|
||
In Meta for Developers → Your App → WhatsApp → API Setup:
|
||
<ul>
|
||
<li><strong>Phone Number ID</strong> — the ID of your registered number</li>
|
||
<li><strong>Business Account ID</strong> — your WABA ID</li>
|
||
<li><strong>Permanent Access Token</strong> — generate from System Users in Business Manager</li>
|
||
</ul>
|
||
</div>
|
||
</li>
|
||
<li>
|
||
<div>
|
||
<strong>Enter credentials in dashboard</strong>
|
||
Open SquareMCP dashboard → WhatsApp → Connect → paste all three values → Save.
|
||
</div>
|
||
</li>
|
||
<li>
|
||
<div>
|
||
<strong>Configure the webhook (optional — for inbound messages)</strong>
|
||
In Meta for Developers → Webhooks, set the callback URL to <code>https://hermes.squaremcp.com/webhook/whatsapp</code> and the verify token to your <code>WA_VERIFY_TOKEN</code> (ask support for this). Subscribe to the <code>messages</code> field.
|
||
Then configure a forwarding URL in SquareMCP dashboard → Webhooks so inbound messages reach your server.
|
||
</div>
|
||
</li>
|
||
</ol>
|
||
|
||
<h3>Sending messages</h3>
|
||
<p class="code-label">Freeform message (within 24-hour session window)</p>
|
||
<pre><code>Send a WhatsApp message to +447911123456 saying:
|
||
"Hi! Your order #12345 has shipped and will arrive tomorrow."</code></pre>
|
||
|
||
<p class="code-label">Template message (anytime)</p>
|
||
<pre><code>List my WhatsApp message templates
|
||
|
||
Send the "order_confirmation" template to +447911123456
|
||
with variables: order_id=12345, delivery_date="14 May 2026"</code></pre>
|
||
|
||
<div class="callout">
|
||
<strong>24-hour rule</strong>
|
||
WhatsApp only allows freeform messages within 24 hours of a customer contacting you first. Outside that window, use approved template messages.
|
||
</div>
|
||
|
||
<!-- ── Instagram ─────────────────────────────────────────────────── -->
|
||
<h2 id="instagram"><span class="icon" style="background:linear-gradient(45deg,#f09433,#dc2743,#bc1888);color:#fff;margin-right:8px;">📷</span> Instagram</h2>
|
||
|
||
<h3>What you can do</h3>
|
||
<ul>
|
||
<li>Publish image posts and reels</li>
|
||
<li>View profile and recent media</li>
|
||
</ul>
|
||
|
||
<h3>Connecting Instagram</h3>
|
||
<p>Instagram posting requires a <strong>Business or Creator account</strong> connected to a Facebook Page.</p>
|
||
|
||
<ol class="steps">
|
||
<li>
|
||
<div>
|
||
<strong>Get a Graph API access token</strong>
|
||
Open the <a href="https://developers.facebook.com/tools/explorer/" target="_blank">Graph API Explorer</a>, select your app, and request <code>instagram_basic</code>, <code>instagram_content_publish</code>, and <code>pages_read_engagement</code> permissions. Generate a User Access Token and exchange it for a long-lived token.
|
||
</div>
|
||
</li>
|
||
<li>
|
||
<div>
|
||
<strong>Find your Business Account ID</strong>
|
||
Call <code>GET /me/accounts</code> then <code>GET /{page_id}?fields=instagram_business_account</code> to find your Instagram Business Account ID.
|
||
</div>
|
||
</li>
|
||
<li>
|
||
<div>
|
||
<strong>Enter credentials in dashboard</strong>
|
||
SquareMCP dashboard → Instagram → Connect → paste the access token and Business Account ID.
|
||
</div>
|
||
</li>
|
||
</ol>
|
||
|
||
<p class="code-label">Example prompts</p>
|
||
<pre><code>Post an Instagram reel from https://cdn.example.com/reel.mp4
|
||
with caption "Behind the scenes of our product shoot 🎬 #startup"
|
||
|
||
Get my last 10 Instagram posts</code></pre>
|
||
|
||
<!-- ── Twitter ────────────────────────────────────────────────────── -->
|
||
<h2 id="twitter"><span class="icon" style="background:#000;color:#fff;margin-right:8px;">𝕏</span> Twitter / X</h2>
|
||
|
||
<h3>Connecting Twitter / X</h3>
|
||
<ol class="steps">
|
||
<li>
|
||
<div>
|
||
<strong>Create a developer app</strong>
|
||
Go to <a href="https://developer.twitter.com/en/portal/dashboard" target="_blank">developer.twitter.com</a> and create a project and app. Enable <strong>OAuth 1.0a</strong> with Read and Write permissions.
|
||
</div>
|
||
</li>
|
||
<li>
|
||
<div>
|
||
<strong>Generate all four credentials</strong>
|
||
In your app → Keys and tokens: copy the <strong>API Key</strong>, <strong>API Secret</strong>, <strong>Access Token</strong>, and <strong>Access Token Secret</strong> (all four are required).
|
||
</div>
|
||
</li>
|
||
<li>
|
||
<div>
|
||
<strong>Enter credentials in dashboard</strong>
|
||
SquareMCP dashboard → Twitter / X → Connect → paste all four values.
|
||
</div>
|
||
</li>
|
||
</ol>
|
||
|
||
<p class="code-label">Example prompts</p>
|
||
<pre><code>Tweet: "We just shipped our v2 release 🚀 Read the changelog at squaremcp.com"
|
||
|
||
Upload the video at /tmp/demo.mp4 and tweet "Watch our new feature demo!"
|
||
|
||
Search Twitter for tweets mentioning "SquareMCP"</code></pre>
|
||
|
||
<!-- ── Telegram ───────────────────────────────────────────────────── -->
|
||
<h2 id="telegram"><span class="icon" style="background:#0088cc;color:#fff;margin-right:8px;">✈️</span> Telegram</h2>
|
||
|
||
<h3>Connecting Telegram</h3>
|
||
<ol class="steps">
|
||
<li>
|
||
<div>
|
||
<strong>Create a bot with BotFather</strong>
|
||
Open Telegram and message <code>@BotFather</code>. Send <code>/newbot</code>, choose a name and username, and copy the <strong>API token</strong> it provides (format: <code>123456789:ABCdef...</code>).
|
||
</div>
|
||
</li>
|
||
<li>
|
||
<div>
|
||
<strong>Enter the token in dashboard</strong>
|
||
SquareMCP dashboard → Telegram → Connect → paste the bot token.
|
||
</div>
|
||
</li>
|
||
<li>
|
||
<div>
|
||
<strong>Add your bot to a chat or group</strong>
|
||
Bots can only send messages to chats they're a member of. Add your bot to the target chat, then use <code>telegram_get_updates</code> to find the chat ID.
|
||
</div>
|
||
</li>
|
||
</ol>
|
||
|
||
<p class="code-label">Example prompts</p>
|
||
<pre><code>Send a Telegram message to chat ID -1001234567890 saying "Daily report ready!"
|
||
|
||
Get the latest Telegram messages in my channel</code></pre>
|
||
</div>
|
||
|
||
</body>
|
||
</html>
|