feat(docker): 🚀 Update server port to 8025
- Change default server port from 8080 to 8025 across all configurations. - Update Dockerfile, docker-compose.yml, and related documentation. - Ensure all CLI commands and API endpoints reflect the new port. - Adjust example configurations and health check URLs accordingly.
This commit is contained in:
@@ -18,6 +18,7 @@ Get a list of all configured WhatsApp accounts.
|
|||||||
**Endpoint:** `GET /api/accounts`
|
**Endpoint:** `GET /api/accounts`
|
||||||
|
|
||||||
**Response:**
|
**Response:**
|
||||||
|
|
||||||
```json
|
```json
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
@@ -45,6 +46,7 @@ Add a new WhatsApp account to the system.
|
|||||||
**Endpoint:** `POST /api/accounts/add`
|
**Endpoint:** `POST /api/accounts/add`
|
||||||
|
|
||||||
**Request Body (WhatsApp Web/WhatsMe ow):**
|
**Request Body (WhatsApp Web/WhatsMe ow):**
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"id": "my-account",
|
"id": "my-account",
|
||||||
@@ -57,6 +59,7 @@ Add a new WhatsApp account to the system.
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Request Body (Business API):**
|
**Request Body (Business API):**
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"id": "business-account",
|
"id": "business-account",
|
||||||
@@ -74,6 +77,7 @@ Add a new WhatsApp account to the system.
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Response:**
|
**Response:**
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"status": "ok",
|
"status": "ok",
|
||||||
@@ -82,6 +86,7 @@ Add a new WhatsApp account to the system.
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Status Codes:**
|
**Status Codes:**
|
||||||
|
|
||||||
- `201 Created` - Account added successfully
|
- `201 Created` - Account added successfully
|
||||||
- `400 Bad Request` - Invalid request body
|
- `400 Bad Request` - Invalid request body
|
||||||
- `500 Internal Server Error` - Failed to connect or save config
|
- `500 Internal Server Error` - Failed to connect or save config
|
||||||
@@ -95,6 +100,7 @@ Update an existing WhatsApp account configuration.
|
|||||||
**Endpoint:** `POST /api/accounts/update` or `PUT /api/accounts/update`
|
**Endpoint:** `POST /api/accounts/update` or `PUT /api/accounts/update`
|
||||||
|
|
||||||
**Request Body:**
|
**Request Body:**
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"id": "business-account",
|
"id": "business-account",
|
||||||
@@ -112,6 +118,7 @@ Update an existing WhatsApp account configuration.
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Response:**
|
**Response:**
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"status": "ok",
|
"status": "ok",
|
||||||
@@ -120,12 +127,14 @@ Update an existing WhatsApp account configuration.
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Notes:**
|
**Notes:**
|
||||||
|
|
||||||
- The `id` field is required to identify which account to update
|
- The `id` field is required to identify which account to update
|
||||||
- The `type` field cannot be changed (preserved from original)
|
- The `type` field cannot be changed (preserved from original)
|
||||||
- If the account is enabled, it will be disconnected and reconnected with new settings
|
- If the account is enabled, it will be disconnected and reconnected with new settings
|
||||||
- Configuration is saved to disk after successful update
|
- Configuration is saved to disk after successful update
|
||||||
|
|
||||||
**Status Codes:**
|
**Status Codes:**
|
||||||
|
|
||||||
- `200 OK` - Account updated successfully
|
- `200 OK` - Account updated successfully
|
||||||
- `400 Bad Request` - Invalid request or missing ID
|
- `400 Bad Request` - Invalid request or missing ID
|
||||||
- `404 Not Found` - Account not found
|
- `404 Not Found` - Account not found
|
||||||
@@ -140,6 +149,7 @@ Disable a WhatsApp account (disconnect and prevent auto-connect on restart).
|
|||||||
**Endpoint:** `POST /api/accounts/disable`
|
**Endpoint:** `POST /api/accounts/disable`
|
||||||
|
|
||||||
**Request Body:**
|
**Request Body:**
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"id": "my-account"
|
"id": "my-account"
|
||||||
@@ -147,6 +157,7 @@ Disable a WhatsApp account (disconnect and prevent auto-connect on restart).
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Response:**
|
**Response:**
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"status": "ok",
|
"status": "ok",
|
||||||
@@ -155,12 +166,14 @@ Disable a WhatsApp account (disconnect and prevent auto-connect on restart).
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Behavior:**
|
**Behavior:**
|
||||||
|
|
||||||
- Disconnects the account immediately
|
- Disconnects the account immediately
|
||||||
- Sets `disabled: true` in config
|
- Sets `disabled: true` in config
|
||||||
- Account will not auto-connect on server restart
|
- Account will not auto-connect on server restart
|
||||||
- Account remains in config (can be re-enabled)
|
- Account remains in config (can be re-enabled)
|
||||||
|
|
||||||
**Status Codes:**
|
**Status Codes:**
|
||||||
|
|
||||||
- `200 OK` - Account disabled successfully
|
- `200 OK` - Account disabled successfully
|
||||||
- `400 Bad Request` - Invalid request body
|
- `400 Bad Request` - Invalid request body
|
||||||
- `404 Not Found` - Account not found
|
- `404 Not Found` - Account not found
|
||||||
@@ -175,6 +188,7 @@ Enable a previously disabled WhatsApp account.
|
|||||||
**Endpoint:** `POST /api/accounts/enable`
|
**Endpoint:** `POST /api/accounts/enable`
|
||||||
|
|
||||||
**Request Body:**
|
**Request Body:**
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"id": "my-account"
|
"id": "my-account"
|
||||||
@@ -182,6 +196,7 @@ Enable a previously disabled WhatsApp account.
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Response:**
|
**Response:**
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"status": "ok",
|
"status": "ok",
|
||||||
@@ -190,12 +205,14 @@ Enable a previously disabled WhatsApp account.
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Behavior:**
|
**Behavior:**
|
||||||
|
|
||||||
- Sets `disabled: false` in config
|
- Sets `disabled: false` in config
|
||||||
- Connects the account immediately
|
- Connects the account immediately
|
||||||
- Account will auto-connect on server restart
|
- Account will auto-connect on server restart
|
||||||
- If connection fails, account remains disabled
|
- If connection fails, account remains disabled
|
||||||
|
|
||||||
**Status Codes:**
|
**Status Codes:**
|
||||||
|
|
||||||
- `200 OK` - Account enabled and connected successfully
|
- `200 OK` - Account enabled and connected successfully
|
||||||
- `400 Bad Request` - Invalid request body
|
- `400 Bad Request` - Invalid request body
|
||||||
- `404 Not Found` - Account not found
|
- `404 Not Found` - Account not found
|
||||||
@@ -210,6 +227,7 @@ Permanently remove a WhatsApp account from the system.
|
|||||||
**Endpoint:** `POST /api/accounts/remove` or `DELETE /api/accounts/remove`
|
**Endpoint:** `POST /api/accounts/remove` or `DELETE /api/accounts/remove`
|
||||||
|
|
||||||
**Request Body:**
|
**Request Body:**
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"id": "my-account"
|
"id": "my-account"
|
||||||
@@ -217,6 +235,7 @@ Permanently remove a WhatsApp account from the system.
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Response:**
|
**Response:**
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"status": "ok"
|
"status": "ok"
|
||||||
@@ -224,11 +243,13 @@ Permanently remove a WhatsApp account from the system.
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Behavior:**
|
**Behavior:**
|
||||||
|
|
||||||
- Disconnects the account
|
- Disconnects the account
|
||||||
- Removes from config permanently
|
- Removes from config permanently
|
||||||
- Session data is NOT deleted (manual cleanup required)
|
- Session data is NOT deleted (manual cleanup required)
|
||||||
|
|
||||||
**Status Codes:**
|
**Status Codes:**
|
||||||
|
|
||||||
- `200 OK` - Account removed successfully
|
- `200 OK` - Account removed successfully
|
||||||
- `400 Bad Request` - Invalid request body
|
- `400 Bad Request` - Invalid request body
|
||||||
- `404 Not Found` - Account not found
|
- `404 Not Found` - Account not found
|
||||||
@@ -271,7 +292,7 @@ Account settings are stored in `config.json`:
|
|||||||
### Configuration Fields
|
### Configuration Fields
|
||||||
|
|
||||||
| Field | Type | Required | Description |
|
| Field | Type | Required | Description |
|
||||||
|-------|------|----------|-------------|
|
| -------------- | ------- | ----------- | --------------------------------------------------- |
|
||||||
| `id` | string | Yes | Unique identifier for the account |
|
| `id` | string | Yes | Unique identifier for the account |
|
||||||
| `type` | string | Yes | Account type: `whatsmeow` or `business-api` |
|
| `type` | string | Yes | Account type: `whatsmeow` or `business-api` |
|
||||||
| `phone_number` | string | Yes | Phone number with country code |
|
| `phone_number` | string | Yes | Phone number with country code |
|
||||||
@@ -283,7 +304,7 @@ Account settings are stored in `config.json`:
|
|||||||
### Business API Configuration
|
### Business API Configuration
|
||||||
|
|
||||||
| Field | Type | Required | Description |
|
| Field | Type | Required | Description |
|
||||||
|-------|------|----------|-------------|
|
| --------------------- | ------ | -------- | --------------------------------- |
|
||||||
| `phone_number_id` | string | Yes | WhatsApp Business phone number ID |
|
| `phone_number_id` | string | Yes | WhatsApp Business phone number ID |
|
||||||
| `access_token` | string | Yes | Meta Graph API access token |
|
| `access_token` | string | Yes | Meta Graph API access token |
|
||||||
| `business_account_id` | string | No | Business account ID |
|
| `business_account_id` | string | No | Business account ID |
|
||||||
@@ -297,11 +318,13 @@ Account settings are stored in `config.json`:
|
|||||||
### cURL Examples
|
### cURL Examples
|
||||||
|
|
||||||
**List accounts:**
|
**List accounts:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -u username:password http://localhost:8080/api/accounts
|
curl -u username:password http://localhost:8025/api/accounts
|
||||||
```
|
```
|
||||||
|
|
||||||
**Add account:**
|
**Add account:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -u username:password \
|
curl -u username:password \
|
||||||
-X POST \
|
-X POST \
|
||||||
@@ -313,10 +336,11 @@ curl -u username:password \
|
|||||||
"session_path": "./sessions/new-account",
|
"session_path": "./sessions/new-account",
|
||||||
"show_qr": true
|
"show_qr": true
|
||||||
}' \
|
}' \
|
||||||
http://localhost:8080/api/accounts/add
|
http://localhost:8025/api/accounts/add
|
||||||
```
|
```
|
||||||
|
|
||||||
**Update account:**
|
**Update account:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -u username:password \
|
curl -u username:password \
|
||||||
-X POST \
|
-X POST \
|
||||||
@@ -331,34 +355,37 @@ curl -u username:password \
|
|||||||
"api_version": "v21.0"
|
"api_version": "v21.0"
|
||||||
}
|
}
|
||||||
}' \
|
}' \
|
||||||
http://localhost:8080/api/accounts/update
|
http://localhost:8025/api/accounts/update
|
||||||
```
|
```
|
||||||
|
|
||||||
**Disable account:**
|
**Disable account:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -u username:password \
|
curl -u username:password \
|
||||||
-X POST \
|
-X POST \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d '{"id": "my-account"}' \
|
-d '{"id": "my-account"}' \
|
||||||
http://localhost:8080/api/accounts/disable
|
http://localhost:8025/api/accounts/disable
|
||||||
```
|
```
|
||||||
|
|
||||||
**Enable account:**
|
**Enable account:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -u username:password \
|
curl -u username:password \
|
||||||
-X POST \
|
-X POST \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d '{"id": "my-account"}' \
|
-d '{"id": "my-account"}' \
|
||||||
http://localhost:8080/api/accounts/enable
|
http://localhost:8025/api/accounts/enable
|
||||||
```
|
```
|
||||||
|
|
||||||
**Remove account:**
|
**Remove account:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -u username:password \
|
curl -u username:password \
|
||||||
-X POST \
|
-X POST \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d '{"id": "my-account"}' \
|
-d '{"id": "my-account"}' \
|
||||||
http://localhost:8080/api/accounts/remove
|
http://localhost:8025/api/accounts/remove
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -419,11 +446,13 @@ All endpoints return proper HTTP status codes and JSON error messages:
|
|||||||
```
|
```
|
||||||
|
|
||||||
Or plain text for simple errors:
|
Or plain text for simple errors:
|
||||||
|
|
||||||
```
|
```
|
||||||
Account ID required in path
|
Account ID required in path
|
||||||
```
|
```
|
||||||
|
|
||||||
Common error scenarios:
|
Common error scenarios:
|
||||||
|
|
||||||
- Account already exists (when adding)
|
- Account already exists (when adding)
|
||||||
- Account not found (when updating/removing)
|
- Account not found (when updating/removing)
|
||||||
- Connection failed (when enabling)
|
- Connection failed (when enabling)
|
||||||
|
|||||||
32
CLI.md
32
CLI.md
@@ -52,7 +52,7 @@ Create a configuration file at `~/.whatshooked/cli.json`:
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"server_url": "http://localhost:8080",
|
"server_url": "http://localhost:8025",
|
||||||
"auth_key": "your-api-key-here",
|
"auth_key": "your-api-key-here",
|
||||||
"username": "",
|
"username": "",
|
||||||
"password": ""
|
"password": ""
|
||||||
@@ -63,7 +63,7 @@ Or use API key authentication:
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"server_url": "http://localhost:8080",
|
"server_url": "http://localhost:8025",
|
||||||
"auth_key": "your-secure-api-key"
|
"auth_key": "your-secure-api-key"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -72,7 +72,7 @@ Or use username/password authentication:
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"server_url": "http://localhost:8080",
|
"server_url": "http://localhost:8025",
|
||||||
"username": "admin",
|
"username": "admin",
|
||||||
"password": "your-secure-password"
|
"password": "your-secure-password"
|
||||||
}
|
}
|
||||||
@@ -90,14 +90,14 @@ cp .whatshooked-cli.example.json .whatshooked-cli.json
|
|||||||
Set environment variables (useful for CI/CD):
|
Set environment variables (useful for CI/CD):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
export WHATSHOOKED_SERVER_URL="http://localhost:8080"
|
export WHATSHOOKED_SERVER_URL="http://localhost:8025"
|
||||||
export WHATSHOOKED_AUTH_KEY="your-api-key-here"
|
export WHATSHOOKED_AUTH_KEY="your-api-key-here"
|
||||||
```
|
```
|
||||||
|
|
||||||
Or with username/password:
|
Or with username/password:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
export WHATSHOOKED_SERVER_URL="http://localhost:8080"
|
export WHATSHOOKED_SERVER_URL="http://localhost:8025"
|
||||||
export WHATSHOOKED_USERNAME="admin"
|
export WHATSHOOKED_USERNAME="admin"
|
||||||
export WHATSHOOKED_PASSWORD="your-password"
|
export WHATSHOOKED_PASSWORD="your-password"
|
||||||
```
|
```
|
||||||
@@ -107,7 +107,7 @@ export WHATSHOOKED_PASSWORD="your-password"
|
|||||||
Pass credentials via command-line flags:
|
Pass credentials via command-line flags:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./bin/whatshook-cli --server http://localhost:8080 health
|
./bin/whatshook-cli --server http://localhost:8025 health
|
||||||
```
|
```
|
||||||
|
|
||||||
Note: Currently, authentication credentials can only be set via config file or environment variables. Command-line flags for auth credentials may be added in future versions.
|
Note: Currently, authentication credentials can only be set via config file or environment variables. Command-line flags for auth credentials may be added in future versions.
|
||||||
@@ -118,7 +118,7 @@ If your server doesn't require authentication, simply omit the authentication fi
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"server_url": "http://localhost:8080"
|
"server_url": "http://localhost:8025"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -135,8 +135,8 @@ The CLI looks for configuration files in the following locations (in order):
|
|||||||
### Configuration Options
|
### Configuration Options
|
||||||
|
|
||||||
| Option | Type | Default | Description |
|
| Option | Type | Default | Description |
|
||||||
|--------|------|---------|-------------|
|
| ------------ | ------ | ----------------------- | -------------------------- |
|
||||||
| `server_url` | string | `http://localhost:8080` | WhatsHooked server URL |
|
| `server_url` | string | `http://localhost:8025` | WhatsHooked server URL |
|
||||||
| `auth_key` | string | `""` | API key for authentication |
|
| `auth_key` | string | `""` | API key for authentication |
|
||||||
| `username` | string | `""` | Username for Basic Auth |
|
| `username` | string | `""` | Username for Basic Auth |
|
||||||
| `password` | string | `""` | Password for Basic Auth |
|
| `password` | string | `""` | Password for Basic Auth |
|
||||||
@@ -178,6 +178,7 @@ Add a new webhook interactively:
|
|||||||
```
|
```
|
||||||
|
|
||||||
You'll be prompted for:
|
You'll be prompted for:
|
||||||
|
|
||||||
- Hook ID
|
- Hook ID
|
||||||
- Hook Name
|
- Hook Name
|
||||||
- Webhook URL
|
- Webhook URL
|
||||||
@@ -188,6 +189,7 @@ You'll be prompted for:
|
|||||||
**Available Event Types:**
|
**Available Event Types:**
|
||||||
|
|
||||||
WhatsApp Connection Events:
|
WhatsApp Connection Events:
|
||||||
|
|
||||||
- `whatsapp.connected` - WhatsApp client connected
|
- `whatsapp.connected` - WhatsApp client connected
|
||||||
- `whatsapp.disconnected` - WhatsApp client disconnected
|
- `whatsapp.disconnected` - WhatsApp client disconnected
|
||||||
- `whatsapp.qr.code` - QR code generated for pairing
|
- `whatsapp.qr.code` - QR code generated for pairing
|
||||||
@@ -198,6 +200,7 @@ WhatsApp Connection Events:
|
|||||||
- `whatsapp.pair.event` - Generic pairing event
|
- `whatsapp.pair.event` - Generic pairing event
|
||||||
|
|
||||||
Message Events:
|
Message Events:
|
||||||
|
|
||||||
- `message.received` - Message received from WhatsApp
|
- `message.received` - Message received from WhatsApp
|
||||||
- `message.sent` - Message sent successfully
|
- `message.sent` - Message sent successfully
|
||||||
- `message.failed` - Message sending failed
|
- `message.failed` - Message sending failed
|
||||||
@@ -205,6 +208,7 @@ Message Events:
|
|||||||
- `message.read` - Message read by recipient
|
- `message.read` - Message read by recipient
|
||||||
|
|
||||||
Hook Events:
|
Hook Events:
|
||||||
|
|
||||||
- `hook.triggered` - Hook was triggered
|
- `hook.triggered` - Hook was triggered
|
||||||
- `hook.success` - Hook executed successfully
|
- `hook.success` - Hook executed successfully
|
||||||
- `hook.failed` - Hook execution failed
|
- `hook.failed` - Hook execution failed
|
||||||
@@ -239,6 +243,7 @@ Add a new WhatsApp account interactively:
|
|||||||
```
|
```
|
||||||
|
|
||||||
You'll be prompted for:
|
You'll be prompted for:
|
||||||
|
|
||||||
- Account ID
|
- Account ID
|
||||||
- Phone Number (with country code, e.g., +1234567890)
|
- Phone Number (with country code, e.g., +1234567890)
|
||||||
- Session Path (where to store session data)
|
- Session Path (where to store session data)
|
||||||
@@ -256,6 +261,7 @@ Send a text message interactively:
|
|||||||
```
|
```
|
||||||
|
|
||||||
You'll be prompted for:
|
You'll be prompted for:
|
||||||
|
|
||||||
- Account ID
|
- Account ID
|
||||||
- Recipient (phone number or JID)
|
- Recipient (phone number or JID)
|
||||||
- Message text
|
- Message text
|
||||||
@@ -299,7 +305,7 @@ Supported formats: PDF, DOC, DOCX, XLS, XLSX, TXT, ZIP, and more
|
|||||||
mkdir -p ~/.whatshooked
|
mkdir -p ~/.whatshooked
|
||||||
cat > ~/.whatshooked/cli.json <<EOF
|
cat > ~/.whatshooked/cli.json <<EOF
|
||||||
{
|
{
|
||||||
"server_url": "http://localhost:8080",
|
"server_url": "http://localhost:8025",
|
||||||
"auth_key": "my-secure-api-key"
|
"auth_key": "my-secure-api-key"
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
@@ -315,7 +321,7 @@ EOF
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Set environment variables
|
# Set environment variables
|
||||||
export WHATSHOOKED_SERVER_URL="https://my-server.com:8080"
|
export WHATSHOOKED_SERVER_URL="https://my-server.com:8025"
|
||||||
export WHATSHOOKED_AUTH_KEY="production-api-key"
|
export WHATSHOOKED_AUTH_KEY="production-api-key"
|
||||||
|
|
||||||
# Use CLI without config file
|
# Use CLI without config file
|
||||||
@@ -375,7 +381,7 @@ export WHATSHOOKED_AUTH_KEY="production-api-key"
|
|||||||
{
|
{
|
||||||
"server": {
|
"server": {
|
||||||
"host": "0.0.0.0",
|
"host": "0.0.0.0",
|
||||||
"port": 8080,
|
"port": 8025,
|
||||||
"auth_key": "super-secret-production-key"
|
"auth_key": "super-secret-production-key"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -452,7 +458,7 @@ cp .whatshooked-cli.example.json ~/.whatshooked/cli.json
|
|||||||
Verify the server is running:
|
Verify the server is running:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl http://localhost:8080/health
|
curl http://localhost:8025/health
|
||||||
```
|
```
|
||||||
|
|
||||||
### Authentication Required
|
### Authentication Required
|
||||||
|
|||||||
83
DOCKER.md
83
DOCKER.md
@@ -10,6 +10,7 @@ This guide explains how to run WhatsHooked using Docker and Docker Compose.
|
|||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
1. **Copy the example configuration file:**
|
1. **Copy the example configuration file:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cp config.example.json config.json
|
cp config.example.json config.json
|
||||||
```
|
```
|
||||||
@@ -21,54 +22,64 @@ This guide explains how to run WhatsHooked using Docker and Docker Compose.
|
|||||||
- Server settings (port, authentication)
|
- Server settings (port, authentication)
|
||||||
|
|
||||||
3. **Create required directories:**
|
3. **Create required directories:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mkdir -p sessions data/media
|
mkdir -p sessions data/media
|
||||||
```
|
```
|
||||||
|
|
||||||
4. **Build and start the server:**
|
4. **Build and start the server:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker-compose up -d
|
docker-compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
5. **View logs to scan QR code (first run):**
|
5. **View logs to scan QR code (first run):**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker-compose logs -f whatshooked
|
docker-compose logs -f whatshooked
|
||||||
```
|
```
|
||||||
|
|
||||||
Scan the QR code with WhatsApp on your phone to authenticate.
|
Scan the QR code with WhatsApp on your phone to authenticate.
|
||||||
|
|
||||||
6. **Check server health:**
|
6. **Check server health:**
|
||||||
```bash
|
```bash
|
||||||
curl http://localhost:8080/health
|
curl http://localhost:8025/health
|
||||||
```
|
```
|
||||||
|
|
||||||
## Docker Commands
|
## Docker Commands
|
||||||
|
|
||||||
### Build the image
|
### Build the image
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker-compose build
|
docker-compose build
|
||||||
```
|
```
|
||||||
|
|
||||||
### Start the service
|
### Start the service
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker-compose up -d
|
docker-compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
### Stop the service
|
### Stop the service
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker-compose down
|
docker-compose down
|
||||||
```
|
```
|
||||||
|
|
||||||
### View logs
|
### View logs
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker-compose logs -f
|
docker-compose logs -f
|
||||||
```
|
```
|
||||||
|
|
||||||
### Restart the service
|
### Restart the service
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker-compose restart
|
docker-compose restart
|
||||||
```
|
```
|
||||||
|
|
||||||
### Access the container shell
|
### Access the container shell
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker-compose exec whatshooked sh
|
docker-compose exec whatshooked sh
|
||||||
```
|
```
|
||||||
@@ -87,9 +98,10 @@ These volumes ensure your data persists across container restarts.
|
|||||||
|
|
||||||
### Port Mapping
|
### Port Mapping
|
||||||
|
|
||||||
By default, the server runs on port 8080. To change the port:
|
By default, the server runs on port 8025. To change the port:
|
||||||
|
|
||||||
**Option 1: Update config.json**
|
**Option 1: Update config.json**
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"server": {
|
"server": {
|
||||||
@@ -97,16 +109,19 @@ By default, the server runs on port 8080. To change the port:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Then update docker-compose.yml:
|
Then update docker-compose.yml:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
ports:
|
ports:
|
||||||
- "9090:9090"
|
- "9090:9090"
|
||||||
```
|
```
|
||||||
|
|
||||||
**Option 2: Map to different host port**
|
**Option 2: Map to different host port**
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
ports:
|
ports:
|
||||||
- "3000:8080" # Access via localhost:3000, server still runs on 8080 internally
|
- "3000:8025" # Access via localhost:3000, server still runs on 8025 internally
|
||||||
```
|
```
|
||||||
|
|
||||||
### Authentication
|
### Authentication
|
||||||
@@ -114,6 +129,7 @@ ports:
|
|||||||
Set authentication in config.json:
|
Set authentication in config.json:
|
||||||
|
|
||||||
**Option 1: API Key**
|
**Option 1: API Key**
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"server": {
|
"server": {
|
||||||
@@ -123,6 +139,7 @@ Set authentication in config.json:
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Option 2: Username/Password**
|
**Option 2: Username/Password**
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"server": {
|
"server": {
|
||||||
@@ -140,10 +157,10 @@ Uncomment the deploy section in docker-compose.yml to set resource limits:
|
|||||||
deploy:
|
deploy:
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
cpus: '1.0'
|
cpus: "1.0"
|
||||||
memory: 512M
|
memory: 512M
|
||||||
reservations:
|
reservations:
|
||||||
cpus: '0.25'
|
cpus: "0.25"
|
||||||
memory: 128M
|
memory: 128M
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -152,6 +169,7 @@ deploy:
|
|||||||
When you first start the server, you'll need to scan a QR code to authenticate with WhatsApp.
|
When you first start the server, you'll need to scan a QR code to authenticate with WhatsApp.
|
||||||
|
|
||||||
### View QR Code in Logs
|
### View QR Code in Logs
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker-compose logs -f whatshooked
|
docker-compose logs -f whatshooked
|
||||||
```
|
```
|
||||||
@@ -159,19 +177,22 @@ docker-compose logs -f whatshooked
|
|||||||
The QR code will be displayed in ASCII art in the terminal along with a browser link. You have two options:
|
The QR code will be displayed in ASCII art in the terminal along with a browser link. You have two options:
|
||||||
|
|
||||||
**Option 1: Scan from Terminal**
|
**Option 1: Scan from Terminal**
|
||||||
|
|
||||||
1. Open WhatsApp
|
1. Open WhatsApp
|
||||||
2. Go to Settings > Linked Devices
|
2. Go to Settings > Linked Devices
|
||||||
3. Tap "Link a Device"
|
3. Tap "Link a Device"
|
||||||
4. Scan the QR code from the terminal
|
4. Scan the QR code from the terminal
|
||||||
|
|
||||||
**Option 2: View in Browser**
|
**Option 2: View in Browser**
|
||||||
1. Look for the line: `Or open in browser: http://localhost:8080/api/qr/{account_id}`
|
|
||||||
|
1. Look for the line: `Or open in browser: http://localhost:8025/api/qr/{account_id}`
|
||||||
2. Open that URL in your web browser to see a larger PNG image
|
2. Open that URL in your web browser to see a larger PNG image
|
||||||
3. Scan the QR code from your browser
|
3. Scan the QR code from your browser
|
||||||
|
|
||||||
### Alternative: Use CLI Tool
|
### Alternative: Use CLI Tool
|
||||||
|
|
||||||
You can also use the CLI tool outside Docker to link accounts, then mount the session:
|
You can also use the CLI tool outside Docker to link accounts, then mount the session:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./bin/whatshook-cli accounts add
|
./bin/whatshook-cli accounts add
|
||||||
```
|
```
|
||||||
@@ -183,33 +204,39 @@ The Docker image includes both the server and CLI binaries in the `/app/bin` dir
|
|||||||
### Available CLI Commands
|
### Available CLI Commands
|
||||||
|
|
||||||
List all hooks:
|
List all hooks:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker exec whatshooked-server /app/bin/whatshook-cli --server http://localhost:8080 hooks list
|
docker exec whatshooked-server /app/bin/whatshook-cli --server http://localhost:8025 hooks list
|
||||||
```
|
```
|
||||||
|
|
||||||
Add a new hook:
|
Add a new hook:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker exec -it whatshooked-server /app/bin/whatshook-cli --server http://localhost:8080 hooks add
|
docker exec -it whatshooked-server /app/bin/whatshook-cli --server http://localhost:8025 hooks add
|
||||||
```
|
```
|
||||||
|
|
||||||
Remove a hook:
|
Remove a hook:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker exec whatshooked-server /app/bin/whatshook-cli --server http://localhost:8080 hooks remove <hook_id>
|
docker exec whatshooked-server /app/bin/whatshook-cli --server http://localhost:8025 hooks remove <hook_id>
|
||||||
```
|
```
|
||||||
|
|
||||||
List WhatsApp accounts:
|
List WhatsApp accounts:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker exec whatshooked-server /app/bin/whatshook-cli --server http://localhost:8080 accounts list
|
docker exec whatshooked-server /app/bin/whatshook-cli --server http://localhost:8025 accounts list
|
||||||
```
|
```
|
||||||
|
|
||||||
Send a message:
|
Send a message:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker exec -it whatshooked-server /app/bin/whatshook-cli --server http://localhost:8080 send
|
docker exec -it whatshooked-server /app/bin/whatshook-cli --server http://localhost:8025 send
|
||||||
```
|
```
|
||||||
|
|
||||||
Check server health:
|
Check server health:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker exec whatshooked-server /app/bin/whatshook-cli --server http://localhost:8080 health
|
docker exec whatshooked-server /app/bin/whatshook-cli --server http://localhost:8025 health
|
||||||
```
|
```
|
||||||
|
|
||||||
### Authentication with CLI
|
### Authentication with CLI
|
||||||
@@ -217,9 +244,10 @@ docker exec whatshooked-server /app/bin/whatshook-cli --server http://localhost:
|
|||||||
If your server has authentication enabled, you need to configure it in the CLI:
|
If your server has authentication enabled, you need to configure it in the CLI:
|
||||||
|
|
||||||
**Option 1: Using command-line flags**
|
**Option 1: Using command-line flags**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker exec whatshooked-server /app/bin/whatshook-cli \
|
docker exec whatshooked-server /app/bin/whatshook-cli \
|
||||||
--server http://localhost:8080 \
|
--server http://localhost:8025 \
|
||||||
--api-key your-api-key \
|
--api-key your-api-key \
|
||||||
hooks list
|
hooks list
|
||||||
```
|
```
|
||||||
@@ -227,15 +255,17 @@ docker exec whatshooked-server /app/bin/whatshook-cli \
|
|||||||
**Option 2: Create a CLI config file**
|
**Option 2: Create a CLI config file**
|
||||||
|
|
||||||
1. Access the container:
|
1. Access the container:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker exec -it whatshooked-server sh
|
docker exec -it whatshooked-server sh
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Create the CLI config:
|
2. Create the CLI config:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cat > /app/.whatshooked-cli.json <<EOF
|
cat > /app/.whatshooked-cli.json <<EOF
|
||||||
{
|
{
|
||||||
"server_url": "http://localhost:8080",
|
"server_url": "http://localhost:8025",
|
||||||
"api_key": "your-api-key"
|
"api_key": "your-api-key"
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
@@ -251,10 +281,11 @@ docker exec whatshooked-server /app/bin/whatshook-cli \
|
|||||||
Create an alias on your host machine for easier CLI access:
|
Create an alias on your host machine for easier CLI access:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
alias whatshook-cli='docker exec -it whatshooked-server /app/bin/whatshook-cli --server http://localhost:8080'
|
alias whatshook-cli='docker exec -it whatshooked-server /app/bin/whatshook-cli --server http://localhost:8025'
|
||||||
```
|
```
|
||||||
|
|
||||||
Then use it like:
|
Then use it like:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
whatshook-cli hooks list
|
whatshook-cli hooks list
|
||||||
whatshook-cli send
|
whatshook-cli send
|
||||||
@@ -265,25 +296,33 @@ Add this to your `~/.bashrc` or `~/.zshrc` to make it permanent.
|
|||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
### Container won't start
|
### Container won't start
|
||||||
|
|
||||||
Check logs for errors:
|
Check logs for errors:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker-compose logs
|
docker-compose logs
|
||||||
```
|
```
|
||||||
|
|
||||||
### Config file not found
|
### Config file not found
|
||||||
|
|
||||||
Ensure config.json exists in the project root:
|
Ensure config.json exists in the project root:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
ls -la config.json
|
ls -la config.json
|
||||||
```
|
```
|
||||||
|
|
||||||
### Permission issues with volumes
|
### Permission issues with volumes
|
||||||
|
|
||||||
Fix ownership of mounted directories:
|
Fix ownership of mounted directories:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo chown -R $(id -u):$(id -g) sessions data
|
sudo chown -R $(id -u):$(id -g) sessions data
|
||||||
```
|
```
|
||||||
|
|
||||||
### QR code not displaying
|
### QR code not displaying
|
||||||
|
|
||||||
Ensure `show_qr: true` is set in config.json:
|
Ensure `show_qr: true` is set in config.json:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"whatsapp": [
|
"whatsapp": [
|
||||||
@@ -295,12 +334,15 @@ Ensure `show_qr: true` is set in config.json:
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Cannot connect to server
|
### Cannot connect to server
|
||||||
|
|
||||||
Check if the container is running:
|
Check if the container is running:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker-compose ps
|
docker-compose ps
|
||||||
```
|
```
|
||||||
|
|
||||||
Check health status:
|
Check health status:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker inspect whatshooked-server | grep -A 10 Health
|
docker inspect whatshooked-server | grep -A 10 Health
|
||||||
```
|
```
|
||||||
@@ -332,11 +374,13 @@ docker inspect whatshooked-server | grep -A 10 Health
|
|||||||
### Example with Reverse Proxy (nginx)
|
### Example with Reverse Proxy (nginx)
|
||||||
|
|
||||||
Create a network:
|
Create a network:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker network create whatshooked-net
|
docker network create whatshooked-net
|
||||||
```
|
```
|
||||||
|
|
||||||
Update docker-compose.yml:
|
Update docker-compose.yml:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
services:
|
services:
|
||||||
whatshooked:
|
whatshooked:
|
||||||
@@ -344,7 +388,7 @@ services:
|
|||||||
- whatshooked-net
|
- whatshooked-net
|
||||||
# Don't expose ports to host, only to network
|
# Don't expose ports to host, only to network
|
||||||
# ports:
|
# ports:
|
||||||
# - "8080:8080"
|
# - "8025:8025"
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
whatshooked-net:
|
whatshooked-net:
|
||||||
@@ -352,6 +396,7 @@ networks:
|
|||||||
```
|
```
|
||||||
|
|
||||||
Configure nginx to proxy to the container:
|
Configure nginx to proxy to the container:
|
||||||
|
|
||||||
```nginx
|
```nginx
|
||||||
server {
|
server {
|
||||||
listen 443 ssl;
|
listen 443 ssl;
|
||||||
@@ -361,7 +406,7 @@ server {
|
|||||||
ssl_certificate_key /path/to/key.pem;
|
ssl_certificate_key /path/to/key.pem;
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
proxy_pass http://whatshooked:8080;
|
proxy_pass http://whatshooked:8025;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
}
|
}
|
||||||
@@ -373,6 +418,7 @@ server {
|
|||||||
### Health Checks
|
### Health Checks
|
||||||
|
|
||||||
The compose file includes a health check that runs every 30 seconds:
|
The compose file includes a health check that runs every 30 seconds:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker inspect --format='{{.State.Health.Status}}' whatshooked-server
|
docker inspect --format='{{.State.Health.Status}}' whatshooked-server
|
||||||
```
|
```
|
||||||
@@ -380,6 +426,7 @@ docker inspect --format='{{.State.Health.Status}}' whatshooked-server
|
|||||||
### Log Management
|
### Log Management
|
||||||
|
|
||||||
Limit log size to prevent disk space issues:
|
Limit log size to prevent disk space issues:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
services:
|
services:
|
||||||
whatshooked:
|
whatshooked:
|
||||||
@@ -395,11 +442,13 @@ services:
|
|||||||
To update to the latest version:
|
To update to the latest version:
|
||||||
|
|
||||||
1. Pull latest code:
|
1. Pull latest code:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git pull
|
git pull
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Rebuild the image:
|
2. Rebuild the image:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker-compose build --no-cache
|
docker-compose build --no-cache
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ COPY --from=builder /build/bin ./bin
|
|||||||
RUN mkdir -p /app/sessions /app/data/media /app/data/certs
|
RUN mkdir -p /app/sessions /app/data/media /app/data/certs
|
||||||
|
|
||||||
# Expose the default server port
|
# Expose the default server port
|
||||||
EXPOSE 8080
|
EXPOSE 8025
|
||||||
|
|
||||||
# Run the server
|
# Run the server
|
||||||
ENTRYPOINT ["/app/bin/whatshook-server"]
|
ENTRYPOINT ["/app/bin/whatshook-server"]
|
||||||
|
|||||||
@@ -56,11 +56,13 @@ Add the following to your `config.json`:
|
|||||||
### Published Events
|
### Published Events
|
||||||
|
|
||||||
Events are published to topics in the format:
|
Events are published to topics in the format:
|
||||||
|
|
||||||
```
|
```
|
||||||
{topic_prefix}/{account_id}/{event_type}
|
{topic_prefix}/{account_id}/{event_type}
|
||||||
```
|
```
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
- `whatshooked/my-account/message.received`
|
- `whatshooked/my-account/message.received`
|
||||||
- `whatshooked/my-account/whatsapp.connected`
|
- `whatshooked/my-account/whatsapp.connected`
|
||||||
- `whatshooked/business-account/message.sent`
|
- `whatshooked/business-account/message.sent`
|
||||||
@@ -68,6 +70,7 @@ Examples:
|
|||||||
### Sending Messages (Subscribe Mode)
|
### Sending Messages (Subscribe Mode)
|
||||||
|
|
||||||
When `subscribe: true` is enabled, you can send WhatsApp messages by publishing to:
|
When `subscribe: true` is enabled, you can send WhatsApp messages by publishing to:
|
||||||
|
|
||||||
```
|
```
|
||||||
{topic_prefix}/{account_id}/send
|
{topic_prefix}/{account_id}/send
|
||||||
```
|
```
|
||||||
@@ -145,6 +148,7 @@ When `subscribe: true` is enabled, you can send WhatsApp messages by publishing
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Payload Fields:**
|
**Payload Fields:**
|
||||||
|
|
||||||
- `type`: Message type - "text", "image", "video", or "document" (default: "text")
|
- `type`: Message type - "text", "image", "video", or "document" (default: "text")
|
||||||
- `to`: Phone number in JID format (required)
|
- `to`: Phone number in JID format (required)
|
||||||
- `text`: Message text (required for text messages)
|
- `text`: Message text (required for text messages)
|
||||||
@@ -161,6 +165,7 @@ When `subscribe: true` is enabled, you can send WhatsApp messages by publishing
|
|||||||
Available event types for filtering:
|
Available event types for filtering:
|
||||||
|
|
||||||
### WhatsApp Connection Events
|
### WhatsApp Connection Events
|
||||||
|
|
||||||
- `whatsapp.connected`
|
- `whatsapp.connected`
|
||||||
- `whatsapp.disconnected`
|
- `whatsapp.disconnected`
|
||||||
- `whatsapp.pair.success`
|
- `whatsapp.pair.success`
|
||||||
@@ -171,6 +176,7 @@ Available event types for filtering:
|
|||||||
- `whatsapp.pair.event`
|
- `whatsapp.pair.event`
|
||||||
|
|
||||||
### Message Events
|
### Message Events
|
||||||
|
|
||||||
- `message.received`
|
- `message.received`
|
||||||
- `message.sent`
|
- `message.sent`
|
||||||
- `message.failed`
|
- `message.failed`
|
||||||
@@ -178,6 +184,7 @@ Available event types for filtering:
|
|||||||
- `message.read`
|
- `message.read`
|
||||||
|
|
||||||
### Hook Events
|
### Hook Events
|
||||||
|
|
||||||
- `hook.triggered`
|
- `hook.triggered`
|
||||||
- `hook.success`
|
- `hook.success`
|
||||||
- `hook.failed`
|
- `hook.failed`
|
||||||
@@ -263,7 +270,7 @@ script:
|
|||||||
{
|
{
|
||||||
"server": {
|
"server": {
|
||||||
"host": "0.0.0.0",
|
"host": "0.0.0.0",
|
||||||
"port": 8080
|
"port": 8025
|
||||||
},
|
},
|
||||||
"whatsapp": [
|
"whatsapp": [
|
||||||
{
|
{
|
||||||
|
|||||||
118
README.md
118
README.md
@@ -3,6 +3,7 @@
|
|||||||
A Go library and service that connects to WhatsApp and forwards messages to registered webhooks. Supports both personal WhatsApp accounts (via whatsmeow) and WhatsApp Business API. Enables two-way communication by allowing webhooks to respond with messages to be sent through WhatsApp.
|
A Go library and service that connects to WhatsApp and forwards messages to registered webhooks. Supports both personal WhatsApp accounts (via whatsmeow) and WhatsApp Business API. Enables two-way communication by allowing webhooks to respond with messages to be sent through WhatsApp.
|
||||||
|
|
||||||
**Use WhatsHooked as:**
|
**Use WhatsHooked as:**
|
||||||
|
|
||||||
- 📦 **Go Library** - Import into your own applications for programmatic WhatsApp integration
|
- 📦 **Go Library** - Import into your own applications for programmatic WhatsApp integration
|
||||||
- 🚀 **Standalone Server** - Run as a service with HTTP API and CLI management
|
- 🚀 **Standalone Server** - Run as a service with HTTP API and CLI management
|
||||||
- 🔧 **Custom Integration** - Mount individual handlers in your existing HTTP servers
|
- 🔧 **Custom Integration** - Mount individual handlers in your existing HTTP servers
|
||||||
@@ -59,7 +60,7 @@ Or with programmatic configuration:
|
|||||||
|
|
||||||
```go
|
```go
|
||||||
wh, err := whatshooked.New(
|
wh, err := whatshooked.New(
|
||||||
whatshooked.WithServer("0.0.0.0", 8080),
|
whatshooked.WithServer("0.0.0.0", 8025),
|
||||||
whatshooked.WithAuth("my-api-key", "", ""),
|
whatshooked.WithAuth("my-api-key", "", ""),
|
||||||
whatshooked.WithWhatsmeowAccount("personal", "+1234567890", "./session", true),
|
whatshooked.WithWhatsmeowAccount("personal", "+1234567890", "./session", true),
|
||||||
)
|
)
|
||||||
@@ -79,7 +80,9 @@ make build
|
|||||||
When using personal WhatsApp accounts (whatsmeow), you'll need to pair the device on first launch. The QR code will be displayed in two ways:
|
When using personal WhatsApp accounts (whatsmeow), you'll need to pair the device on first launch. The QR code will be displayed in two ways:
|
||||||
|
|
||||||
### Terminal Display
|
### Terminal Display
|
||||||
|
|
||||||
The QR code is shown as ASCII art directly in the terminal:
|
The QR code is shown as ASCII art directly in the terminal:
|
||||||
|
|
||||||
```
|
```
|
||||||
========================================
|
========================================
|
||||||
WhatsApp QR Code for account: personal
|
WhatsApp QR Code for account: personal
|
||||||
@@ -89,25 +92,29 @@ Scan this QR code with WhatsApp on your phone:
|
|||||||
|
|
||||||
[ASCII QR Code displayed here]
|
[ASCII QR Code displayed here]
|
||||||
|
|
||||||
Or open in browser: http://localhost:8080/api/qr/personal
|
Or open in browser: http://localhost:8025/api/qr/personal
|
||||||
========================================
|
========================================
|
||||||
```
|
```
|
||||||
|
|
||||||
### Browser Display
|
### Browser Display
|
||||||
|
|
||||||
For easier scanning, open the provided URL in your browser to view a larger PNG image:
|
For easier scanning, open the provided URL in your browser to view a larger PNG image:
|
||||||
- URL format: `http://localhost:8080/api/qr/{account_id}`
|
|
||||||
|
- URL format: `http://localhost:8025/api/qr/{account_id}`
|
||||||
- No authentication required for this endpoint
|
- No authentication required for this endpoint
|
||||||
- The QR code updates automatically when a new code is generated
|
- The QR code updates automatically when a new code is generated
|
||||||
|
|
||||||
### Webhook Events
|
### Webhook Events
|
||||||
|
|
||||||
The QR code URL is also included in the `whatsapp.qr.code` event:
|
The QR code URL is also included in the `whatsapp.qr.code` event:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"type": "whatsapp.qr.code",
|
"type": "whatsapp.qr.code",
|
||||||
"data": {
|
"data": {
|
||||||
"account_id": "personal",
|
"account_id": "personal",
|
||||||
"qr_code": "2@...",
|
"qr_code": "2@...",
|
||||||
"qr_url": "http://localhost:8080/api/qr/personal"
|
"qr_url": "http://localhost:8025/api/qr/personal"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -152,6 +159,7 @@ The system uses a central event bus to decouple components:
|
|||||||
- Webhook responses trigger message sends
|
- Webhook responses trigger message sends
|
||||||
|
|
||||||
This architecture enables:
|
This architecture enables:
|
||||||
|
|
||||||
- Loose coupling between WhatsApp and webhooks
|
- Loose coupling between WhatsApp and webhooks
|
||||||
- Easy addition of new event subscribers
|
- Easy addition of new event subscribers
|
||||||
- Centralized event logging and monitoring
|
- Centralized event logging and monitoring
|
||||||
@@ -202,7 +210,7 @@ func main() {
|
|||||||
// Your own handlers
|
// Your own handlers
|
||||||
mux.HandleFunc("/api/v1/custom", yourCustomHandler)
|
mux.HandleFunc("/api/v1/custom", yourCustomHandler)
|
||||||
|
|
||||||
http.ListenAndServe(":8080", mux)
|
http.ListenAndServe(":8025", mux)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -212,7 +220,7 @@ Configure WhatsHooked entirely in code without a config file:
|
|||||||
|
|
||||||
```go
|
```go
|
||||||
wh, err := whatshooked.New(
|
wh, err := whatshooked.New(
|
||||||
whatshooked.WithServer("0.0.0.0", 8080),
|
whatshooked.WithServer("0.0.0.0", 8025),
|
||||||
whatshooked.WithAuth("my-api-key", "", ""),
|
whatshooked.WithAuth("my-api-key", "", ""),
|
||||||
whatshooked.WithWhatsmeowAccount(
|
whatshooked.WithWhatsmeowAccount(
|
||||||
"personal",
|
"personal",
|
||||||
@@ -347,6 +355,7 @@ make build
|
|||||||
```
|
```
|
||||||
|
|
||||||
Or manually:
|
Or manually:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mkdir -p bin
|
mkdir -p bin
|
||||||
go build -o bin/whatshook-server ./cmd/server
|
go build -o bin/whatshook-server ./cmd/server
|
||||||
@@ -362,6 +371,7 @@ cp config.example.json config.json
|
|||||||
```
|
```
|
||||||
|
|
||||||
Or use one of the HTTPS examples:
|
Or use one of the HTTPS examples:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Self-signed certificate (development)
|
# Self-signed certificate (development)
|
||||||
cp config.https-self-signed.example.json config.json
|
cp config.https-self-signed.example.json config.json
|
||||||
@@ -379,7 +389,7 @@ Edit the configuration file to add your WhatsApp accounts and webhooks:
|
|||||||
{
|
{
|
||||||
"server": {
|
"server": {
|
||||||
"host": "localhost",
|
"host": "localhost",
|
||||||
"port": 8080,
|
"port": 8025,
|
||||||
"default_country_code": "27"
|
"default_country_code": "27"
|
||||||
},
|
},
|
||||||
"whatsapp": [
|
"whatsapp": [
|
||||||
@@ -423,23 +433,27 @@ Edit the configuration file to add your WhatsApp accounts and webhooks:
|
|||||||
### Configuration Options
|
### Configuration Options
|
||||||
|
|
||||||
**Server Configuration:**
|
**Server Configuration:**
|
||||||
|
|
||||||
- `host`: Server hostname (default: "localhost")
|
- `host`: Server hostname (default: "localhost")
|
||||||
- `port`: Server port (default: 8080)
|
- `port`: Server port (default: 8025)
|
||||||
- `default_country_code`: Default country code for phone number formatting (e.g., "27" for South Africa, "1" for US/Canada)
|
- `default_country_code`: Default country code for phone number formatting (e.g., "27" for South Africa, "1" for US/Canada)
|
||||||
- `username`: Username for HTTP Basic Authentication (optional)
|
- `username`: Username for HTTP Basic Authentication (optional)
|
||||||
- `password`: Password for HTTP Basic Authentication (optional)
|
- `password`: Password for HTTP Basic Authentication (optional)
|
||||||
- `auth_key`: API key for x-api-key header or Authorization Bearer token authentication (optional)
|
- `auth_key`: API key for x-api-key header or Authorization Bearer token authentication (optional)
|
||||||
|
|
||||||
**WhatsApp Account Configuration:**
|
**WhatsApp Account Configuration:**
|
||||||
|
|
||||||
- `id`: Unique identifier for this account
|
- `id`: Unique identifier for this account
|
||||||
- `type`: Client type - `"whatsmeow"` for personal or `"business-api"` for Business API (defaults to "whatsmeow")
|
- `type`: Client type - `"whatsmeow"` for personal or `"business-api"` for Business API (defaults to "whatsmeow")
|
||||||
- `phone_number`: Phone number with country code
|
- `phone_number`: Phone number with country code
|
||||||
|
|
||||||
**For whatsmeow (personal) accounts:**
|
**For whatsmeow (personal) accounts:**
|
||||||
|
|
||||||
- `session_path`: Path to store session data (default: `./sessions/{id}`)
|
- `session_path`: Path to store session data (default: `./sessions/{id}`)
|
||||||
- `show_qr`: Display QR code in terminal for pairing (default: false)
|
- `show_qr`: Display QR code in terminal for pairing (default: false)
|
||||||
|
|
||||||
**For business-api accounts:**
|
**For business-api accounts:**
|
||||||
|
|
||||||
- `business_api`: Business API configuration object
|
- `business_api`: Business API configuration object
|
||||||
- `phone_number_id`: WhatsApp Business Phone Number ID from Meta
|
- `phone_number_id`: WhatsApp Business Phone Number ID from Meta
|
||||||
- `access_token`: Access token from Meta Business Manager
|
- `access_token`: Access token from Meta Business Manager
|
||||||
@@ -448,6 +462,7 @@ Edit the configuration file to add your WhatsApp accounts and webhooks:
|
|||||||
- `verify_token`: Token for webhook verification (required for receiving messages)
|
- `verify_token`: Token for webhook verification (required for receiving messages)
|
||||||
|
|
||||||
**Hook Configuration:**
|
**Hook Configuration:**
|
||||||
|
|
||||||
- `id`: Unique identifier for this hook
|
- `id`: Unique identifier for this hook
|
||||||
- `name`: Human-readable name
|
- `name`: Human-readable name
|
||||||
- `url`: Webhook URL to call
|
- `url`: Webhook URL to call
|
||||||
@@ -480,6 +495,7 @@ Automatically generates and manages self-signed certificates. Ideal for developm
|
|||||||
```
|
```
|
||||||
|
|
||||||
Or programmatically:
|
Or programmatically:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
wh, err := whatshooked.New(
|
wh, err := whatshooked.New(
|
||||||
whatshooked.WithServer("0.0.0.0", 8443),
|
whatshooked.WithServer("0.0.0.0", 8443),
|
||||||
@@ -488,6 +504,7 @@ wh, err := whatshooked.New(
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Features:**
|
**Features:**
|
||||||
|
|
||||||
- Automatically generates certificates on first run
|
- Automatically generates certificates on first run
|
||||||
- Certificates valid for 1 year
|
- Certificates valid for 1 year
|
||||||
- Auto-renewal when expiring within 30 days
|
- Auto-renewal when expiring within 30 days
|
||||||
@@ -516,6 +533,7 @@ Use your own certificate files from a trusted Certificate Authority (CA) or an e
|
|||||||
```
|
```
|
||||||
|
|
||||||
Or programmatically:
|
Or programmatically:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
wh, err := whatshooked.New(
|
wh, err := whatshooked.New(
|
||||||
whatshooked.WithServer("0.0.0.0", 8443),
|
whatshooked.WithServer("0.0.0.0", 8443),
|
||||||
@@ -524,6 +542,7 @@ wh, err := whatshooked.New(
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Features:**
|
**Features:**
|
||||||
|
|
||||||
- Use certificates from any CA (Let's Encrypt, DigiCert, etc.)
|
- Use certificates from any CA (Let's Encrypt, DigiCert, etc.)
|
||||||
- Full control over certificate lifecycle
|
- Full control over certificate lifecycle
|
||||||
- Validates certificate files on startup
|
- Validates certificate files on startup
|
||||||
@@ -551,6 +570,7 @@ Automatically obtains and renews SSL certificates from Let's Encrypt. Best for p
|
|||||||
```
|
```
|
||||||
|
|
||||||
Or programmatically:
|
Or programmatically:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
wh, err := whatshooked.New(
|
wh, err := whatshooked.New(
|
||||||
whatshooked.WithServer("0.0.0.0", 443),
|
whatshooked.WithServer("0.0.0.0", 443),
|
||||||
@@ -559,6 +579,7 @@ wh, err := whatshooked.New(
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Features:**
|
**Features:**
|
||||||
|
|
||||||
- Automatic certificate provisioning from Let's Encrypt
|
- Automatic certificate provisioning from Let's Encrypt
|
||||||
- Automatic certificate renewal before expiration
|
- Automatic certificate renewal before expiration
|
||||||
- Fully managed - no manual intervention required
|
- Fully managed - no manual intervention required
|
||||||
@@ -566,6 +587,7 @@ wh, err := whatshooked.New(
|
|||||||
- Production and staging modes available
|
- Production and staging modes available
|
||||||
|
|
||||||
**Requirements:**
|
**Requirements:**
|
||||||
|
|
||||||
- Server must be publicly accessible
|
- Server must be publicly accessible
|
||||||
- Port 443 (HTTPS) must be open
|
- Port 443 (HTTPS) must be open
|
||||||
- Port 80 (HTTP) must be open for ACME challenges
|
- Port 80 (HTTP) must be open for ACME challenges
|
||||||
@@ -573,6 +595,7 @@ wh, err := whatshooked.New(
|
|||||||
- Email address for Let's Encrypt notifications
|
- Email address for Let's Encrypt notifications
|
||||||
|
|
||||||
**Important Notes:**
|
**Important Notes:**
|
||||||
|
|
||||||
- Set `production: false` for testing to use Let's Encrypt staging environment (avoids rate limits)
|
- Set `production: false` for testing to use Let's Encrypt staging environment (avoids rate limits)
|
||||||
- Set `production: true` for production deployments to get trusted certificates
|
- Set `production: true` for production deployments to get trusted certificates
|
||||||
- Ensure your domain's DNS A/AAAA record points to your server's IP
|
- Ensure your domain's DNS A/AAAA record points to your server's IP
|
||||||
@@ -614,7 +637,7 @@ To disable HTTPS and use HTTP, set `enabled: false` or omit the `tls` section en
|
|||||||
{
|
{
|
||||||
"server": {
|
"server": {
|
||||||
"host": "localhost",
|
"host": "localhost",
|
||||||
"port": 8080
|
"port": 8025
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -624,13 +647,14 @@ To disable HTTPS and use HTTP, set `enabled: false` or omit the `tls` section en
|
|||||||
The server supports two authentication methods to protect API endpoints:
|
The server supports two authentication methods to protect API endpoints:
|
||||||
|
|
||||||
#### 1. HTTP Basic Authentication
|
#### 1. HTTP Basic Authentication
|
||||||
|
|
||||||
Set both `username` and `password` in the server configuration:
|
Set both `username` and `password` in the server configuration:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"server": {
|
"server": {
|
||||||
"host": "localhost",
|
"host": "localhost",
|
||||||
"port": 8080,
|
"port": 8025,
|
||||||
"username": "admin",
|
"username": "admin",
|
||||||
"password": "secure_password"
|
"password": "secure_password"
|
||||||
}
|
}
|
||||||
@@ -638,31 +662,34 @@ Set both `username` and `password` in the server configuration:
|
|||||||
```
|
```
|
||||||
|
|
||||||
Clients must provide credentials in the Authorization header:
|
Clients must provide credentials in the Authorization header:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -u admin:secure_password http://localhost:8080/api/hooks
|
curl -u admin:secure_password http://localhost:8025/api/hooks
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 2. API Key Authentication
|
#### 2. API Key Authentication
|
||||||
|
|
||||||
Set `auth_key` in the server configuration:
|
Set `auth_key` in the server configuration:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"server": {
|
"server": {
|
||||||
"host": "localhost",
|
"host": "localhost",
|
||||||
"port": 8080,
|
"port": 8025,
|
||||||
"auth_key": "your-secret-api-key"
|
"auth_key": "your-secret-api-key"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Clients can provide the API key using either:
|
Clients can provide the API key using either:
|
||||||
|
|
||||||
- **x-api-key header**:
|
- **x-api-key header**:
|
||||||
```bash
|
```bash
|
||||||
curl -H "x-api-key: your-secret-api-key" http://localhost:8080/api/hooks
|
curl -H "x-api-key: your-secret-api-key" http://localhost:8025/api/hooks
|
||||||
```
|
```
|
||||||
- **Authorization Bearer token**:
|
- **Authorization Bearer token**:
|
||||||
```bash
|
```bash
|
||||||
curl -H "Authorization: Bearer your-secret-api-key" http://localhost:8080/api/hooks
|
curl -H "Authorization: Bearer your-secret-api-key" http://localhost:8025/api/hooks
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Authentication Notes
|
#### Authentication Notes
|
||||||
@@ -716,6 +743,7 @@ Add a Business API account to your `config.json`:
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Important Notes:**
|
**Important Notes:**
|
||||||
|
|
||||||
- Use a **permanent access token**, not the temporary 24-hour token
|
- Use a **permanent access token**, not the temporary 24-hour token
|
||||||
- The `verify_token` is a random string you create - it will be used to verify Meta's webhook requests
|
- The `verify_token` is a random string you create - it will be used to verify Meta's webhook requests
|
||||||
- Keep your access token secure and never commit it to version control
|
- Keep your access token secure and never commit it to version control
|
||||||
@@ -727,7 +755,7 @@ To receive incoming messages from WhatsApp Business API, you must register your
|
|||||||
1. **Start the WhatsHooked server** with your Business API configuration
|
1. **Start the WhatsHooked server** with your Business API configuration
|
||||||
2. **Ensure your server is publicly accessible** (use ngrok for testing):
|
2. **Ensure your server is publicly accessible** (use ngrok for testing):
|
||||||
```bash
|
```bash
|
||||||
ngrok http 8080
|
ngrok http 8025
|
||||||
```
|
```
|
||||||
3. **In Meta for Developers**, go to **WhatsApp** → **Configuration**
|
3. **In Meta for Developers**, go to **WhatsApp** → **Configuration**
|
||||||
4. **Add Webhook URL**:
|
4. **Add Webhook URL**:
|
||||||
@@ -750,11 +778,13 @@ Once configured, start the server and the Business API account will connect auto
|
|||||||
```
|
```
|
||||||
|
|
||||||
Look for logs indicating successful connection:
|
Look for logs indicating successful connection:
|
||||||
|
|
||||||
```
|
```
|
||||||
Business API client connected account_id=business phone=+1234567890
|
Business API client connected account_id=business phone=+1234567890
|
||||||
```
|
```
|
||||||
|
|
||||||
Send a test message:
|
Send a test message:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./bin/whatshook-cli send
|
./bin/whatshook-cli send
|
||||||
# Select your business account
|
# Select your business account
|
||||||
@@ -765,6 +795,7 @@ Send a test message:
|
|||||||
### Business API Features
|
### Business API Features
|
||||||
|
|
||||||
**Supported:**
|
**Supported:**
|
||||||
|
|
||||||
- ✅ Send/receive text messages
|
- ✅ Send/receive text messages
|
||||||
- ✅ Send/receive images with captions
|
- ✅ Send/receive images with captions
|
||||||
- ✅ Send/receive videos with captions
|
- ✅ Send/receive videos with captions
|
||||||
@@ -783,6 +814,7 @@ Send a test message:
|
|||||||
- ✅ Event publishing to webhooks (same format as whatsmeow)
|
- ✅ Event publishing to webhooks (same format as whatsmeow)
|
||||||
|
|
||||||
**Differences from whatsmeow:**
|
**Differences from whatsmeow:**
|
||||||
|
|
||||||
- No QR code pairing (uses access token authentication)
|
- No QR code pairing (uses access token authentication)
|
||||||
- Rate limits apply based on your Meta Business tier
|
- Rate limits apply based on your Meta Business tier
|
||||||
- Official support from Meta
|
- Official support from Meta
|
||||||
@@ -816,6 +848,7 @@ You can run both personal (whatsmeow) and Business API accounts at the same time
|
|||||||
```
|
```
|
||||||
|
|
||||||
Both accounts will:
|
Both accounts will:
|
||||||
|
|
||||||
- Receive messages independently
|
- Receive messages independently
|
||||||
- Trigger the same webhooks
|
- Trigger the same webhooks
|
||||||
- Publish identical event formats
|
- Publish identical event formats
|
||||||
@@ -846,6 +879,7 @@ The QR code is also published as an event (`whatsapp.qr.code`) so you can handle
|
|||||||
### Using the CLI
|
### Using the CLI
|
||||||
|
|
||||||
The CLI uses Cobra and supports configuration from multiple sources with the following priority:
|
The CLI uses Cobra and supports configuration from multiple sources with the following priority:
|
||||||
|
|
||||||
1. Command-line flags (highest priority)
|
1. Command-line flags (highest priority)
|
||||||
2. Environment variables
|
2. Environment variables
|
||||||
3. Configuration file (lowest priority)
|
3. Configuration file (lowest priority)
|
||||||
@@ -853,34 +887,40 @@ The CLI uses Cobra and supports configuration from multiple sources with the fol
|
|||||||
#### Configuration
|
#### Configuration
|
||||||
|
|
||||||
Create a CLI configuration file (optional):
|
Create a CLI configuration file (optional):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cp .whatshooked-cli.example.json .whatshooked-cli.json
|
cp .whatshooked-cli.example.json .whatshooked-cli.json
|
||||||
```
|
```
|
||||||
|
|
||||||
Or set via environment variable:
|
Or set via environment variable:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
export WHATSHOOKED_SERVER_URL=http://localhost:8080
|
export WHATSHOOKED_SERVER_URL=http://localhost:8025
|
||||||
```
|
```
|
||||||
|
|
||||||
Or use command-line flag:
|
Or use command-line flag:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./bin/whatshook-cli --server http://localhost:8080 health
|
./bin/whatshook-cli --server http://localhost:8025 health
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Commands
|
#### Commands
|
||||||
|
|
||||||
Get help:
|
Get help:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./bin/whatshook-cli --help
|
./bin/whatshook-cli --help
|
||||||
./bin/whatshook-cli hooks --help
|
./bin/whatshook-cli hooks --help
|
||||||
```
|
```
|
||||||
|
|
||||||
Check server health:
|
Check server health:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./bin/whatshook-cli health
|
./bin/whatshook-cli health
|
||||||
```
|
```
|
||||||
|
|
||||||
List all hooks:
|
List all hooks:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./bin/whatshook-cli hooks list
|
./bin/whatshook-cli hooks list
|
||||||
# or just
|
# or just
|
||||||
@@ -888,16 +928,19 @@ List all hooks:
|
|||||||
```
|
```
|
||||||
|
|
||||||
Add a new hook:
|
Add a new hook:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./bin/whatshook-cli hooks add
|
./bin/whatshook-cli hooks add
|
||||||
```
|
```
|
||||||
|
|
||||||
Remove a hook:
|
Remove a hook:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./bin/whatshook-cli hooks remove <hook_id>
|
./bin/whatshook-cli hooks remove <hook_id>
|
||||||
```
|
```
|
||||||
|
|
||||||
List WhatsApp accounts:
|
List WhatsApp accounts:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./bin/whatshook-cli accounts list
|
./bin/whatshook-cli accounts list
|
||||||
# or just
|
# or just
|
||||||
@@ -905,11 +948,13 @@ List WhatsApp accounts:
|
|||||||
```
|
```
|
||||||
|
|
||||||
Add a WhatsApp account:
|
Add a WhatsApp account:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./bin/whatshook-cli accounts add
|
./bin/whatshook-cli accounts add
|
||||||
```
|
```
|
||||||
|
|
||||||
Send a message:
|
Send a message:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./bin/whatshook-cli send
|
./bin/whatshook-cli send
|
||||||
```
|
```
|
||||||
@@ -918,10 +963,10 @@ Send a message:
|
|||||||
|
|
||||||
The CLI loads configuration with the following priority (highest to lowest):
|
The CLI loads configuration with the following priority (highest to lowest):
|
||||||
|
|
||||||
1. **Command-line flags**: `--server http://example.com:8080`
|
1. **Command-line flags**: `--server http://example.com:8025`
|
||||||
2. **Environment variables**: `WHATSHOOKED_SERVER_URL=http://example.com:8080`
|
2. **Environment variables**: `WHATSHOOKED_SERVER_URL=http://example.com:8025`
|
||||||
3. **Config file**: `.whatshooked-cli.json` in current directory or `$HOME/.whatshooked/cli.json`
|
3. **Config file**: `.whatshooked-cli.json` in current directory or `$HOME/.whatshooked/cli.json`
|
||||||
4. **Defaults**: `http://localhost:8080`
|
4. **Defaults**: `http://localhost:8025`
|
||||||
|
|
||||||
## Webhook Integration
|
## Webhook Integration
|
||||||
|
|
||||||
@@ -968,6 +1013,7 @@ Or using full JID format:
|
|||||||
```
|
```
|
||||||
|
|
||||||
Fields:
|
Fields:
|
||||||
|
|
||||||
- `send_message`: Set to `true` to send a message
|
- `send_message`: Set to `true` to send a message
|
||||||
- `to`: Recipient phone number or JID. Can be:
|
- `to`: Recipient phone number or JID. Can be:
|
||||||
- Plain phone number (e.g., `"0834606792"`) - will be formatted using `default_country_code`
|
- Plain phone number (e.g., `"0834606792"`) - will be formatted using `default_country_code`
|
||||||
@@ -989,6 +1035,7 @@ The server automatically formats phone numbers to WhatsApp JID format:
|
|||||||
- Appends `@s.whatsapp.net` suffix
|
- Appends `@s.whatsapp.net` suffix
|
||||||
|
|
||||||
Examples with `default_country_code: "27"`:
|
Examples with `default_country_code: "27"`:
|
||||||
|
|
||||||
- `0834606792` → `27834606792@s.whatsapp.net` (replaces leading 0 with 27)
|
- `0834606792` → `27834606792@s.whatsapp.net` (replaces leading 0 with 27)
|
||||||
- `083-460-6792` → `27834606792@s.whatsapp.net` (removes dashes, replaces 0)
|
- `083-460-6792` → `27834606792@s.whatsapp.net` (removes dashes, replaces 0)
|
||||||
- `27834606792` → `27834606792@s.whatsapp.net` (already has country code)
|
- `27834606792` → `27834606792@s.whatsapp.net` (already has country code)
|
||||||
@@ -1000,12 +1047,14 @@ Examples with `default_country_code: "27"`:
|
|||||||
The server exposes the following HTTP endpoints:
|
The server exposes the following HTTP endpoints:
|
||||||
|
|
||||||
**Public Endpoints:**
|
**Public Endpoints:**
|
||||||
|
|
||||||
- `GET /health` - Health check (no authentication required)
|
- `GET /health` - Health check (no authentication required)
|
||||||
- `GET/POST /webhooks/whatsapp/{accountID}` - Business API webhook verification and events (no authentication, validated by Meta's verify_token)
|
- `GET/POST /webhooks/whatsapp/{accountID}` - Business API webhook verification and events (no authentication, validated by Meta's verify_token)
|
||||||
|
|
||||||
**Protected Endpoints (require authentication if enabled):**
|
**Protected Endpoints (require authentication if enabled):**
|
||||||
|
|
||||||
*Hooks & Accounts:*
|
_Hooks & Accounts:_
|
||||||
|
|
||||||
- `GET /api/hooks` - List all hooks
|
- `GET /api/hooks` - List all hooks
|
||||||
- `POST /api/hooks/add` - Add a new hook
|
- `POST /api/hooks/add` - Add a new hook
|
||||||
- `POST /api/hooks/remove` - Remove a hook
|
- `POST /api/hooks/remove` - Remove a hook
|
||||||
@@ -1016,7 +1065,8 @@ The server exposes the following HTTP endpoints:
|
|||||||
- `POST /api/accounts/disable` - Disable a WhatsApp account
|
- `POST /api/accounts/disable` - Disable a WhatsApp account
|
||||||
- `POST /api/accounts/enable` - Enable a WhatsApp account
|
- `POST /api/accounts/enable` - Enable a WhatsApp account
|
||||||
|
|
||||||
*Send Messages:*
|
_Send Messages:_
|
||||||
|
|
||||||
- `POST /api/send` - Send a text message
|
- `POST /api/send` - Send a text message
|
||||||
- `POST /api/send/image` - Send an image
|
- `POST /api/send/image` - Send an image
|
||||||
- `POST /api/send/video` - Send a video
|
- `POST /api/send/video` - Send a video
|
||||||
@@ -1031,12 +1081,14 @@ The server exposes the following HTTP endpoints:
|
|||||||
- `POST /api/send/reaction` - React to a message with an emoji (Business API)
|
- `POST /api/send/reaction` - React to a message with an emoji (Business API)
|
||||||
- `POST /api/messages/read` - Mark a message as read (Business API)
|
- `POST /api/messages/read` - Mark a message as read (Business API)
|
||||||
|
|
||||||
*Templates (Business API):*
|
_Templates (Business API):_
|
||||||
|
|
||||||
- `POST /api/templates` - List all message templates for an account
|
- `POST /api/templates` - List all message templates for an account
|
||||||
- `POST /api/templates/upload` - Create a new message template
|
- `POST /api/templates/upload` - Create a new message template
|
||||||
- `POST /api/templates/delete` - Delete a template by name and language
|
- `POST /api/templates/delete` - Delete a template by name and language
|
||||||
|
|
||||||
*Flows (Business API):*
|
_Flows (Business API):_
|
||||||
|
|
||||||
- `POST /api/flows` - List all flows for an account
|
- `POST /api/flows` - List all flows for an account
|
||||||
- `POST /api/flows/create` - Create a new flow
|
- `POST /api/flows/create` - Create a new flow
|
||||||
- `POST /api/flows/get` - Get details of a specific flow
|
- `POST /api/flows/get` - Get details of a specific flow
|
||||||
@@ -1045,28 +1097,33 @@ The server exposes the following HTTP endpoints:
|
|||||||
- `POST /api/flows/deprecate` - Deprecate a flow (blocks new sessions; existing sessions continue)
|
- `POST /api/flows/deprecate` - Deprecate a flow (blocks new sessions; existing sessions continue)
|
||||||
- `POST /api/flows/delete` - Permanently delete a flow
|
- `POST /api/flows/delete` - Permanently delete a flow
|
||||||
|
|
||||||
*Phone Numbers (Business API):*
|
_Phone Numbers (Business API):_
|
||||||
|
|
||||||
- `POST /api/phone-numbers` - List phone numbers for an account
|
- `POST /api/phone-numbers` - List phone numbers for an account
|
||||||
- `POST /api/phone-numbers/request-code` - Request a verification code (SMS or VOICE)
|
- `POST /api/phone-numbers/request-code` - Request a verification code (SMS or VOICE)
|
||||||
- `POST /api/phone-numbers/verify-code` - Verify a phone number with the received code
|
- `POST /api/phone-numbers/verify-code` - Verify a phone number with the received code
|
||||||
|
|
||||||
*Business Profile (Business API):*
|
_Business Profile (Business API):_
|
||||||
|
|
||||||
- `POST /api/business-profile` - Retrieve the business profile for an account
|
- `POST /api/business-profile` - Retrieve the business profile for an account
|
||||||
- `POST /api/business-profile/update` - Update business profile fields (about, address, description, email, websites, vertical)
|
- `POST /api/business-profile/update` - Update business profile fields (about, address, description, email, websites, vertical)
|
||||||
|
|
||||||
*Catalog / Commerce (Business API):*
|
_Catalog / Commerce (Business API):_
|
||||||
|
|
||||||
- `POST /api/catalogs` - List product catalogs linked to an account
|
- `POST /api/catalogs` - List product catalogs linked to an account
|
||||||
- `POST /api/catalogs/products` - List products in a specific catalog
|
- `POST /api/catalogs/products` - List products in a specific catalog
|
||||||
- `POST /api/send/catalog` - Send a catalog message (shares full product catalog)
|
- `POST /api/send/catalog` - Send a catalog message (shares full product catalog)
|
||||||
- `POST /api/send/product` - Send a single-product interactive message
|
- `POST /api/send/product` - Send a single-product interactive message
|
||||||
- `POST /api/send/product-list` - Send a multi-product list message (up to 30 products across 10 sections)
|
- `POST /api/send/product-list` - Send a multi-product list message (up to 30 products across 10 sections)
|
||||||
|
|
||||||
*Media:*
|
_Media:_
|
||||||
|
|
||||||
- `GET /api/media/{accountID}/{filename}` - Serve media files
|
- `GET /api/media/{accountID}/{filename}` - Serve media files
|
||||||
- `POST /api/media/upload` - Upload a media file to Meta and return its media_id (Business API)
|
- `POST /api/media/upload` - Upload a media file to Meta and return its media_id (Business API)
|
||||||
- `POST /api/media-delete` - Delete a previously uploaded media file from Meta (Business API)
|
- `POST /api/media-delete` - Delete a previously uploaded media file from Meta (Business API)
|
||||||
|
|
||||||
*Message Cache:*
|
_Message Cache:_
|
||||||
|
|
||||||
- `GET /api/cache` - List cached events
|
- `GET /api/cache` - List cached events
|
||||||
- `GET /api/cache/stats` - Cache statistics
|
- `GET /api/cache/stats` - Cache statistics
|
||||||
- `POST /api/cache/replay` - Replay all cached events
|
- `POST /api/cache/replay` - Replay all cached events
|
||||||
@@ -1135,6 +1192,7 @@ whatshooked/
|
|||||||
The system publishes the following event types:
|
The system publishes the following event types:
|
||||||
|
|
||||||
**WhatsApp Events:**
|
**WhatsApp Events:**
|
||||||
|
|
||||||
- `whatsapp.connected` - WhatsApp client connected
|
- `whatsapp.connected` - WhatsApp client connected
|
||||||
- `whatsapp.disconnected` - WhatsApp client disconnected
|
- `whatsapp.disconnected` - WhatsApp client disconnected
|
||||||
- `whatsapp.pair.success` - Device pairing successful
|
- `whatsapp.pair.success` - Device pairing successful
|
||||||
@@ -1145,11 +1203,13 @@ The system publishes the following event types:
|
|||||||
- `whatsapp.pair.event` - Generic pairing event
|
- `whatsapp.pair.event` - Generic pairing event
|
||||||
|
|
||||||
**Message Events:**
|
**Message Events:**
|
||||||
|
|
||||||
- `message.received` - New message received from WhatsApp
|
- `message.received` - New message received from WhatsApp
|
||||||
- `message.sent` - Message successfully sent to WhatsApp
|
- `message.sent` - Message successfully sent to WhatsApp
|
||||||
- `message.failed` - Message send failed
|
- `message.failed` - Message send failed
|
||||||
|
|
||||||
**Hook Events:**
|
**Hook Events:**
|
||||||
|
|
||||||
- `hook.triggered` - Webhook is being called
|
- `hook.triggered` - Webhook is being called
|
||||||
- `hook.success` - Webhook responded successfully
|
- `hook.success` - Webhook responded successfully
|
||||||
- `hook.failed` - Webhook call failed
|
- `hook.failed` - Webhook call failed
|
||||||
|
|||||||
@@ -574,40 +574,40 @@ Events are automatically cached when:
|
|||||||
**List cached events:**
|
**List cached events:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -u username:password http://localhost:8080/api/cache
|
curl -u username:password http://localhost:8025/api/cache
|
||||||
```
|
```
|
||||||
|
|
||||||
**Get cache statistics:**
|
**Get cache statistics:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -u username:password http://localhost:8080/api/cache/stats
|
curl -u username:password http://localhost:8025/api/cache/stats
|
||||||
```
|
```
|
||||||
|
|
||||||
**Replay all cached events:**
|
**Replay all cached events:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -X POST -u username:password http://localhost:8080/api/cache/replay
|
curl -X POST -u username:password http://localhost:8025/api/cache/replay
|
||||||
```
|
```
|
||||||
|
|
||||||
**Replay specific event:**
|
**Replay specific event:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -X POST -u username:password \
|
curl -X POST -u username:password \
|
||||||
"http://localhost:8080/api/cache/event/replay?id=EVENT_ID"
|
"http://localhost:8025/api/cache/event/replay?id=EVENT_ID"
|
||||||
```
|
```
|
||||||
|
|
||||||
**Delete cached event:**
|
**Delete cached event:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -X DELETE -u username:password \
|
curl -X DELETE -u username:password \
|
||||||
"http://localhost:8080/api/cache/event/delete?id=EVENT_ID"
|
"http://localhost:8025/api/cache/event/delete?id=EVENT_ID"
|
||||||
```
|
```
|
||||||
|
|
||||||
**Clear all cache:**
|
**Clear all cache:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -X DELETE -u username:password \
|
curl -X DELETE -u username:password \
|
||||||
"http://localhost:8080/api/cache/clear?confirm=true"
|
"http://localhost:8025/api/cache/clear?confirm=true"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Cache Workflow Example
|
### Cache Workflow Example
|
||||||
@@ -662,7 +662,7 @@ curl -X DELETE -u username:password \
|
|||||||
|
|
||||||
1. `message_cache.enabled` is `true` in config
|
1. `message_cache.enabled` is `true` in config
|
||||||
2. Hooks are actually inactive or not matching events
|
2. Hooks are actually inactive or not matching events
|
||||||
3. Check cache stats: `curl -u user:pass http://localhost:8080/api/cache/stats`
|
3. Check cache stats: `curl -u user:pass http://localhost:8025/api/cache/stats`
|
||||||
|
|
||||||
### No Hooks Configured Error
|
### No Hooks Configured Error
|
||||||
|
|
||||||
@@ -715,7 +715,7 @@ Enable debug logging to trace the issue:
|
|||||||
"type": "image",
|
"type": "image",
|
||||||
"mime_type": "image/jpeg",
|
"mime_type": "image/jpeg",
|
||||||
"filename": "wamid.xxx_a1b2c3d4.jpg",
|
"filename": "wamid.xxx_a1b2c3d4.jpg",
|
||||||
"url": "http://localhost:8080/api/media/business/wamid.xxx_a1b2c3d4.jpg",
|
"url": "http://localhost:8025/api/media/business/wamid.xxx_a1b2c3d4.jpg",
|
||||||
"base64": "..." // Only if media.mode is "base64" or "both"
|
"base64": "..." // Only if media.mode is "base64" or "both"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -776,7 +776,7 @@ Here's a complete `config.json` with all Business API features:
|
|||||||
{
|
{
|
||||||
"server": {
|
"server": {
|
||||||
"host": "0.0.0.0",
|
"host": "0.0.0.0",
|
||||||
"port": 8080,
|
"port": 8025,
|
||||||
"default_country_code": "1",
|
"default_country_code": "1",
|
||||||
"username": "admin",
|
"username": "admin",
|
||||||
"password": "secure_password",
|
"password": "secure_password",
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ func LoadCLIConfig(configFile string, serverFlag string) (*CLIConfig, error) {
|
|||||||
v := viper.New()
|
v := viper.New()
|
||||||
|
|
||||||
// Set defaults
|
// Set defaults
|
||||||
v.SetDefault("server_url", "http://localhost:8080")
|
v.SetDefault("server_url", "http://localhost:8025")
|
||||||
v.SetDefault("auth_key", "")
|
v.SetDefault("auth_key", "")
|
||||||
v.SetDefault("username", "")
|
v.SetDefault("username", "")
|
||||||
v.SetDefault("password", "")
|
v.SetDefault("password", "")
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ var rootCmd = &cobra.Command{
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default: $HOME/.whatshooked/cli.json)")
|
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default: $HOME/.whatshooked/cli.json)")
|
||||||
rootCmd.PersistentFlags().StringVar(&serverURL, "server", "", "server URL (default: http://localhost:8080)")
|
rootCmd.PersistentFlags().StringVar(&serverURL, "server", "", "server URL (default: http://localhost:8025)")
|
||||||
|
|
||||||
// Add all command groups
|
// Add all command groups
|
||||||
rootCmd.AddCommand(healthCmd)
|
rootCmd.AddCommand(healthCmd)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"server_url": "http://localhost:8080",
|
"server_url": "http://localhost:8025",
|
||||||
"auth_key": "",
|
"auth_key": "",
|
||||||
"username": "",
|
"username": "",
|
||||||
"password": ""
|
"password": ""
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"server": {
|
"server": {
|
||||||
"host": "localhost",
|
"host": "localhost",
|
||||||
"port": 8080,
|
"port": 8025,
|
||||||
"default_country_code": "27",
|
"default_country_code": "27",
|
||||||
"username": "",
|
"username": "",
|
||||||
"password": "",
|
"password": "",
|
||||||
@@ -66,10 +66,7 @@
|
|||||||
"Authorization": "Bearer your-token-here"
|
"Authorization": "Bearer your-token-here"
|
||||||
},
|
},
|
||||||
"active": true,
|
"active": true,
|
||||||
"events": [
|
"events": ["whatsapp.connected", "whatsapp.disconnected"],
|
||||||
"whatsapp.connected",
|
|
||||||
"whatsapp.disconnected"
|
|
||||||
],
|
|
||||||
"description": "Monitors WhatsApp connection status changes"
|
"description": "Monitors WhatsApp connection status changes"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -100,7 +97,7 @@
|
|||||||
"media": {
|
"media": {
|
||||||
"data_path": "./data/media",
|
"data_path": "./data/media",
|
||||||
"mode": "link",
|
"mode": "link",
|
||||||
"base_url": "http://localhost:8080"
|
"base_url": "http://localhost:8025"
|
||||||
},
|
},
|
||||||
"database": {
|
"database": {
|
||||||
"type": "postgres",
|
"type": "postgres",
|
||||||
@@ -113,10 +110,7 @@
|
|||||||
},
|
},
|
||||||
"event_logger": {
|
"event_logger": {
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"targets": [
|
"targets": ["file", "sqlite"],
|
||||||
"file",
|
|
||||||
"sqlite"
|
|
||||||
],
|
|
||||||
"file_dir": "./data/events",
|
"file_dir": "./data/events",
|
||||||
"table_name": "event_logs"
|
"table_name": "event_logs"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ services:
|
|||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
container_name: whatshooked-server
|
container_name: whatshooked-server
|
||||||
ports:
|
ports:
|
||||||
- "8080:8080"
|
- "8025:8025"
|
||||||
volumes:
|
volumes:
|
||||||
# Mount config file
|
# Mount config file
|
||||||
- ./bin/config.json:/app/config.json:ro
|
- ./bin/config.json:/app/config.json:ro
|
||||||
@@ -15,14 +15,14 @@ services:
|
|||||||
# Mount sessions directory for WhatsApp authentication persistence
|
# Mount sessions directory for WhatsApp authentication persistence
|
||||||
- ./bin/sessions:/app/sessions
|
- ./bin/sessions:/app/sessions
|
||||||
|
|
||||||
# Mount media directory for storing downloaded media files
|
# Mount data directory for storing data files
|
||||||
- ./bin/data/media:/app/data/media
|
- ./bin/data/:/app/data/
|
||||||
|
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
# Health check
|
# Health check
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:8080/health"]
|
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:8025/health"]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
retries: 3
|
retries: 3
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ func Load(path string) (*Config, error) {
|
|||||||
cfg.Server.Host = "localhost"
|
cfg.Server.Host = "localhost"
|
||||||
}
|
}
|
||||||
if cfg.Server.Port == 0 {
|
if cfg.Server.Port == 0 {
|
||||||
cfg.Server.Port = 8080
|
cfg.Server.Port = 8025
|
||||||
}
|
}
|
||||||
if cfg.Media.DataPath == "" {
|
if cfg.Media.DataPath == "" {
|
||||||
cfg.Media.DataPath = "./data/media"
|
cfg.Media.DataPath = "./data/media"
|
||||||
|
|||||||
@@ -432,7 +432,7 @@ func (c *Client) saveMediaFile(messageID string, data []byte, mimeType string) (
|
|||||||
func (c *Client) generateMediaURL(messageID, filename string) string {
|
func (c *Client) generateMediaURL(messageID, filename string) string {
|
||||||
baseURL := c.mediaConfig.BaseURL
|
baseURL := c.mediaConfig.BaseURL
|
||||||
if baseURL == "" {
|
if baseURL == "" {
|
||||||
baseURL = "http://localhost:8080"
|
baseURL = "http://localhost:8025"
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%s/api/media/%s/%s", baseURL, c.id, filename)
|
return fmt.Sprintf("%s/api/media/%s/%s", baseURL, c.id, filename)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -678,7 +678,7 @@ func (c *Client) saveMediaFile(messageID string, data []byte, mimeType string) (
|
|||||||
func (c *Client) generateMediaURL(messageID, filename string) string {
|
func (c *Client) generateMediaURL(messageID, filename string) string {
|
||||||
baseURL := c.mediaConfig.BaseURL
|
baseURL := c.mediaConfig.BaseURL
|
||||||
if baseURL == "" {
|
if baseURL == "" {
|
||||||
baseURL = "http://localhost:8080"
|
baseURL = "http://localhost:8025"
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%s/api/media/%s/%s", baseURL, c.id, filename)
|
return fmt.Sprintf("%s/api/media/%s/%s", baseURL, c.id, filename)
|
||||||
}
|
}
|
||||||
@@ -737,7 +737,7 @@ func getExtensionFromMimeType(mimeType string) string {
|
|||||||
func (c *Client) generateQRCodeURL() string {
|
func (c *Client) generateQRCodeURL() string {
|
||||||
baseURL := c.mediaConfig.BaseURL
|
baseURL := c.mediaConfig.BaseURL
|
||||||
if baseURL == "" {
|
if baseURL == "" {
|
||||||
baseURL = "http://localhost:8080"
|
baseURL = "http://localhost:8025"
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%s/api/qr/%s", baseURL, c.id)
|
return fmt.Sprintf("%s/api/qr/%s", baseURL, c.id)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ func New(opts ...Option) (*WhatsHooked, error) {
|
|||||||
cfg := &config.Config{
|
cfg := &config.Config{
|
||||||
Server: config.ServerConfig{
|
Server: config.ServerConfig{
|
||||||
Host: "localhost",
|
Host: "localhost",
|
||||||
Port: 8080,
|
Port: 8025,
|
||||||
},
|
},
|
||||||
Media: config.MediaConfig{
|
Media: config.MediaConfig{
|
||||||
DataPath: "./data/media",
|
DataPath: "./data/media",
|
||||||
|
|||||||
Reference in New Issue
Block a user