Skip to content

Repository files navigation

Plane Telegram AI Bot

A self-hosted Docker service that connects Plane.so to Telegram via AI. Ask questions about your projects, issues, cycles, and more — right from Telegram.

Supports two deployment modes:

  • Personal mode (default) — one workspace, one user, zero setup friction
  • Multi-user mode — any Telegram user can /login with their own Plane credentials; ideal for shared team bots or public deployments

Architecture

Telegram → Bot (python-telegram-bot) → AI (Claude/GPT) + Plane Tools → Plane.so

The AI uses Plane tools to query and interact with your workspace. It decides which tools to call based on your natural language questions. Tools are built on the official plane-sdk with lean schemas to minimise token usage, backed by an SQLite cache for workspace data.

Prerequisites

  1. Plane PAT (API Key) — Generate from your Plane workspace settings → API Tokens
  2. Telegram Bot Token — Create a bot via @BotFather on Telegram
  3. AI API Key — From Anthropic or OpenAI
  4. Docker — Installed on your server

Setup Telegram Bot

  1. Open Telegram and search for @BotFather
  2. Send /newbot and follow the prompts:
    • Bot name: Choose a display name (e.g., "Plane AI Assistant")
    • Bot username: Must end in "bot" (e.g., "my_plane_ai_bot")
  3. BotFather will give you a bot token — save it for TELEGRAM_BOT_TOKEN

Note: No need to set bot commands in BotFather. The bot registers all commands with Telegram automatically on startup.

Optional extras via BotFather:

  • /setdescription — Description shown in the chat header
  • /setabouttext — Text shown in the bot's profile
  • /setuserpic — Profile picture

Quick Start

Personal Mode (single user)

Run the pre-built Docker image:

docker run -d \
  --name plane-telegram \
  -v $(pwd)/data:/app/data \
  -e PLANE_PAT=your_plane_api_key \
  -e PLANE_WORKSPACE_SLUG=your-workspace-slug \
  -e TELEGRAM_BOT_TOKEN=your_telegram_bot_token \
  -e AI_PROVIDER=anthropic \
  -e AI_API_KEY=your_ai_api_key \
  --restart unless-stopped \
  mguptahub/plane-telegram:latest

That's it! Replace the values with your credentials, find your bot on Telegram, and send /start.

Multi-User Mode (shared / team bot)

Add MULTI_USER=true and omit PLANE_PAT / PLANE_WORKSPACE_SLUG:

docker run -d \
  --name plane-telegram \
  -v $(pwd)/data:/app/data \
  -e MULTI_USER=true \
  -e TELEGRAM_BOT_TOKEN=your_telegram_bot_token \
  -e AI_PROVIDER=anthropic \
  -e AI_API_KEY=your_ai_api_key \
  --restart unless-stopped \
  mguptahub/plane-telegram:latest

Each user (or group chat) runs /login to connect their own Plane account. See Multi-User Mode for details.

Additional Configuration (Optional)

docker run -d \
  --name plane-telegram \
  -v $(pwd)/data:/app/data \
  -e PLANE_PAT=your_plane_api_key \
  -e PLANE_WORKSPACE_SLUG=your-workspace-slug \
  -e TELEGRAM_BOT_TOKEN=your_telegram_bot_token \
  -e AI_PROVIDER=openai \
  -e AI_API_KEY=your_ai_api_key \
  -e AI_MODEL=gpt-4o \
  -e AI_BASE_URL=https://api.openai.com/v1 \
  -e MAX_HISTORY_MESSAGES=15 \
  -e SESSION_TIMEOUT_MINUTES=60 \
  -e DEBUG_LOGGING=false \
  --restart unless-stopped \
  mguptahub/plane-telegram:latest

Environment Variables

Variable Required Default Description
MULTI_USER No false Enable multi-user mode — each Telegram chat registers its own Plane account
PLANE_PAT Yes* Plane API key / Personal Access Token (*not required when MULTI_USER=true)
PLANE_WORKSPACE_SLUG Yes* Default workspace slug (*not required when MULTI_USER=true)
PLANE_BASE_URL If self-hosted https://app.plane.so Your self-hosted Plane URL
TELEGRAM_BOT_TOKEN Yes Telegram bot token from BotFather
AI_PROVIDER Yes anthropic or openai (any OpenAI-compatible)
AI_API_KEY Yes API key for your AI provider
AI_MODEL No Auto Model name (defaults to claude-sonnet-4-20250514 or gpt-4o)
AI_BASE_URL No Provider default Optional base URL override
AI_APP_REFERER No HTTP-Referer header (used by OpenRouter for attribution)
AI_APP_TITLE No Plane Telegram AI X-Title header (used by OpenRouter for attribution)
MAX_HISTORY_MESSAGES No 15 Number of messages to include as context
SESSION_TIMEOUT_MINUTES No 60 Auto-expire old messages from context
LOG_LEVEL No INFO Logging level
DEBUG_LOGGING No false Write per-request debug logs to data/debug_logs/

AI_BASE_URL Examples

Provider AI_PROVIDER AI_BASE_URL
Anthropic (default) anthropic
OpenAI (default) openai
Groq openai https://api.groq.com/openai/v1
OpenRouter openai https://openrouter.ai/api/v1
Together AI openai https://api.together.xyz/v1
LiteLLM proxy openai http://localhost:4000/v1
Azure OpenAI openai https://your-resource.openai.azure.com/

Available Tools

Tool Description
get_me Get current user info
get_workspace_members List all workspace members
list_projects List all projects
get_project Get a project by UUID
get_project_members List members of a project
list_states List workflow states for a project
list_labels List labels for a project
list_work_items List work items (filterable by state, priority, assignee, label)
get_work_item Get a work item by UUID or identifier (e.g. PROJ-42)
create_work_item Create a new work item
update_work_item Update an existing work item
list_initiatives List workspace initiatives

Bot Commands

The bot registers all commands with Telegram automatically — they appear in the / menu.

Account (multi-user mode only)

Command Description
/login Connect your Plane account (PAT + workspace slug)
/logout Remove your credentials and clear all chat data
/status Show connection status, cache state, and active project

General

Command Description
/start Show welcome message
/help Show help and command reference
/reset Clear conversation history and start fresh
/tools List all available Plane tools
/status Show connection status and active context

Workspace

Command Description
/workspace Show the currently active workspace and project
/workspace show Same as above
/workspace <slug> Switch workspace, rebuild cache, and clear active project

Examples:

/workspace
/workspace my-company
/workspace show

Each chat session has its own active workspace. The default is set by PLANE_WORKSPACE_SLUG. Switching workspace rebuilds the cache and resets the active project (projects are workspace-scoped).

Project Context

Set an active project once so you don't need to type the identifier on every /workitems call.

Command Description
/project Show the currently active project
/project show Same as above
/project <IDENTIFIER> Set the active project (validated against cache)

Examples:

/project
/project BACK
/project INVESTOS

The active project is cleared automatically when you switch workspace.

Quick Lists

Explicit mode — project identifier always required, ignores active project context. Useful for one-off lookups across projects.

Command Description
/list projects List all projects in the active workspace
/list workitems <PROJ> [query] List work items for a project
/list states <PROJ> List workflow states for a project
/list labels <PROJ> List labels for a project
/list members <PROJ> List members of a project

Context mode — uses the active project set by /project. Set it once, then query freely.

Command Description
/workitems [query] List work items using the active project context
/states List workflow states for the active project
/labels List labels for the active project
/members List members of the active project

<PROJ> is the project identifier (e.g. BACK, INVESTOS). The optional [query] for work items is plain English — the AI resolves it into filters (state, priority, assignee, label). Only one filter value is supported per field.

Examples:

/list projects

# Explicit — project always required
/list workitems BACK
/list workitems BACK todo
/list workitems BACK high priority
/list workitems BACK assigned to me
/list workitems BACK labeled as James
/list states BACK
/list labels BACK
/list members BACK

# Context — /project BACK must be set first
/workitems
/workitems todo
/workitems in progress
/workitems urgent
/workitems assigned to me
/workitems labeled as James
/states
/labels
/members

Cache Management

The bot caches workspace data (user info, projects, states, labels, members) in SQLite to reduce API calls and speed up responses.

Command Description
/cache Show all cache entries (same as show)
/cache show List cache entries with size and age
/cache update Refresh all cached data (top-level + existing project data)
/cache clean Delete project-level caches, refresh top-level only

Project states, labels, and members are lazily cached on first use and reused for subsequent calls. Use /cache clean after making structural changes in Plane (new states, members, etc.).

Example Conversations

These are natural language queries you can send directly to the bot (no commands needed):

General Questions

Who am I?
What workspace am I in?

Projects

List all my projects
How many projects do I have?
Tell me about the Backend project

Work Items

What are the open issues in project Backend?
Show me all urgent items in INVESTOS
What issues are assigned to me in BACK?
Get me issue BACK-42
What's the status of PROJ-7?

Creating & Updating

Create an issue titled "Fix auth bug" with high priority in project Backend
Create a new todo in INVESTOS: "Update pricing page"
Update BACK-42 to Done
Change the priority of PROJ-7 to urgent
Assign BACK-15 to John

Workspace & Members

Who are the members of the BACK project?
List all workspace members
What states does the INVESTOS project have?
What labels are available in BACK?

Multi-User Mode

Set MULTI_USER=true to allow any Telegram user (or group chat) to connect their own Plane account. The bot stores credentials per-chat and isolates all data (cache, history, active workspace) between chats.

Registration flow

User:  /login
Bot:   Step 1 — reply with your Plane API token
User:  plane_pat_abc123...          ← bot deletes this message for security
Bot:   ✅ Verified as John (john@example.com)
       Step 2 — reply with your workspace slug
User:  my-company
Bot:   ✅ Registered! Found 5 projects in workspace my-company.

Multi-user commands

Command Description
/login Connect a Plane account (PAT + workspace slug)
/logout Remove credentials and clear all chat data

How it works

  • Each chat gets its own credential store and cache namespace in SQLite
  • PLANE_PAT and PLANE_WORKSPACE_SLUG environment variables are optional when MULTI_USER=true
  • In groups, the /login flow uses Telegram's ForceReply so the bot receives replies even with privacy mode enabled
  • /logout removes the registration, all conversation history, and all cache entries for that chat

Per-chat workspace switching

In multi-user mode, each chat also has its own active workspace. The registered workspace is the default — users can switch with /workspace <slug> at any time. Each chat tracks its own:

  • Active workspace — default is the registered workspace slug
  • Active project — set with /project <IDENTIFIER>
  • Cache — scoped to the chat, rebuilt on /login and /cache clean

Data & Privacy

  • Self-hosted: Your Plane PAT, AI keys, and conversation data never leave your infrastructure
  • SQLite: Chat history and cache are stored locally in ./data/chat_history.db (volume-mapped)
  • No telemetry: The bot doesn't phone home

Updating

Pull the latest image and restart:

docker pull mguptahub/plane-telegram:latest
docker stop plane-telegram
docker rm plane-telegram
# Then run the docker run command from Quick Start

Your chat history and cache persist in the ./data volume.

Troubleshooting

Bot not responding?

  • Check logs: docker logs -f plane-telegram
  • Verify your Telegram bot token is correct
  • Make sure the bot is not blocked or hasn't been stopped

Plane connection fails?

  • Verify your PLANE_PAT is valid and has the right permissions
  • Verify your PLANE_WORKSPACE_SLUG is correct (the slug, not the full URL)
  • For self-hosted: ensure PLANE_BASE_URL is reachable from inside the container
  • Check logs: docker logs -f plane-telegram

AI errors?

  • Verify your AI_API_KEY is valid and has credits
  • Check the model name in AI_MODEL is correct for your provider

Work item filters not working?

  • Run /cache clean to ensure states and members are freshly cached
  • Try /cache show to inspect what's cached
  • Note: each filter (state, priority, assignee, label) accepts only one value at a time

Commands not showing in Telegram?

  • Send /help to force re-registration of commands
  • Force-close and reopen Telegram (the commands menu is cached client-side)

Development

Clone and Setup

git clone https://github.com/mguptahub/plane-telegram-ai
cd plane-telegram-ai
cp .env.example .env
# Edit .env with your credentials

Build and Run with Docker Compose

docker compose up -d --build

Check logs:

docker compose logs -f

Debug Logging

Set DEBUG_LOGGING=true to write per-request JSON logs to data/debug_logs/. Each file captures the full AI exchange including tool calls, token usage, and cache hits.

License

MIT

About

A self-hosted Docker service that connects Plane.so to Telegram via AI. Ask questions about your projects, issues, cycles, and more — right from Telegram.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages