{"id":30701282,"url":"https://github.com/wgtechlabs/unthread-webhook-server","last_synced_at":"2026-05-20T07:02:42.348Z","repository":{"id":296712486,"uuid":"959665615","full_name":"wgtechlabs/unthread-webhook-server","owner":"wgtechlabs","description":"A reliable, production-ready Node.js server for processing Unthread.io webhooks with signature verification and smart platform handling. 🎫⚡","archived":false,"fork":false,"pushed_at":"2025-08-09T15:27:23.000Z","size":310,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-29T17:56:46.622Z","etag":null,"topics":["bots","discord","server","telegram","ticket-system","unthread","webhook"],"latest_commit_sha":null,"homepage":"https://unthread.io","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wgtechlabs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"wgtechlabs","buy_me_a_coffee":"wgtechlabs"}},"created_at":"2025-04-03T06:45:43.000Z","updated_at":"2025-08-09T15:26:44.000Z","dependencies_parsed_at":"2025-07-10T17:26:45.148Z","dependency_job_id":"c7ad4930-bbd9-414b-93e2-fd709778dab4","html_url":"https://github.com/wgtechlabs/unthread-webhook-server","commit_stats":null,"previous_names":["wgtechlabs/unthread-webhook-server"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/wgtechlabs/unthread-webhook-server","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wgtechlabs%2Funthread-webhook-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wgtechlabs%2Funthread-webhook-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wgtechlabs%2Funthread-webhook-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wgtechlabs%2Funthread-webhook-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wgtechlabs","download_url":"https://codeload.github.com/wgtechlabs/unthread-webhook-server/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wgtechlabs%2Funthread-webhook-server/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273289241,"owners_count":25078916,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-02T02:00:09.530Z","response_time":77,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bots","discord","server","telegram","ticket-system","unthread","webhook"],"created_at":"2025-09-02T13:20:11.612Z","updated_at":"2026-05-20T07:02:42.339Z","avatar_url":"https://github.com/wgtechlabs.png","language":"TypeScript","funding_links":["https://github.com/sponsors/wgtechlabs","https://buymeacoffee.com/wgtechlabs"],"categories":[],"sub_categories":[],"readme":"# Unthread Webhook Server 🎫🛰️\n\n[![made by](https://img.shields.io/badge/made%20by-WG%20Tech%20Labs-0060a0.svg?logo=github\u0026longCache=true\u0026labelColor=181717\u0026style=flat-square)](https://github.com/wgtechlabs) [![official](https://img.shields.io/badge/official-Unthread%20Extension-FF5241.svg?logo=discord\u0026logoColor=white\u0026labelColor=181717\u0026style=flat-square)](https://unthread.com) [![sponsors](https://img.shields.io/badge/sponsor-%E2%9D%A4-%23db61a2.svg?\u0026logo=github\u0026logoColor=white\u0026labelColor=181717\u0026style=flat-square)](https://github.com/sponsors/wgtechlabs)\n\n[![banner](https://raw.githubusercontent.com/wgtechlabs/unthread-webhook-server/main/.github/assets/repo_banner.jpg)](https://github.com/wgtechlabs/unthread-webhook-server)\n\n[![release workflow](https://img.shields.io/github/actions/workflow/status/wgtechlabs/unthread-webhook-server/release.yml?style=flat-square\u0026logo=github\u0026labelColor=181717\u0026label=release)](https://github.com/wgtechlabs/unthread-webhook-server/actions/workflows/release.yml) [![build workflow](https://img.shields.io/github/actions/workflow/status/wgtechlabs/unthread-webhook-server/build.yml?branch=dev\u0026style=flat-square\u0026logo=github\u0026labelColor=181717\u0026label=build)](https://github.com/wgtechlabs/unthread-webhook-server/actions/workflows/build.yml) [![version](https://img.shields.io/github/release/wgtechlabs/unthread-webhook-server.svg?logo=github\u0026labelColor=181717\u0026color=green\u0026style=flat-square\u0026label=version)](https://github.com/wgtechlabs/unthread-webhook-server/releases) [![star](https://img.shields.io/github/stars/wgtechlabs/unthread-webhook-server.svg?\u0026logo=github\u0026labelColor=181717\u0026color=yellow\u0026style=flat-square)](https://github.com/wgtechlabs/unthread-webhook-server/stargazers) [![license](https://img.shields.io/github/license/wgtechlabs/unthread-webhook-server.svg?\u0026logo=github\u0026labelColor=181717\u0026style=flat-square)](https://github.com/wgtechlabs/unthread-webhook-server/blob/main/license)\n\nA 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.\n\n## 🤗 Special Thanks\n\n### 🤝 Partner Organizations\n\nThese outstanding organizations partner with us to support our open-source work:\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n| \u003cdiv align=\"center\"\u003e💎 Platinum Sponsor\u003c/div\u003e |\n|:-------------------------------------------:|\n| \u003ca href=\"https://unthread.com\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/wgtechlabs/unthread-discord-bot/main/.github/assets/sponsors/platinum_unthread.png\" width=\"250\" alt=\"Unthread\"\u003e\u003c/a\u003e |\n| \u003cdiv align=\"center\"\u003e\u003ca href=\"https://unthread.com\" target=\"_blank\"\u003e\u003cb\u003eUnthread\u003c/b\u003e\u003c/a\u003e\u003cbr/\u003eStreamlined support ticketing for modern teams.\u003c/div\u003e |\n\u003c!-- markdownlint-enable MD033 --\u003e\n\n## 🚀 Quick Start\n\n**Requirements**: Node.js 22+, Redis, Bun\n\n```bash\n# 1. Install dependencies\nbun install\n\n# 2. Configure environment\ncp .env.example .env\n# Edit .env with your Unthread webhook secret\n\n# 3. Start Redis (choose one)\nredis-server                          # Local installation\nbrew services start redis             # macOS\nsudo systemctl start redis-server     # Linux\ndocker run -d -p 6379:6379 redis:alpine  # Docker\n\n# 4. Run the server\nbun run dev     # Development with auto-reload\nbun run start   # Production mode\n```\n\nServer runs on `http://localhost:3000` with endpoints:\n\n- `GET /health` - Health check\n- `POST /unthread-webhook` - Webhook endpoint\n\n## ✨ Features\n\n### 🔐 Security \u0026 Reliability\n\n- **HMAC-SHA256 Signature Verification**: Secure webhook authentication\n- **Event Deduplication**: Redis-based TTL cache prevents duplicate processing\n- **Rate Limiting**: Built-in protection against spam and abuse\n\n### 🎯 Smart Platform Detection\n\n- **Intelligent Source Identification**: Automatically detects Dashboard vs. target platform events\n- **File Attachment Correlation**: Revolutionary system that links file uploads with their true source platforms\n- **Multi-Platform Support**: Discord, Telegram, and extensible for other platforms\n\n### 📎 Advanced File Handling\n\n- **Source Platform Accuracy**: Eliminates \"unknown\" file sources through intelligent correlation\n- **Rich Metadata Generation**: Automatic file summaries with counts, sizes, types, and names\n- **Multi-Event Buffering**: Handles multiple file attachments with timeout-based processing\n- **Memory-Based Correlation**: 15-second correlation windows with automatic fallbacks\n\n### 🚀 Production-Ready Architecture\n\n- **Redis Queue Integration**: Efficient FIFO event processing\n- **Comprehensive Logging**: Detailed operation logs with emoji indicators\n- **Health Monitoring**: Built-in health checks for system status\n- **TypeScript**: Full type safety throughout the codebase\n- **Security-First Linting**: ESLint with comprehensive security plugins (security, no-secrets, promise handling)\n- **Code Quality**: Automated code quality checks with TypeScript-ESLint integration\n\n## 🚂 One-Click Deploy\n\nDeploy instantly to Railway with a single click:\n\n[![deploy on railway](https://railway.com/button.svg)](https://railway.com/deploy/unthread-webhook-server?referralCode=dTwT-i)\n\n## 🐳 Docker Setup\n\n```bash\n# 1. Create external network (if not already created)\ndocker network create unthread-integration-network\n\n# 2. Copy environment template\ncp .env.example .env\n# Edit .env with your webhook secret\n\n# 3. Start with Docker Compose\ndocker-compose up -d\n\n# 4. Check status\ndocker-compose ps\n\n# 5. View logs\ndocker-compose logs -f webhook-server\ndocker-compose logs -f redis-webhook\n\n# 6. Stop services\ndocker-compose down\n```\n\n**Environment Files:**\n\n- `.env` - Single config file for both local development and Docker\n- `.env.example` - Template with default values\n- `.env.railway` - Railway deployment template\n\n## 🏗️ Development Container\n\nDev container with Node.js 22.16, Bun, and essential VS Code extensions (Copilot, ESLint, Docker, GitLens).\n\n**Quick Start:** Open in VS Code → Click \"Reopen in Container\" → Start coding\n\n## ⚙️ Configuration\n\n### Environment Variables\n\nCreate a `.env` file from the example:\n\n```bash\ncp .env.example .env\n```\n\nRequired variables:\n\n| Variable | Description | Default | Required |\n|----------|-------------|---------|----------|\n| `UNTHREAD_WEBHOOK_SECRET` | Your Unthread.io signing secret | - | ✅ |\n| `NODE_ENV` | Environment mode | `development` | ❌ |\n| `PORT` | Server port | `3000` | ❌ |\n| `TARGET_PLATFORM` | Platform identifier (e.g., telegram, discord) | - | ✅ |\n| `REDIS_URL` | Redis connection URL | `redis://localhost:6379` | ❌ |\n\n### Getting Your Unthread Signing Secret\n\n1. Go to [Unthread Dashboard](https://dashboard.unthread.io)\n2. Navigate to **Webhooks** settings\n3. Copy your signing secret to `UNTHREAD_WEBHOOK_SECRET` in `.env`\n4. Set your webhook URL to: `https://your-domain.com/unthread-webhook`\n\nFor local testing, use [ngrok](https://ngrok.com/): `ngrok http 3000`\n\n## 🔧 How It Works\n\n1. **Webhook Reception**: Receives POST requests from Unthread.io at `/unthread-webhook`\n2. **Security**: Validates HMAC-SHA256 signatures using your webhook secret\n3. **Deduplication**: Prevents duplicate event processing with Redis TTL cache\n4. **Platform Detection**: Identifies if events come from dashboard or target platform\n5. **File Attachment Correlation**: Smart correlation system that links file attachments with their source platforms instead of marking them as \"unknown\"\n6. **Queue Publishing**: Sends processed events to Redis `unthread-events` queue with enhanced attachment metadata\n\n### 🎯 File Attachment Intelligence\n\nThis server features advanced file attachment correlation that:\n\n- **Eliminates \"Unknown\" Sources**: Automatically correlates file upload events with their originating platform (Dashboard, Telegram, Discord, etc.)\n- **Memory-Based Correlation**: Uses intelligent caching to match message events with subsequent file upload events\n- **Rich Metadata Generation**: Provides comprehensive attachment summaries including file count, total size, MIME types, and file names\n- **Multi-Event Buffering**: Handles multiple file attachments in a single conversation with timeout-based processing\n- **Backwards Compatibility**: Existing integrations continue to work without modification\n\n## 📊 Event Processing\n\n### Supported Events\n\n- `url_verification` - Automatic URL verification\n- `conversation_created` - New conversations\n- `conversation_updated` - Status changes  \n- `conversation_deleted` - Conversation removal\n- `message_created` - New messages\n\n### Redis Queue Format\n\nEvents are queued with this enhanced structure:\n\n```json\n{\n  \"platform\": \"unthread\",\n  \"targetPlatform\": \"telegram\",\n  \"type\": \"message_created\", \n  \"sourcePlatform\": \"dashboard\",\n  \"data\": {\n    \"eventId\": \"evt_123456789\",\n    \"conversationId\": \"conv_abc123\",\n    \"content\": \"Hello from support!\",\n    \"eventTimestamp\": 1733097600000,\n    \"files\": [\n      {\n        \"id\": \"F123ABC456\",\n        \"name\": \"document.pdf\",\n        \"size\": 524288,\n        \"mimetype\": \"application/pdf\"\n      }\n    ]\n  },\n  \"attachments\": {\n    \"hasFiles\": true,\n    \"fileCount\": 1,\n    \"totalSize\": 524288,\n    \"types\": [\"application/pdf\"],\n    \"names\": [\"document.pdf\"]\n  },\n  \"timestamp\": 1733097600000\n}\n```\n\n**New Enhancement**: Events with file attachments now include an `attachments` metadata object providing:\n\n- `hasFiles`: Boolean indicating presence of files\n- `fileCount`: Total number of attached files  \n- `totalSize`: Combined size of all files in bytes\n- `types`: Array of unique MIME types (deduplicated)\n- `names`: Array of all file names (maintains order)\n\n## 💻 Development\n\n### Build Commands\n\n```bash\nbun run clean       # Clean previous builds\nbun run build       # Build for production\nbun run type-check  # TypeScript type checking only\nbun run dev         # Development with hot-reload\nbun run start       # Run production build\n```\n\n### Code Quality \u0026 Linting\n\nThis project enforces strict code quality and security standards using ESLint with comprehensive security plugins.\n\n```bash\nbun run lint              # Run ESLint on all source files\nbun run lint:fix          # Run ESLint with auto-fix\nbun run lint:security     # Focus on security-related issues\nbun run lint:ci           # CI-friendly linting (fails on warnings)\n```\n\n**Security Plugins Enabled:**\n\n- `eslint-plugin-security` - Detects common security vulnerabilities\n- `eslint-plugin-no-secrets` - Prevents hardcoded secrets and credentials\n- `eslint-plugin-n` - Node.js best practices and deprecated API detection\n- `eslint-plugin-import` - Validates ES6 import/export syntax\n- `eslint-plugin-promise` - Ensures proper promise handling\n\nFor detailed ESLint configuration and security rules, see [eslint.config.js](./eslint.config.js).\n\n### Project Structure\n\n```text\nsrc/\n├── app.ts              # Main application entry\n├── config/             # Configuration files\n│   ├── env.ts         # Environment validation\n│   └── redis.ts       # Redis configuration\n├── controllers/        # Request handlers\n│   └── webhookController.ts\n├── middleware/         # Auth \u0026 validation\n│   ├── auth.ts        # HMAC signature verification\n│   └── validation.ts  # Request validation\n├── services/           # Business logic\n│   ├── redisService.ts      # Redis operations\n│   └── webhookService.ts    # Webhook processing\n├── types/              # TypeScript types\n│   └── index.ts       # All type definitions\n└── utils/              # Helper functions\n    ├── signature.ts         # HMAC utilities\n    └── fileAttachmentCorrelation.ts  # File correlation system\n```\n\n## 🧪 Testing\n\nThis project uses [Bun's built-in test runner](https://bun.com/docs/cli/test) (`bun:test`) for fast, modern testing with first-class TypeScript support.\n\n### Running Tests\n\n```bash\n# Run all tests (one-time)\nbun run test\n\n# Run tests in watch mode (development)\nbun run test:watch\n\n# Generate coverage report\nbun run test:coverage\n```\n\n### Writing Tests\n\nTests are co-located with source files using the `.test.ts` suffix:\n\n```text\nsrc/\n├── utils/\n│   ├── signature.ts\n│   └── signature.test.ts\n```\n\n### Coverage Requirements\n\n- Lines: 80%\n- Functions: 80%\n- Branches: 80%\n- Statements: 80%\n\n## 🔍 Monitoring\n\n### Health Check\n\n```bash\ncurl http://localhost:3000/health\n```\n\n**Healthy Response:**\n\n```json\n{\n  \"status\": \"OK\",\n  \"redis\": \"connected\",\n  \"timestamp\": \"2025-06-21T12:00:00.000Z\"\n}\n```\n\n**Error Response:**\n\n```json\n{\n  \"status\": \"ERROR\", \n  \"redis\": \"disconnected\",\n  \"timestamp\": \"2025-06-21T12:00:00.000Z\"\n}\n```\n\n### Troubleshooting\n\n**Redis Connection Issues:**\n\n- Verify Redis is running: `redis-cli ping`\n- Check `REDIS_URL` in your `.env` file\n- Review server logs for connection errors\n\n**Platform Detection Issues:**\n\n- Check logs for detection summary details\n- Verify event structure matches Unthread format\n- Events may be classified as \"unknown\" for edge cases\n\n**File Attachment Correlation Issues:**\n\n- Verify `TARGET_PLATFORM` is set correctly in your `.env` file\n- Check correlation logs for timing and buffering details\n- File events without correlation data will fall back to \"unknown\" source\n- Correlation window is 15 seconds - events outside this window may not correlate\n\n**Common Solutions:**\n\n- Restart the server if platform detection seems inconsistent\n- Clear Redis cache if experiencing correlation issues: `redis-cli FLUSHDB`\n- Enable debug logging by setting `NODE_ENV=development` for detailed correlation logs\n\n## 🚀 Integration Benefits\n\n### For Bot Developers\n\n- **Accurate Source Detection**: No more \"unknown\" file attachment sources - get precise platform identification\n- **Rich File Metadata**: Access file counts, sizes, types, and names without parsing complex file arrays\n- **Simplified Integration**: Use the `attachments` metadata for quick file handling logic\n- **Backwards Compatibility**: Existing code continues to work unchanged\n\n### For Production Systems\n\n- **Reliable Correlation**: Memory-based correlation system with 15-second timing windows and automatic fallbacks\n- **Robust Error Handling**: Comprehensive timeout management and duplicate prevention\n- **Scalable Architecture**: Efficient Redis-based queuing with TTL cleanup and deduplication\n- **Production-Ready**: Extensive logging, monitoring, and error recovery mechanisms\n\n## 🎯 Contributing\n\nContributions 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!\n\nWhen contributing, please ensure your code follows the existing TypeScript patterns and includes appropriate error handling.\n\n## 🔄 Recent Updates\n\n### v1.0.0-beta.5.2 - File Attachment Intelligence\n\n**Major Enhancement**: Revolutionary file attachment correlation system that eliminates \"unknown\" source platforms.\n\n**New Features:**\n\n- **Smart File Correlation**: Memory-based system that links file uploads with their originating platforms\n- **Rich Attachment Metadata**: Automatic generation of file summaries for easier integration\n- **Multi-Event Buffering**: Handles multiple files per conversation with robust timeout management\n- **Enhanced Platform Detection**: Required `TARGET_PLATFORM` configuration for improved accuracy\n- **Production-Ready**: Comprehensive error handling, logging, and resource cleanup\n\n**Breaking Changes:**\n\n- `TARGET_PLATFORM` is now required (no default value)\n- Enhanced Redis queue format includes `attachments` metadata object\n\n**Migration Guide:**\n\n- Set `TARGET_PLATFORM` in your `.env` file (e.g., `telegram`, `discord`)\n- Existing integrations will continue to work - new `attachments` field is additive\n\n## 🙏 Sponsor\n\nLike this project? **Leave a star**! ⭐⭐⭐⭐⭐\n\nThere are several ways you can support this project:\n\n- [Become a sponsor](https://github.com/sponsors/wgtechlabs) and get some perks! 💖\n- [Buy me a coffee](https://buymeacoffee.com/wgtechlabs) if you just love what I do! ☕\n\n## ⭐ GitHub Star Nomination\n\nFound this project helpful? Consider nominating me **(@warengonzaga)** for the [GitHub Star program](https://stars.github.com/nominate/)! This recognition supports ongoing development of this project and [my other open-source projects](https://github.com/warengonzaga?tab=repositories). GitHub Stars are recognized for their significant contributions to the developer community - your nomination makes a difference and encourages continued innovation!\n\n## 📃 License\n\nLicensed under [GNU General Public License v3.0](LICENSE) - ensuring modifications remain open source.\n\n## 📝 Author\n\nThis project is created by **[Waren Gonzaga](https://github.com/warengonzaga)** under [WG Technology Labs](https://github.com/wgtechlabs), with the help of awesome [contributors](https://github.com/wgtechlabs/unthread-webhook-server/graphs/contributors).\n\n[![contributors](https://contrib.rocks/image?repo=wgtechlabs/unthread-webhook-server)](https://github.com/wgtechlabs/unthread-webhook-server/graphs/contributors)\n\n---\n\n💻 Made with ❤️ by [Waren Gonzaga](https://warengonzaga.com) under [WG Technology Labs](https://wgtechlabs.com)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwgtechlabs%2Funthread-webhook-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwgtechlabs%2Funthread-webhook-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwgtechlabs%2Funthread-webhook-server/lists"}