A reliable, production-ready Node.js server for processing Unthread.io webhooks with signature verification and smart platform handling. Built with TypeScript, Express.js, and Redis, this webhook server provides secure HMAC-SHA256 signature validation, intelligent event deduplication, seamless integration with multiple platforms including Discord and Telegram, and advanced file attachment correlation that accurately detects source platforms for file uploads. The server automatically detects event sources, processes various webhook events (conversations, messages, status updates), correlates file attachments with their originating platforms, and efficiently queues them through Redis for downstream consumption by your bot applications, ensuring reliable and scalable webhook processing for your Unthread.io integrations.
These outstanding organizations partner with us to support our open-source work:
π Platinum Sponsor |
---|
![]() |
Unthread Streamlined support ticketing for modern teams. |
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 mode
Server runs on http://localhost:3000
with endpoints:
GET /health
- Health checkPOST /unthread-webhook
- Webhook endpoint
- HMAC-SHA256 Signature Verification: Secure webhook authentication
- Event Deduplication: Redis-based TTL cache prevents duplicate processing
- Rate Limiting: Built-in protection against spam and abuse
- Intelligent Source Identification: Automatically detects Dashboard vs. target platform events
- File Attachment Correlation: Revolutionary system that links file uploads with their true source platforms
- Multi-Platform Support: Discord, Telegram, and extensible for other platforms
- Source Platform Accuracy: Eliminates "unknown" file sources through intelligent correlation
- Rich Metadata Generation: Automatic file summaries with counts, sizes, types, and names
- Multi-Event Buffering: Handles multiple file attachments with timeout-based processing
- Memory-Based Correlation: 15-second correlation windows with automatic fallbacks
- Redis Queue Integration: Efficient FIFO event processing
- Comprehensive Logging: Detailed operation logs with emoji indicators
- Health Monitoring: Built-in health checks for system status
- TypeScript: Full type safety throughout the codebase
Deploy instantly to Railway with a single click:
# 1. Create external network (if not already created)
docker network create unthread-integration-network
# 2. Copy environment template
cp .env.example .env
# Edit .env with your webhook secret
# 3. Start with Docker Compose
docker-compose up -d
# 4. Check status
docker-compose ps
# 5. View logs
docker-compose logs -f webhook-server
docker-compose logs -f redis-webhook
# 6. Stop services
docker-compose down
Environment Files:
.env
- Single config file for both local development and Docker.env.example
- Template with default values.env.railway
- Railway deployment template
Create a .env
file from the example:
cp .env.example .env
Required 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) | - | β |
REDIS_URL |
Redis connection URL | redis://localhost:6379 |
β |
- Go to Unthread Dashboard
- Navigate to Webhooks settings
- Copy your signing secret to
UNTHREAD_WEBHOOK_SECRET
in.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
- File Attachment Correlation: Smart correlation system that links file attachments with their source platforms instead of marking them as "unknown"
- Queue Publishing: Sends processed events to Redis
unthread-events
queue with enhanced attachment metadata
This server features advanced file attachment correlation that:
- Eliminates "Unknown" Sources: Automatically correlates file upload events with their originating platform (Dashboard, Telegram, Discord, etc.)
- Memory-Based Correlation: Uses intelligent caching to match message events with subsequent file upload events
- Rich Metadata Generation: Provides comprehensive attachment summaries including file count, total size, MIME types, and file names
- Multi-Event Buffering: Handles multiple file attachments in a single conversation with timeout-based processing
- Backwards Compatibility: Existing integrations continue to work without modification
url_verification
- Automatic URL verificationconversation_created
- New conversationsconversation_updated
- Status changesconversation_deleted
- Conversation removalmessage_created
- New messages
Events are queued with this enhanced structure:
{
"platform": "unthread",
"targetPlatform": "telegram",
"type": "message_created",
"sourcePlatform": "dashboard",
"data": {
"eventId": "evt_123456789",
"conversationId": "conv_abc123",
"content": "Hello from support!",
"eventTimestamp": 1733097600000,
"files": [
{
"id": "F123ABC456",
"name": "document.pdf",
"size": 524288,
"mimetype": "application/pdf"
}
]
},
"attachments": {
"hasFiles": true,
"fileCount": 1,
"totalSize": 524288,
"types": ["application/pdf"],
"names": ["document.pdf"]
},
"timestamp": 1733097600000
}
New Enhancement: Events with file attachments now include an attachments
metadata object providing:
hasFiles
: Boolean indicating presence of filesfileCount
: Total number of attached filestotalSize
: Combined size of all files in bytestypes
: Array of unique MIME types (deduplicated)names
: Array of all file names (maintains order)
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 build
src/
βββ app.ts # Main application entry
βββ config/ # Configuration files
β βββ env.ts # Environment validation
β βββ redis.ts # Redis configuration
βββ controllers/ # Request handlers
β βββ webhookController.ts
βββ middleware/ # Auth & validation
β βββ auth.ts # HMAC signature verification
β βββ validation.ts # Request validation
βββ services/ # Business logic
β βββ redisService.ts # Redis operations
β βββ webhookService.ts # Webhook processing
βββ types/ # TypeScript types
β βββ index.ts # All type definitions
βββ utils/ # Helper functions
βββ signature.ts # HMAC utilities
βββ fileAttachmentCorrelation.ts # File correlation system
curl http://localhost:3000/health
Healthy 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_URL
in your.env
file - 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
File Attachment Correlation Issues:
- Verify
TARGET_PLATFORM
is set correctly in your.env
file - Check correlation logs for timing and buffering details
- File events without correlation data will fall back to "unknown" source
- Correlation window is 15 seconds - events outside this window may not correlate
Common Solutions:
- Restart the server if platform detection seems inconsistent
- Clear Redis cache if experiencing correlation issues:
redis-cli FLUSHDB
- Enable debug logging by setting
NODE_ENV=development
for detailed correlation logs
- Accurate Source Detection: No more "unknown" file attachment sources - get precise platform identification
- Rich File Metadata: Access file counts, sizes, types, and names without parsing complex file arrays
- Simplified Integration: Use the
attachments
metadata for quick file handling logic - Backwards Compatibility: Existing code continues to work unchanged
- Reliable Correlation: Memory-based correlation system with 15-second timing windows and automatic fallbacks
- Robust Error Handling: Comprehensive timeout management and duplicate prevention
- Scalable Architecture: Efficient Redis-based queuing with TTL cleanup and deduplication
- Production-Ready: Extensive logging, monitoring, and error recovery mechanisms
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.
Major Enhancement: Revolutionary file attachment correlation system that eliminates "unknown" source platforms.
New Features:
- Smart File Correlation: Memory-based system that links file uploads with their originating platforms
- Rich Attachment Metadata: Automatic generation of file summaries for easier integration
- Multi-Event Buffering: Handles multiple files per conversation with robust timeout management
- Enhanced Platform Detection: Required
TARGET_PLATFORM
configuration for improved accuracy - Production-Ready: Comprehensive error handling, logging, and resource cleanup
Breaking Changes:
TARGET_PLATFORM
is now required (no default value)- Enhanced Redis queue format includes
attachments
metadata object
Migration Guide:
- Set
TARGET_PLATFORM
in your.env
file (e.g.,telegram
,discord
) - Existing integrations will continue to work - new
attachments
field is additive
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