A lightweight, secure Telegram message delivery API
Featuresā ⢠Quick Startā ⢠APIā ⢠Configurationā ⢠Examplesā ⢠Contributingā
Pusher is a simple yet powerful HTTP API server that acts as a proxy for sending messages to Telegram. Built with Echoā framework in Go, it simplifies message delivery by remembering your bot credentials and providing an easy-to-use REST interface.
| Feature | Description |
|---|---|
| šØ Multiple Formats | Support for plain text and Telegram MarkdownV2 |
| š Request Compression | Automatic gzip compression for API calls |
| š Optional Auth | Secure your endpoint with custom header authentication |
| šØ Message Splitting | Automatically splits long messages into chunks |
| š CORS Enabled | Works seamlessly with web applications |
| š„ Health Checks | Built-in /pulse endpoint for monitoring |
| š Link Preview Control | Enable/disable link previews per message |
| š IP Tracking | Automatically includes sender IP in messages |
Basic Setup:
docker run -d \
--name pusher \
-p 3333:3333 \
-e TG_TOKEN=your_telegram_bot_token \
-e CHAT_ID=your_chat_id \
bipy/pusher:latest
With Security & Custom Port:
docker run -d \
--name pusher \
-p 8080:8080 \
-e TG_TOKEN=your_telegram_bot_token \
-e CHAT_ID=your_chat_id \
-e SERVER_HOST=0.0.0.0 \
-e SERVER_PORT=8080 \
-e SECURE_KEY=your_secure_password \
bipy/pusher:latest
Create a docker-compose.yml:
version: '3.8'
services:
pusher:
image: bipy/pusher:latest
container_name: pusher
restart: unless-stopped
ports:
- "3333:3333"
environment:
TG_TOKEN: "your_telegram_bot_token"
CHAT_ID: "your_chat_id"
SECURE_KEY: "your_secure_password" # Optional
# For production, use behind a reverse proxy with HTTPS
Then run:
docker-compose up -d
# Clone the repository
git clone https://github.com/bipy/pusher.git
cd pusher
# Build the binary
go build -o pusher .
# Run with environment variables
export TG_TOKEN=your_telegram_bot_token
export CHAT_ID=your_chat_id
./pusher
Configure Pusher using environment variables:
| Variable | Type | Required | Default | Description |
|---|---|---|---|---|
TG_TOKEN | string | ā Yes | - | Your Telegram bot token from @BotFatherā |
CHAT_ID | integer | ā Yes | - | Target chat ID to receive messages |
SERVER_HOST | string | No | 0.0.0.0 | Server binding address |
SERVER_PORT | integer | No | 3333 | Server listening port |
SECURE_KEY | string | No | - | Optional authentication key |
Get Bot Token:
/newbotGet Chat ID:
https://api.telegram.org/bot<YOUR_TOKEN>/getUpdatesPOST / - Send Message (JSON)Send a message using JSON payload.
Request Body:
{
"text": "Your message here",
"preview": false,
"markdown": false
}
Parameters:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
text | string | ā Yes* | - | Message content |
msg | string | No | - | Alternative to text (fallback) |
preview | boolean | No | false | Enable link preview |
markdown | boolean | No | false | Enable Telegram MarkdownV2 parsing |
Authentication:
If SECURE_KEY is configured, provide authentication via:
POST /?key=your_secure_passwordSecure-Key: your_secure_passwordResponse:
{
"code": 0,
"msg": "OK",
"resp": null
}
GET / - Send Message (Query String)Send a message using URL parameters.
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
text | string | ā Yes* | Message content (URL encoded) |
msg | string | No | Alternative to text (fallback) |
preview | flag | No | Include this parameter to enable link preview |
markdown | flag | No | Include this parameter to enable markdown |
key | string | Conditional | Authentication key (required if SECURE_KEY is set) |
Example:
# Without authentication
curl "http://localhost:3333/?text=Hello%20World"
# With authentication via query parameter
curl "http://localhost:3333/?text=Hello%20World&key=your_secure_password"
GET /pulse - Health CheckReturns HTTP 204 No Content if the server is healthy.
Example:
curl -I http://localhost:3333/pulse
If SECURE_KEY is configured, include it in your requests using either method:
Method 1: Query Parameter (Easier - No Custom Headers Needed)
ā ļø Security Note: Query parameters are visible in URL logs, browser history, and may be leaked via referrer headers. Use this method only in trusted environments or for non-sensitive deployments. For production use with sensitive data, prefer the header method below.
Add key parameter to your URL:
# GET request
curl "http://localhost:3333/?text=Hello&key=your_secure_password"
# POST request
curl -X POST "http://localhost:3333/?key=your_secure_password" \
-H "Content-Type: application/json" \
-d '{"text": "Authenticated message"}'
Method 2: Custom Header (Recommended for Production)
š More Secure: Headers are not logged in URLs, don't appear in browser history, and aren't leaked via referrer headers. This is the recommended method for production deployments.
# With Secure-Key header
curl -X POST http://localhost:3333/ \
-H "Content-Type: application/json" \
-H "Secure-Key: your_secure_password" \
-d '{"text": "Authenticated message"}'
> **Note:** When `SECURE_KEY` is not set (empty), authentication is disabled and all requests are allowed.
---
## š” Usage Examples
### Basic cURL Examples
**Simple Message:**
```bash
curl -X POST http://localhost:3333/ \
-H "Content-Type: application/json" \
-d '{"text": "Hello from Pusher!"}'
With Authentication (Query Parameter):
# GET with authentication
curl "http://localhost:3333/?text=Secure%20message&key=your_password"
# POST with authentication
curl -X POST "http://localhost:3333/?key=your_password" \
-H "Content-Type: application/json" \
-d '{"text": "Authenticated message"}'
With Link Preview:
curl "http://localhost:3333/?text=Check%20this%20out%20https://github.com&preview"
With Markdown:
curl -X POST http://localhost:3333/ \
-H "Content-Type: application/json" \
-d '{"text": "*Bold* and _italic_ text", "markdown": true}'
HTTPieā makes it even simpler:
# Simple message
http POST localhost:3333 text="Hello World"
# With authentication (query parameter - easier)
http POST "localhost:3333?key=your_password" text="Secure message"
# With authentication (header method)
http POST localhost:3333 text="Secure message" Secure-Key:your_password
# With markdown
http POST localhost:3333 text="**Important** update" markdown:=true
import requests
def send_telegram_message(text, markdown=False, secure_key=None):
# Method 1: Using query parameter (simpler)
params = {}
if secure_key:
params['key'] = secure_key
response = requests.post(
'http://localhost:3333/',
params=params,
json={
'text': text,
'markdown': markdown,
'preview': False
}
)
return response.json()
# Alternatively, using header authentication:
def send_with_header(text, secure_key=None):
headers = {}
if secure_key:
headers['Secure-Key'] = secure_key
response = requests.post(
'http://localhost:3333/',
json={'text': text},
headers=headers
)
return response.json()
# Usage
send_telegram_message("Deployment successful! š")
send_telegram_message("Secure message", secure_key="your_password")
// Method 1: Using query parameter (simpler, no custom headers)
async function sendTelegramMessage(text, options = {}) {
const params = new URLSearchParams();
if (options.secureKey) {
params.append('key', options.secureKey);
}
const url = `http://localhost:3333/?${params}`;
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
text,
preview: options.preview || false,
markdown: options.markdown || false
})
});
return response.json();
}
// Method 2: Using header authentication
async function sendWithHeader(text, secureKey) {
const headers = {
'Content-Type': 'application/json'
};
if (secureKey) {
headers['Secure-Key'] = secureKey;
}
const response = await fetch('http://localhost:3333/', {
method: 'POST',
headers,
body: JSON.stringify({ text })
});
return response.json();
}
// Usage
await sendTelegramMessage('Build completed successfully!');
await sendTelegramMessage('Secure message', { secureKey: 'your_password' });
#!/bin/bash
PUSHER_URL="http://localhost:3333/"
SECURE_KEY="your_secure_password"
# Method 1: Using query parameter (simpler)
function notify_simple() {
local message="$1"
curl -s -X POST "${PUSHER_URL}?key=${SECURE_KEY}" \
-H "Content-Type: application/json" \
-d "{\"text\": \"$message\"}"
}
# Method 2: Using header
function notify_header() {
local message="$1"
curl -s -X POST "$PUSHER_URL" \
-H "Content-Type: application/json" \
-H "Secure-Key: $SECURE_KEY" \
-d "{\"text\": \"$message\"}"
}
# Usage
notify_simple "Backup completed at $(date)"
Pusher supports Uptime Kumaā webhook notifications out of the box!
http://your-server:3333/āāāāāāāāāāāāāāā āāāāāāāāāāāāāāā āāāāāāāāāāāāāāāāāāāā
ā Client ā ā Pusher ā ā Telegram API ā
ā ā ā ā ā ā
ā HTTP GET āāāāāāāāāā¶ā Echo Web āāāāāāāāāā¶ā /sendMessage ā
ā HTTP POST ā ā Framework ā ā ā
āāāāāāāāāāāāāāā āāāāāāāāāāāāāāā āāāāāāāāāāāāāāāāāāāā
ā
āā Authentication (optional)
āā Markdown Escaping
āā Message Splitting
āā Gzip Compression
āā Error Handling
/pulse endpoint for monitoringUse HTTPS in Production
SECURE_KEY in transitChoose Authentication Method Wisely
Secure-Key header in production environments
key parameter only in trusted environments
Strong SECURE_KEY
Network Security
Rate Limiting
Example nginx configuration:
server {
listen 443 ssl http2;
server_name pusher.example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://localhost:3333;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Rate limiting
limit_req zone=pusher_limit burst=10 nodelay;
}
}
Problem: "TG_TOKEN environment variable is required"
TG_TOKEN is set correctly in your environment or Docker configurationProblem: "invalid CHAT_ID"
CHAT_ID must be a valid integer. Remove quotes in Docker compose filesProblem: Messages not received
/start to it)Problem: 502 Bad Gateway errors
Use the /pulse endpoint for monitoring:
# Check if service is running
curl -f http://localhost:3333/pulse || echo "Service down"
Add to your docker-compose.yml:
services:
pusher:
image: bipy/pusher:latest
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3333/pulse"]
interval: 30s
timeout: 10s
retries: 3
start_period: 5s
Pusher uses Echo's built-in logger. To view logs:
# Docker logs
docker logs -f pusher
# Follow logs with timestamps
docker logs -f --timestamps pusher
Contributions are welcome! Here's how you can help:
git checkout -b feature/amazing-feature)git commit -m 'Add amazing feature')git push origin feature/amazing-feature)# Clone your fork
git clone https://github.com/yourusername/pusher.git
cd pusher
# Install dependencies
go mod download
# Run locally
export TG_TOKEN=your_token
export CHAT_ID=your_chat_id
go run main.go
gofmt before committing: gofmt -w .go vet to check for issues: go vet ./...This project is licensed under the MIT License - see the LICENSEā file for details.
MIT License
Copyright (c) 2021 bipy
Made with ā¤ļø using Go
Content type
Image
Digest
sha256:599a30f99ā¦
Size
6.9 MB
Last updated
9 months ago
docker pull bipy/pusher