Skip to content

Latest commit

 

History

8 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Herdr Telegram Notifier

A lightweight Herdr plugin that sends Telegram notifications when an OpenCode agent changes state.

The plugin is written in Go and supports macOS and Linux.

Features

  • Detects OpenCode agent status changes through Herdr.
  • Sends Telegram notifications when an agent:
    • finishes (done)
    • becomes blocked (blocked)
  • Includes:
    • project
    • workspace
    • agent
    • execution duration
    • latest assistant response
  • Retrieves only the latest assistant text from the OpenCode session.
  • Excludes MCP activity, tool calls, tool results, reasoning and other OpenCode metadata.
  • Resolves the OpenCode session from the Herdr pane working directory.
  • Selects the most recently updated session for that directory.
  • Uses opencode export to retrieve the session.
  • Writes the export directly to a temporary file to avoid stdout pipe truncation.
  • Stores lightweight pane state using Herdr's plugin state directory.
  • Uses Telegram HTML formatting.
  • Has no external Go dependencies.

Requirements

Runtime

  • Herdr 0.8.0 or newer
  • OpenCode CLI
  • A Telegram bot
  • A Telegram chat ID
  • macOS or Linux

Build

Go 1.22+ is required when installing or building the plugin from source.

The plugin itself uses only the Go standard library.

Installation

The recommended installation method is Herdr's GitHub plugin installer:

herdr plugin install gpando/herdr-telegram

Herdr will:

  1. Clone the repository.
  2. Read herdr-plugin.toml.
  3. Build the Go plugin.
  4. Install and enable the plugin.

Verify the installation:

herdr plugin list

You should see:

gpando.telegram-notifier (Telegram Notifier) enabled

Configuration

Find the plugin configuration directory using Herdr:

herdr plugin config-dir gpando.telegram-notifier

Create telegram.json in that directory:

{
  "telegram_token": "YOUR_TELEGRAM_BOT_TOKEN",
  "telegram_chat_id": "YOUR_TELEGRAM_CHAT_ID",
  "include_last_message": true,
  "max_message_length": 1800,
  "session_search_limit": 100
}

Protect the configuration file:

chmod 600 "$(herdr plugin config-dir gpando.telegram-notifier)/telegram.json"

Configuration options

Option Description Default
telegram_token Telegram Bot API token required
telegram_chat_id Destination Telegram chat ID required
include_last_message Include the latest OpenCode assistant response true
max_message_length Maximum response length 1800
session_search_limit Number of OpenCode sessions inspected 100

Telegram Bot

Create a Telegram bot using BotFather and obtain its bot token.

The bot token is a credential and must not be committed to Git. Keep it only in the local telegram.json configuration.

If a bot token is accidentally committed, revoke/regenerate it immediately.

Plugin Manifest

The repository contains a platform-independent Herdr manifest:

id = "gpando.telegram-notifier"
name = "Telegram Notifier"
version = "0.1.0"
description = "Send Herdr OpenCode agent status changes to Telegram"
min_herdr_version = "0.8.0"
platforms = ["linux", "macos"]

[[build]]
command = ["go", "build", "-o", "herdr-telegram", "."]

The Go binary is built natively on the machine where the plugin is installed.

No platform-specific binary needs to be committed to the repository.

Development

Clone the repository:

git clone https://github.com/gpando/herdr-telegram.git
cd herdr-telegram

Link it locally into Herdr:

herdr plugin link .

After changing the Go source:

gofmt -w main.go
go build -o herdr-telegram .

The plugin is invoked by Herdr for each event; it does not run as a persistent daemon.

Architecture

OpenCode
    │
    │ agent status change
    ▼
Herdr
    │
    │ pane.agent_status_changed
    ▼
herdr-telegram
    │
    ├── HERDR_PLUGIN_CONTEXT_JSON
    │       │
    │       └── focused_pane_cwd
    │
    ├── opencode session list
    │       │
    │       └── latest session for project directory
    │
    ├── opencode export
    │       │
    │       └── temporary JSON file
    │
    ├── last assistant message
    │
    ▼
Telegram Bot API
    │
    ▼
Telegram client

OpenCode Session Resolution

The plugin does not rely on Herdr's native agent session information.

It reads:

HERDR_PLUGIN_CONTEXT_JSON

and specifically:

{
  "focused_pane_cwd": "/path/to/project"
}

The plugin then runs:

cd /path/to/project
opencode session list -n 100 --format json

Sessions are filtered using an exact directory match:

session.directory == focused_pane_cwd

The session with the newest updated timestamp is selected.

This avoids relying on:

  • session titles
  • pane titles
  • native Herdr agent session IDs
  • global session ordering

Retrieving the Latest Assistant Response

After resolving the session, the plugin executes:

opencode export <session-id>

The export is written directly to a temporary file.

This is intentional.

Capturing a large opencode export through a stdout pipe can result in truncated output and errors such as:

unexpected end of JSON input

The plugin therefore uses:

opencode export
      │
      └── stdout → temporary file
                         │
                         ▼
                    os.ReadFile()
                         │
                         ▼
                    JSON parsing

Once parsed, the plugin searches the messages backwards and selects the last message where:

role == "assistant"

Only parts where:

type == "text"

are included.

This deliberately excludes:

  • MCP activity
  • tool calls
  • tool results
  • reasoning
  • token information
  • model information
  • context statistics
  • other UI metadata

The resulting text is sent as the Latest response section of the Telegram notification.

Notification Format

A completed execution produces a notification similar to:

✅ OpenCode finished

Project: hello
Workspace: Uno
Agent: opencode
Duration: 54s

Latest response:

The agent's latest assistant response...

A blocked agent produces:

⚠️ OpenCode needs your attention

Project: hello
Workspace: Uno
Agent: opencode

Latest response:

The agent's latest assistant response...

State Tracking

Herdr provides:

HERDR_PLUGIN_STATE_DIR

The plugin stores:

$HERDR_PLUGIN_STATE_DIR/state.json

The state tracks the last known status and the start time of working events.

This allows the plugin to calculate the current:

working → done

interval.

Plugin Logs

Inspect plugin executions with:

herdr plugin log list \
  --plugin gpando.telegram-notifier \
  --limit 20

Useful diagnostic messages include:

herdr-telegram: resolved OpenCode session ses_...
herdr-telegram: OpenCode export returned ... bytes

A successful invocation should report:

status: succeeded
exit_code: 0

Testing

The repository contains test.sh for manually testing the plugin environment.

Run it from an OpenCode project directory:

./test.sh

You can also specify the project explicitly:

PROJECT_DIR="$HOME/projects/my-project" ./test.sh

The test uses a synthetic Herdr pane ID so that it does not interfere with the state of real panes.

A valid Telegram configuration is required.

Troubleshooting

Plugin is not listed

Check:

herdr plugin list

For local development:

herdr plugin unlink gpando.telegram-notifier
herdr plugin link .

Telegram notification is not received

Inspect the plugin logs:

herdr plugin log list \
  --plugin gpando.telegram-notifier \
  --limit 20

Verify the configuration directory:

herdr plugin config-dir gpando.telegram-notifier

Then check telegram.json.

OpenCode executable is not found

The plugin requires the opencode executable to be available in the environment used by Herdr.

Check:

which opencode
opencode --version

Also verify from the project directory:

cd /path/to/project
opencode session list -n 10 --format json

No OpenCode session found

The plugin uses an exact match between:

HERDR_PLUGIN_CONTEXT_JSON.focused_pane_cwd

and:

OpenCode session.directory

Check manually:

cd /path/to/project
opencode session list -n 100 --format json

unexpected end of JSON input

This indicates that the exported JSON was truncated.

The plugin avoids the stdout-pipe problem by writing opencode export directly to a temporary file before parsing it.

Inspect:

herdr plugin log list \
  --plugin gpando.telegram-notifier \
  --limit 20

Security

The Telegram bot token is a credential. Treat it like a password.

If a token is accidentally committed:

  1. Revoke or regenerate it through BotFather.
  2. Remove it from the repository.
  3. Remove it from Git history if necessary.
  4. Store the replacement only in local configuration or a secret manager.

The plugin communicates with:

  • the local Herdr plugin environment
  • the local OpenCode CLI
  • the Telegram Bot API

Platform Support

Platform Architecture Status
macOS Apple Silicon Supported
macOS Intel Supported
Linux x86_64 Supported
Linux ARM64 Supported

The Go build is performed natively by Herdr during plugin installation.

Repository

Source code:

https://github.com/gpando/herdr-telegram

License

MIT License.

See LICENSE.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages