PaperValet
English | 中文
A production-grade Telegram userbot built with gotd/td — pure Go MTProto, no CGO.
Clean modular architecture, 15 built-in plugins, and a hot-loadable external plugin ecosystem.
Quick Start
curl -fsSL https://raw.githubusercontent.com/PaperValet/PaperValet/master/scripts/install.sh | bash
The installer asks for your api_id, api_hash (from my.telegram.org) and phone number, installs to ~/.papervalet, then:
~/.papervalet/run.sh # enter the Telegram code, done
Send .ping to yourself in any chat — the bot answers 🏓 Pong!.
Full walkthrough including systemd and Docker: Installation Guide.
Built-in Plugins
| Plugin |
Commands |
Description |
core |
.version, .ping, .restart |
Core bot management |
help |
.help |
Command help by category |
status |
.status |
Runtime status |
apt |
.apt list/install/remove/load/unload |
Plugin manager |
info |
.info, .fwd |
Chat/user info + forward |
alias |
.alias set/del/list |
Runtime command aliases |
exec |
.exec |
System command execution |
sudo |
.sudo on/off/add/remove/list |
Permission delegation |
reload |
.reload |
External plugin hot reload |
log |
.loglevel, .sendlog |
Log level + log delivery |
prefix |
.prefix list/add/del/set |
Command prefix management |
backup |
.backup |
Config/session backup + restore |
update |
.update, .autofix |
Git sync + restart |
dme |
.dme, .dme all |
Message cleanup |
lang |
.lang |
Language switching |
External Plugins
Third-party plugins live in the separate PaperValet-Plugins repo (21 available) and install with one command:
.apt install weather
Writing your own: Plugin SDK / 中文版.
Configuration
config.json (generated by the installer, see config.example.json):
{
"telegram": {
"api_id": 12345,
"api_hash": "your_api_hash",
"session_file": "session.json",
"database_file": "sessions.db"
},
"bot": {
"command_prefix": ".",
"plugins_dir": "plugins",
"owner_id": 0
},
"logger": {
"level": "INFO",
"format": "console"
}
}
command_prefix — command trigger (default .)
owner_id — Telegram user ID for owner-only commands (0 = first logged-in user)
logger.level — DEBUG, INFO, WARN, ERROR
Headless / Container Login
| Variable |
Purpose |
PAPERVALET_PHONE |
E.164 phone number, e.g. +8613800138000 |
PAPERVALET_CODE |
One-time login code sent by Telegram |
PAPERVALET_2FA_PASSWORD |
Cloud 2FA password |
PAPERVALET_NONINTERACTIVE |
1/true to fail fast instead of prompting on stdin |
Architecture
cmd/papervalet/ entry point
internal/
app/ orchestrator + auth + update handler
command/ parser, registry, middleware
config/ JSON config with defaults
eventbus/ priority pub/sub
media/ download/upload helpers
peer/ access hash cache + resolver
plugin/ manager + .so loader
session/ SQLite session store
i18n/ zh-CN / en-US catalogs
plugins/builtin/ compiled-in plugins
pkg/plugin/ PUBLIC SDK for external plugins
pkg/logger/ zap wrapper
| Concern |
Approach |
| Commands |
Typed CommandContext with Reply/Edit/Delete helpers |
| Plugins |
Minimal interface: Init/Start/Stop + RegisterCommand |
| Events |
EventBus with priority, filters, async emit |
| Peers |
Cache-first AccessHashManager → API → ID-pattern fallback |
| Sessions |
SQLite (WAL) + in-memory cache, TTL cleanup |
Development
go build -o papervalet ./cmd/papervalet # build
go test ./... # test
go vet ./... && golangci-lint run # lint
Requires Go 1.25+.
License
MIT — see LICENSE.