A production-ready Node.js webhook server for Unthread.io integration. Built with TypeScript, Express.js, and Redis for reliable webhook event processing with HMAC signature verification and intelligent platform detection.
These outstanding organizations partner with us to support our open-source work:
π Platinum Sponsor |
|---|
![]() |
Unthread Streamlined support ticketing for modern teams. |
Open source development is resource-intensive. These sponsored ads help keep Log Engine free and actively maintained while connecting you with tools and services that support open-source development.
Requirements: Node.js 20+, Redis, Yarn
# 1. Install dependencies
yarn install
# 2. Configure environment
cp .env.example .env
# Edit .env with your Unthread webhook secret
# 3. Start Redis (choose one)
redis-server # Local installation
brew services start redis # macOS
sudo systemctl start redis-server # Linux
docker run -d -p 6379:6379 redis:alpine # Docker
# 4. Run the server
yarn dev # Development with auto-reload
yarn start # Production modeServer runs on http://localhost:3000 with endpoints:
GET /health- Health checkPOST /unthread-webhook- Webhook endpoint
# Copy Docker template
cp .env.docker.example .env.docker
# Edit .env.docker with your secrets
# Start Redis for Docker
docker run -d --name docker-redis -p 6379:6379 redis:7-alpine
# Run with Docker (using cloud builder)
docker run --name docker-unthread-webhook-server --env-file .env.docker -p 3000:3000 --rm wgtechlabs/unthread-webhook-server:latestEnvironment Files:
.env- Local development (Node.js directly).env.docker- Docker testing (redis://host.docker.internal:6379).env.example+.env.docker.example- Safe templates (committed to git)
Create a .env file from the example:
cp .env.example .envRequired variables:
| Variable | Description | Default | Required |
|---|---|---|---|
UNTHREAD_WEBHOOK_SECRET |
Your Unthread.io signing secret | - | β |
NODE_ENV |
Environment mode | development |
β |
PORT |
Server port | 3000 |
β |
TARGET_PLATFORM |
Platform identifier (e.g., telegram, discord) | telegram |
β |
REDIS_URL |
Redis connection URL | redis://localhost:6379 |
β |
- Go to Unthread Dashboard
- Navigate to Webhooks settings
- Copy your signing secret to
UNTHREAD_WEBHOOK_SECRETin.env - Set your webhook URL to:
https://your-domain.com/unthread-webhook
For local testing, use ngrok: ngrok http 3000
- Webhook Reception: Receives POST requests from Unthread.io at
/unthread-webhook - Security: Validates HMAC-SHA256 signatures using your webhook secret
- Deduplication: Prevents duplicate event processing with Redis TTL cache
- Platform Detection: Identifies if events come from dashboard or target platform
- Queue Publishing: Sends processed events to Redis
unthread-eventsqueue
url_verification- Automatic URL verificationconversation_created- New conversationsconversation_updated- Status changesconversation_deleted- Conversation removalmessage_created- New messages
Events are queued with this structure:
{
"platform": "unthread",
"targetPlatform": "telegram",
"type": "message_created",
"sourcePlatform": "dashboard",
"data": {
"eventId": "evt_123456789",
"conversationId": "conv_abc123",
"content": "Hello from support!",
"eventTimestamp": 1733097600000
},
"timestamp": 1733097600000
}yarn clean # Clean previous builds
yarn build # Build for production
yarn type-check # TypeScript type checking only
yarn dev # Development with hot-reload
yarn start # Run production buildsrc/
βββ app.ts # Main application entry
βββ config/ # Configuration files
βββ controllers/ # Request handlers
βββ middleware/ # Auth & validation
βββ services/ # Business logic
βββ types/ # TypeScript types
βββ utils/ # Helper functions
curl http://localhost:3000/healthHealthy Response:
{
"status": "OK",
"redis": "connected",
"timestamp": "2025-06-21T12:00:00.000Z"
}Error Response:
{
"status": "ERROR",
"redis": "disconnected",
"timestamp": "2025-06-21T12:00:00.000Z"
}Redis Connection Issues:
- Verify Redis is running:
redis-cli ping - Check
REDIS_URLin your.envfile - Review server logs for connection errors
Platform Detection Issues:
- Check logs for detection summary details
- Verify event structure matches Unthread format
- Events may be classified as "unknown" for edge cases
Contributions are welcome, create a pull request to this repo and I will review your code. Please consider to submit your pull request to the dev branch. Thank you!
When contributing, please ensure your code follows the existing TypeScript patterns and includes appropriate error handling.
Like this project? Leave a star! βββββ
There are several ways you can support this project:
- Become a sponsor and get some perks! π
- Buy me a coffee if you just love what I do! β
Found this project helpful? Consider nominating me (@warengonzaga) for the GitHub Star program! This recognition supports ongoing development of this project and my other open-source projects. GitHub Stars are recognized for their significant contributions to the developer community - your nomination makes a difference and encourages continued innovation!
Licensed under GNU General Public License v3.0 - ensuring modifications remain open source.
This project is created by Waren Gonzaga under WG Technology Labs, with the help of awesome contributors.
π» Made with β€οΈ by Waren Gonzaga under WG Technology Labs
