Files
Ben Sabic 79227ae991 docs: refresh adapter pages with hand-authored MDX (#474)
## Summary

Refreshes the adapter docs end-to-end so every adapter — official,
vendor-official, and community — now ships hand-authored MDX, lives
under a clean URL structure, and renders on a polished
sidebar/right-rail layout dedicated to `/adapters` (the shared `/docs`
chrome is untouched).

```mermaid
flowchart LR
  subgraph Before
    direction TB
    OB[official] --> CB[community<br/>incl. 5 vendor pages]
  end
  subgraph After
    direction TB
    OA[official] --> VA[vendor-official<br/>5 pages] --> CA[community]
  end
  Before -.-> After
```

### Content & routing

- **New `/adapters/vendor-official/<slug>` route** for vendor-maintained
adapters (Beeper Matrix, Photon iMessage, Liveblocks, Resend, Zernio).
Sidebar gets a third labelled group ("Vendor-Official Adapters") between
Official and Community, with a top divider matching the existing
Community treatment.
- **All 13 vendor-official + community adapters migrated** from runtime
README fetching to hand-authored MDX with rich `features:` matrices and
full body content (install, quick start, configuration, auth,
gateway/streaming, troubleshooting). README fetch stays as a fallback
for any future community adapter that hasn't been migrated yet, gated by
a new `mdxBody: true` frontmatter flag.
- **Messenger filter pages removed** (`/adapters/for/<messenger>` + the
"Browse by messenger" chip row on `/adapters`). Existing URLs
308-redirect to `/adapters`.
- **Permanent redirects** from
`/adapters/community/{matrix,imessage,resend,zernio,liveblocks}` to
their new `/adapters/vendor-official/...` paths.
- **Fixed** `/docs/adapters` and `/docs/state` so the bare pages are
accessible again — the previous catch-all redirect (`:slug*`) was
swallowing them. Switched to `:slug+` so subpath URLs still 308 while
the bare pages render.

### Visual polish

- **Adapter-only sidebar variant** (`AdaptersDocsLayout` +
`AdaptersSidebar`) with uppercase eyebrow separators, tighter rows, and
a thin themed scrollbar utility class. The shared `/docs` sidebar is
untouched.
- **Restyled `AdapterHero`**: drops the badges row + packageName, sits
the title inline with the logo, larger 17 px tagline, horizontal divider
beneath the block.
- **Restyled `PackageInstall`** as a tabbed dark single-line snippet
with a `$` prompt prefix and a copy button — replaces the previous
multi-line `CodeBlock` layout.
- **New "Deploy your chat app on Vercel" upsell card** (`<Upsell />`)
replaces the old `EditSource / ScrollTop / Feedback / CopyPage` footer
cluster on every adapter detail page.
- **Listing & messenger pages**: align the H1 to a tighter `text-4xl
sm:text-[44px]`, and the section headers to `text-base font-medium
tracking-tight` with a one-line muted lede.

### Tooling & tests

- Added `mdxBody: true` opt-in to the adapter frontmatter schema
(`source.config.ts`), and updated both detail-page handlers
(`community/[slug]` and the new `vendor-official/[slug]`) to render the
MDX body when present, falling back to README fetch otherwise.
- Refactored both detail-page handlers to flatten the body-render
branches into a `renderBody()` helper, removing the nested ternaries
that were tripping `lint/style/noNestedTernary`.
- New test file
[`packages/integration-tests/src/docs-adapters.test.ts`](https://github.com/vercel/chat/blob/docs/refresh-adapters/packages/integration-tests/src/docs-adapters.test.ts)
— **220 new assertions** covering:
- Adapter MDX frontmatter completeness, slug ↔ filename consistency, and
`type ∈ {platform, state}`.
- Vendor-official invariants: exactly the expected slugs,
`vendorOfficial: true`, `community: true`, `author`, `mdxBody: true`,
`<FeatureSupport />` rendered.
- Community invariants: `community: true` (never vendor-official),
`mdxBody: true`, `<FeatureSupport />`.
- Official invariants: never flagged, `packageName` always under
`@chat-adapter/*`.
- `adapters.json` ↔ MDX sync on `packageName` / `type` / `community` /
`vendorOfficial`.
- Extended `VALID_DOC_PACKAGES` so `docs-content.test.ts` accepts the
new vendor-official + community packages, plus `@chat-adapter/web`,
`@chat-adapter/web/react`, and `@chat-adapter/messenger`.

### Per-package AGENTS.md

- Added `AGENTS.md` to every official adapter and state adapter (14
packages), each tailored to that adapter's surface — overview, directory
layout, build/test commands, public exports, thread ID format, webhook
flow, authentication, format conversion, cards/streaming, platform
quirks, testing approach, coding conventions, and release rules.
- Added a one-line `CLAUDE.md` (`@AGENTS.md`) beside each so Claude Code
picks up the same instructions through its built-in resolver — same
convention as the root.

### Web adapter copy

- Cleaned up the Web adapter tagline (removed inline backticks) and
dropped the now-redundant "v1 scope" section from the body.

---------

Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com>
2026-05-12 16:01:19 +10:00

157 lines
4.5 KiB
Plaintext

---
title: Webex
description: Community Webex adapter for Chat SDK with support for spaces, threads, adaptive cards, and modals.
packageName: "@bitbasti/chat-adapter-webex"
slug: webex
type: platform
tagline: Community Webex adapter for Chat SDK. Supports spaces, threads, adaptive cards (buttons, selects, fields, sections), modals, and webhook signature verification.
community: true
mdxBody: true
features:
postMessage: yes
editMessage: no
deleteMessage: yes
fileUploads:
status: partial
label: 1 file per message
streaming:
status: partial
label: post+edit
scheduledMessages: no
cardFormat:
status: yes
label: Adaptive Cards
buttons: yes
linkButtons: yes
selectMenus: yes
tables: no
fields: yes
imagesInCards: yes
modals: yes
slashCommands: no
mentions: yes
addReactions: no
removeReactions: no
typingIndicator: no
directMessages: yes
ephemeralMessages: no
userLookup: yes
customApiEndpoint:
status: yes
label: baseUrl
fetchMessages: yes
fetchSingleMessage: yes
fetchThreadInfo: yes
fetchChannelMessages: yes
listThreads: yes
fetchChannelInfo: yes
postChannelMessage: yes
---
## Install
<PackageInstall package="chat @bitbasti/chat-adapter-webex" />
## Quick start
```typescript title="lib/bot.ts" lineNumbers
import { Chat } from "chat";
import { createWebexAdapter } from "@bitbasti/chat-adapter-webex";
const bot = new Chat({
userName: "mybot",
adapters: {
webex: createWebexAdapter({
botToken: process.env.WEBEX_BOT_TOKEN,
webhookSecret: process.env.WEBEX_WEBHOOK_SECRET,
}),
},
});
bot.onNewMention(async (thread, message) => {
await thread.post(`Hello from Webex! You said: ${message.text}`);
});
```
## Environment variables
| Variable | Required | Description |
| --- | --- | --- |
| `WEBEX_BOT_TOKEN` | Yes | Bot access token from the Webex Developer Portal |
| `WEBEX_WEBHOOK_SECRET` | Recommended | Shared secret for webhook signature verification |
| `WEBEX_BASE_URL` | No | Override the Webex API base URL (default: `https://webexapis.com/v1`) |
| `WEBEX_BOT_USERNAME` | No | Override the bot display name |
## Configuration
<TypeTable
type={{
botToken: {
type: "string",
description: "Bot access token. Auto-detected from `WEBEX_BOT_TOKEN`.",
},
webhookSecret: {
type: "string",
description:
"Shared secret for verifying webhook signatures. Auto-detected from `WEBEX_WEBHOOK_SECRET`.",
},
baseUrl: {
type: "string",
default: '"https://webexapis.com/v1"',
description: "Webex API base URL.",
},
userName: {
type: "string",
default: '"webex-bot"',
description:
"Bot display name. Overridden by the bot's Webex profile on initialization.",
},
botUserId: {
type: "string",
description:
"Webex person ID of the bot. Skips the `/people/me` call when provided.",
},
logger: {
type: "Logger",
default: "ConsoleLogger",
description: "Custom logger instance.",
},
}}
/>
## Platform setup
1. Go to the [Webex Developer Portal](https://developer.webex.com/) and sign in.
2. Navigate to **My Webex Apps → Create a New App → Create a Bot**.
3. Fill in the bot name, username, and icon, then click **Add Bot**.
4. Copy the **Bot Access Token** — this is your `WEBEX_BOT_TOKEN`. Store it securely; it is only shown once.
5. Create a webhook pointing to your server:
- **Target URL:** `https://your-domain.com/api/webhooks/webex`
- **Resource:** `messages` | **Event:** `created`
- **Resource:** `attachmentActions` | **Event:** `created`
- **Secret:** a random string — this is your `WEBEX_WEBHOOK_SECRET`
6. Add the bot to a Webex space and mention it to verify the integration.
See the [Webex Webhooks Guide](https://developer.webex.com/messaging/docs/api/guides/webhooks) for details on webhook registration.
## Capabilities
- Mentions and DMs
- Rich text (bold, italic, code, links) via Markdown
- Adaptive Cards — buttons, selects, radio selects, fields, sections
- Modals — form cards with submit/close actions
- File uploads (single file per message)
- Thread support via parent IDs
- Webhook signature verification (HMAC-SHA1)
## Limitations
- **Reactions** are not supported by Webex bot tokens — `addReaction` / `removeReaction` throw `NotImplementedError`.
- **Typing indicators** are not available in the Webex Messaging API.
- Only **one file upload per message** is supported.
- **Cards and file uploads** cannot be combined in the same message.
## Feature support
<FeatureSupport />