{"id":28171203,"url":"https://github.com/green-api/greenapi-integration","last_synced_at":"2026-04-29T15:37:55.028Z","repository":{"id":291827387,"uuid":"900770295","full_name":"green-api/greenapi-integration","owner":"green-api","description":"This flexible integration platform will help you connect GREEN-API's WhatsApp gateway to various third-party services.","archived":false,"fork":false,"pushed_at":"2025-05-15T11:58:11.000Z","size":654,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-05-15T12:41:10.259Z","etag":null,"topics":["whatsapp","whatsapp-api","whatsapp-integration","whatsapp-send-message","whatsapp-sender"],"latest_commit_sha":null,"homepage":"https://green-api.com/en","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/green-api.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-12-09T12:48:56.000Z","updated_at":"2025-05-15T11:58:11.000Z","dependencies_parsed_at":"2025-05-06T18:49:23.474Z","dependency_job_id":"0565b606-3c45-4b0f-992d-c6549dd912da","html_url":"https://github.com/green-api/greenapi-integration","commit_stats":null,"previous_names":["green-api/greenapi-integration"],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/green-api%2Fgreenapi-integration","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/green-api%2Fgreenapi-integration/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/green-api%2Fgreenapi-integration/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/green-api%2Fgreenapi-integration/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/green-api","download_url":"https://codeload.github.com/green-api/greenapi-integration/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254394693,"owners_count":22063985,"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","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":["whatsapp","whatsapp-api","whatsapp-integration","whatsapp-send-message","whatsapp-sender"],"created_at":"2025-05-15T18:16:19.404Z","updated_at":"2026-04-29T15:37:54.994Z","avatar_url":"https://github.com/green-api.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Universal Integration Platform for GREEN-API\n\n## Support links\n\n[![Support](https://img.shields.io/badge/support@green--api.com-D14836?style=for-the-badge\u0026logo=gmail\u0026logoColor=white)](mailto:support@greenapi.com)\n[![Support](https://img.shields.io/badge/Telegram-2CA5E0?style=for-the-badge\u0026logo=telegram\u0026logoColor=white)](https://t.me/greenapi_support_eng_bot)\n[![Support](https://img.shields.io/badge/WhatsApp-25D366?style=for-the-badge\u0026logo=whatsapp\u0026logoColor=white)](https://wa.me/77273122366)\n\n## Guides \u0026 News\n\n[![Guides](https://img.shields.io/badge/YouTube-%23FF0000.svg?style=for-the-badge\u0026logo=YouTube\u0026logoColor=white)](https://www.youtube.com/@greenapi-en)\n[![News](https://img.shields.io/badge/Telegram-2CA5E0?style=for-the-badge\u0026logo=telegram\u0026logoColor=white)](https://t.me/green_api)\n[![News](https://img.shields.io/badge/WhatsApp-25D366?style=for-the-badge\u0026logo=whatsapp\u0026logoColor=white)](https://whatsapp.com/channel/0029VaLj6J4LNSa2B5Jx6s3h)\n\n[![NPM Version](https://img.shields.io/npm/v/@green-api/greenapi-integration)](https://www.npmjs.com/package/@green-api/whatsapp-chatbot-js-v2)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n- [Документация на русском языке](./README.ru.md)\n\nA flexible integration platform designed to simplify the process of connecting GREEN-API's WhatsApp gateway with various\nthird-party services.\n\n## Table of Contents\n\n- [Installation](#installation)\n- [Core Components](#core-components)\n- [Developer Guide](#developer-guide)\n- [Working Example](#working-example)\n- [Real-World Examples](#real-world-examples)\n\n## Installation\n\n```bash\nnpm install @green-api/greenapi-integration\n```\n\n## Core Components\n\n### 1. BaseAdapter\n\nThe foundation of your integration. Handles message \u0026 instance management, and platform-specific logic.\n\n```typescript\nabstract class BaseAdapter\u003cTPlatformWebhook, TPlatformMessage, TUser extends BaseUser = BaseUser, TInstance extends Instance = Instance\u003e {\n    private readonly gaLogger = GreenApiLogger.getInstance(this.constructor.name);\n\n    public constructor(\n            transformer: MessageTransformer\u003cTPlatformWebhook, TPlatformMessage\u003e,\n            storage: StorageProvider\u003cTUser, TInstance\u003e,\n    );\n\n    public abstract createPlatformClient(params: any): Promise\u003cany\u003e;\n\n    public abstract sendToPlatform(message: TPlatformMessage, instance: TInstance): Promise\u003cvoid\u003e;\n}\n```\n\n#### Methods\n\nWhen extending BaseAdapter, your implementation has access to several methods:\n\n##### Webhook Handling\n\nThese webhook handling methods call your message transformation methods automatically, without the need to use them\ndirectly in your code.\n\n```typescript\n// Handle webhooks from your platform\nawait adapter.handlePlatformWebhook(webhookData, instanceId);\n\n// Handle webhooks from GREEN-API. The second parameter is telling the function to handle only specific webhooks.\n// The second parameter must be specified, otherwise webhooks will not be processed.\nawait adapter.handleGreenApiWebhook(webhook, ['incomingMessageReceived']);\n```\n\n##### Instance Management\n\n```typescript\n// Create new instance\nconst instance = await adapter.createInstance(instanceData, settings, userEmail);\n\n// Get instance details\nconst details = await adapter.getInstance(instanceId);\n\n// Remove instance\nawait adapter.removeInstance(instanceId);\n```\n\n##### User Management\n\n```typescript\n// Create new user\nconst user = await adapter.createUser(userEmail, userData);\n\n// Update user\nawait adapter.updateUser(userEmail, updateData);\n```\n\n#### Webhook Implementation Example\n\n```typescript\n// Platform webhook endpoint\napp.post('/webhook/platform', async (req, res) =\u003e {\n    try {\n        await adapter.handlePlatformWebhook(req.body, instanceId);\n        res.status(200).send();\n    } catch (error) {\n        console.error('Failed to handle platform webhook:', error);\n        res.status(500).send();\n    }\n});\n\n// GREEN-API webhook endpoint\napp.post('/webhook/green-api', async (req, res) =\u003e {\n    try {\n        // Process specific webhook types\n        await adapter.handleGreenApiWebhook(req.body, [\n            'incomingMessageReceived',\n            'outgoingMessageStatus'\n        ]);\n        res.status(200).send();\n    } catch (error) {\n        console.error('Failed to handle GREEN-API webhook:', error);\n        res.status(500).send();\n    }\n});\n```\n\n### 2. MessageTransformer\n\nHandles message format conversion between GREEN-API and your platform.\n\n```typescript\nabstract class MessageTransformer\u003cTPlatformWebhook, TPlatformMessage\u003e {\n    abstract toPlatformMessage(webhook: GreenApiWebhook): TPlatformMessage;\n\n    abstract toGreenApiMessage(message: TPlatformWebhook): Message;\n}\n```\n\n### 3. StorageProvider\n\nInterface for data persistence operations.\n\n```typescript\nabstract class StorageProvider\u003c\n        TUser extends BaseUser = BaseUser,\n        TInstance extends Instance = Instance,\n        TUserCreate extends Record\u003cstring, any\u003e = any,\n        TUserUpdate extends Record\u003cstring, any\u003e = any\n\u003e {\n    abstract createInstance(instance: Instance): Promise\u003cTInstance\u003e;\n\n    abstract getInstance(idInstance: number | bigint): Promise\u003cTInstance | null\u003e;\n\n    abstract removeInstance(instanceId: number | bigint): Promise\u003cTInstance\u003e;\n\n    abstract createUser(data: TUserCreate): Promise\u003cTUser\u003e;\n\n    abstract findUser(identifier: string): Promise\u003cTUser | null\u003e;\n\n    abstract updateUser(identifier: string, data: Partial\u003cTUserUpdate\u003e): Promise\u003cTUser\u003e;\n}\n```\n\n### 4. BaseGreenApiAuthGuard\n\nHandles webhook authentication for incoming GREEN-API requests.\n\n```typescript\nabstract class BaseGreenApiAuthGuard\u003cT extends BaseRequest = BaseRequest\u003e {\n    private readonly gaLogger = GreenApiLogger.getInstance(this.constructor.name);\n\n    constructor(protected storage: StorageProvider);\n\n    // Validates incoming webhook requests\n    async validateRequest(request: T): Promise\u003cboolean\u003e;\n}\n```\n\nExample implementation of `BaseGreenApiAuthGuard`:\n\n```typescript\nclass YourAuthGuard extends BaseGreenApiAuthGuard\u003cYourRequest\u003e {\n    constructor(storage: StorageProvider) {\n        super(storage);\n    }\n}\n\n// Using with Express\napp.post('/webhook', async (req, res) =\u003e {\n    const guard = new YourAuthGuard(storage);\n    try {\n        await guard.validateRequest(req);\n        // Process webhook\n    } catch (error) {\n        if (error instanceof AuthenticationError) {\n            res.status(401).json({error: error.message});\n            return;\n        }\n        res.status(500).json({error: 'Internal server error'});\n    }\n});\n```\n\n### 5. GreenApiLogger\n\nA structured JSON logger with colored output. Provides consistent logging format across your application with\nproper error handling and serialization support.\n\n```typescript\nconst logger = GreenApiLogger.getInstance(\"YourComponent\");\n\n// Basic logging\nlogger.debug(\"Debug message\", {someContext: \"value\"});\nlogger.info(\"Info message\", {userId: 123});\nlogger.warn(\"Warning message\", {alert: true});\nlogger.error(\"Error occurred\", {errorCode: 500});\nlogger.fatal(\"Fatal error\", {critical: true});\n\n// Error logging with full context\ntry {\n    await someOperation();\n} catch (error) {\n    logger.logErrorResponse(error, \"Operation failed\", {\n        operationId: \"123\",\n        additionalInfo: \"some context\"\n    });\n}\n```\n\n#### Features\n\n- Structured JSON logging with consistent format\n- Colored output based on log level (debug=cyan, info=green, warn=yellow, error=red, fatal=magenta)\n- Built-in error handling with stack trace formatting\n- Automatic serialization\n- Framework agnostic - works with any Node.js application\n- Special handling for Axios errors with detailed request/response info\n\n#### Log Levels\n\n- `debug` - Detailed information for debugging\n- `info` - General information about system operation\n- `warn` - Warning messages for potentially harmful situations\n- `error` - Error messages for serious problems\n- `fatal` - Critical errors that require immediate attention\n- `log` - Alternative to info (for compatibility)\n\n#### Output Format\n\n```json\n{\n    \"timestamp\": \"30/01/2025, 04:34:49\",\n    \"level\": \"error\",\n    \"context\": \"CoreService\",\n    \"message\": \"Operation failed\",\n    \"error\": \"Failed to process request\",\n    \"stack\": [\n        \"Error: Failed to process request\",\n        \"    at CoreService.process (/app/service.js:123:45)\",\n        \"    at async Router.handle (/app/router.js:67:89)\"\n    ],\n    \"additionalContext\": {\n        \"requestId\": \"abc-123\",\n        \"userId\": \"user_456\"\n    }\n}\n```\n\n#### Error Handling\n\n```typescript\n// Axios error handling\ntry {\n    await apiRequest();\n} catch (error) {\n    logger.logErrorResponse(error, \"API Request failed\", {\n        endpoint: \"/users\",\n        method: \"POST\"\n    });\n}\n```\n\n// Will output detailed API error info:\n\n```\n{\n    \"timestamp\": \"30/01/2025, 04:34:49\",\n    \"level\": \"error\",\n    \"context\": \"ApiService\",\n    \"message\": \"API Request failed - API Error:\",\n    \"status\": 400,\n    \"statusText\": \"Bad Request\",\n    \"data\": { \"error\": \"Invalid input\" },\n    \"url\": \"https://api.example.com/users\",\n    \"method\": \"POST\",\n    \"endpoint\": \"/users\"\n}\n```\n\n#### Using with Frameworks\n\nThe logger is framework-agnostic but can be easily integrated with any framework:\n\n```typescript\n// Express example\napp.use((err, req, res, next) =\u003e {\n    const logger = GreenApiLogger.getInstance(\"Express\");\n    logger.error(\"Request failed\", {\n        path: req.path,\n        method: req.method,\n        error: err.message\n    });\n    next(err);\n});\n```\n\n#### Important Note on Logger Usage\n\nWhile you can use this logger alongside other logging solutions, it's recommended to disable your\nframework's built-in logger to avoid duplicate or malformed logs.\n\nFor example, when using NestJS, you can disable its built-in logger like this:\n\n```typescript\n// main.ts\nconst app = await NestFactory.create(AppModule, {\n    logger: false  // Disable NestJS logger\n});\n```\n\nAnd then use it in your class like this:\n\n```typescript\ngaLogger = GreenApiLogger.getInstance(YourClass.name);\n```\n\n#### Methods\n\n##### Basic Logging Methods\n\n- `debug(message: string, context?: Record\u003cstring, any\u003e)`: Log debug level message\n- `info(message: string, context?: Record\u003cstring, any\u003e)`: Log info level message\n- `warn(message: string, context?: Record\u003cstring, any\u003e)`: Log warning level message\n- `error(message: string, context?: Record\u003cstring, any\u003e)`: Log error level message\n- `fatal(message: string, context?: Record\u003cstring, any\u003e)`: Log fatal level message\n- `log(message: string, context?: string)`: Alternative to info method\n\n##### Special Methods\n\n- `logErrorResponse(error: any, context: string, additionalContext?: Record\u003cstring, any\u003e)`:\n  Enhanced error logging with special handling for Axios errors and stack traces\n\n##### Utility Methods\n\n- `getInstance(context: string = \"Global\"): GreenApiLogger`: Get or create logger instance for specified context\n\n### 6. GreenApiClient\n\nDirect interface to GREEN-API methods.\n\n```typescript\nconst client = new GreenApiClient({\n    idInstance: 'your_instance_id',\n    apiTokenInstance: 'your_token'\n});\n\n// Examples:\nawait client.setProfilePicture(fileBlob);\nawait client.getAuthorizationCode(phoneNumber);\nawait client.getQR();\n```\n\n## Developer Guide\n\nThis guide will walk you through creating your first integration with GREEN-API's WhatsApp gateway.\n\n### Project Structure\n\n```\nyour-integration/\n├── src/\n│   ├── core/\n│   │   ├── adapter.ts         # Your platform adapter\n│   │   ├── transformer.ts     # Message transformer\n│   │   ├── storage.ts         # Data storage implementation\n│   │   └── router.ts          # Webhook endpoints\n│   ├── types/\n│   │   └── types.ts           # Platform-specific types\n│   └── main.ts               # Main exports\n├── package.json\n└── tsconfig.json\n```\n\n```mermaid\ngraph TB\n    subgraph \"WhatsApp to Platform\"\n        WA[WhatsApp] --\u003e|Send message| GA1[GREEN-API]\n        GA1 --\u003e|Webhook| INT1[Your Integration]\n        INT1 --\u003e|1 . Validate webhook| GD1[BaseGreenApiAuthGuard]\n        INT1 --\u003e|2 . Transform message| TR1[MessageTransformer]\n        INT1 --\u003e|3 . Send to platform| PL1[Your Platform]\n    end\n\n    subgraph \"Platform to WhatsApp\"\n        PL2[Your Platform] --\u003e|Webhook| INT2[Your Integration]\n        INT2 --\u003e|1 . Transform message| TR2[MessageTransformer]\n        INT2 --\u003e|2 . Send via API| GA2[GREEN-API]\n        GA2 --\u003e|Send message| WA2[WhatsApp]\n    end\n\n    subgraph \"Components\"\n        style Components fill: #f9f9f9, stroke: #333, stroke-width: 2px\n        TR[MessageTransformer]\n        ST[StorageProvider]\n        AD[BaseAdapter]\n        GD[WebhookGuard]\n    end\n```\n\n### Implementation Steps\n\n#### Step 1: Define Platform Types\n\nFirst, define the message types for your platform:\n\n```typescript\n// types/types.ts\nexport interface YourPlatformWebhook {\n    id: string;\n    from: string;\n    message: string;\n    timestamp: number;\n    // Add other platform-specific fields\n}\n\nexport interface YourPlatformMessage {\n    recipient: string;\n    content: string;\n    // Add other platform-specific fields\n}\n```\n\n#### Step 2: Create Message Transformer\n\nCreate a transformer that converts messages between your platform's format and GREEN-API's format:\n\n```typescript\n// core/transformer.ts\nimport { MessageTransformer, Message, GreenApiWebhook } from '@green-api/greenapi-integration';\nimport { YourPlatformWebhook, YourPlatformMessage } from '../types/types';\n\nexport class YourTransformer extends MessageTransformer\u003cYourPlatformWebhook, YourPlatformMessage\u003e {\n    toPlatformMessage(webhook: GreenApiWebhook): YourPlatformMessage {\n        // Transform GREEN-API webhook to your platform format\n        return {\n            recipient: webhook.senderData.sender,\n            content: webhook.messageData.textMessageData?.textMessage || '',\n        };\n    }\n\n    toGreenApiMessage(message: YourPlatformWebhook): Message {\n        // Transform your platform webhook to GREEN-API format\n        return {\n            type: 'text',\n            chatId: message.from,\n            message: message.message,\n        };\n    }\n}\n```\n\n#### Step 3: Implement Storage Provider\n\nCreate a storage provider to manage users and instances. You can use any database or ORM:\n\n```typescript\n// core/storage.ts\nimport { StorageProvider, BaseUser, Instance, Settings } from '@green-api/greenapi-integration';\nimport { PrismaClient } from '@prisma/client'; // Or your database client\n\nexport class YourStorage extends StorageProvider {\n    private db: PrismaClient;\n\n    constructor() {\n        this.db = new PrismaClient();\n    }\n\n    async findUserByEmail(email: string) {\n        return this.db.user.findUnique({where: {email}});\n    }\n\n    async createInstance(instance: Instance) {\n        return this.db.instance.create({\n            data: {\n                idInstance: instance.idInstance,\n                apiTokenInstance: instance.apiTokenInstance,\n                userId: instance.userId,\n                settings: instance.settings || {},\n            },\n        });\n    }\n\n    // Implement other required methods\n}\n```\n\n#### Step 4: Create Your Platform Adapter\n\nThe adapter handles the actual communication between platforms:\n\n```typescript\n// core/adapter.ts\nimport { BaseAdapter, BaseInstance } from '@green-api/greenapi-integration';\nimport { YourPlatformClient } from 'your-platform-sdk';\nimport { YourPlatformWebhook, YourPlatformMessage } from '../types/types';\n\nexport class YourAdapter extends BaseAdapter\u003cYourPlatformWebhook, YourPlatformMessage\u003e {\n    async createPlatformClient(config: { apiKey: string, apiUrl: string }) {\n        return new YourPlatformClient({\n            baseUrl: config.apiUrl,\n            apiKey: config.apiKey,\n        });\n    }\n\n    async sendToPlatform(message: YourPlatformMessage, instance: Instance) {\n        const client = await this.createPlatformClient(instance.config);\n        await client.sendMessage(message);\n    }\n}\n```\n\n#### Step 5: Implement Webhook Controller\n\nDefine webhook endpoints that your application will listen to:\n\n```typescript\n// core/webhook.ts\nimport express from 'express';\nimport { YourAdapter } from '../core/adapter';\nimport { YourTransformer } from '../core/transformer';\nimport { YourStorage } from '../core/storage';\n\nconst router = express.Router();\nconst storage = new YourStorage();\nconst transformer = new YourTransformer();\nconst adapter = new YourAdapter(transformer, storage);\n\nclass WebhookGuard extends BaseGreenApiAuthGuard {\n    constructor(storage: StorageProvider) {\n        super(storage);\n    }\n}\n\nconst guard = new WebhookGuard(storage);\n\n// Webhook endpoints\nrouter.post('/green-api', async (req, res) =\u003e {\n    try {\n        // Validate webhook first\n        await guard.validateRequest(req);\n\n        // Process webhook if validation passed\n        // As the second parameter, specfify the types of webhooks to be processed (otherwise skipped)\n        await adapter.handleGreenApiWebhook(req.body, ['incomingMessageReceived']);\n        res.status(200).json({status: 'ok'});\n    } catch (error) {\n        if (error instanceof AuthenticationError) {\n            res.status(401).json({error: error.message});\n            return;\n        }\n        console.error('Webhook error:', error);\n        res.status(500).json({error: 'Internal server error'});\n    }\n});\n\nrouter.post('/platform', async (req, res) =\u003e {\n    try {\n        const instanceId = req.query.instanceId;\n        await adapter.handlePlatformWebhook(req.body, instanceId);\n        res.status(200).json({status: 'ok'});\n    } catch (error) {\n        console.error('Platform webhook error:', error);\n        res.status(500).json({error: 'Internal server error'});\n    }\n});\n\nrouter.post('/instance', async (req, res) =\u003e {\n    try {\n        const {idInstance, apiTokenInstance, userEmail} = req.body;\n\n        if (!idInstance || !apiTokenInstance || !userEmail) {\n            throw new BadRequestError('Required fields missing');\n        }\n\n        const user = await storage.findUserByEmail(userEmail);\n        const instance = await adapter.createInstance({\n            idInstance: Number(idInstance),\n            apiTokenInstance,\n            settings: {\n                webhookUrl: `${process.env.APP_URL}/webhook/green-api`,\n                webhookUrlToken: `token_${Date.now()}`,\n                incomingWebhook: 'yes'\n            },\n            userId: user.id\n        });\n\n        res.status(200).json({\n            status: 'ok',\n            data: instance,\n            message: 'Instance created successfully. Please wait 2 minutes for settings to apply.'\n        });\n\n    } catch (error) {\n        console.error('Instance creation error:', error);\n        res.status(500).json({error: 'Failed to create instance'});\n    }\n});\n\nexport default router;\n```\n\n#### Step 6: Create Application Entry Point\n\nPut it all together in your entrypoint:\n\n```typescript\n// main.ts\nimport express from 'express';\nimport bodyParser from 'body-parser';\nimport dotenv from 'dotenv';\nimport webhookRouter from './controllers/webhook';\nimport { YourAdapter } from './core/adapter';\nimport { YourTransformer } from './core/transformer';\nimport { YourStorage } from './core/storage';\n\n// Load environment variables\ndotenv.config();\n\nasync function bootstrap() {\n    // Initialize components\n    const storage = new YourStorage();\n    const transformer = new YourTransformer();\n    const adapter = new YourAdapter(transformer, storage);\n\n    // Create Express application\n    const app = express();\n    app.use(bodyParser.json());\n\n    // Set up webhook routes\n    app.use('/webhook', webhookRouter);\n\n    // Start server\n    const port = process.env.PORT || 3000;\n    app.listen(port, () =\u003e {\n        console.log(`Server running on port ${port}`);\n    });\n\n    console.log('Integration platform ready!');\n}\n\n// Handle errors\nbootstrap();\n```\n\n### Publishing Your Integration\n\n1. **Prepare package.json**\n\n```json\n{\n    \"name\": \"greenapi-integration-yourplatform\",\n    \"version\": \"1.0.0\",\n    \"main\": \"dist/index.js\",\n    \"types\": \"dist/index.d.ts\",\n    \"scripts\": {\n        \"build\": \"tsc\",\n        \"prepublishOnly\": \"npm run build\"\n    },\n    \"dependencies\": {\n        \"@green-api/greenapi-integration\": \"^0.4.0\",\n        \"express\": \"^4.18.2\"\n        // other dependencies\n    }\n}\n```\n\n2. **Build and Publish**\n\n```bash\nnpm run build\nnpm publish\n```\n\n## Working Example\n\nCheck out the `/examples/custom-adapter` directory for a complete working example showing:\n\n- Two-way message flow between WhatsApp and a custom platform\n- Webhook handling\n- Instance setup and configuration\n- Message transformation\n- Error handling\n\n### Running the Example\n\n1. Clone the repository\n2. Update .env with your GREEN-API credentials:\n\n```env\nVISITOR_ID_INSTANCE=your_visitor_instance_id\nVISITOR_API_TOKEN=your_visitor_instance_token\nAGENT_ID_INSTANCE=your_agent_instance_id\nAGENT_API_TOKEN=your_agent_instance_token\nAGENT_PHONE_NUMBER=your_agent_phone_number\nWEBHOOK_URL=your_webhook_url\nPORT=3000\n```\n\n3. Install dependencies and run:\n\n```bash\ncd examples/custom-adapter\nnpm install\nnpm start\n```\n\n## Complete Example Implementation\n\n### Project Structure\n\n```\nexamples/\n└── custom-adapter/\n    ├── src/\n    │   ├── main.ts\n    │   ├── simple-adapter.ts\n    │   ├── simple-transformer.ts\n    │   ├── simple-storage.ts\n    │   └── types.ts\n    ├── .env\n    └── package.json\n```\n\n### types.ts\n\n```typescript\ninterface SimplePlatformWebhook {\n    messageId: string;\n    from: string;\n    text: string;\n    timestamp: number;\n}\n\ninterface SimplePlatformMessage {\n    to: string;\n    content: string;\n    replyTo?: string;\n}\n```\n\n### simple-transformer.ts\n\n```typescript\nimport {\n    MessageTransformer,\n    Message,\n    GreenApiWebhook,\n    formatPhoneNumber,\n    IntegrationError,\n} from \"@green-api/greenapi-integration\";\nimport { SimplePlatformMessage, SimplePlatformWebhook } from \"./types\";\n\nexport class SimpleTransformer extends MessageTransformer\u003cSimplePlatformWebhook, SimplePlatformMessage\u003e {\n    toPlatformMessage(webhook: GreenApiWebhook): SimplePlatformMessage {\n        if (webhook.typeWebhook === \"incomingMessageReceived\") {\n            if (webhook.messageData.typeMessage !== \"extendedTextMessage\") {\n                throw new IntegrationError(\"Only text messages are supported\", \"BAD_REQUEST_ERROR\", 400);\n            }\n\n            return {\n                to: webhook.senderData.sender,\n                content: webhook.messageData.extendedTextMessageData?.text || \"\",\n            };\n        }\n        throw new IntegrationError(\"Only incomingMessageReceived type webhooks are supported\", \"INTEGRATION_ERROR\", 500);\n    }\n\n    toGreenApiMessage(message: SimplePlatformWebhook): Message {\n        return {\n            type: \"text\",\n            chatId: formatPhoneNumber(message.from),\n            message: message.text,\n        };\n    }\n}\n```\n\n### simple-storage.ts\n\n```typescript\nimport { StorageProvider, BaseUser, Instance } from '@green-api/greenapi-integration';\n\nexport class SimpleStorage extends StorageProvider {\n    private users: Map\u003cstring, BaseUser\u003e = new Map();\n    private instances: Map\u003cnumber, Instance\u003e = new Map();\n\n    async createInstance(instance: Instance, userId: bigint): Promise\u003cInstance\u003e {\n        this.instances.set(Number(instance.idInstance), {\n            ...instance,\n        });\n        return instance;\n    }\n\n    async getInstance(idInstance: number): Promise\u003cInstance | null\u003e {\n        return this.instances.get(idInstance) || null;\n    }\n\n    async removeInstance(instanceId: number): Promise\u003cInstance\u003e {\n        const instance = this.instances.get(instanceId);\n        if (!instance) throw new Error('Instance not found');\n        this.instances.delete(instanceId);\n        return instance;\n    }\n\n    async createUser(data: any): Promise\u003cBaseUser\u003e {\n        const user = {id: Date.now(), ...data};\n        this.users.set(data.email, user);\n        return user;\n    }\n\n    async findUser(identifier: string): Promise\u003cBaseUser | null\u003e {\n        return this.users.get(identifier) || null;\n    }\n\n    async updateUser(identifier: string, data: any): Promise\u003cBaseUser\u003e {\n        const user = await this.findUser(identifier);\n        if (!user) throw new Error('User not found');\n        const updated = {...user, ...data};\n        this.users.set(identifier, updated);\n        return updated;\n    }\n}\n```\n\n### simple-adapter.ts\n\n```typescript\nimport { BaseAdapter, Instance } from \"@green-api/greenapi-integration\";\nimport { SimplePlatformMessage, SimplePlatformWebhook } from \"./types\";\nimport axios from 'axios';\n\nexport class SimpleAdapter extends BaseAdapter\u003cSimplePlatformWebhook, SimplePlatformMessage\u003e {\n    async createPlatformClient(config: { apiKey: string, apiUrl: string }) {\n        return axios.create({\n            baseURL: config.apiUrl,\n            headers: {\n                'Authorization': `Bearer ${config.apiKey}`,\n                'Content-Type': 'application/json'\n            }\n        });\n    }\n\n    async sendToPlatform(message: SimplePlatformMessage, instance: Instance): Promise\u003cvoid\u003e {\n        // In a real implementation, we would send to the platform\n        // For demo, we'll just log and simulate a response\n        console.log('Platform received message:', message);\n\n        // Simulate platform processing and responding\n        setTimeout(() =\u003e {\n            console.log('Platform processing complete, sending response...');\n            this.simulatePlatformResponse(message, instance.idInstance);\n        }, 1000);\n    }\n\n    private async simulatePlatformResponse(originalMessage: SimplePlatformMessage, idInstance: number | bigint) {\n        const platformWebhook: SimplePlatformWebhook = {\n            messageId: `resp_${Date.now()}`,\n            from: originalMessage.to.replace('@c.us', ''),\n            text: `Thanks for your message: \"${originalMessage.content}\". This is an automated response.`,\n            timestamp: Date.now()\n        };\n\n        await this.handlePlatformWebhook(platformWebhook, idInstance);\n    }\n}\n```\n\n### main.ts\n\n```typescript\nimport express from \"express\";\nimport bodyParser from \"body-parser\";\nimport { formatPhoneNumber, GreenApiClient } from \"@green-api/greenapi-integration\";\nimport { SimpleTransformer } from \"./simple-transformer\";\nimport { SimpleStorage } from \"./simple-storage\";\nimport { SimpleAdapter } from \"./simple-adapter\";\nimport * as dotenv from \"dotenv\";\n\ndotenv.config();\n\nasync function main() {\n    // Initialize components\n    const transformer = new SimpleTransformer();\n    const storage = new SimpleStorage();\n    const adapter = new SimpleAdapter(transformer, storage);\n\n    // Configuration for both instances\n    const visitorInstance = {\n        idInstance: Number(process.env.VISITOR_ID_INSTANCE),\n        apiTokenInstance: process.env.VISITOR_API_TOKEN!,\n    };\n\n    const agentInstance = {\n        idInstance: Number(process.env.AGENT_ID_INSTANCE),\n        apiTokenInstance: process.env.AGENT_API_TOKEN!,\n    };\n    console.log(visitorInstance, agentInstance);\n\n    // Create visitor's GREEN-API client (for sending initial message)\n    const visitorClient = new GreenApiClient(visitorInstance);\n\n    // Set up agent instance\n    console.log(\"Setting up agent instance...\");\n    const user = await adapter.createUser(\"agent@example.com\", {\n        email: \"agent@example.com\",\n        name: \"Agent\",\n    });\n\n    const instance = await adapter.createInstance({\n        idInstance: agentInstance.idInstance, apiTokenInstance: agentInstance.apiTokenInstance, settings: {\n            webhookUrl: process.env.WEBHOOK_URL + \"/webhook/green-api\",\n            webhookUrlToken: \"your-secure-token\",\n            incomingWebhook: \"yes\",\n        },\n    }, user.email);\n\n    console.log(\"Waiting 2 minutes for settings to apply...\");\n    await new Promise(resolve =\u003e setTimeout(resolve, 120000));\n    console.log(\"Instance ready!\");\n\n    // Set up webhook server\n    const app = express();\n    app.use(bodyParser.json());\n\n    // Handle GREEN-API webhooks\n    app.post(\"/webhook/green-api\", async (req, res) =\u003e {\n        try {\n            console.log(\"Received webhook from GREEN-API:\", req.body);\n            await adapter.handleGreenApiWebhook(req.body, [\"incomingMessageReceived\"]);\n            res.status(200).json({status: \"ok\"});\n        } catch (error) {\n            console.error(\"Error handling webhook:\", error);\n            res.status(500).json({error: \"Internal server error\"});\n        }\n    });\n\n    // Start the server\n    const port = Number(process.env.PORT) || 3000;\n    app.listen(port, () =\u003e {\n        console.log(`Webhook server listening on port ${port}`);\n    });\n\n    // Send initial message from visitor\n    console.log(\"Sending initial message from visitor...\");\n    await visitorClient.sendMessage({\n        chatId: formatPhoneNumber(process.env.AGENT_PHONE_NUMBER!),\n        message: \"Hello! This is a test message from a visitor.\",\n    });\n\n    console.log(\"Initial message sent! Check the agent WhatsApp app to see the response.\");\n}\n\nmain().catch(console.error);\n```\n\n## Real-World Examples\n\nFor complete real-world integration examples, check out:\n\n- [Rocket.Chat Integration](https://github.com/green-api/greenapi-integration-rocketchat)\n\n## Utilities\n\nThe platform provides several utility functions:\n\n```typescript\n// Format phone numbers for GREEN-API\nformatPhoneNumber('+1234567890') // Returns '1234567890@c.us'\n\n// Generate secure random tokens\ngenerateRandomToken(32) // Returns a 32-character random token\n\n// Extract phone number from vcard\nconst vcard = 'BEGIN:VCARD\\nTEL:+1234567890\\nEND:VCARD'\nextractPhoneNumberFromVCard(vcard) // Returns '+1234567890'\n\n// Validate settings values \nisValidSettingValue('webhookUrl', 'https://example.com') // Returns true\n\n// Clean settings\nconst input = {\n    webhookUrl: 'https://example.com',\n    outgoingWebhook: 'yes',\n    invalidKey: 'value',\n    delaySendMessagesMilliseconds: 'invalid'\n}\nvalidateAndCleanSettings(input) // Returns { webhookUrl: 'https://example.com', outgoingWebhook: 'yes' }\n```\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgreen-api%2Fgreenapi-integration","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgreen-api%2Fgreenapi-integration","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgreen-api%2Fgreenapi-integration/lists"}