https://github.com/ad/snitch-bot
https://github.com/ad/snitch-bot
Last synced: 4 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/ad/snitch-bot
- Owner: ad
- License: mit
- Created: 2025-10-29T13:03:25.000Z (7 months ago)
- Default Branch: main
- Last Pushed: 2025-10-29T14:50:31.000Z (7 months ago)
- Last Synced: 2025-10-29T16:40:34.428Z (7 months ago)
- Language: JavaScript
- Size: 29.3 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Anonymous Feedback Bot
Telegram-бот для анонимной обратной связи сотрудников компании, работающий на платформе Cloudflare Workers.
## Features
- 🔐 Secure activation via secret deeplink
- 💬 Anonymous message forwarding to admin group
- 🎯 Message categorization (Ideas, Problems, Gratitude)
- 🏷️ Topic selection (Processes, Colleagues, Conditions, Salary, Management, Other)
- 💪 Inspirational responses to users
- 🚀 Serverless deployment on Cloudflare Workers
## Table of Contents
- [Prerequisites](#prerequisites)
- [Setup](#setup)
- [Deployment](#deployment)
- [Environment Variables](#environment-variables)
- [User Activation](#user-activation)
- [Usage](#usage)
- [TEST_MODE for Staging](#test_mode-for-staging)
- [Maintenance](#maintenance)
- [Security](#security)
- [Troubleshooting](#troubleshooting)
- [License](#license)
## Prerequisites
- Cloudflare account with Workers plan
- Telegram Bot Token (get from [@BotFather](https://t.me/BotFather))
- Telegram group for admins
- Node.js (v16 or higher) and npm installed locally
- Wrangler CLI (`npm install -g wrangler`)
## Setup
### 1. Clone and Install
```bash
git clone
cd anonymous-feedback-bot
npm install
```
### 2. Create Telegram Bot
1. Open Telegram and find [@BotFather](https://t.me/BotFather)
2. Send `/newbot` command
3. Follow instructions to create your bot
4. Save the bot token (format: `123456789:ABCdefGHIjklMNOpqrsTUVwxyz`)
5. Save your bot username (e.g., `my_feedback_bot`)
### 3. Create Admin Group
1. Create a new Telegram group
2. Add your bot to the group
3. Make the bot an admin (optional, but recommended)
4. Send a test message in the group
5. Get the chat ID:
```bash
curl https://api.telegram.org/bot/getUpdates
```
6. Look for `"chat":{"id":-1001234567890,...}` in the response
7. The chat ID will be a negative number starting with `-100`
### 4. Create KV Namespace
```bash
# Login to Cloudflare
wrangler login
# Create production KV namespace
wrangler kv:namespace create "KV"
# Create preview KV namespace for development
wrangler kv:namespace create "KV" --preview
```
Copy the namespace IDs from the output and update `wrangler.toml`:
```toml
[[kv_namespaces]]
binding = "KV"
id = "your-production-kv-namespace-id"
preview_id = "your-preview-kv-namespace-id"
```
### 5. Generate Access Token
Generate a secure random token for user activation:
```bash
# On macOS/Linux
openssl rand -hex 32
# Or use Node.js
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
```
Save this token - you'll use it for the deeplink and as the `ACCESS_TOKEN` environment variable.
### 6. Configure Secrets
Set required secrets using Wrangler:
```bash
# Required secrets
wrangler secret put TELEGRAM_TOKEN
# Enter your bot token when prompted
wrangler secret put ADMIN_CHAT_ID
# Enter your admin group chat ID (e.g., -1001234567890)
wrangler secret put ACCESS_TOKEN
# Enter the token you generated in step 5
```
Optional secrets for staging/testing:
```bash
wrangler secret put ADMIN_CHAT_ID_TEST
# Enter your test group chat ID for staging environment
```
## Deployment
### Production Deployment
1. **Update wrangler.toml** with your worker name:
```toml
name = "anonymous-feedback-bot"
main = "src/index.js"
compatibility_date = "2024-01-01"
[env.production]
vars = { TEST_MODE = "false" }
[[kv_namespaces]]
binding = "KV"
id = "your-production-kv-namespace-id"
```
2. **Deploy to Cloudflare Workers**:
```bash
wrangler deploy --env production
```
3. **Note your Worker URL** from the output (e.g., `https://anonymous-feedback-bot.your-subdomain.workers.dev`)
4. **Register Webhook with Telegram**:
```bash
curl -X POST "https://api.telegram.org/bot/setWebhook" \
-H "Content-Type: application/json" \
-d '{"url": "https://anonymous-feedback-bot.your-subdomain.workers.dev"}'
```
Expected response:
```json
{"ok":true,"result":true,"description":"Webhook was set"}
```
5. **Verify Webhook Registration**:
```bash
curl "https://api.telegram.org/bot/getWebhookInfo"
```
Expected response should show:
```json
{
"ok": true,
"result": {
"url": "https://anonymous-feedback-bot.your-subdomain.workers.dev",
"has_custom_certificate": false,
"pending_update_count": 0,
"max_connections": 40
}
}
```
### Staging Deployment
For testing in a staging environment:
1. **Create a test bot** (optional, or reuse the same bot)
2. **Create a test admin group**
3. **Update wrangler.toml** with staging configuration:
```toml
[env.staging]
vars = { TEST_MODE = "true" }
[[env.staging.kv_namespaces]]
binding = "KV"
id = "your-staging-kv-namespace-id"
```
4. **Set staging-specific secrets**:
```bash
wrangler secret put ADMIN_CHAT_ID_TEST --env staging
# Enter your test group chat ID
```
5. **Deploy to staging**:
```bash
wrangler deploy --env staging
```
6. **Register webhook for staging**:
```bash
curl -X POST "https://api.telegram.org/bot/setWebhook" \
-H "Content-Type: application/json" \
-d '{"url": "https://anonymous-feedback-bot-staging.your-subdomain.workers.dev"}'
```
### Deployment Commands Reference
```bash
# Deploy to production
wrangler deploy --env production
# Deploy to staging
wrangler deploy --env staging
# View deployment logs
wrangler tail --env production
# View KV storage
wrangler kv:key list --binding KV --env production
# Delete a KV key (for testing)
wrangler kv:key delete "session:123456" --binding KV --env production
```
## Environment Variables
### Required Variables
| Variable | Description | Example | How to Set |
|----------|-------------|---------|------------|
| `TELEGRAM_TOKEN` | Bot API token from @BotFather | `123456789:ABCdefGHI...` | `wrangler secret put TELEGRAM_TOKEN` |
| `ADMIN_CHAT_ID` | Admin group chat ID (negative number) | `-1001234567890` | `wrangler secret put ADMIN_CHAT_ID` |
| `ACCESS_TOKEN` | Secret activation token (min 32 chars) | `a1b2c3d4e5f6...` | `wrangler secret put ACCESS_TOKEN` |
### Optional Variables (Testing & Administration)
| Variable | Description | Example | How to Set |
|----------|-------------|---------|------------|
| `TEST_MODE` | Enable test mode (set in wrangler.toml) | `true` / `false` | Set in `wrangler.toml` vars |
| `ADMIN_CHAT_ID_TEST` | Test admin group chat ID | `-1009876543210` | `wrangler secret put ADMIN_CHAT_ID_TEST` |
| `REVOKE_ALL_ACCESS` | Revoke all user access | `true` / `false` | `wrangler secret put REVOKE_ALL_ACCESS` |
### Environment Variable Configuration
**Via Wrangler Secrets** (recommended for sensitive data):
```bash
wrangler secret put VARIABLE_NAME
```
**Via wrangler.toml** (for non-sensitive configuration):
```toml
[env.production]
vars = { TEST_MODE = "false" }
```
**Via .env file** (local development only):
```bash
cp .env.example .env
# Edit .env with your values
```
## User Activation
### Deeplink Format
The deeplink format for user activation is:
```
https://t.me/?start=
```
**Example**:
```
https://t.me/my_feedback_bot?start=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
```
### Creating the Deeplink
1. Replace `` with your bot's username (without @)
2. Replace `` with the token you set in environment variables
3. Share this link with employees via email, intranet, or internal communication channels
### Security Considerations
- Keep the `ACCESS_TOKEN` secret - only share the complete deeplink with authorized employees
- The token should be at least 32 random characters
- Rotate the token periodically (quarterly recommended)
- When rotating, use `REVOKE_ALL_ACCESS=true` to force re-activation
### Activation Flow
1. Employee clicks the deeplink
2. Telegram opens the bot with the `/start ` command
3. Bot validates the token against `ACCESS_TOKEN` environment variable
4. If valid: user is marked as trusted (stored in KV for 90 days)
5. If invalid: user receives a neutral message without revealing bot purpose
## Usage
### For Employees (End Users)
1. **Activate the bot**: Click the deeplink provided by your company
2. **Start conversation**: The bot will show a welcome message
3. **Select category**: Choose from:
- 💬 Идея / предложение (Idea / Suggestion)
- ⚠️ Проблема / жалоба (Problem / Complaint)
- ❤️ Благодарность / признание (Gratitude / Recognition)
4. **Select topic**: Choose from:
- Процессы (Processes)
- Коллеги (Colleagues)
- Условия (Conditions)
- Зарплата (Salary)
- Менеджмент (Management)
- Другое (Other)
5. **Write message**: Type your message (text + optional photo/video/document)
6. **Confirm**: Review and confirm sending
7. **Receive response**: Get an inspirational message confirming submission
### For Administrators
Messages appear in the admin group with this format:
```
📩 Новое анонимное сообщение
Категория: 💬 Идея / предложение
Тема: Процессы
Текст:
[User's message here]
```
## TEST_MODE for Staging
`TEST_MODE` is a special environment variable that enables safe testing without affecting production data.
### When to Use TEST_MODE
- Testing bot functionality before production deployment
- Developing new features
- Training administrators
- Debugging issues
### How TEST_MODE Works
When `TEST_MODE=true`:
1. **Separate Admin Group**: Messages are sent to `ADMIN_CHAT_ID_TEST` instead of `ADMIN_CHAT_ID`
2. **Message Logging**: All messages are logged to KV storage with `test_log:` prefix
3. **No Production Impact**: Production admin group receives no test messages
### Setting Up TEST_MODE
**In wrangler.toml**:
```toml
[env.staging]
vars = { TEST_MODE = "true" }
[[env.staging.kv_namespaces]]
binding = "KV"
id = "your-staging-kv-namespace-id"
```
**Set test admin group**:
```bash
wrangler secret put ADMIN_CHAT_ID_TEST --env staging
```
**Deploy staging environment**:
```bash
wrangler deploy --env staging
```
### Switching Between Environments
**Production** (TEST_MODE=false):
```bash
wrangler deploy --env production
```
**Staging** (TEST_MODE=true):
```bash
wrangler deploy --env staging
```
### Viewing Test Logs
```bash
# List all test logs
wrangler kv:key list --binding KV --env staging --prefix "test_log:"
# Get specific log
wrangler kv:key get "test_log:1234567890" --binding KV --env staging
# Clear test logs
wrangler kv:key delete "test_log:1234567890" --binding KV --env staging
```
## Development
### Local Development
```bash
# Install dependencies
npm install
# Run locally with wrangler
npm run dev
# Or use wrangler directly
wrangler dev
```
### Testing Locally
1. Set up a local `.env` file (copy from `.env.example`)
2. Use `wrangler dev` to run locally
3. Use a tool like `ngrok` to expose your local server:
```bash
ngrok http 8787
```
4. Register the ngrok URL as webhook:
```bash
curl -X POST "https://api.telegram.org/bot/setWebhook" \
-H "Content-Type: application/json" \
-d '{"url": "https://your-ngrok-url.ngrok.io"}'
```
### Viewing Logs
```bash
# Real-time logs for production
wrangler tail --env production
# Real-time logs for staging
wrangler tail --env staging
# Filter logs
wrangler tail --env production --format pretty
```
## Maintenance
### Rotating Access Token
To change the access token (e.g., after employee departures):
1. **Generate new token**:
```bash
openssl rand -hex 32
```
2. **Update secret**:
```bash
wrangler secret put ACCESS_TOKEN --env production
```
3. **Revoke all existing access** (optional):
```bash
wrangler secret put REVOKE_ALL_ACCESS --env production
# Enter: true
```
4. **Deploy**:
```bash
wrangler deploy --env production
```
5. **Distribute new deeplink** with new token to employees
6. **Reset REVOKE_ALL_ACCESS** (after all users re-activate):
```bash
wrangler secret put REVOKE_ALL_ACCESS --env production
# Enter: false
```
### Monitoring
**Cloudflare Dashboard**:
- Navigate to Workers & Pages → Your Worker
- View Analytics: requests, errors, CPU time
- View Logs: real-time execution logs
**KV Storage Monitoring**:
```bash
# List all keys
wrangler kv:key list --binding KV --env production
# Check specific user session
wrangler kv:key get "session:123456789" --binding KV --env production
# Check trusted users
wrangler kv:key list --binding KV --env production --prefix "trusted:"
```
### Updating the Bot
1. Make code changes
2. Test locally with `wrangler dev`
3. Deploy to staging: `wrangler deploy --env staging`
4. Test in staging environment
5. Deploy to production: `wrangler deploy --env production`
## Security
### Best Practices
- **Access Token**: Use at least 32 random characters (use `openssl rand -hex 32`)
- **Token Rotation**: Rotate access token quarterly or after employee departures
- **Anonymity**: User telegram IDs are never stored in forwarded messages
- **Data Retention**:
- Session data expires automatically (1 hour TTL)
- Trusted user status expires after 90 days
- **Secrets Management**: Always use `wrangler secret put` for sensitive data
- **Webhook Security**: Telegram validates webhook requests from known IP ranges
- **Environment Isolation**: Use separate bots/groups for staging and production
### Privacy Guarantees
- No user identifying information is stored beyond the trusted user flag
- Messages forwarded to admin group contain no sender information
- KV storage entries have automatic expiration (TTL)
- No persistent logging of message content (except in TEST_MODE)
## Troubleshooting
### Bot Not Responding
**Check webhook status**:
```bash
curl "https://api.telegram.org/bot/getWebhookInfo"
```
**Verify webhook is set correctly**:
- URL should match your Worker URL
- `pending_update_count` should be 0
- No errors in `last_error_message`
**Check Worker logs**:
```bash
wrangler tail --env production
```
### Messages Not Reaching Admin Group
**Verify admin chat ID**:
- Must be a negative number starting with `-100`
- Bot must be added to the group
- Bot should have permission to send messages
**Test manually**:
```bash
curl -X POST "https://api.telegram.org/bot/sendMessage" \
-H "Content-Type: application/json" \
-d '{"chat_id": "", "text": "Test message"}'
```
### Users Cannot Activate
**Verify access token**:
```bash
# Check if secret is set
wrangler secret list --env production
```
**Check deeplink format**:
- Format: `https://t.me/?start=`
- Bot username should not include `@`
- Access token must match exactly
**Check KV storage**:
```bash
# List trusted users
wrangler kv:key list --binding KV --env production --prefix "trusted:"
```
### KV Storage Issues
**Check namespace binding**:
- Verify `wrangler.toml` has correct KV namespace IDs
- Ensure binding name is `KV`
**Check storage quota**:
- Free tier: 1 GB storage, 100,000 reads/day, 1,000 writes/day
- Upgrade plan if limits exceeded
### Webhook Registration Fails
**Common issues**:
- URL must be HTTPS
- URL must be publicly accessible
- Telegram must be able to reach the URL
**Re-register webhook**:
```bash
# Delete existing webhook
curl -X POST "https://api.telegram.org/bot/deleteWebhook"
# Set new webhook
curl -X POST "https://api.telegram.org/bot/setWebhook" \
-H "Content-Type: application/json" \
-d '{"url": "https://your-worker.workers.dev"}'
```
## Additional Resources
- [Cloudflare Workers Documentation](https://developers.cloudflare.com/workers/)
- [Cloudflare KV Documentation](https://developers.cloudflare.com/kv/)
- [Telegram Bot API Documentation](https://core.telegram.org/bots/api)
- [Wrangler CLI Documentation](https://developers.cloudflare.com/workers/wrangler/)
## License
MIT