Skip to content

Docs authoring guide

Tagline: Async Python framework for resilient Signal bots (community SDK, not the official Signal app).

Use this guide when editing docs so pages stay consistent and on-brand.

Brand voice

  • Audience: Python developers building Signal bots on signal-cli-rest-api.
  • Positioning: community, async-first bot runtime with resilient ingestion and typed helpers; not an official Signal client.
  • Tone: practical, concise, confident. Lead with the problem solved; avoid hype.
  • Word bank: async, resilient, backpressure, typed, bot runtime, Signal bot, open source, production-minded.
  • Avoid: “official Signal client,” “sealed/enterprise,” “magic,” “webhook-only,” “unsupported hacks.”

Page structure template

Every first-level page should include: front matter (title, description), a lead/CTA, prerequisites (if applicable), at least one runnable snippet, a diagram for flows, troubleshooting, and “Next steps”. Use Overview and Getting started as references.

Macros & snippets

  • Buttons: <a class="md-button md-button--primary" href="getting_started.md">Get started</a> renders a Material-styled button.
  • Badges: <span class='badge badge--beta'>Beta</span> or <span class='badge badge--experimental'>Experimental</span>.
  • Env block: reuse bash export SIGNAL_PHONE_NUMBER=+15551234567 export SIGNAL_SERVICE_URL=http://localhost:8080 export SIGNAL_API_URL=http://localhost:8080 instead of duplicating exports.
  • Pull code from the repo using pymdownx.snippets:

```python
"""Minimal ping/pong bot to verify your Signal setup."""

from __future__ import annotations

import asyncio

from signal_client import Context, SignalClient, command


@command("!ping")
async def ping(ctx: Context) -> None:
    """Reply with a basic pong."""
    await ctx.reply_text("pong")  # (1)


async def main() -> None:
    """Run the ping bot."""
    bot = SignalClient()  # (2)
    bot.register(ping)  # (3)
    await bot.start()  # (4)


if __name__ == "__main__":
    asyncio.run(main())
``` - See live output in Components playground.

Annotated code

Describe important steps with a short bullet list aligned to each snippet instead of relying on automatic callouts:

@command("!ping")
async def ping(ctx):
    await ctx.reply_text("pong")
  • Summaries live immediately after the code block.
  • Keep explanations concise and focused on what each highlighted action does.

Tabs, cards, and grids

  • Tabs: use === "Tab" blocks for alternative flows (e.g., pip vs Poetry).
  • Cards/grids: wrap content in <div class="brand-grid"> + <div class="brand-card"> for a consistent layout.

Media and diagrams

  • Diagrams: prefer Mermaid fenced blocks (```mermaid). Keep flows short and legible.
  • Images: Markdown images gain a lightbox automatically; add data-gallery="assets" when grouping screenshots.
  • Icons: use Material icons (:material-rocket:) sparingly to anchor cards.

Cross-linking

  • Use relative links; autorefs resolves headings automatically. Example: [Advanced usage](../guides/advanced_usage.md).
  • When moving content, add redirects in mkdocs.yml under redirect_maps.

Voice checks

  • Mention the community/non-official disclaimer on landing pages and marketing copy.
  • Lead with capability + safety: backpressure, DLQ, redaction.
  • Invite contributions with clear next actions (issues, PRs, docs edits).

Playground

Preview all components on Components playground before rolling them into guides.