Spaces:
Runtime error
Runtime error
Upload 384 files
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .dockerignore +48 -0
- .env.example +120 -0
- .eslintignore +3 -0
- .gitattributes +3 -0
- .github/FUNDING.yml +14 -0
- .github/ISSUE_TEMPLATE/bug_report.md +59 -0
- .github/ISSUE_TEMPLATE/feature_request.md +25 -0
- .github/ISSUE_TEMPLATE/question.md +11 -0
- .github/clear-gh-runs.sh +18 -0
- .github/gh-team-labels.yml +10 -0
- .github/workflows/build.yaml +150 -0
- .gitignore +56 -0
- .nvmrc +1 -0
- .oxlintrc.json +15 -0
- .pre-commit-config.yaml +75 -0
- .precommit/validate_commit_message.py +38 -0
- .prettierrc +13 -0
- .yarn/releases/yarn-3.6.3.cjs +0 -0
- .yarnrc +1 -0
- .yarnrc.yml +3 -0
- CHANGELOG.md +4 -0
- CNAME +1 -0
- Dockerfile +202 -53
- LICENSE +201 -0
- Makefile +60 -0
- docker-compose.yaml +104 -0
- docker-compose/chatwoot/.chatwoot.env +260 -0
- docker-compose/chatwoot/.waha.env +115 -0
- docker-compose/chatwoot/docker-compose.yaml +97 -0
- docker-compose/docker-compose.workers.yaml +97 -0
- docker-compose/n8n/docker-compose.yaml +34 -0
- docker-compose/test/docker-compose.yaml +112 -0
- entrypoint.sh +87 -0
- examples/dev.likeapro.jpg +0 -0
- examples/dev.likeapro.opus +0 -0
- examples/example.pdf +0 -0
- examples/python/README.md +128 -0
- examples/python/requirements.txt +3 -0
- examples/python/whatsapp_download_files_bot.py +84 -0
- examples/python/whatsapp_echo_bot.py +123 -0
- examples/video.avi +3 -0
- examples/video.mp4 +3 -0
- examples/voice.mp3 +3 -0
- examples/waha.jpg +0 -0
- logo.png +0 -0
- nest-cli.json +14 -0
- package.json +158 -0
- prepare-chatgpt.sh +22 -0
- scripts/gows-proto.js +144 -0
- src/api/auth.controller.ts +65 -0
.dockerignore
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Dockerfile
|
| 2 |
+
docker-compose
|
| 3 |
+
src/core/engines/gows/proto
|
| 4 |
+
.*sessions
|
| 5 |
+
sessions
|
| 6 |
+
files
|
| 7 |
+
venv
|
| 8 |
+
.wwebjs_auth
|
| 9 |
+
docs
|
| 10 |
+
examples
|
| 11 |
+
.github
|
| 12 |
+
.git
|
| 13 |
+
|
| 14 |
+
# compiled output
|
| 15 |
+
/dist
|
| 16 |
+
/node_modules
|
| 17 |
+
.yarn
|
| 18 |
+
|
| 19 |
+
# Logs
|
| 20 |
+
logs
|
| 21 |
+
*.log
|
| 22 |
+
npm-debug.log*
|
| 23 |
+
yarn-debug.log*
|
| 24 |
+
yarn-error.log*
|
| 25 |
+
lerna-debug.log*
|
| 26 |
+
|
| 27 |
+
# OS
|
| 28 |
+
.DS_Store
|
| 29 |
+
|
| 30 |
+
# Tests
|
| 31 |
+
/coverage
|
| 32 |
+
/.nyc_output
|
| 33 |
+
|
| 34 |
+
# IDEs and editors
|
| 35 |
+
/.idea
|
| 36 |
+
.project
|
| 37 |
+
.classpath
|
| 38 |
+
.c9/
|
| 39 |
+
*.launch
|
| 40 |
+
.settings/
|
| 41 |
+
*.sublime-workspace
|
| 42 |
+
|
| 43 |
+
# IDE - VSCode
|
| 44 |
+
.vscode/*
|
| 45 |
+
!.vscode/settings.json
|
| 46 |
+
!.vscode/tasks.json
|
| 47 |
+
!.vscode/launch.json
|
| 48 |
+
!.vscode/extensions.json
|
.env.example
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# WAHA - WhatsApp HTTP API
|
| 2 |
+
#
|
| 3 |
+
# https://waha.devlike.pro/docs/how-to/config/
|
| 4 |
+
#
|
| 5 |
+
|
| 6 |
+
# ==================
|
| 7 |
+
# ===== COMMON =====
|
| 8 |
+
# ==================
|
| 9 |
+
# Base URL for the API (used for webhooks, file URLs, etc.)
|
| 10 |
+
WAHA_BASE_URL=http://localhost:3000
|
| 11 |
+
|
| 12 |
+
# Server configuration (if you need to customize hostname/port)
|
| 13 |
+
# WHATSAPP_API_SCHEMA=http
|
| 14 |
+
# WHATSAPP_API_PORT=3000
|
| 15 |
+
# WHATSAPP_API_HOSTNAME=localhost
|
| 16 |
+
|
| 17 |
+
# ====================
|
| 18 |
+
# ===== SECURITY =====
|
| 19 |
+
# ====================
|
| 20 |
+
# "sha512:{SHA}" format - below is "admin" api key
|
| 21 |
+
WAHA_API_KEY=sha512:c7ad44cbad762a5da0a452f9e854fdc1e0e7a52a38015f23f3eab1d80b931dd472634dfac71cd34ebc35d16ab7fb8a90c81f975113d6c7538dc69dd8de9077ec
|
| 22 |
+
WAHA_DASHBOARD_ENABLED=True
|
| 23 |
+
WAHA_DASHBOARD_USERNAME=admin
|
| 24 |
+
WAHA_DASHBOARD_PASSWORD=admin
|
| 25 |
+
WHATSAPP_SWAGGER_ENABLED=True
|
| 26 |
+
WHATSAPP_SWAGGER_USERNAME=admin
|
| 27 |
+
WHATSAPP_SWAGGER_PASSWORD=admin
|
| 28 |
+
|
| 29 |
+
# WhatsApp engine (WEBJS is default, GOWS or NOWEB for better performance)
|
| 30 |
+
WHATSAPP_DEFAULT_ENGINE=WEBJS
|
| 31 |
+
|
| 32 |
+
# ===================
|
| 33 |
+
# ===== LOGGING =====
|
| 34 |
+
# ===================
|
| 35 |
+
# Log format: JSON (for log management systems) or PRETTY (for development)
|
| 36 |
+
WAHA_LOG_FORMAT=JSON
|
| 37 |
+
|
| 38 |
+
# Log level: info, debug, error, warn
|
| 39 |
+
WAHA_LOG_LEVEL=info
|
| 40 |
+
|
| 41 |
+
# Don't print QR codes in logs
|
| 42 |
+
WAHA_PRINT_QR=False
|
| 43 |
+
|
| 44 |
+
# =========================
|
| 45 |
+
# ===== MEDIA STORAGE =====
|
| 46 |
+
# =========================
|
| 47 |
+
# Local storage (default)
|
| 48 |
+
WAHA_MEDIA_STORAGE=LOCAL
|
| 49 |
+
WHATSAPP_FILES_LIFETIME=0
|
| 50 |
+
WHATSAPP_FILES_FOLDER=/app/.media
|
| 51 |
+
|
| 52 |
+
# Media download settings
|
| 53 |
+
# WHATSAPP_DOWNLOAD_MEDIA=true
|
| 54 |
+
# WHATSAPP_FILES_MIMETYPES=image/jpeg,image/png
|
| 55 |
+
|
| 56 |
+
# S3 storage (uncomment to use)
|
| 57 |
+
# WAHA_MEDIA_STORAGE=S3
|
| 58 |
+
# WAHA_S3_REGION=eu-west-2
|
| 59 |
+
# WAHA_S3_BUCKET=waha
|
| 60 |
+
# WAHA_S3_ACCESS_KEY_ID=minioadmin
|
| 61 |
+
# WAHA_S3_SECRET_ACCESS_KEY=minioadmin
|
| 62 |
+
# WAHA_S3_ENDPOINT=http://minio:9000
|
| 63 |
+
# WAHA_S3_FORCE_PATH_STYLE=True
|
| 64 |
+
# WAHA_S3_PROXY_FILES=True
|
| 65 |
+
|
| 66 |
+
# PostgreSQL storage (uncomment to use)
|
| 67 |
+
# WAHA_MEDIA_STORAGE=POSTGRESQL
|
| 68 |
+
# WAHA_MEDIA_POSTGRESQL_URL=postgres://postgres:postgres@postgres:5432/postgres?sslmode=disable
|
| 69 |
+
|
| 70 |
+
# ===========================
|
| 71 |
+
# ===== SESSION STORAGE =====
|
| 72 |
+
# ===========================
|
| 73 |
+
# PostgreSQL for sessions (uncomment to use)
|
| 74 |
+
# WHATSAPP_SESSIONS_POSTGRESQL_URL=postgres://postgres:postgres@postgres:5432/postgres?sslmode=disable
|
| 75 |
+
|
| 76 |
+
# MongoDB for sessions (uncomment to use)
|
| 77 |
+
# WHATSAPP_SESSIONS_MONGO_URL=mongodb://mongouser:mongopassword@mongodb:27017
|
| 78 |
+
|
| 79 |
+
# =================
|
| 80 |
+
# ===== APPS ======
|
| 81 |
+
# =================
|
| 82 |
+
# WAHA_APPS_ENABLED=True
|
| 83 |
+
# REDIS_URL=redis://:redis@redis:6379
|
| 84 |
+
|
| 85 |
+
# Apps Jobs configuration - *_AGE in seconds
|
| 86 |
+
# WAHA_APPS_JOBS_REMOVE_ON_COMPLETE_AGE=
|
| 87 |
+
# WAHA_APPS_JOBS_REMOVE_ON_COMPLETE_COUNT=
|
| 88 |
+
# WAHA_APPS_JOBS_REMOVE_ON_FAIL_AGE=
|
| 89 |
+
# WAHA_APPS_JOBS_REMOVE_ON_FAIL_COUNT
|
| 90 |
+
|
| 91 |
+
|
| 92 |
+
# ==================================
|
| 93 |
+
# ===== ADVANCED CONFIGURATION =====
|
| 94 |
+
# ==================================
|
| 95 |
+
|
| 96 |
+
# Timezone for screenshots and logs
|
| 97 |
+
# TZ=Europe/Dublin
|
| 98 |
+
|
| 99 |
+
# Session management
|
| 100 |
+
# WHATSAPP_START_SESSION=session1,session2
|
| 101 |
+
# WHATSAPP_RESTART_ALL_SESSIONS=False
|
| 102 |
+
|
| 103 |
+
# Webhooks
|
| 104 |
+
# WHATSAPP_HOOK_URL=https://webhook.site/11111111-1111-1111-1111-11111111
|
| 105 |
+
# WHATSAPP_HOOK_CUSTOM_HEADERS=custom_header_key:custom_header_value
|
| 106 |
+
# WHATSAPP_HOOK_EVENTS=session.status,message,message.reaction
|
| 107 |
+
|
| 108 |
+
# Proxy configuration
|
| 109 |
+
# WHATSAPP_PROXY_SERVER=proxy.example.com:3128
|
| 110 |
+
# WHATSAPP_PROXY_SERVER_USERNAME=user
|
| 111 |
+
# WHATSAPP_PROXY_SERVER_PASSWORD=pass
|
| 112 |
+
|
| 113 |
+
# HTTPS configuration
|
| 114 |
+
# !DEPRECATED!
|
| 115 |
+
# Setup nginx reverse proxy to handle TLS connection
|
| 116 |
+
# using Let's encrypt or self-issued certificate
|
| 117 |
+
# WAHA_HTTPS_ENABLED=true
|
| 118 |
+
# WAHA_HTTPS_PATH_KEY=/etc/letsencrypt/live/waha.example.pro/privkey.pem
|
| 119 |
+
# WAHA_HTTPS_PATH_CERT=/etc/letsencrypt/live/waha.example.pro/cert.pem
|
| 120 |
+
# WAHA_HTTPS_PATH_CA=/etc/letsencrypt/live/waha.example.pro/chain.pem
|
.eslintignore
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
src/core/engines/gows/grpc/*
|
| 2 |
+
src/core/engines/gows/proto/*
|
| 3 |
+
src/core/engines/webjs/_lodash.js
|
.gitattributes
CHANGED
|
@@ -33,3 +33,6 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
examples/video.avi filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
examples/video.mp4 filter=lfs diff=lfs merge=lfs -text
|
| 38 |
+
examples/voice.mp3 filter=lfs diff=lfs merge=lfs -text
|
.github/FUNDING.yml
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# These are supported funding model platforms
|
| 2 |
+
|
| 3 |
+
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
| 4 |
+
patreon: wa_http_api
|
| 5 |
+
open_collective: # doks Replace with a single Open Collective username
|
| 6 |
+
ko_fi: # Replace with a single Ko-fi username
|
| 7 |
+
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
| 8 |
+
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
| 9 |
+
liberapay: # Replace with a single Liberapay username
|
| 10 |
+
issuehunt: # Replace with a single IssueHunt username
|
| 11 |
+
otechie: # Replace with a single Otechie username
|
| 12 |
+
custom:
|
| 13 |
+
- https://boosty.to/wa-http-api
|
| 14 |
+
- https://portal.devlike.pro/
|
.github/ISSUE_TEMPLATE/bug_report.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
name: Bug report
|
| 3 |
+
about: Create a report to help us improve
|
| 4 |
+
title: '[WEBJS] - '
|
| 5 |
+
labels: bug
|
| 6 |
+
assignees: ''
|
| 7 |
+
type: 'BUG'
|
| 8 |
+
---
|
| 9 |
+
|
| 10 |
+
### Describe the bug
|
| 11 |
+
|
| 12 |
+
A clear and concise description of what the bug is. Feel free to remove sections
|
| 13 |
+
that you don't feel to make the text shorter!
|
| 14 |
+
|
| 15 |
+
### Version
|
| 16 |
+
|
| 17 |
+
Get the WAHA version by calling `GET /api/version`
|
| 18 |
+
|
| 19 |
+
```json
|
| 20 |
+
{
|
| 21 |
+
"version": "YYYY.MM.DD",
|
| 22 |
+
"engine": "ENGINE",
|
| 23 |
+
"tier": "TIER"
|
| 24 |
+
}
|
| 25 |
+
```
|
| 26 |
+
|
| 27 |
+
Try to update to
|
| 28 |
+
[the latest version](https://github.com/devlikeapro/waha/releases) before
|
| 29 |
+
creating an issue!
|
| 30 |
+
|
| 31 |
+
## Steps
|
| 32 |
+
|
| 33 |
+
**To Reproduce** Steps to reproduce the behavior:
|
| 34 |
+
|
| 35 |
+
1. Go to '...'
|
| 36 |
+
2. Click on '....'
|
| 37 |
+
3. Scroll down to '....'
|
| 38 |
+
4. See error
|
| 39 |
+
|
| 40 |
+
### Expected behavior
|
| 41 |
+
|
| 42 |
+
A clear and concise description of what you expected to happen.
|
| 43 |
+
|
| 44 |
+
### Requests - Responses
|
| 45 |
+
|
| 46 |
+
Please attach all sent requests, responses that you sent.
|
| 47 |
+
|
| 48 |
+
### Docker Logs
|
| 49 |
+
|
| 50 |
+
Collect and attach related docker logs if you have any
|
| 51 |
+
https://waha.devlike.pro/docs/how-to/deploy/#viewing-the-logs
|
| 52 |
+
|
| 53 |
+
### Screenshots
|
| 54 |
+
|
| 55 |
+
If applicable, add screenshots to help explain your problem.
|
| 56 |
+
|
| 57 |
+
### Additional context
|
| 58 |
+
|
| 59 |
+
Add any other context about the problem here.
|
.github/ISSUE_TEMPLATE/feature_request.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
name: Feature request
|
| 3 |
+
about: Suggest an idea for this project
|
| 4 |
+
title: ''
|
| 5 |
+
labels: ''
|
| 6 |
+
assignees: ''
|
| 7 |
+
type: 'Feature'
|
| 8 |
+
---
|
| 9 |
+
|
| 10 |
+
**Is your feature request related to a problem? Please describe.** I'm always
|
| 11 |
+
frustrated when [...]
|
| 12 |
+
|
| 13 |
+
A clear and concise description of what the problem is. Ex.
|
| 14 |
+
|
| 15 |
+
**Describe the solution you'd like**
|
| 16 |
+
|
| 17 |
+
A clear and concise description of what you want to happen.
|
| 18 |
+
|
| 19 |
+
**Describe alternatives you've considered**
|
| 20 |
+
|
| 21 |
+
A clear and concise description of any alternative solutions or features you've
|
| 22 |
+
considered.
|
| 23 |
+
|
| 24 |
+
**Additional context** Add any other context or screenshots about the feature
|
| 25 |
+
request here.
|
.github/ISSUE_TEMPLATE/question.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
name: Question
|
| 3 |
+
about: I have a question about the project or feature
|
| 4 |
+
title: '[Question] '
|
| 5 |
+
labels: 'question'
|
| 6 |
+
assignees: ''
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
👉 Kindly use
|
| 10 |
+
[GitHub Discussions](https://github.com/devlikeapro/waha/discussions) to ask
|
| 11 |
+
questions!
|
.github/clear-gh-runs.sh
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Idea from
|
| 2 |
+
# https://stackoverflow.com/a/65539398/6753144
|
| 3 |
+
#
|
| 4 |
+
|
| 5 |
+
OWNER=devlikeapro
|
| 6 |
+
REPO=waha-plus
|
| 7 |
+
|
| 8 |
+
# list workflows
|
| 9 |
+
gh api -X GET /repos/$OWNER/$REPO/actions/workflows | jq '.workflows[] | .name,.id'
|
| 10 |
+
|
| 11 |
+
# copy the ID of the workflow you want to clear and set it
|
| 12 |
+
WORKFLOW_ID=40218610
|
| 13 |
+
|
| 14 |
+
# list runs
|
| 15 |
+
gh api -X GET /repos/$OWNER/$REPO/actions/workflows/$WORKFLOW_ID/runs --paginate | jq '.workflow_runs[] | .id'
|
| 16 |
+
|
| 17 |
+
# delete runs
|
| 18 |
+
gh api -X GET /repos/$OWNER/$REPO/actions/workflows/$WORKFLOW_ID/runs --paginate | jq '.workflow_runs[] | .id' | xargs -I{} gh api -X DELETE /repos/$OWNER/$REPO/actions/runs/{} --silent
|
.github/gh-team-labels.yml
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
teamLabels:
|
| 2 |
+
- team: waha-patrons-pro
|
| 3 |
+
label: patron:PRO
|
| 4 |
+
comment: '[](https://waha.devlike.pro/docs/how-to/plus-version/#tiers)'
|
| 5 |
+
- team: waha-patrons-advanced
|
| 6 |
+
label: patron:ADVANCED
|
| 7 |
+
comment: '[](https://waha.devlike.pro/docs/how-to/plus-version/#tiers)'
|
| 8 |
+
- team: waha-patrons-plus
|
| 9 |
+
label: patron:PLUS
|
| 10 |
+
comment: '[](https://waha.devlike.pro/docs/how-to/plus-version/#tiers)'
|
.github/workflows/build.yaml
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
name: Release
|
| 2 |
+
|
| 3 |
+
on:
|
| 4 |
+
push:
|
| 5 |
+
tags:
|
| 6 |
+
- '*'
|
| 7 |
+
|
| 8 |
+
jobs:
|
| 9 |
+
docker-build:
|
| 10 |
+
runs-on: ${{ matrix.runner }}
|
| 11 |
+
name:
|
| 12 |
+
${{ matrix.engine }} - ${{ matrix.browser }} - ${{ matrix.platform }} -
|
| 13 |
+
${{ matrix.tag }}
|
| 14 |
+
strategy:
|
| 15 |
+
matrix:
|
| 16 |
+
include:
|
| 17 |
+
# Chromium - x86
|
| 18 |
+
- runner: 'buildjet-4vcpu-ubuntu-2204'
|
| 19 |
+
tag: 'latest'
|
| 20 |
+
platform: 'amd64'
|
| 21 |
+
browser: 'chromium'
|
| 22 |
+
engine: 'WEBJS'
|
| 23 |
+
goss: 'goss-linux-amd64'
|
| 24 |
+
|
| 25 |
+
# Chromium - ARM
|
| 26 |
+
- runner: 'buildjet-4vcpu-ubuntu-2204-arm'
|
| 27 |
+
tag: 'arm'
|
| 28 |
+
platform: 'linux/arm64'
|
| 29 |
+
browser: 'chromium'
|
| 30 |
+
engine: 'WEBJS'
|
| 31 |
+
goss: 'goss-linux-arm'
|
| 32 |
+
|
| 33 |
+
# Chrome - x86
|
| 34 |
+
- runner: 'buildjet-4vcpu-ubuntu-2204'
|
| 35 |
+
tag: 'chrome'
|
| 36 |
+
platform: 'amd64'
|
| 37 |
+
browser: 'chrome'
|
| 38 |
+
engine: 'WEBJS'
|
| 39 |
+
goss: 'goss-linux-amd64'
|
| 40 |
+
|
| 41 |
+
# Chrome - ARM (Chrome is not available for ARM)
|
| 42 |
+
#- runner: "buildjet-4vcpu-ubuntu-2204-arm"
|
| 43 |
+
# tag: "chrome-arm"
|
| 44 |
+
# platform: "linux/arm64"
|
| 45 |
+
# browser: "chrome"
|
| 46 |
+
# goss: 'goss-linux-arm'
|
| 47 |
+
|
| 48 |
+
# NOWEB - x86
|
| 49 |
+
- runner: 'buildjet-4vcpu-ubuntu-2204'
|
| 50 |
+
tag: 'noweb'
|
| 51 |
+
platform: 'amd64'
|
| 52 |
+
browser: 'none'
|
| 53 |
+
engine: 'NOWEB'
|
| 54 |
+
goss: 'goss-linux-amd64'
|
| 55 |
+
|
| 56 |
+
# NOWEB - ARM
|
| 57 |
+
- runner: 'buildjet-4vcpu-ubuntu-2204-arm'
|
| 58 |
+
tag: 'noweb-arm'
|
| 59 |
+
platform: 'linux/arm64'
|
| 60 |
+
browser: 'none'
|
| 61 |
+
engine: 'NOWEB'
|
| 62 |
+
goss: 'goss-linux-arm'
|
| 63 |
+
|
| 64 |
+
# GOWS - x86
|
| 65 |
+
- runner: 'buildjet-4vcpu-ubuntu-2204'
|
| 66 |
+
tag: 'gows'
|
| 67 |
+
platform: 'amd64'
|
| 68 |
+
browser: 'none'
|
| 69 |
+
engine: 'GOWS'
|
| 70 |
+
goss: 'goss-linux-amd64'
|
| 71 |
+
|
| 72 |
+
# No browser - ARM
|
| 73 |
+
- runner: 'buildjet-4vcpu-ubuntu-2204-arm'
|
| 74 |
+
tag: 'gows-arm'
|
| 75 |
+
platform: 'linux/arm64'
|
| 76 |
+
browser: 'none'
|
| 77 |
+
engine: 'GOWS'
|
| 78 |
+
goss: 'goss-linux-arm'
|
| 79 |
+
|
| 80 |
+
steps:
|
| 81 |
+
- name: Checkout
|
| 82 |
+
uses: actions/checkout@v3
|
| 83 |
+
- name: Set up Docker Buildx
|
| 84 |
+
uses: docker/setup-buildx-action@v2
|
| 85 |
+
|
| 86 |
+
- name: Docker meta
|
| 87 |
+
id: meta
|
| 88 |
+
uses: docker/metadata-action@v4
|
| 89 |
+
with:
|
| 90 |
+
images: ${{ vars.DOCKER_IMAGE }}
|
| 91 |
+
flavor: latest=false
|
| 92 |
+
tags: |
|
| 93 |
+
type=raw,value=${{ matrix.tag }}
|
| 94 |
+
type=raw,value=${{ matrix.tag }}-{{tag}}
|
| 95 |
+
|
| 96 |
+
- name: Login to image repository
|
| 97 |
+
if: github.ref_type == 'tag'
|
| 98 |
+
uses: docker/login-action@v2
|
| 99 |
+
with:
|
| 100 |
+
username: ${{ secrets.DOCKER_USER }}
|
| 101 |
+
password: ${{ secrets.DOCKER_TOKEN }}
|
| 102 |
+
|
| 103 |
+
- name: Build
|
| 104 |
+
uses: docker/build-push-action@v4
|
| 105 |
+
with:
|
| 106 |
+
context: .
|
| 107 |
+
file: Dockerfile
|
| 108 |
+
platforms: ${{ matrix.platform }}
|
| 109 |
+
build-args: |
|
| 110 |
+
USE_BROWSER=${{ matrix.browser }}
|
| 111 |
+
WHATSAPP_DEFAULT_ENGINE=${{ matrix.engine }}
|
| 112 |
+
push: false
|
| 113 |
+
load: true
|
| 114 |
+
tags: ${{ steps.meta.outputs.tags }}
|
| 115 |
+
labels: ${{ steps.meta.outputs.labels }}
|
| 116 |
+
|
| 117 |
+
- name: Install goss
|
| 118 |
+
env:
|
| 119 |
+
GOSS_DOWNLOAD: 'https://github.com/goss-org/goss/releases/download'
|
| 120 |
+
GOSS_VERSION: 'v0.4.8'
|
| 121 |
+
run: |
|
| 122 |
+
curl -L https://github.com/goss-org/goss/releases/download/${{ env.GOSS_VERSION }}/${{ matrix.goss }} -o /usr/local/bin/goss
|
| 123 |
+
chmod +rx /usr/local/bin/goss
|
| 124 |
+
|
| 125 |
+
- name: Run smoke tests
|
| 126 |
+
working-directory: tests/smoke
|
| 127 |
+
timeout-minutes: 2
|
| 128 |
+
run: |
|
| 129 |
+
docker run -d \
|
| 130 |
+
--name smoke \
|
| 131 |
+
--rm -p3000:3000 \
|
| 132 |
+
${{ vars.DOCKER_IMAGE }}:${{ matrix.tag }}
|
| 133 |
+
|
| 134 |
+
sleep 3
|
| 135 |
+
docker logs smoke
|
| 136 |
+
goss validate --retry-timeout 30s --sleep 1s
|
| 137 |
+
docker rm --force smoke
|
| 138 |
+
|
| 139 |
+
- name: Push
|
| 140 |
+
uses: docker/build-push-action@v4
|
| 141 |
+
with:
|
| 142 |
+
context: .
|
| 143 |
+
file: Dockerfile
|
| 144 |
+
platforms: ${{ matrix.platform }}
|
| 145 |
+
build-args: |
|
| 146 |
+
USE_BROWSER=${{ matrix.browser }}
|
| 147 |
+
WHATSAPP_DEFAULT_ENGINE=${{ matrix.engine }}
|
| 148 |
+
push: ${{ github.ref_type == 'tag' }}
|
| 149 |
+
tags: ${{ steps.meta.outputs.tags }}
|
| 150 |
+
labels: ${{ steps.meta.outputs.labels }}
|
.gitignore
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
src/core/engines/gows/proto
|
| 2 |
+
.env
|
| 3 |
+
*.heapsnapshot
|
| 4 |
+
.yarn
|
| 5 |
+
example.ts
|
| 6 |
+
.*sessions
|
| 7 |
+
sessions
|
| 8 |
+
.secrets
|
| 9 |
+
.minio
|
| 10 |
+
.media
|
| 11 |
+
tokens
|
| 12 |
+
files
|
| 13 |
+
venv
|
| 14 |
+
.wwebjs_auth
|
| 15 |
+
src/test.ts
|
| 16 |
+
src/test.js
|
| 17 |
+
test.js
|
| 18 |
+
.wwebjs_cache
|
| 19 |
+
src/dashboard
|
| 20 |
+
.eslintcache
|
| 21 |
+
__pycache__
|
| 22 |
+
|
| 23 |
+
# compiled output
|
| 24 |
+
/dist
|
| 25 |
+
/node_modules
|
| 26 |
+
|
| 27 |
+
# Logs
|
| 28 |
+
logs
|
| 29 |
+
*.log
|
| 30 |
+
npm-debug.log*
|
| 31 |
+
yarn-debug.log*
|
| 32 |
+
yarn-error.log*
|
| 33 |
+
lerna-debug.log*
|
| 34 |
+
|
| 35 |
+
# OS
|
| 36 |
+
.DS_Store
|
| 37 |
+
|
| 38 |
+
# Tests
|
| 39 |
+
/coverage
|
| 40 |
+
/.nyc_output
|
| 41 |
+
|
| 42 |
+
# IDEs and editors
|
| 43 |
+
/.idea
|
| 44 |
+
.project
|
| 45 |
+
.classpath
|
| 46 |
+
.c9/
|
| 47 |
+
*.launch
|
| 48 |
+
.settings/
|
| 49 |
+
*.sublime-workspace
|
| 50 |
+
|
| 51 |
+
# IDE - VSCode
|
| 52 |
+
.vscode/*
|
| 53 |
+
!.vscode/settings.json
|
| 54 |
+
!.vscode/tasks.json
|
| 55 |
+
!.vscode/launch.json
|
| 56 |
+
!.vscode/extensions.json
|
.nvmrc
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
v22.16
|
.oxlintrc.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"$schema": "./node_modules/oxlint/configuration_schema.json",
|
| 3 |
+
"plugins": ["typescript"],
|
| 4 |
+
"env": {
|
| 5 |
+
"builtin": true
|
| 6 |
+
},
|
| 7 |
+
"rules": {
|
| 8 |
+
"@typescript-eslint/explicit-function-return-type": "off",
|
| 9 |
+
"@typescript-eslint/explicit-module-boundary-types": "off",
|
| 10 |
+
"@typescript-eslint/no-inferrable-types": "off",
|
| 11 |
+
"@typescript-eslint/no-explicit-any": "off",
|
| 12 |
+
"@typescript-eslint/ban-ts-comment": "off",
|
| 13 |
+
"no-unused-vars": "off"
|
| 14 |
+
}
|
| 15 |
+
}
|
.pre-commit-config.yaml
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
exclude: |
|
| 2 |
+
(?x)^(
|
| 3 |
+
^src/dashboard/.*|
|
| 4 |
+
^src/core/engines/webjs/.*html|
|
| 5 |
+
^src/core/engines/gows/grpc/.*|
|
| 6 |
+
^src/core/engines/gows/proto/.*|
|
| 7 |
+
^src/plus/engines/webjs/.*html|
|
| 8 |
+
^.yarn/.*
|
| 9 |
+
)$
|
| 10 |
+
|
| 11 |
+
repos:
|
| 12 |
+
- repo: local
|
| 13 |
+
hooks:
|
| 14 |
+
- id: commit-message-prefix
|
| 15 |
+
name: Validate Commit Message for src/plus Changes
|
| 16 |
+
entry: python ./.precommit/validate_commit_message.py
|
| 17 |
+
language: python
|
| 18 |
+
stages: [commit-msg]
|
| 19 |
+
|
| 20 |
+
- id: oxlint
|
| 21 |
+
name: oxlint
|
| 22 |
+
entry: npx oxlint --fix --deny-warnings
|
| 23 |
+
language: system
|
| 24 |
+
pass_filenames: true
|
| 25 |
+
files: \.(ts|tsx|js|jsx)$
|
| 26 |
+
|
| 27 |
+
- repo: https://github.com/pre-commit/mirrors-prettier
|
| 28 |
+
rev: 'v3.1.0'
|
| 29 |
+
hooks:
|
| 30 |
+
- id: prettier
|
| 31 |
+
stages: [pre-commit]
|
| 32 |
+
exclude: |
|
| 33 |
+
(?x)^(
|
| 34 |
+
docs/.*|
|
| 35 |
+
README.md|
|
| 36 |
+
tests/smoke/goss.yaml|
|
| 37 |
+
)$
|
| 38 |
+
- repo: https://github.com/Lucas-C/pre-commit-hooks-nodejs
|
| 39 |
+
rev: v1.1.2
|
| 40 |
+
hooks:
|
| 41 |
+
- id: markdown-toc
|
| 42 |
+
stages: [pre-commit]
|
| 43 |
+
name: README.md
|
| 44 |
+
files: ^README.md$
|
| 45 |
+
- repo: local
|
| 46 |
+
hooks:
|
| 47 |
+
- id: no-plus-in-core
|
| 48 |
+
stages: [pre-commit]
|
| 49 |
+
name: No "plus" in core
|
| 50 |
+
language: pygrep
|
| 51 |
+
entry: 'plus'
|
| 52 |
+
files: |
|
| 53 |
+
(?x)^(
|
| 54 |
+
src/api/.*|
|
| 55 |
+
src/core/.*|
|
| 56 |
+
src/structures/.*|
|
| 57 |
+
src/config.service.ts|
|
| 58 |
+
)$
|
| 59 |
+
|
| 60 |
+
- repo: local
|
| 61 |
+
hooks:
|
| 62 |
+
- id: no-console-log
|
| 63 |
+
stages: [pre-commit]
|
| 64 |
+
name: No console.log() calls
|
| 65 |
+
language: pygrep
|
| 66 |
+
entry: 'console\.log'
|
| 67 |
+
exclude: |
|
| 68 |
+
(?x)^(
|
| 69 |
+
entrypoint.sh|
|
| 70 |
+
.pre-commit-config.yaml|
|
| 71 |
+
^src/core/engines/webjs/session.webjs.core.ts|
|
| 72 |
+
^src/core/engines/webjs/_lodash.js|
|
| 73 |
+
^tests/perf/.*|
|
| 74 |
+
^scripts/.*|
|
| 75 |
+
)$
|
.precommit/validate_commit_message.py
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import subprocess
|
| 2 |
+
import sys
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
def get_staged_files():
|
| 6 |
+
result = subprocess.run(["git", "diff", "--cached", "--name-only"], stdout=subprocess.PIPE, text=True)
|
| 7 |
+
files = result.stdout.splitlines()
|
| 8 |
+
return files
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
def get_commit_message(commit_msg_filepath):
|
| 12 |
+
with open(commit_msg_filepath, 'r') as f:
|
| 13 |
+
return f.readline().strip()
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
def main():
|
| 17 |
+
commit_msg_filepath = sys.argv[1]
|
| 18 |
+
commit_message = get_commit_message(commit_msg_filepath)
|
| 19 |
+
staged_files = get_staged_files()
|
| 20 |
+
|
| 21 |
+
has_plus_changes = any(f.startswith('src/plus') for f in staged_files)
|
| 22 |
+
print(commit_message)
|
| 23 |
+
starts_with_plus = commit_message.startswith('[PLUS]')
|
| 24 |
+
|
| 25 |
+
if has_plus_changes and not starts_with_plus:
|
| 26 |
+
print("'[PLUS]' not found in commit message, but there's changes are from 'src/plus'.")
|
| 27 |
+
return 1
|
| 28 |
+
|
| 29 |
+
if starts_with_plus and not all(f.startswith('src/plus') for f in staged_files):
|
| 30 |
+
print("'[PLUS]' found in commit message, but there's changes from other directories. \n"
|
| 31 |
+
"Changes MUST be only from 'src/plus'.")
|
| 32 |
+
return 1
|
| 33 |
+
|
| 34 |
+
return 0
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
if __name__ == "__main__":
|
| 38 |
+
sys.exit(main())
|
.prettierrc
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"singleQuote": true,
|
| 3 |
+
"trailingComma": "all",
|
| 4 |
+
"endOfLine": "auto",
|
| 5 |
+
"arrowParens": "always",
|
| 6 |
+
"bracketSpacing": true,
|
| 7 |
+
"useTabs": false,
|
| 8 |
+
"tabWidth": 2,
|
| 9 |
+
"semi": true,
|
| 10 |
+
"quoteProps": "as-needed",
|
| 11 |
+
"proseWrap": "always",
|
| 12 |
+
"printWidth": 80
|
| 13 |
+
}
|
.yarn/releases/yarn-3.6.3.cjs
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
.yarnrc
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
network-timeout 60000
|
.yarnrc.yml
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
nodeLinker: node-modules
|
| 2 |
+
|
| 3 |
+
yarnPath: .yarn/releases/yarn-3.6.3.cjs
|
CHANGELOG.md
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Changelog
|
| 2 |
+
|
| 3 |
+
You can find changelog on
|
| 4 |
+
[the changelog page](https://waha.devlike.pro/docs/help/changelog/)
|
CNAME
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
waha.devlike.pro
|
Dockerfile
CHANGED
|
@@ -1,65 +1,214 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
|
| 4 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
|
| 6 |
-
#
|
| 7 |
-
|
|
|
|
|
|
|
|
|
|
| 8 |
|
| 9 |
-
#
|
| 10 |
-
|
| 11 |
-
# chown -R node:node /app/.sessions /app/data /tmp/whatsapp-files && \
|
| 12 |
-
# chmod -R 755 /app/.sessions /app/data /tmp/whatsapp-files
|
| 13 |
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
|
| 18 |
-
#
|
| 19 |
-
|
|
|
|
|
|
|
|
|
|
| 20 |
|
| 21 |
-
#
|
| 22 |
-
#
|
|
|
|
|
|
|
| 23 |
|
| 24 |
-
#
|
| 25 |
-
|
| 26 |
-
# WARNING: This approach has security implications and complexity
|
| 27 |
-
# =================================================================
|
| 28 |
|
| 29 |
-
|
|
|
|
| 30 |
|
| 31 |
-
|
| 32 |
-
RUN
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
|
| 34 |
-
#
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
echo 'git clone https://github.com/devlikeapro/waha.git /tmp/waha' >> /start.sh && \
|
| 39 |
-
echo 'docker pull devlikeapro/waha' >> /start.sh && \
|
| 40 |
-
echo 'docker run -it --rm -p 3000:3000/tcp --name waha devlikeapro/waha' >> /start.sh && \
|
| 41 |
-
chmod +x /start.sh
|
| 42 |
|
| 43 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
#
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
ARG NODE_IMAGE_TAG=22.16-bookworm-slim
|
| 2 |
+
ARG GOLANG_IMAGE_TAG=1.23-bookworm
|
| 3 |
|
| 4 |
+
#
|
| 5 |
+
# Build
|
| 6 |
+
#
|
| 7 |
+
FROM node:${NODE_IMAGE_TAG} AS build
|
| 8 |
+
ENV PUPPETEER_SKIP_DOWNLOAD=True
|
| 9 |
|
| 10 |
+
# npm packages
|
| 11 |
+
WORKDIR /git
|
| 12 |
+
COPY package.json .
|
| 13 |
+
COPY yarn.lock .
|
| 14 |
+
ENV YARN_CHECKSUM_BEHAVIOR=update
|
| 15 |
|
| 16 |
+
# git
|
| 17 |
+
RUN apt-get update && apt-get install -y git
|
|
|
|
|
|
|
| 18 |
|
| 19 |
+
RUN npm install -g corepack && corepack enable
|
| 20 |
+
RUN yarn set version 3.6.3
|
| 21 |
+
RUN yarn install
|
| 22 |
|
| 23 |
+
# App
|
| 24 |
+
WORKDIR /git
|
| 25 |
+
ADD . /git
|
| 26 |
+
RUN yarn install
|
| 27 |
+
RUN yarn build && find ./dist -name "*.d.ts" -delete
|
| 28 |
|
| 29 |
+
#
|
| 30 |
+
# Dashboard
|
| 31 |
+
#
|
| 32 |
+
FROM node:${NODE_IMAGE_TAG} AS dashboard
|
| 33 |
|
| 34 |
+
# jq to parse json
|
| 35 |
+
RUN apt-get update && apt-get install -y jq && rm -rf /var/lib/apt/lists/*
|
|
|
|
|
|
|
| 36 |
|
| 37 |
+
# wget, unzip
|
| 38 |
+
RUN apt-get update && apt-get install -y wget unzip && rm -rf /var/lib/apt/lists/*
|
| 39 |
|
| 40 |
+
COPY waha.config.json /tmp/waha.config.json
|
| 41 |
+
RUN \
|
| 42 |
+
WAHA_DASHBOARD_GITHUB_REPO=$(jq -r '.waha.dashboard.repo' /tmp/waha.config.json) && \
|
| 43 |
+
WAHA_DASHBOARD_SHA=$(jq -r '.waha.dashboard.ref' /tmp/waha.config.json) && \
|
| 44 |
+
wget https://github.com/${WAHA_DASHBOARD_GITHUB_REPO}/archive/${WAHA_DASHBOARD_SHA}.zip \
|
| 45 |
+
&& unzip ${WAHA_DASHBOARD_SHA}.zip -d /tmp/dashboard \
|
| 46 |
+
&& mkdir -p /dashboard \
|
| 47 |
+
&& mv /tmp/dashboard/dashboard-${WAHA_DASHBOARD_SHA}/* /dashboard/ \
|
| 48 |
+
&& rm -rf ${WAHA_DASHBOARD_SHA}.zip \
|
| 49 |
+
&& rm -rf /tmp/dashboard/dashboard-${WAHA_DASHBOARD_SHA}
|
| 50 |
|
| 51 |
+
#
|
| 52 |
+
# GOWS
|
| 53 |
+
#
|
| 54 |
+
FROM golang:${GOLANG_IMAGE_TAG} AS gows
|
|
|
|
|
|
|
|
|
|
|
|
|
| 55 |
|
| 56 |
+
# jq to parse json
|
| 57 |
+
RUN apt-get update && apt-get install -y jq && rm -rf /var/lib/apt/lists/*
|
| 58 |
+
|
| 59 |
+
# install protoc
|
| 60 |
+
RUN apt-get update && \
|
| 61 |
+
apt-get install protobuf-compiler -y
|
| 62 |
+
|
| 63 |
+
# Image processing for thumbnails
|
| 64 |
+
RUN apt-get update \
|
| 65 |
+
&& apt-get install -y libvips-dev \
|
| 66 |
+
&& rm -rf /var/lib/apt/lists/*
|
| 67 |
+
|
| 68 |
+
COPY waha.config.json /tmp/waha.config.json
|
| 69 |
+
WORKDIR /go/gows
|
| 70 |
+
RUN \
|
| 71 |
+
GOWS_GITHUB_REPO=$(jq -r '.waha.gows.repo' /tmp/waha.config.json) && \
|
| 72 |
+
GOWS_SHA=$(jq -r '.waha.gows.ref' /tmp/waha.config.json) && \
|
| 73 |
+
ARCH=$(uname -m) && \
|
| 74 |
+
if [ "$ARCH" = "x86_64" ]; then ARCH="amd64"; \
|
| 75 |
+
elif [ "$ARCH" = "aarch64" ]; then ARCH="arm64"; \
|
| 76 |
+
else echo "Unsupported architecture: $ARCH" && exit 1; fi && \
|
| 77 |
+
mkdir -p /go/gows/bin && \
|
| 78 |
+
wget -O /go/gows/bin/gows https://github.com/${GOWS_GITHUB_REPO}/releases/download/${GOWS_SHA}/gows-${ARCH} && \
|
| 79 |
+
chmod +x /go/gows/bin/gows
|
| 80 |
+
|
| 81 |
+
|
| 82 |
+
#
|
| 83 |
+
# Final
|
| 84 |
+
#
|
| 85 |
+
FROM node:${NODE_IMAGE_TAG} AS release
|
| 86 |
+
ENV PUPPETEER_SKIP_DOWNLOAD=True
|
| 87 |
+
# Quick fix for memory potential memory leaks
|
| 88 |
+
# https://github.com/devlikeapro/waha/issues/347
|
| 89 |
+
ENV NODE_OPTIONS="--max-old-space-size=16384"
|
| 90 |
+
ARG USE_BROWSER=chromium
|
| 91 |
+
ARG WHATSAPP_DEFAULT_ENGINE
|
| 92 |
+
|
| 93 |
+
RUN echo "USE_BROWSER=$USE_BROWSER"
|
| 94 |
+
|
| 95 |
+
# Install ffmpeg to generate previews for videos
|
| 96 |
+
RUN apt-get update && apt-get install -y ffmpeg --no-install-recommends && rm -rf /var/lib/apt/lists/*
|
| 97 |
+
|
| 98 |
+
# Image processing for thumbnails
|
| 99 |
+
RUN apt-get update \
|
| 100 |
+
&& apt-get install -y libvips \
|
| 101 |
+
&& rm -rf /var/lib/apt/lists/*
|
| 102 |
+
|
| 103 |
+
# Install zip and unzip - either for chromium or chrome
|
| 104 |
+
RUN if [ "$USE_BROWSER" = "chromium" ] || [ "$USE_BROWSER" = "chrome" ]; then \
|
| 105 |
+
apt-get update \
|
| 106 |
+
&& apt-get install -y zip unzip \
|
| 107 |
+
&& rm -rf /var/lib/apt/lists/*; \
|
| 108 |
+
fi
|
| 109 |
+
|
| 110 |
+
# Install wget - either for chromium or chrome
|
| 111 |
+
RUN if [ "$USE_BROWSER" = "chromium" ] || [ "$USE_BROWSER" = "chrome" ]; then \
|
| 112 |
+
apt-get update \
|
| 113 |
+
&& apt-get install -y wget \
|
| 114 |
+
&& rm -rf /var/lib/apt/lists/*; \
|
| 115 |
+
fi
|
| 116 |
+
|
| 117 |
+
# Install fonts if using either chromium or chrome
|
| 118 |
+
RUN if [ "$USE_BROWSER" = "chromium" ] || [ "$USE_BROWSER" = "chrome" ]; then \
|
| 119 |
+
apt-get update \
|
| 120 |
+
&& apt-get install -y \
|
| 121 |
+
fontconfig \
|
| 122 |
+
fonts-freefont-ttf \
|
| 123 |
+
fonts-gfs-neohellenic \
|
| 124 |
+
fonts-indic \
|
| 125 |
+
fonts-ipafont-gothic \
|
| 126 |
+
fonts-kacst \
|
| 127 |
+
fonts-liberation \
|
| 128 |
+
fonts-noto-cjk \
|
| 129 |
+
fonts-noto-color-emoji \
|
| 130 |
+
fonts-roboto \
|
| 131 |
+
fonts-thai-tlwg \
|
| 132 |
+
fonts-wqy-zenhei \
|
| 133 |
+
fonts-open-sans \
|
| 134 |
+
--no-install-recommends \
|
| 135 |
+
&& rm -rf /var/lib/apt/lists/*; \
|
| 136 |
+
fi
|
| 137 |
|
| 138 |
+
# Install xvfb, xauth
|
| 139 |
+
RUN if [ "$USE_BROWSER" = "chromium" ] || [ "$USE_BROWSER" = "chrome" ]; then \
|
| 140 |
+
apt-get update && apt-get install -y --no-install-recommends \
|
| 141 |
+
xvfb \
|
| 142 |
+
xauth \
|
| 143 |
+
libnss3 \
|
| 144 |
+
libxss1 \
|
| 145 |
+
libasound2 \
|
| 146 |
+
libatk-bridge2.0-0 \
|
| 147 |
+
libgtk-3-0 \
|
| 148 |
+
libdrm2 \
|
| 149 |
+
ca-certificates \
|
| 150 |
+
&& rm -rf /var/lib/apt/lists/*; \
|
| 151 |
+
fi
|
| 152 |
+
|
| 153 |
+
# Install Chromium
|
| 154 |
+
RUN if [ "$USE_BROWSER" = "chromium" ]; then \
|
| 155 |
+
apt-get update \
|
| 156 |
+
&& apt-get update \
|
| 157 |
+
&& apt-get install -y chromium \
|
| 158 |
+
--no-install-recommends \
|
| 159 |
+
&& rm -rf /var/lib/apt/lists/*; \
|
| 160 |
+
fi
|
| 161 |
+
|
| 162 |
+
# Install Chrome
|
| 163 |
+
# Available versions:
|
| 164 |
+
# https://www.ubuntuupdates.org/package/google_chrome/stable/main/base/google-chrome-stable
|
| 165 |
+
ARG CHROME_VERSION="137.0.7151.103-1"
|
| 166 |
+
RUN if [ "$USE_BROWSER" = "chrome" ]; then \
|
| 167 |
+
wget --no-verbose -O /tmp/chrome.deb https://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_${CHROME_VERSION}_amd64.deb \
|
| 168 |
+
&& apt-get update \
|
| 169 |
+
&& apt install -y /tmp/chrome.deb \
|
| 170 |
+
&& rm /tmp/chrome.deb \
|
| 171 |
+
&& rm -rf /var/lib/apt/lists/*; \
|
| 172 |
+
fi
|
| 173 |
+
|
| 174 |
+
# curl
|
| 175 |
+
RUN apt-get update \
|
| 176 |
+
&& apt-get install -y curl \
|
| 177 |
+
&& rm -rf /var/lib/apt/lists/*
|
| 178 |
+
|
| 179 |
+
# GOWS requirements
|
| 180 |
+
# libc6
|
| 181 |
+
RUN apt-get update \
|
| 182 |
+
&& apt-get install -y libc6 \
|
| 183 |
+
&& rm -rf /var/lib/apt/lists/*
|
| 184 |
+
|
| 185 |
+
# Install tini for proper init process
|
| 186 |
+
RUN apt-get update && apt-get install -y tini && rm -rf /var/lib/apt/lists/*
|
| 187 |
+
|
| 188 |
+
# Set the ENV for docker image
|
| 189 |
+
ENV WHATSAPP_DEFAULT_ENGINE=$WHATSAPP_DEFAULT_ENGINE
|
| 190 |
+
|
| 191 |
+
# Attach sources, install packages
|
| 192 |
+
WORKDIR /app
|
| 193 |
+
COPY package.json ./
|
| 194 |
+
COPY --from=build /git/node_modules ./node_modules
|
| 195 |
+
COPY --from=build /git/dist ./dist
|
| 196 |
+
COPY --from=dashboard /dashboard ./dist/dashboard
|
| 197 |
+
COPY --from=gows /go/gows/bin/gows /app/gows
|
| 198 |
+
ENV WAHA_GOWS_PATH=/app/gows
|
| 199 |
+
ENV WAHA_GOWS_SOCKET=/tmp/gows.sock
|
| 200 |
+
|
| 201 |
+
COPY entrypoint.sh /entrypoint.sh
|
| 202 |
+
|
| 203 |
+
# Chokidar options to monitor file changes
|
| 204 |
+
ENV CHOKIDAR_USEPOLLING=1
|
| 205 |
+
ENV CHOKIDAR_INTERVAL=5000
|
| 206 |
+
|
| 207 |
+
# WAHA variables
|
| 208 |
+
ENV WAHA_ZIPPER=ZIPUNZIP
|
| 209 |
+
|
| 210 |
+
# Run command, etc
|
| 211 |
+
EXPOSE 3000
|
| 212 |
+
# Use tini as init system to handle zombie processes properly
|
| 213 |
+
ENTRYPOINT ["/usr/bin/tini", "--"]
|
| 214 |
+
CMD ["/entrypoint.sh"]
|
LICENSE
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Apache License
|
| 2 |
+
Version 2.0, January 2004
|
| 3 |
+
http://www.apache.org/licenses/
|
| 4 |
+
|
| 5 |
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
| 6 |
+
|
| 7 |
+
1. Definitions.
|
| 8 |
+
|
| 9 |
+
"License" shall mean the terms and conditions for use, reproduction,
|
| 10 |
+
and distribution as defined by Sections 1 through 9 of this document.
|
| 11 |
+
|
| 12 |
+
"Licensor" shall mean the copyright owner or entity authorized by
|
| 13 |
+
the copyright owner that is granting the License.
|
| 14 |
+
|
| 15 |
+
"Legal Entity" shall mean the union of the acting entity and all
|
| 16 |
+
other entities that control, are controlled by, or are under common
|
| 17 |
+
control with that entity. For the purposes of this definition,
|
| 18 |
+
"control" means (i) the power, direct or indirect, to cause the
|
| 19 |
+
direction or management of such entity, whether by contract or
|
| 20 |
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
| 21 |
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
| 22 |
+
|
| 23 |
+
"You" (or "Your") shall mean an individual or Legal Entity
|
| 24 |
+
exercising permissions granted by this License.
|
| 25 |
+
|
| 26 |
+
"Source" form shall mean the preferred form for making modifications,
|
| 27 |
+
including but not limited to software source code, documentation
|
| 28 |
+
source, and configuration files.
|
| 29 |
+
|
| 30 |
+
"Object" form shall mean any form resulting from mechanical
|
| 31 |
+
transformation or translation of a Source form, including but
|
| 32 |
+
not limited to compiled object code, generated documentation,
|
| 33 |
+
and conversions to other media types.
|
| 34 |
+
|
| 35 |
+
"Work" shall mean the work of authorship, whether in Source or
|
| 36 |
+
Object form, made available under the License, as indicated by a
|
| 37 |
+
copyright notice that is included in or attached to the work
|
| 38 |
+
(an example is provided in the Appendix below).
|
| 39 |
+
|
| 40 |
+
"Derivative Works" shall mean any work, whether in Source or Object
|
| 41 |
+
form, that is based on (or derived from) the Work and for which the
|
| 42 |
+
editorial revisions, annotations, elaborations, or other modifications
|
| 43 |
+
represent, as a whole, an original work of authorship. For the purposes
|
| 44 |
+
of this License, Derivative Works shall not include works that remain
|
| 45 |
+
separable from, or merely link (or bind by name) to the interfaces of,
|
| 46 |
+
the Work and Derivative Works thereof.
|
| 47 |
+
|
| 48 |
+
"Contribution" shall mean any work of authorship, including
|
| 49 |
+
the original version of the Work and any modifications or additions
|
| 50 |
+
to that Work or Derivative Works thereof, that is intentionally
|
| 51 |
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
| 52 |
+
or by an individual or Legal Entity authorized to submit on behalf of
|
| 53 |
+
the copyright owner. For the purposes of this definition, "submitted"
|
| 54 |
+
means any form of electronic, verbal, or written communication sent
|
| 55 |
+
to the Licensor or its representatives, including but not limited to
|
| 56 |
+
communication on electronic mailing lists, source code control systems,
|
| 57 |
+
and issue tracking systems that are managed by, or on behalf of, the
|
| 58 |
+
Licensor for the purpose of discussing and improving the Work, but
|
| 59 |
+
excluding communication that is conspicuously marked or otherwise
|
| 60 |
+
designated in writing by the copyright owner as "Not a Contribution."
|
| 61 |
+
|
| 62 |
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
| 63 |
+
on behalf of whom a Contribution has been received by Licensor and
|
| 64 |
+
subsequently incorporated within the Work.
|
| 65 |
+
|
| 66 |
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
| 67 |
+
this License, each Contributor hereby grants to You a perpetual,
|
| 68 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
| 69 |
+
copyright license to reproduce, prepare Derivative Works of,
|
| 70 |
+
publicly display, publicly perform, sublicense, and distribute the
|
| 71 |
+
Work and such Derivative Works in Source or Object form.
|
| 72 |
+
|
| 73 |
+
3. Grant of Patent License. Subject to the terms and conditions of
|
| 74 |
+
this License, each Contributor hereby grants to You a perpetual,
|
| 75 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
| 76 |
+
(except as stated in this section) patent license to make, have made,
|
| 77 |
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
| 78 |
+
where such license applies only to those patent claims licensable
|
| 79 |
+
by such Contributor that are necessarily infringed by their
|
| 80 |
+
Contribution(s) alone or by combination of their Contribution(s)
|
| 81 |
+
with the Work to which such Contribution(s) was submitted. If You
|
| 82 |
+
institute patent litigation against any entity (including a
|
| 83 |
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
| 84 |
+
or a Contribution incorporated within the Work constitutes direct
|
| 85 |
+
or contributory patent infringement, then any patent licenses
|
| 86 |
+
granted to You under this License for that Work shall terminate
|
| 87 |
+
as of the date such litigation is filed.
|
| 88 |
+
|
| 89 |
+
4. Redistribution. You may reproduce and distribute copies of the
|
| 90 |
+
Work or Derivative Works thereof in any medium, with or without
|
| 91 |
+
modifications, and in Source or Object form, provided that You
|
| 92 |
+
meet the following conditions:
|
| 93 |
+
|
| 94 |
+
(a) You must give any other recipients of the Work or
|
| 95 |
+
Derivative Works a copy of this License; and
|
| 96 |
+
|
| 97 |
+
(b) You must cause any modified files to carry prominent notices
|
| 98 |
+
stating that You changed the files; and
|
| 99 |
+
|
| 100 |
+
(c) You must retain, in the Source form of any Derivative Works
|
| 101 |
+
that You distribute, all copyright, patent, trademark, and
|
| 102 |
+
attribution notices from the Source form of the Work,
|
| 103 |
+
excluding those notices that do not pertain to any part of
|
| 104 |
+
the Derivative Works; and
|
| 105 |
+
|
| 106 |
+
(d) If the Work includes a "NOTICE" text file as part of its
|
| 107 |
+
distribution, then any Derivative Works that You distribute must
|
| 108 |
+
include a readable copy of the attribution notices contained
|
| 109 |
+
within such NOTICE file, excluding those notices that do not
|
| 110 |
+
pertain to any part of the Derivative Works, in at least one
|
| 111 |
+
of the following places: within a NOTICE text file distributed
|
| 112 |
+
as part of the Derivative Works; within the Source form or
|
| 113 |
+
documentation, if provided along with the Derivative Works; or,
|
| 114 |
+
within a display generated by the Derivative Works, if and
|
| 115 |
+
wherever such third-party notices normally appear. The contents
|
| 116 |
+
of the NOTICE file are for informational purposes only and
|
| 117 |
+
do not modify the License. You may add Your own attribution
|
| 118 |
+
notices within Derivative Works that You distribute, alongside
|
| 119 |
+
or as an addendum to the NOTICE text from the Work, provided
|
| 120 |
+
that such additional attribution notices cannot be construed
|
| 121 |
+
as modifying the License.
|
| 122 |
+
|
| 123 |
+
You may add Your own copyright statement to Your modifications and
|
| 124 |
+
may provide additional or different license terms and conditions
|
| 125 |
+
for use, reproduction, or distribution of Your modifications, or
|
| 126 |
+
for any such Derivative Works as a whole, provided Your use,
|
| 127 |
+
reproduction, and distribution of the Work otherwise complies with
|
| 128 |
+
the conditions stated in this License.
|
| 129 |
+
|
| 130 |
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
| 131 |
+
any Contribution intentionally submitted for inclusion in the Work
|
| 132 |
+
by You to the Licensor shall be under the terms and conditions of
|
| 133 |
+
this License, without any additional terms or conditions.
|
| 134 |
+
Notwithstanding the above, nothing herein shall supersede or modify
|
| 135 |
+
the terms of any separate license agreement you may have executed
|
| 136 |
+
with Licensor regarding such Contributions.
|
| 137 |
+
|
| 138 |
+
6. Trademarks. This License does not grant permission to use the trade
|
| 139 |
+
names, trademarks, service marks, or product names of the Licensor,
|
| 140 |
+
except as required for reasonable and customary use in describing the
|
| 141 |
+
origin of the Work and reproducing the content of the NOTICE file.
|
| 142 |
+
|
| 143 |
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
| 144 |
+
agreed to in writing, Licensor provides the Work (and each
|
| 145 |
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
| 146 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
| 147 |
+
implied, including, without limitation, any warranties or conditions
|
| 148 |
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
| 149 |
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
| 150 |
+
appropriateness of using or redistributing the Work and assume any
|
| 151 |
+
risks associated with Your exercise of permissions under this License.
|
| 152 |
+
|
| 153 |
+
8. Limitation of Liability. In no event and under no legal theory,
|
| 154 |
+
whether in tort (including negligence), contract, or otherwise,
|
| 155 |
+
unless required by applicable law (such as deliberate and grossly
|
| 156 |
+
negligent acts) or agreed to in writing, shall any Contributor be
|
| 157 |
+
liable to You for damages, including any direct, indirect, special,
|
| 158 |
+
incidental, or consequential damages of any character arising as a
|
| 159 |
+
result of this License or out of the use or inability to use the
|
| 160 |
+
Work (including but not limited to damages for loss of goodwill,
|
| 161 |
+
work stoppage, computer failure or malfunction, or any and all
|
| 162 |
+
other commercial damages or losses), even if such Contributor
|
| 163 |
+
has been advised of the possibility of such damages.
|
| 164 |
+
|
| 165 |
+
9. Accepting Warranty or Additional Liability. While redistributing
|
| 166 |
+
the Work or Derivative Works thereof, You may choose to offer,
|
| 167 |
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
| 168 |
+
or other liability obligations and/or rights consistent with this
|
| 169 |
+
License. However, in accepting such obligations, You may act only
|
| 170 |
+
on Your own behalf and on Your sole responsibility, not on behalf
|
| 171 |
+
of any other Contributor, and only if You agree to indemnify,
|
| 172 |
+
defend, and hold each Contributor harmless for any liability
|
| 173 |
+
incurred by, or claims asserted against, such Contributor by reason
|
| 174 |
+
of your accepting any such warranty or additional liability.
|
| 175 |
+
|
| 176 |
+
END OF TERMS AND CONDITIONS
|
| 177 |
+
|
| 178 |
+
APPENDIX: How to apply the Apache License to your work.
|
| 179 |
+
|
| 180 |
+
To apply the Apache License to your work, attach the following
|
| 181 |
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
| 182 |
+
replaced with your own identifying information. (Don't include
|
| 183 |
+
the brackets!) The text should be enclosed in the appropriate
|
| 184 |
+
comment syntax for the file format. We also recommend that a
|
| 185 |
+
file or class name and description of purpose be included on the
|
| 186 |
+
same "printed page" as the copyright notice for easier
|
| 187 |
+
identification within third-party archives.
|
| 188 |
+
|
| 189 |
+
Copyright [yyyy] [name of copyright owner]
|
| 190 |
+
|
| 191 |
+
Licensed under the Apache License, Version 2.0 (the "License");
|
| 192 |
+
you may not use this file except in compliance with the License.
|
| 193 |
+
You may obtain a copy of the License at
|
| 194 |
+
|
| 195 |
+
http://www.apache.org/licenses/LICENSE-2.0
|
| 196 |
+
|
| 197 |
+
Unless required by applicable law or agreed to in writing, software
|
| 198 |
+
distributed under the License is distributed on an "AS IS" BASIS,
|
| 199 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 200 |
+
See the License for the specific language governing permissions and
|
| 201 |
+
limitations under the License.
|
Makefile
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
build-all: build-plus build-chrome build-gows build-noweb
|
| 2 |
+
|
| 3 |
+
build:
|
| 4 |
+
docker build . -t devlikeapro/waha
|
| 5 |
+
|
| 6 |
+
build-plus:
|
| 7 |
+
docker build . -t devlikeapro/waha-plus
|
| 8 |
+
|
| 9 |
+
build-chrome:
|
| 10 |
+
docker build . -t devlikeapro/waha-plus:chrome --build-arg USE_BROWSER=chrome
|
| 11 |
+
|
| 12 |
+
build-noweb:
|
| 13 |
+
docker build . -t devlikeapro/waha-plus:noweb --build-arg USE_BROWSER=none --build-arg WHATSAPP_DEFAULT_ENGINE=NOWEB
|
| 14 |
+
|
| 15 |
+
build-gows:
|
| 16 |
+
docker build . -t devlikeapro/waha-plus:gows --build-arg USE_BROWSER=none --build-arg WHATSAPP_DEFAULT_ENGINE=GOWS
|
| 17 |
+
|
| 18 |
+
build-ssh:
|
| 19 |
+
# check IMAGE provided
|
| 20 |
+
@[ "${IMAGE}" ] || ( echo "Add APP: make build-ssh image=devlikeapro/waha"; exit 1 );
|
| 21 |
+
eval $(ssh-agent) && \
|
| 22 |
+
ssh-add ~/.ssh/id_rsa && \
|
| 23 |
+
docker buildx build --ssh default=${SSH_AUTH_SOCK} . -t ${IMAGE} --build-arg USE_BROWSER=none
|
| 24 |
+
|
| 25 |
+
stop:
|
| 26 |
+
docker stop waha
|
| 27 |
+
|
| 28 |
+
clean: stop
|
| 29 |
+
sudo rm -rf .sessions
|
| 30 |
+
|
| 31 |
+
push:
|
| 32 |
+
docker push devlikeapro/waha
|
| 33 |
+
|
| 34 |
+
for-swagger:
|
| 35 |
+
WHATSAPP_SWAGGER_CONFIG_ADVANCED=true . ${NVM_DIR}/nvm.sh && nvm exec yarn start
|
| 36 |
+
|
| 37 |
+
up-noweb:
|
| 38 |
+
. ${NVM_DIR}/nvm.sh && nvm exec yarn up @adiwajshing/baileys@github:devlikeapro/Baileys#fork-master-2025-07-04
|
| 39 |
+
|
| 40 |
+
up-noweb-libsignal:
|
| 41 |
+
. ${NVM_DIR}/nvm.sh && nvm exec yarn up libsignal@github:devlikeapro/libsignal-node#fork-master
|
| 42 |
+
|
| 43 |
+
up-webjs:
|
| 44 |
+
. ${NVM_DIR}/nvm.sh && nvm exec yarn up whatsapp-web.js@github:devlikeapro/whatsapp-web.js#fork-main-2025-06-09
|
| 45 |
+
|
| 46 |
+
start-proxy:
|
| 47 |
+
docker run --rm -d --name squid-container -e TZ=UTC -p 3128:3128 ubuntu/squid:5.2-22.04_beta
|
| 48 |
+
|
| 49 |
+
proto-gows:
|
| 50 |
+
node scripts/gows-proto.js build --dir ../gows/proto
|
| 51 |
+
|
| 52 |
+
gows:
|
| 53 |
+
cd ../gows && \
|
| 54 |
+
export PATH=${HOME}/go/bin:${PATH} && \
|
| 55 |
+
make all
|
| 56 |
+
|
| 57 |
+
copy-dashboard:
|
| 58 |
+
cd ../waha-hub/ui && \
|
| 59 |
+
make copy-waha
|
| 60 |
+
|
docker-compose.yaml
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# https://waha.devlike.pro/docs/how-to/install/
|
| 2 |
+
services:
|
| 3 |
+
waha:
|
| 4 |
+
restart: always
|
| 5 |
+
# https://waha.devlike.pro/docs/how-to/engines/#docker-images
|
| 6 |
+
# https://portal.devlike.pro/docker-image
|
| 7 |
+
image: devlikeapro/waha-plus
|
| 8 |
+
# WAHA Core
|
| 9 |
+
# image: devlikeapro/waha:latest
|
| 10 |
+
|
| 11 |
+
# Add "dns" if you have a problem with resolving "web.whatsapp.com"
|
| 12 |
+
dns:
|
| 13 |
+
- 1.1.1.1
|
| 14 |
+
- 8.8.8.8
|
| 15 |
+
|
| 16 |
+
logging:
|
| 17 |
+
driver: 'json-file'
|
| 18 |
+
options:
|
| 19 |
+
max-size: '100m'
|
| 20 |
+
max-file: '10'
|
| 21 |
+
|
| 22 |
+
ports:
|
| 23 |
+
- '127.0.0.1:3000:3000/tcp'
|
| 24 |
+
|
| 25 |
+
volumes:
|
| 26 |
+
# Store sessions in the .sessions folder (comment it if you're using MongoDB)
|
| 27 |
+
- './sessions:/app/.sessions'
|
| 28 |
+
|
| 29 |
+
# Save media files
|
| 30 |
+
# https://waha.devlike.pro/docs/how-to/storages/#save-media-files-between-the-container-restarts
|
| 31 |
+
- './media:/app/.media'
|
| 32 |
+
|
| 33 |
+
env_file:
|
| 34 |
+
- .env
|
| 35 |
+
|
| 36 |
+
# NOTE: Only if you're using PostgreSQL to save sessions
|
| 37 |
+
# https://waha.devlike.pro/docs/how-to/storages/#media---postgresql
|
| 38 |
+
# postgres:
|
| 39 |
+
# image: postgres:17
|
| 40 |
+
# restart: always
|
| 41 |
+
# environment:
|
| 42 |
+
# POSTGRES_USER: postgres
|
| 43 |
+
# POSTGRES_PASSWORD: postgres
|
| 44 |
+
# POSTGRES_DB: postgres
|
| 45 |
+
# ports:
|
| 46 |
+
# - "127.0.0.1:5432:5432"
|
| 47 |
+
# volumes:
|
| 48 |
+
# - pg_data:/var/lib/postgresql/data
|
| 49 |
+
# command:
|
| 50 |
+
# - postgres
|
| 51 |
+
# - "-c"
|
| 52 |
+
# - "max_connections=3000"
|
| 53 |
+
# logging:
|
| 54 |
+
# driver: "json-file"
|
| 55 |
+
# options:
|
| 56 |
+
# max-size: "100m"
|
| 57 |
+
# max-file: "10"
|
| 58 |
+
|
| 59 |
+
# NOTE: Only if you're using MongoDB
|
| 60 |
+
# https://waha.devlike.pro/docs/how-to/storages/#sessions---mongodb
|
| 61 |
+
# Uncomment this block if you're using MongoDB
|
| 62 |
+
# mongodb:
|
| 63 |
+
# image: mongo
|
| 64 |
+
# container_name: mongodb
|
| 65 |
+
# ports:
|
| 66 |
+
# - '127.0.0.1:27017:27017/tcp'
|
| 67 |
+
# volumes:
|
| 68 |
+
# - mongodb_data:/data/db
|
| 69 |
+
# environment:
|
| 70 |
+
# - MONGO_INITDB_ROOT_USERNAME=mongouser
|
| 71 |
+
# - MONGO_INITDB_ROOT_PASSWORD=mongopassword
|
| 72 |
+
# logging:
|
| 73 |
+
# driver: "json-file"
|
| 74 |
+
# options:
|
| 75 |
+
# max-size: "100m"
|
| 76 |
+
# max-file: "10"
|
| 77 |
+
|
| 78 |
+
# NOTE: Only if you're using S3 to save media files
|
| 79 |
+
# https://waha.devlike.pro/docs/how-to/storages/#media---s3
|
| 80 |
+
# Uncomment this block if you're using AWS S3
|
| 81 |
+
# minio:
|
| 82 |
+
# image: quay.io/minio/minio
|
| 83 |
+
# container_name: minio
|
| 84 |
+
# restart: always
|
| 85 |
+
# ports:
|
| 86 |
+
# - '127.0.0.1:9000:9000'
|
| 87 |
+
# - '127.0.0.1:9001:9001'
|
| 88 |
+
# environment:
|
| 89 |
+
# MINIO_REGION: 'eu-west-2'
|
| 90 |
+
# MINIO_ROOT_USER: 'minioadmin'
|
| 91 |
+
# MINIO_ROOT_PASSWORD: 'minioadmin'
|
| 92 |
+
# volumes:
|
| 93 |
+
# - minio_data:/data
|
| 94 |
+
# command: server /data --console-address ":9001"
|
| 95 |
+
# logging:
|
| 96 |
+
# driver: "json-file"
|
| 97 |
+
# options:
|
| 98 |
+
# max-size: "100m"
|
| 99 |
+
# max-file: "10"
|
| 100 |
+
|
| 101 |
+
volumes:
|
| 102 |
+
mongodb_data: {}
|
| 103 |
+
minio_data: {}
|
| 104 |
+
pg_data: {}
|
docker-compose/chatwoot/.chatwoot.env
ADDED
|
@@ -0,0 +1,260 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Learn about the various environment variables at
|
| 2 |
+
# https://www.chatwoot.com/docs/self-hosted/configuration/environment-variables/#rails-production-variables
|
| 3 |
+
|
| 4 |
+
# Used to verify the integrity of signed cookies. so ensure a secure value is set
|
| 5 |
+
# SECRET_KEY_BASE should be alphanumeric. Avoid special characters or symbols.
|
| 6 |
+
# Use `rake secret` to generate this variable
|
| 7 |
+
SECRET_KEY_BASE=replace_with_lengthy_secure_hex
|
| 8 |
+
|
| 9 |
+
# Replace with the URL you are planning to use for your app
|
| 10 |
+
FRONTEND_URL=http://chatwoot:3009
|
| 11 |
+
# To use a dedicated URL for help center pages
|
| 12 |
+
# HELPCENTER_URL=http://0.0.0.0:3000
|
| 13 |
+
|
| 14 |
+
# If the variable is set, all non-authenticated pages would fallback to the default locale.
|
| 15 |
+
# Whenever a new account is created, the default language will be DEFAULT_LOCALE instead of en
|
| 16 |
+
# DEFAULT_LOCALE=en
|
| 17 |
+
|
| 18 |
+
# If you plan to use CDN for your assets, set Asset CDN Host
|
| 19 |
+
ASSET_CDN_HOST=
|
| 20 |
+
|
| 21 |
+
# Force all access to the app over SSL, default is set to false
|
| 22 |
+
FORCE_SSL=false
|
| 23 |
+
|
| 24 |
+
# This lets you control new sign ups on your chatwoot installation
|
| 25 |
+
# true : default option, allows sign ups
|
| 26 |
+
# false : disables all the end points related to sign ups
|
| 27 |
+
# api_only: disables the UI for signup, but you can create sign ups via the account apis
|
| 28 |
+
ENABLE_ACCOUNT_SIGNUP=false
|
| 29 |
+
|
| 30 |
+
# Redis config
|
| 31 |
+
# specify the configs via single URL or individual variables
|
| 32 |
+
# ref: https://www.iana.org/assignments/uri-schemes/prov/redis
|
| 33 |
+
# You can also use the following format for the URL: redis://:password@host:port/db_number
|
| 34 |
+
REDIS_URL=redis://redis:6379
|
| 35 |
+
# If you are using docker-compose, set this variable's value to be any string,
|
| 36 |
+
# which will be the password for the redis service running inside the docker-compose
|
| 37 |
+
# to make it secure
|
| 38 |
+
REDIS_PASSWORD=redis
|
| 39 |
+
# Redis Sentinel can be used by passing list of sentinel host and ports e,g. sentinel_host1:port1,sentinel_host2:port2
|
| 40 |
+
REDIS_SENTINELS=
|
| 41 |
+
# Redis sentinel master name is required when using sentinel, default value is "mymaster".
|
| 42 |
+
# You can find list of master using "SENTINEL masters" command
|
| 43 |
+
REDIS_SENTINEL_MASTER_NAME=
|
| 44 |
+
|
| 45 |
+
# By default Chatwoot will pass REDIS_PASSWORD as the password value for sentinels
|
| 46 |
+
# Use the following environment variable to customize passwords for sentinels.
|
| 47 |
+
# Use empty string if sentinels are configured with out passwords
|
| 48 |
+
# REDIS_SENTINEL_PASSWORD=
|
| 49 |
+
|
| 50 |
+
# Redis premium breakage in heroku fix
|
| 51 |
+
# enable the following configuration
|
| 52 |
+
# ref: https://github.com/chatwoot/chatwoot/issues/2420
|
| 53 |
+
# REDIS_OPENSSL_VERIFY_MODE=none
|
| 54 |
+
|
| 55 |
+
# Postgres Database config variables
|
| 56 |
+
# You can leave POSTGRES_DATABASE blank. The default name of
|
| 57 |
+
# the database in the production environment is chatwoot_production
|
| 58 |
+
POSTGRES_DATABASE=chatwoot
|
| 59 |
+
POSTGRES_HOST=postgres
|
| 60 |
+
POSTGRES_USERNAME=postgres
|
| 61 |
+
POSTGRES_PASSWORD=postgres
|
| 62 |
+
RAILS_ENV=development
|
| 63 |
+
# Changes the Postgres query timeout limit. The default is 14 seconds. Modify only when required.
|
| 64 |
+
# POSTGRES_STATEMENT_TIMEOUT=14s
|
| 65 |
+
RAILS_MAX_THREADS=5
|
| 66 |
+
|
| 67 |
+
# The email from which all outgoing emails are sent
|
| 68 |
+
# could user either `email@yourdomain.com` or `BrandName <email@yourdomain.com>`
|
| 69 |
+
MAILER_SENDER_EMAIL=Chatwoot <accounts@chatwoot.com>
|
| 70 |
+
|
| 71 |
+
#SMTP domain key is set up for HELO checking
|
| 72 |
+
SMTP_DOMAIN=chatwoot.com
|
| 73 |
+
# Set the value to "mailhog" if using docker-compose for development environments,
|
| 74 |
+
# Set the value as "localhost" or your SMTP address in other environments
|
| 75 |
+
# If SMTP_ADDRESS is empty, Chatwoot would try to use sendmail(postfix)
|
| 76 |
+
SMTP_ADDRESS=
|
| 77 |
+
SMTP_PORT=1025
|
| 78 |
+
SMTP_USERNAME=
|
| 79 |
+
SMTP_PASSWORD=
|
| 80 |
+
# plain,login,cram_md5
|
| 81 |
+
SMTP_AUTHENTICATION=
|
| 82 |
+
SMTP_ENABLE_STARTTLS_AUTO=true
|
| 83 |
+
# Can be: 'none', 'peer', 'client_once', 'fail_if_no_peer_cert', see http://api.rubyonrails.org/classes/ActionMailer/Base.html
|
| 84 |
+
SMTP_OPENSSL_VERIFY_MODE=peer
|
| 85 |
+
# Comment out the following environment variables if required by your SMTP server
|
| 86 |
+
# SMTP_TLS=
|
| 87 |
+
# SMTP_SSL=
|
| 88 |
+
# SMTP_OPEN_TIMEOUT
|
| 89 |
+
# SMTP_READ_TIMEOUT
|
| 90 |
+
|
| 91 |
+
# Mail Incoming
|
| 92 |
+
# This is the domain set for the reply emails when conversation continuity is enabled
|
| 93 |
+
MAILER_INBOUND_EMAIL_DOMAIN=
|
| 94 |
+
# Set this to the appropriate ingress channel with regards to incoming emails
|
| 95 |
+
# Possible values are :
|
| 96 |
+
# relay for Exim, Postfix, Qmail
|
| 97 |
+
# mailgun for Mailgun
|
| 98 |
+
# mandrill for Mandrill
|
| 99 |
+
# postmark for Postmark
|
| 100 |
+
# sendgrid for Sendgrid
|
| 101 |
+
RAILS_INBOUND_EMAIL_SERVICE=
|
| 102 |
+
# Use one of the following based on the email ingress service
|
| 103 |
+
# Ref: https://edgeguides.rubyonrails.org/action_mailbox_basics.html
|
| 104 |
+
# Set this to a password of your choice and use it in the Inbound webhook
|
| 105 |
+
RAILS_INBOUND_EMAIL_PASSWORD=
|
| 106 |
+
|
| 107 |
+
MAILGUN_INGRESS_SIGNING_KEY=
|
| 108 |
+
MANDRILL_INGRESS_API_KEY=
|
| 109 |
+
|
| 110 |
+
# Creating Your Inbound Webhook Instructions for Postmark and Sendgrid:
|
| 111 |
+
# Inbound webhook URL format:
|
| 112 |
+
# https://actionmailbox:[YOUR_RAILS_INBOUND_EMAIL_PASSWORD]@[YOUR_CHATWOOT_DOMAIN.COM]/rails/action_mailbox/[RAILS_INBOUND_EMAIL_SERVICE]/inbound_emails
|
| 113 |
+
# Note: Replace the values inside the brackets; do not include the brackets themselves.
|
| 114 |
+
# Example: https://actionmailbox:mYRandomPassword3@chatwoot.example.com/rails/action_mailbox/postmark/inbound_emails
|
| 115 |
+
# For Postmark
|
| 116 |
+
# Ensure the 'Include raw email content in JSON payload' checkbox is selected in the inbound webhook section.
|
| 117 |
+
|
| 118 |
+
# Storage
|
| 119 |
+
ACTIVE_STORAGE_SERVICE=local
|
| 120 |
+
|
| 121 |
+
# Amazon S3
|
| 122 |
+
# documentation: https://www.chatwoot.com/docs/configuring-s3-bucket-as-cloud-storage
|
| 123 |
+
S3_BUCKET_NAME=
|
| 124 |
+
AWS_ACCESS_KEY_ID=
|
| 125 |
+
AWS_SECRET_ACCESS_KEY=
|
| 126 |
+
AWS_REGION=
|
| 127 |
+
|
| 128 |
+
# Log settings
|
| 129 |
+
# Disable if you want to write logs to a file
|
| 130 |
+
RAILS_LOG_TO_STDOUT=true
|
| 131 |
+
LOG_LEVEL=info
|
| 132 |
+
LOG_SIZE=500
|
| 133 |
+
# Configure this environment variable if you want to use lograge instead of rails logger
|
| 134 |
+
#LOGRAGE_ENABLED=true
|
| 135 |
+
|
| 136 |
+
### This environment variables are only required if you are setting up social media channels
|
| 137 |
+
|
| 138 |
+
# Facebook
|
| 139 |
+
# documentation: https://www.chatwoot.com/docs/facebook-setup
|
| 140 |
+
FB_VERIFY_TOKEN=
|
| 141 |
+
FB_APP_SECRET=
|
| 142 |
+
FB_APP_ID=
|
| 143 |
+
|
| 144 |
+
# https://developers.facebook.com/docs/messenger-platform/instagram/get-started#app-dashboard
|
| 145 |
+
IG_VERIFY_TOKEN=
|
| 146 |
+
|
| 147 |
+
# Twitter
|
| 148 |
+
# documentation: https://www.chatwoot.com/docs/twitter-app-setup
|
| 149 |
+
TWITTER_APP_ID=
|
| 150 |
+
TWITTER_CONSUMER_KEY=
|
| 151 |
+
TWITTER_CONSUMER_SECRET=
|
| 152 |
+
TWITTER_ENVIRONMENT=
|
| 153 |
+
|
| 154 |
+
#slack integration
|
| 155 |
+
SLACK_CLIENT_ID=
|
| 156 |
+
SLACK_CLIENT_SECRET=
|
| 157 |
+
|
| 158 |
+
# Google OAuth
|
| 159 |
+
GOOGLE_OAUTH_CLIENT_ID=
|
| 160 |
+
GOOGLE_OAUTH_CLIENT_SECRET=
|
| 161 |
+
GOOGLE_OAUTH_CALLBACK_URL=
|
| 162 |
+
|
| 163 |
+
### Change this env variable only if you are using a custom build mobile app
|
| 164 |
+
## Mobile app env variables
|
| 165 |
+
IOS_APP_ID=L7YLMN4634.com.chatwoot.app
|
| 166 |
+
ANDROID_BUNDLE_ID=com.chatwoot.app
|
| 167 |
+
|
| 168 |
+
# https://developers.google.com/android/guides/client-auth (use keytool to print the fingerprint in the first section)
|
| 169 |
+
ANDROID_SHA256_CERT_FINGERPRINT=AC:73:8E:DE:EB:56:EA:CC:10:87:02:A7:65:37:7B:38:D4:5D:D4:53:F8:3B:FB:D3:C6:28:64:1D:AA:08:1E:D8
|
| 170 |
+
|
| 171 |
+
### Smart App Banner
|
| 172 |
+
# https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/PromotingAppswithAppBanners/PromotingAppswithAppBanners.html
|
| 173 |
+
# You can find your app-id in https://itunesconnect.apple.com
|
| 174 |
+
#IOS_APP_IDENTIFIER=1495796682
|
| 175 |
+
|
| 176 |
+
## Push Notification
|
| 177 |
+
## generate a new key value here : https://d3v.one/vapid-key-generator/
|
| 178 |
+
# VAPID_PUBLIC_KEY=
|
| 179 |
+
# VAPID_PRIVATE_KEY=
|
| 180 |
+
#
|
| 181 |
+
# for mobile apps
|
| 182 |
+
# FCM_SERVER_KEY=
|
| 183 |
+
|
| 184 |
+
### APM and Error Monitoring configurations
|
| 185 |
+
## Elastic APM
|
| 186 |
+
## https://www.elastic.co/guide/en/apm/agent/ruby/current/getting-started-rails.html
|
| 187 |
+
# ELASTIC_APM_SERVER_URL=
|
| 188 |
+
# ELASTIC_APM_SECRET_TOKEN=
|
| 189 |
+
|
| 190 |
+
## Sentry
|
| 191 |
+
# SENTRY_DSN=
|
| 192 |
+
|
| 193 |
+
|
| 194 |
+
## Scout
|
| 195 |
+
## https://scoutapm.com/docs/ruby/configuration
|
| 196 |
+
# SCOUT_KEY=YOURKEY
|
| 197 |
+
# SCOUT_NAME=YOURAPPNAME (Production)
|
| 198 |
+
# SCOUT_MONITOR=true
|
| 199 |
+
|
| 200 |
+
## NewRelic
|
| 201 |
+
# https://docs.newrelic.com/docs/agents/ruby-agent/configuration/ruby-agent-configuration/
|
| 202 |
+
# NEW_RELIC_LICENSE_KEY=
|
| 203 |
+
# Set this to true to allow newrelic apm to send logs.
|
| 204 |
+
# This is turned off by default.
|
| 205 |
+
# NEW_RELIC_APPLICATION_LOGGING_ENABLED=
|
| 206 |
+
|
| 207 |
+
## Datadog
|
| 208 |
+
## https://github.com/DataDog/dd-trace-rb/blob/master/docs/GettingStarted.md#environment-variables
|
| 209 |
+
# DD_TRACE_AGENT_URL=
|
| 210 |
+
|
| 211 |
+
# MaxMindDB API key to download GeoLite2 City database
|
| 212 |
+
# IP_LOOKUP_API_KEY=
|
| 213 |
+
|
| 214 |
+
## Rack Attack configuration
|
| 215 |
+
## To prevent and throttle abusive requests
|
| 216 |
+
# ENABLE_RACK_ATTACK=true
|
| 217 |
+
# RACK_ATTACK_LIMIT=300
|
| 218 |
+
# ENABLE_RACK_ATTACK_WIDGET_API=true
|
| 219 |
+
|
| 220 |
+
## Running chatwoot as an API only server
|
| 221 |
+
## setting this value to true will disable the frontend dashboard endpoints
|
| 222 |
+
# CW_API_ONLY_SERVER=false
|
| 223 |
+
|
| 224 |
+
## Development Only Config
|
| 225 |
+
# if you want to use letter_opener for local emails
|
| 226 |
+
# LETTER_OPENER=true
|
| 227 |
+
# meant to be used in github codespaces
|
| 228 |
+
# WEBPACKER_DEV_SERVER_PUBLIC=
|
| 229 |
+
|
| 230 |
+
# If you want to use official mobile app,
|
| 231 |
+
# the notifications would be relayed via a Chatwoot server
|
| 232 |
+
ENABLE_PUSH_RELAY_SERVER=true
|
| 233 |
+
|
| 234 |
+
# Stripe API key
|
| 235 |
+
STRIPE_SECRET_KEY=
|
| 236 |
+
STRIPE_WEBHOOK_SECRET=
|
| 237 |
+
|
| 238 |
+
# Set to true if you want to upload files to cloud storage using the signed url
|
| 239 |
+
# Make sure to follow https://edgeguides.rubyonrails.org/active_storage_overview.html#cross-origin-resource-sharing-cors-configuration on the cloud storage after setting this to true.
|
| 240 |
+
DIRECT_UPLOADS_ENABLED=
|
| 241 |
+
|
| 242 |
+
#MS OAUTH creds
|
| 243 |
+
AZURE_APP_ID=
|
| 244 |
+
AZURE_APP_SECRET=
|
| 245 |
+
|
| 246 |
+
## Advanced configurations
|
| 247 |
+
## Change these values to fine tune performance
|
| 248 |
+
# control the concurrency setting of sidekiq
|
| 249 |
+
# SIDEKIQ_CONCURRENCY=10
|
| 250 |
+
|
| 251 |
+
|
| 252 |
+
# AI powered features
|
| 253 |
+
## OpenAI key
|
| 254 |
+
# OPENAI_API_KEY=
|
| 255 |
+
|
| 256 |
+
# Housekeeping/Performance related configurations
|
| 257 |
+
# Set to true if you want to remove stale contact inboxes
|
| 258 |
+
# contact_inboxes with no conversation older than 90 days will be removed
|
| 259 |
+
# REMOVE_STALE_CONTACT_INBOX_JOB_STATUS=false
|
| 260 |
+
|
docker-compose/chatwoot/.waha.env
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# WAHA - WhatsApp HTTP API
|
| 2 |
+
#
|
| 3 |
+
# https://waha.devlike.pro/docs/how-to/config/
|
| 4 |
+
#
|
| 5 |
+
|
| 6 |
+
# ==================
|
| 7 |
+
# ===== COMMON =====
|
| 8 |
+
# ==================
|
| 9 |
+
# Base URL for the API (used for webhooks, file URLs, etc.)
|
| 10 |
+
WAHA_BASE_URL=http://waha:3000
|
| 11 |
+
|
| 12 |
+
# Server configuration (if you need to customize hostname/port)
|
| 13 |
+
# WHATSAPP_API_SCHEMA=http
|
| 14 |
+
# WHATSAPP_API_PORT=3000
|
| 15 |
+
# WHATSAPP_API_HOSTNAME=localhost
|
| 16 |
+
|
| 17 |
+
# ====================
|
| 18 |
+
# ===== SECURITY =====
|
| 19 |
+
# ====================
|
| 20 |
+
# WAHA Apps requires both sha and plain version
|
| 21 |
+
WAHA_API_KEY_PLAIN=00000000000000000000000000000000
|
| 22 |
+
WAHA_API_KEY=sha512:98b6d128682e280b74b324ca82a6bae6e8a3f7174e0605bfd52eb9948fad8984854ec08f7652f32055c4a9f12b69add4850481d9503a7f2225501671d6124648
|
| 23 |
+
WAHA_DASHBOARD_USERNAME=admin
|
| 24 |
+
WAHA_DASHBOARD_PASSWORD=11111111111111111111111111111111
|
| 25 |
+
WHATSAPP_SWAGGER_USERNAME=admin
|
| 26 |
+
WHATSAPP_SWAGGER_PASSWORD=11111111111111111111111111111111
|
| 27 |
+
|
| 28 |
+
WAHA_DASHBOARD_ENABLED=True
|
| 29 |
+
WHATSAPP_SWAGGER_ENABLED=True
|
| 30 |
+
|
| 31 |
+
# WhatsApp engine (WEBJS is default, GOWS or NOWEB for better performance)
|
| 32 |
+
WHATSAPP_DEFAULT_ENGINE=GOWS
|
| 33 |
+
|
| 34 |
+
# =================
|
| 35 |
+
# ===== APPS ======
|
| 36 |
+
# =================
|
| 37 |
+
WAHA_APPS_ENABLED=True
|
| 38 |
+
REDIS_URL=redis://:redis@redis:6379
|
| 39 |
+
|
| 40 |
+
# ===================
|
| 41 |
+
# ===== LOGGING =====
|
| 42 |
+
# ===================
|
| 43 |
+
# Log format: JSON (for log management systems) or PRETTY (for development)
|
| 44 |
+
WAHA_LOG_FORMAT=JSON
|
| 45 |
+
|
| 46 |
+
# Log level: info, debug, error, warn
|
| 47 |
+
WAHA_LOG_LEVEL=info
|
| 48 |
+
|
| 49 |
+
# Don't print QR codes in logs
|
| 50 |
+
WAHA_PRINT_QR=False
|
| 51 |
+
|
| 52 |
+
# =========================
|
| 53 |
+
# ===== MEDIA STORAGE =====
|
| 54 |
+
# =========================
|
| 55 |
+
# Local storage (default)
|
| 56 |
+
WAHA_MEDIA_STORAGE=LOCAL
|
| 57 |
+
WHATSAPP_FILES_LIFETIME=1800
|
| 58 |
+
WHATSAPP_FILES_FOLDER=/app/.media
|
| 59 |
+
|
| 60 |
+
# Media download settings
|
| 61 |
+
# WHATSAPP_DOWNLOAD_MEDIA=true
|
| 62 |
+
# WHATSAPP_FILES_MIMETYPES=image/jpeg,image/png
|
| 63 |
+
|
| 64 |
+
# S3 storage (uncomment to use)
|
| 65 |
+
# WAHA_MEDIA_STORAGE=S3
|
| 66 |
+
# WAHA_S3_REGION=eu-west-2
|
| 67 |
+
# WAHA_S3_BUCKET=waha
|
| 68 |
+
# WAHA_S3_ACCESS_KEY_ID=minioadmin
|
| 69 |
+
# WAHA_S3_SECRET_ACCESS_KEY=minioadmin
|
| 70 |
+
# WAHA_S3_ENDPOINT=http://minio:9000
|
| 71 |
+
# WAHA_S3_FORCE_PATH_STYLE=True
|
| 72 |
+
# WAHA_S3_PROXY_FILES=True
|
| 73 |
+
|
| 74 |
+
# PostgreSQL storage (uncomment to use)
|
| 75 |
+
# WAHA_MEDIA_STORAGE=POSTGRESQL
|
| 76 |
+
# WAHA_MEDIA_POSTGRESQL_URL=postgres://postgres:postgres@postgres:5432/postgres?sslmode=disable
|
| 77 |
+
|
| 78 |
+
# ===========================
|
| 79 |
+
# ===== SESSION STORAGE =====
|
| 80 |
+
# ===========================
|
| 81 |
+
# PostgreSQL for sessions (uncomment to use)
|
| 82 |
+
WHATSAPP_SESSIONS_POSTGRESQL_URL=postgres://postgres:postgres@postgres:5432/postgres?sslmode=disable
|
| 83 |
+
|
| 84 |
+
# MongoDB for sessions (uncomment to use)
|
| 85 |
+
# WHATSAPP_SESSIONS_MONGO_URL=mongodb://mongouser:mongopassword@mongodb:27017
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
# ==================================
|
| 89 |
+
# ===== ADVANCED CONFIGURATION =====
|
| 90 |
+
# ==================================
|
| 91 |
+
|
| 92 |
+
# Timezone for screenshots and logs
|
| 93 |
+
# TZ=Europe/Dublin
|
| 94 |
+
|
| 95 |
+
# Session management
|
| 96 |
+
# WHATSAPP_START_SESSION=session1,session2
|
| 97 |
+
# WHATSAPP_RESTART_ALL_SESSIONS=False
|
| 98 |
+
|
| 99 |
+
# Webhooks
|
| 100 |
+
# WHATSAPP_HOOK_URL=https://webhook.site/11111111-1111-1111-1111-11111111
|
| 101 |
+
# WHATSAPP_HOOK_EVENTS=session.status,message,message.reaction
|
| 102 |
+
|
| 103 |
+
# Proxy configuration
|
| 104 |
+
# WHATSAPP_PROXY_SERVER=proxy.example.com:3128
|
| 105 |
+
# WHATSAPP_PROXY_SERVER_USERNAME=user
|
| 106 |
+
# WHATSAPP_PROXY_SERVER_PASSWORD=pass
|
| 107 |
+
|
| 108 |
+
# HTTPS configuration
|
| 109 |
+
# !DEPRECATED!
|
| 110 |
+
# Setup nginx reverse proxy to handle TLS connection
|
| 111 |
+
# using Let's encrypt or self-issued certificate
|
| 112 |
+
# WAHA_HTTPS_ENABLED=true
|
| 113 |
+
# WAHA_HTTPS_PATH_KEY=/etc/letsencrypt/live/waha.example.pro/privkey.pem
|
| 114 |
+
# WAHA_HTTPS_PATH_CERT=/etc/letsencrypt/live/waha.example.pro/cert.pem
|
| 115 |
+
# WAHA_HTTPS_PATH_CA=/etc/letsencrypt/live/waha.example.pro/chain.pem
|
docker-compose/chatwoot/docker-compose.yaml
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
services:
|
| 2 |
+
waha:
|
| 3 |
+
restart: always
|
| 4 |
+
image: devlikeapro/waha-plus
|
| 5 |
+
ports:
|
| 6 |
+
- '127.0.0.1:3000:3000/tcp'
|
| 7 |
+
volumes:
|
| 8 |
+
- './sessions:/app/.sessions' # required for WAHA Core only
|
| 9 |
+
- './media:/app/.media'
|
| 10 |
+
env_file:
|
| 11 |
+
- .waha.env
|
| 12 |
+
depends_on:
|
| 13 |
+
- postgres
|
| 14 |
+
- redis
|
| 15 |
+
- chatwoot
|
| 16 |
+
- chatwoot-sidekiq
|
| 17 |
+
logging:
|
| 18 |
+
driver: 'json-file'
|
| 19 |
+
options:
|
| 20 |
+
max-size: '100m'
|
| 21 |
+
max-file: '10'
|
| 22 |
+
dns:
|
| 23 |
+
- 1.1.1.1
|
| 24 |
+
- 8.8.8.8
|
| 25 |
+
|
| 26 |
+
base: &base
|
| 27 |
+
image: chatwoot/chatwoot:v4.3.0
|
| 28 |
+
env_file: .chatwoot.env ## Change this file for customized env variables
|
| 29 |
+
volumes:
|
| 30 |
+
- chatwoot_storage:/app/storage
|
| 31 |
+
logging:
|
| 32 |
+
driver: 'json-file'
|
| 33 |
+
options:
|
| 34 |
+
max-size: '100m'
|
| 35 |
+
max-file: '10'
|
| 36 |
+
|
| 37 |
+
chatwoot:
|
| 38 |
+
<<: *base
|
| 39 |
+
depends_on:
|
| 40 |
+
- postgres
|
| 41 |
+
- redis
|
| 42 |
+
ports:
|
| 43 |
+
- '127.0.0.1:3009:3009'
|
| 44 |
+
environment:
|
| 45 |
+
- NODE_ENV=production
|
| 46 |
+
- RAILS_ENV=production
|
| 47 |
+
- INSTALLATION_ENV=docker
|
| 48 |
+
entrypoint: docker/entrypoints/rails.sh
|
| 49 |
+
command: ['bundle', 'exec', 'rails', 's', '-p', '3009', '-b', '0.0.0.0']
|
| 50 |
+
restart: always
|
| 51 |
+
|
| 52 |
+
chatwoot-sidekiq:
|
| 53 |
+
<<: *base
|
| 54 |
+
depends_on:
|
| 55 |
+
- postgres
|
| 56 |
+
- redis
|
| 57 |
+
environment:
|
| 58 |
+
- NODE_ENV=production
|
| 59 |
+
- RAILS_ENV=production
|
| 60 |
+
- INSTALLATION_ENV=docker
|
| 61 |
+
command: ['bundle', 'exec', 'sidekiq', '-C', 'config/sidekiq.yml']
|
| 62 |
+
restart: always
|
| 63 |
+
|
| 64 |
+
postgres:
|
| 65 |
+
image: pgvector/pgvector:pg16
|
| 66 |
+
restart: always
|
| 67 |
+
ports:
|
| 68 |
+
- '127.0.0.1:5432:5432'
|
| 69 |
+
volumes:
|
| 70 |
+
- chatwoot_pg_data:/var/lib/postgresql/data
|
| 71 |
+
environment:
|
| 72 |
+
- POSTGRES_DB=chatwoot
|
| 73 |
+
- POSTGRES_USER=postgres
|
| 74 |
+
# Please provide your own password.
|
| 75 |
+
- POSTGRES_PASSWORD=postgres
|
| 76 |
+
- POSTGRES_HOST_AUTH_METHOD=trust
|
| 77 |
+
|
| 78 |
+
redis:
|
| 79 |
+
image: redis:alpine
|
| 80 |
+
restart: always
|
| 81 |
+
command:
|
| 82 |
+
- 'sh'
|
| 83 |
+
- '-c'
|
| 84 |
+
- >
|
| 85 |
+
redis-server --bind 0.0.0.0 --port 6379 --requirepass
|
| 86 |
+
${REDIS_PASSWORD:-redis} --timeout 300 --tcp-keepalive 60 --save 900 1
|
| 87 |
+
--save 300 10 --save 60 10000 --appendonly yes --appendfsync everysec
|
| 88 |
+
env_file: .chatwoot.env
|
| 89 |
+
volumes:
|
| 90 |
+
- chatwoot_redis:/data
|
| 91 |
+
ports:
|
| 92 |
+
- '127.0.0.1:6379:6379'
|
| 93 |
+
|
| 94 |
+
volumes:
|
| 95 |
+
chatwoot_pg_data: {}
|
| 96 |
+
chatwoot_redis: {}
|
| 97 |
+
chatwoot_storage: {}
|
docker-compose/docker-compose.workers.yaml
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# https://waha.devlike.pro/docs/how-to/install/
|
| 2 |
+
services:
|
| 3 |
+
# Just to connect
|
| 4 |
+
waha-dashboard:
|
| 5 |
+
restart: unless-stopped
|
| 6 |
+
image: devlikeapro/waha-plus:latest
|
| 7 |
+
ports:
|
| 8 |
+
- '127.0.0.1:3000:3000/tcp'
|
| 9 |
+
env_file:
|
| 10 |
+
- .env
|
| 11 |
+
environment:
|
| 12 |
+
- WAHA_WORKER_ID=waha-dashboard
|
| 13 |
+
|
| 14 |
+
waha1:
|
| 15 |
+
restart: unless-stopped
|
| 16 |
+
image: devlikeapro/waha-plus:latest
|
| 17 |
+
ports:
|
| 18 |
+
- '127.0.0.1:3001:3000/tcp'
|
| 19 |
+
volumes:
|
| 20 |
+
- './media:/app/.media'
|
| 21 |
+
env_file:
|
| 22 |
+
- .env
|
| 23 |
+
environment:
|
| 24 |
+
- WAHA_WORKER_ID=waha1
|
| 25 |
+
- WAHA_BASE_URL=http://localhost:3001
|
| 26 |
+
- WHATSAPP_DEFAULT_ENGINE=NOWEB
|
| 27 |
+
# MongoDB
|
| 28 |
+
- WHATSAPP_SESSIONS_MONGO_URL=mongodb://mongodb:27017
|
| 29 |
+
# S3
|
| 30 |
+
- WAHA_MEDIA_STORAGE=S3
|
| 31 |
+
- WAHA_S3_REGION=eu-west-2
|
| 32 |
+
- WAHA_S3_BUCKET=waha
|
| 33 |
+
- WAHA_S3_ACCESS_KEY_ID=minioadmin
|
| 34 |
+
- WAHA_S3_SECRET_ACCESS_KEY=minioadmin
|
| 35 |
+
- WAHA_S3_ENDPOINT=http://minio:9000 # Not required if you're using AWS S3
|
| 36 |
+
- WAHA_S3_FORCE_PATH_STYLE=True # Required for Minio
|
| 37 |
+
- WAHA_S3_PROXY_FILES=True # Required for docker-compose setup
|
| 38 |
+
|
| 39 |
+
waha2:
|
| 40 |
+
restart: unless-stopped
|
| 41 |
+
image: devlikeapro/waha-plus:latest
|
| 42 |
+
ports:
|
| 43 |
+
- '127.0.0.1:3002:3000/tcp'
|
| 44 |
+
volumes:
|
| 45 |
+
- './media:/app/.media'
|
| 46 |
+
env_file:
|
| 47 |
+
- .env
|
| 48 |
+
environment:
|
| 49 |
+
- WAHA_WORKER_ID=waha2
|
| 50 |
+
- WAHA_BASE_URL=http://localhost:3002
|
| 51 |
+
- WHATSAPP_DEFAULT_ENGINE=NOWEB
|
| 52 |
+
# MongoDB
|
| 53 |
+
- WHATSAPP_SESSIONS_MONGO_URL=mongodb://mongodb:27017
|
| 54 |
+
# S3
|
| 55 |
+
- WAHA_MEDIA_STORAGE=S3
|
| 56 |
+
- WAHA_S3_REGION=eu-west-2
|
| 57 |
+
- WAHA_S3_BUCKET=waha
|
| 58 |
+
- WAHA_S3_ACCESS_KEY_ID=minioadmin
|
| 59 |
+
- WAHA_S3_SECRET_ACCESS_KEY=minioadmin
|
| 60 |
+
- WAHA_S3_ENDPOINT=http://minio:9000 # Not required if you're using AWS S3
|
| 61 |
+
- WAHA_S3_FORCE_PATH_STYLE=True # Required for Minio
|
| 62 |
+
- WAHA_S3_PROXY_FILES=True # Required for docker-compose setup
|
| 63 |
+
|
| 64 |
+
# NOTE: Only if you're using MongoDB
|
| 65 |
+
# https://waha.devlike.pro/docs/how-to/storages/#sessions---mongodb
|
| 66 |
+
# Comment this block if you're not using MongoDB
|
| 67 |
+
mongodb:
|
| 68 |
+
image: mongo
|
| 69 |
+
container_name: mongodb
|
| 70 |
+
ports:
|
| 71 |
+
- '127.0.0.1:27017:27017/tcp'
|
| 72 |
+
volumes:
|
| 73 |
+
- mongodb_data:/data/db
|
| 74 |
+
restart: always
|
| 75 |
+
|
| 76 |
+
# NOTE: Only if you're using S3 to save media files
|
| 77 |
+
# https://waha.devlike.pro/docs/how-to/storages/#media---s3
|
| 78 |
+
# Comment this block if you're using S3
|
| 79 |
+
minio:
|
| 80 |
+
image: quay.io/minio/minio
|
| 81 |
+
container_name: minio
|
| 82 |
+
restart: always
|
| 83 |
+
ports:
|
| 84 |
+
- '127.0.0.1:9000:9000'
|
| 85 |
+
- '127.0.0.1:9001:9001'
|
| 86 |
+
environment:
|
| 87 |
+
MINIO_REGION: 'eu-west-2'
|
| 88 |
+
MINIO_ROOT_USER: 'minioadmin'
|
| 89 |
+
MINIO_ROOT_PASSWORD: 'minioadmin'
|
| 90 |
+
volumes:
|
| 91 |
+
- minio_data:/data
|
| 92 |
+
command: server /data --console-address ":9001"
|
| 93 |
+
|
| 94 |
+
volumes:
|
| 95 |
+
# NOTE: Only if you're using MongoDB
|
| 96 |
+
mongodb_data: {}
|
| 97 |
+
minio_data: {}
|
docker-compose/n8n/docker-compose.yaml
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
services:
|
| 2 |
+
waha:
|
| 3 |
+
restart: always
|
| 4 |
+
container_name: waha
|
| 5 |
+
# image: devlikeapro/waha:latest
|
| 6 |
+
image: devlikeapro/waha-plus:latest
|
| 7 |
+
ports:
|
| 8 |
+
- '3000:3000/tcp'
|
| 9 |
+
volumes:
|
| 10 |
+
- './sessions:/app/.sessions'
|
| 11 |
+
- './media:/app/.media'
|
| 12 |
+
environment:
|
| 13 |
+
- WAHA_API_KEY=321
|
| 14 |
+
- WAHA_DASHBOARD_USERNAME=admin
|
| 15 |
+
- WAHA_DASHBOARD_PASSWORD=admin
|
| 16 |
+
- WHATSAPP_DEFAULT_ENGINE=WEBJS
|
| 17 |
+
- WAHA_PRINT_QR=False
|
| 18 |
+
- WAHA_MEDIA_STORAGE=LOCAL
|
| 19 |
+
- WHATSAPP_FILES_LIFETIME=0
|
| 20 |
+
- WHATSAPP_FILES_FOLDER=/app/.media
|
| 21 |
+
|
| 22 |
+
n8n:
|
| 23 |
+
image: docker.n8n.io/n8nio/n8n
|
| 24 |
+
container_name: n8n
|
| 25 |
+
restart: always
|
| 26 |
+
environment:
|
| 27 |
+
- WEBHOOK_URL=http://n8n:5678
|
| 28 |
+
ports:
|
| 29 |
+
- '5678:5678'
|
| 30 |
+
volumes:
|
| 31 |
+
- n8n_data:/home/node/.n8n
|
| 32 |
+
|
| 33 |
+
volumes:
|
| 34 |
+
n8n_data: {}
|
docker-compose/test/docker-compose.yaml
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
services:
|
| 2 |
+
waha:
|
| 3 |
+
# Check available Docker images:
|
| 4 |
+
# https://waha.devlike.pro/docs/how-to/engines/#docker-images
|
| 5 |
+
image: devlikeapro/waha
|
| 6 |
+
container_name: waha
|
| 7 |
+
ports:
|
| 8 |
+
- '3000:3000/tcp'
|
| 9 |
+
environment:
|
| 10 |
+
# Environment variables from https://waha.devlike.pro/docs/how-to/config/
|
| 11 |
+
# https://docs.webhook.site/
|
| 12 |
+
- WHATSAPP_HOOK_URL=https://webhook.site/11111111-1111-1111-1111-11111111
|
| 13 |
+
- WHATSAPP_HOOK_EVENTS=message
|
| 14 |
+
- WHATSAPP_DEFAULT_ENGINE=WEBJS
|
| 15 |
+
restart: always
|
| 16 |
+
|
| 17 |
+
waha-plus:
|
| 18 |
+
# Check available Docker images:
|
| 19 |
+
# https://waha.devlike.pro/docs/how-to/engines/#docker-images
|
| 20 |
+
image: devlikeapro/waha-plus:chrome
|
| 21 |
+
container_name: waha-plus
|
| 22 |
+
ports:
|
| 23 |
+
- '3000:3000/tcp'
|
| 24 |
+
volumes:
|
| 25 |
+
- './.sessions:/app/.sessions'
|
| 26 |
+
environment:
|
| 27 |
+
# Environment variables from https://waha.devlike.pro/docs/how-to/config/
|
| 28 |
+
# - WHATSAPP_HOOK_URL=https://webhook.site/11111111-1111-1111-1111-11111111
|
| 29 |
+
# - WHATSAPP_HOOK_EVENTS=message
|
| 30 |
+
# - WHATSAPP_API_HOSTNAME=localhost
|
| 31 |
+
- WHATSAPP_DEFAULT_ENGINE=WEBJS
|
| 32 |
+
- WAHA_API_KEY=321
|
| 33 |
+
# Username and password for Swagger
|
| 34 |
+
- WHATSAPP_SWAGGER_USERNAME=swagger
|
| 35 |
+
- WHATSAPP_SWAGGER_PASSWORD=admin
|
| 36 |
+
# Username and password for WAHA Dashboard
|
| 37 |
+
# you can use the same username and password for both Swagger and Dashboard
|
| 38 |
+
# Default - waha / waha
|
| 39 |
+
- WAHA_DASHBOARD_USERNAME=admin
|
| 40 |
+
- WAHA_DASHBOARD_PASSWORD=admin
|
| 41 |
+
# Engine specific environment variables
|
| 42 |
+
# - WAHA_WEBJS_WEB_VERSION=2.2412.54-videofix
|
| 43 |
+
restart: always
|
| 44 |
+
|
| 45 |
+
waha-plus--mongodb:
|
| 46 |
+
# Check available Docker images:
|
| 47 |
+
# https://waha.devlike.pro/docs/how-to/engines/#docker-images
|
| 48 |
+
image: devlikeapro/waha-plus:chrome
|
| 49 |
+
container_name: waha-plus--mongodb
|
| 50 |
+
ports:
|
| 51 |
+
- '3000:3000/tcp'
|
| 52 |
+
volumes:
|
| 53 |
+
- './.sessions:/app/.sessions'
|
| 54 |
+
environment:
|
| 55 |
+
# Environment variables from https://waha.devlike.pro/docs/how-to/config/
|
| 56 |
+
# - WHATSAPP_HOOK_URL=https://webhook.site/11111111-1111-1111-1111-11111111
|
| 57 |
+
# - WHATSAPP_HOOK_EVENTS=message
|
| 58 |
+
# - WAHA_API_KEY=321
|
| 59 |
+
# - WHATSAPP_SWAGGER_USERNAME=admin
|
| 60 |
+
# - WHATSAPP_SWAGGER_PASSWORD=123
|
| 61 |
+
# - WAHA_DASHBOARD_USERNAME=admin
|
| 62 |
+
# - WAHA_DASHBOARD_PASSWORD=123
|
| 63 |
+
# - WHATSAPP_API_HOSTNAME=localhost
|
| 64 |
+
- WHATSAPP_DEFAULT_ENGINE=WEBJS
|
| 65 |
+
- WHATSAPP_SESSIONS_MONGO_URL=mongodb://mongodb:27017
|
| 66 |
+
restart: always
|
| 67 |
+
|
| 68 |
+
# Let's Encrypt + Certbot
|
| 69 |
+
# https://waha.devlike.pro/docs/how-to/security/#https
|
| 70 |
+
waha-https--certbot:
|
| 71 |
+
image: devlikeapro/waha-plus
|
| 72 |
+
restart: unless-stopped
|
| 73 |
+
ports:
|
| 74 |
+
- '3000:3000'
|
| 75 |
+
volumes:
|
| 76 |
+
- './.sessions:/app/.sessions'
|
| 77 |
+
- '/etc/letsencrypt:/etc/letsencrypt'
|
| 78 |
+
environment:
|
| 79 |
+
- DOMAIN=waha.example.pro
|
| 80 |
+
- WHATSAPP_API_HOSTNAME=${DOMAIN}
|
| 81 |
+
- WAHA_HTTPS_ENABLED=true
|
| 82 |
+
- WAHA_HTTPS_PATH_KEY=/etc/letsencrypt/live/${DOMAIN}/privkey.pem
|
| 83 |
+
- WAHA_HTTPS_PATH_CERT=/etc/letsencrypt/live/${DOMAIN}/cert.pem
|
| 84 |
+
- WAHA_HTTPS_PATH_CA=/etc/letsencrypt/live/${DOMAIN}/chain.pem
|
| 85 |
+
|
| 86 |
+
# Self-signed certificates example
|
| 87 |
+
# https://waha.devlike.pro/docs/how-to/security/#https
|
| 88 |
+
waha-https--self-signed:
|
| 89 |
+
image: devlikeapro/waha-plus
|
| 90 |
+
restart: unless-stopped
|
| 91 |
+
ports:
|
| 92 |
+
- '3000:3000'
|
| 93 |
+
volumes:
|
| 94 |
+
- './.sessions:/app/.sessions'
|
| 95 |
+
- './.secrets:/app/.secrets'
|
| 96 |
+
environment:
|
| 97 |
+
- WAHA_HTTPS_ENABLED=true
|
| 98 |
+
- WAHA_HTTPS_PATH_KEY=.secrets/privkey.pem
|
| 99 |
+
- WAHA_HTTPS_PATH_CERT=.secrets/cert.pem
|
| 100 |
+
- WAHA_HTTPS_PATH_CA=.secrets/chain.pem
|
| 101 |
+
|
| 102 |
+
mongodb:
|
| 103 |
+
image: mongo
|
| 104 |
+
container_name: mongodb
|
| 105 |
+
ports:
|
| 106 |
+
- '27017:27017/tcp'
|
| 107 |
+
volumes:
|
| 108 |
+
- mongodb_data:/data/db
|
| 109 |
+
restart: always
|
| 110 |
+
|
| 111 |
+
volumes:
|
| 112 |
+
mongodb_data: {}
|
entrypoint.sh
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/sh
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
#
|
| 5 |
+
# Calculate UV_THREADPOOL_SIZE based on number of CPUs
|
| 6 |
+
#
|
| 7 |
+
# Try to get CPU count using Node.js, fallback to 1 if it fails
|
| 8 |
+
cpus=$(node -e "const os = require('os'); console.log(os.cpus().length);" 2>/dev/null) || cpus=1
|
| 9 |
+
# Make sure cpus is a number, default to 1 if not
|
| 10 |
+
case $cpus in
|
| 11 |
+
''|*[!0-9]*) cpus=1 ;;
|
| 12 |
+
esac
|
| 13 |
+
uv_threadpool_size=$(($cpus * 2))
|
| 14 |
+
|
| 15 |
+
# Check if uv_threadpool_size is less than 4 (default), set it to 4 if it is
|
| 16 |
+
if [ "$uv_threadpool_size" -lt 4 ]; then
|
| 17 |
+
uv_threadpool_size=4
|
| 18 |
+
fi
|
| 19 |
+
|
| 20 |
+
# Set UV_THREADPOOL_SIZE as an environment variable
|
| 21 |
+
export UV_THREADPOOL_SIZE="${UV_THREADPOOL_SIZE:-$uv_threadpool_size}"
|
| 22 |
+
|
| 23 |
+
#
|
| 24 |
+
# Handle API key hashing
|
| 25 |
+
#
|
| 26 |
+
# Save WHATSAPP_API_KEY or WAHA_API_KEY in a variable (WHATSAPP_API_KEY has priority)
|
| 27 |
+
if [ -n "$WHATSAPP_API_KEY" ]; then
|
| 28 |
+
key="$WHATSAPP_API_KEY"
|
| 29 |
+
elif [ -n "$WAHA_API_KEY" ]; then
|
| 30 |
+
key="$WAHA_API_KEY"
|
| 31 |
+
fi
|
| 32 |
+
|
| 33 |
+
# Unset both environment variables
|
| 34 |
+
unset WHATSAPP_API_KEY
|
| 35 |
+
unset WAHA_API_KEY
|
| 36 |
+
|
| 37 |
+
# Process the key if it exists
|
| 38 |
+
if [ -n "$key" ]; then
|
| 39 |
+
# Check if key is already hashed
|
| 40 |
+
if echo "$key" | grep -q "^sha512:"; then
|
| 41 |
+
# If already hashed, use it as is
|
| 42 |
+
export WAHA_API_KEY="$key"
|
| 43 |
+
else
|
| 44 |
+
# Display warning about using plain text API key
|
| 45 |
+
echo "⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️"
|
| 46 |
+
echo "WARNING: Plain text API key detected. Converting to hashed format for security."
|
| 47 |
+
echo "For better security, use WAHA_API_KEY=sha512:{SHA512_HASH_FOR_YOUR_API_KEY}"
|
| 48 |
+
echo "⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️"
|
| 49 |
+
# Hash the key using sha512sum
|
| 50 |
+
HASHED_KEY=$(echo -n "$key" | sha512sum | awk '{print $1}')
|
| 51 |
+
export WAHA_API_KEY="sha512:$HASHED_KEY"
|
| 52 |
+
fi
|
| 53 |
+
fi
|
| 54 |
+
|
| 55 |
+
#
|
| 56 |
+
# xvfb-run
|
| 57 |
+
#
|
| 58 |
+
USE_XVFB=false
|
| 59 |
+
|
| 60 |
+
# Check WAHA_RUN_XVFB parameter - only test for "false" case, treat all others as True
|
| 61 |
+
if [ "$WAHA_RUN_XVFB" = "false" ] || [ "$WAHA_RUN_XVFB" = "False" ] || [ "$WAHA_RUN_XVFB" = "0" ]; then
|
| 62 |
+
# Explicitly disabled by user
|
| 63 |
+
echo "WAHA_RUN_XVFB value: $WAHA_RUN_XVFB - xvfb is disabled"
|
| 64 |
+
USE_XVFB=false
|
| 65 |
+
else
|
| 66 |
+
# Check engine and run test if it's WEBJS or not specified
|
| 67 |
+
if [ -z "$WHATSAPP_DEFAULT_ENGINE" ] || [ "$WHATSAPP_DEFAULT_ENGINE" = "WEBJS" ]; then
|
| 68 |
+
# Try to run xvfb-run with a test command
|
| 69 |
+
if xvfb-run --auto-servernum echo "xvfb-run is working!"; then
|
| 70 |
+
USE_XVFB=true
|
| 71 |
+
else
|
| 72 |
+
echo "xvfb-run test failed, do not run it"
|
| 73 |
+
USE_XVFB=false
|
| 74 |
+
fi
|
| 75 |
+
fi
|
| 76 |
+
fi
|
| 77 |
+
|
| 78 |
+
#
|
| 79 |
+
# Start your application using node with exec to ensure proper signal handling
|
| 80 |
+
#
|
| 81 |
+
if [ "$USE_XVFB" = "true" ]; then
|
| 82 |
+
echo "Executing node with xvfb-run..."
|
| 83 |
+
exec xvfb-run --auto-servernum node dist/main
|
| 84 |
+
else
|
| 85 |
+
echo "Executing node without xvfb-run..."
|
| 86 |
+
exec node dist/main
|
| 87 |
+
fi
|
examples/dev.likeapro.jpg
ADDED
|
examples/dev.likeapro.opus
ADDED
|
Binary file (18.9 kB). View file
|
|
|
examples/example.pdf
ADDED
|
Binary file (14.7 kB). View file
|
|
|
examples/python/README.md
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# WAHA (WhatsApp HTTP API) Python examples
|
| 2 |
+
|
| 3 |
+
## Installation
|
| 4 |
+
|
| 5 |
+
We assume that you have installed software:
|
| 6 |
+
|
| 7 |
+
1. Python 3
|
| 8 |
+
2. Docker
|
| 9 |
+
|
| 10 |
+
### Download and start image
|
| 11 |
+
|
| 12 |
+
First of all, you must run WhatsApp HTTP API locally (which under the hood it
|
| 13 |
+
runs real WhatsApp Web instance and expose HTTP API for interaction).
|
| 14 |
+
|
| 15 |
+
Here are the steps from
|
| 16 |
+
[Quick Start](https://waha.devlike.pro/docs/overview/quick-start/):
|
| 17 |
+
|
| 18 |
+
Download and start WhatsApp HTTP API docker container
|
| 19 |
+
|
| 20 |
+
```bash
|
| 21 |
+
# Download the image
|
| 22 |
+
docker pull devlikeapro/waha
|
| 23 |
+
# Run the docker container
|
| 24 |
+
docker run -it --rm --network=host -e WHATSAPP_HOOK_URL=http://localhost:5000/bot -e "WHATSAPP_HOOK_EVENTS=*" --name waha devlikeapro/waha
|
| 25 |
+
|
| 26 |
+
# It prints logs and the last line must be
|
| 27 |
+
# WhatsApp HTTP API is running on: http://[::1]:3000
|
| 28 |
+
```
|
| 29 |
+
|
| 30 |
+
#### Download image - ARM
|
| 31 |
+
|
| 32 |
+
If you're using ARM (like Apple Silicon, Apple M1, etc.) - use following
|
| 33 |
+
commands to download the image
|
| 34 |
+
|
| 35 |
+
 For Core version the command is
|
| 36 |
+
|
| 37 |
+
```bash
|
| 38 |
+
# Download the image
|
| 39 |
+
docker pull devlikeapro/waha:arm
|
| 40 |
+
# Rename it, so you can use devlikeapro/waha image in other place
|
| 41 |
+
docker tag devlikeapro/waha:arm devlikeapro/waha
|
| 42 |
+
# Run the docker container
|
| 43 |
+
docker run -it --rm --network=host -e WHATSAPP_HOOK_URL=http://localhost:5000/bot -e "WHATSAPP_HOOK_EVENTS=*" --name waha devlikeapro/waha
|
| 44 |
+
|
| 45 |
+
# It prints logs and the last line must be
|
| 46 |
+
# WhatsApp HTTP API is running on: http://[::1]:3000
|
| 47 |
+
```
|
| 48 |
+
|
| 49 |
+
### Start session and scan QR
|
| 50 |
+
|
| 51 |
+
2. Open Swagger API in the browser http://localhost:3000/
|
| 52 |
+
3. Start session and scan QR code in swagger
|
| 53 |
+
1. Find `POST /api/sessions/` request press **Try it out** and **Execute** it
|
| 54 |
+
with `default` session name
|
| 55 |
+
2. Find `GET /api/screenshot` and execute it - it must show QR code
|
| 56 |
+
3. Scan QR code on your mobile WhatsApp application (that installed on your
|
| 57 |
+
phone)
|
| 58 |
+
4. Execute `GET /api/screenshot` once again - it must show the screenshot
|
| 59 |
+
from WhatsApp Web.
|
| 60 |
+
4. Send test text message - find `POST /api/sendText` and execute it with
|
| 61 |
+
payload (change `12132132130` in the `chatId` to phone number that is
|
| 62 |
+
registered in WhatsApp).
|
| 63 |
+
|
| 64 |
+
```json
|
| 65 |
+
{
|
| 66 |
+
"chatId": "12132132130@c.us",
|
| 67 |
+
"text": "Hi there!",
|
| 68 |
+
"session": "default"
|
| 69 |
+
}
|
| 70 |
+
```
|
| 71 |
+
|
| 72 |
+
If you see **Hi there!** message then you're ready to run bots!
|
| 73 |
+
|
| 74 |
+
## WhatsApp Echo Bot
|
| 75 |
+
|
| 76 |
+
The WhatsApp Echo Bot is a sample flask webhook server application that echoes
|
| 77 |
+
back to you whatever you send it. It can serve as a basic reference for how to
|
| 78 |
+
set up webhooks and reply to incoming messages.
|
| 79 |
+
|
| 80 |
+
```bash
|
| 81 |
+
# Clone the git repository with example
|
| 82 |
+
git clone https://github.com/devlikeapro/waha.git
|
| 83 |
+
# Open python example folder
|
| 84 |
+
cd waha/examples/python
|
| 85 |
+
# Install requirements
|
| 86 |
+
python -mpip install -r requirements.txt
|
| 87 |
+
# Run the bot
|
| 88 |
+
FLASK_APP=whatsapp_echo_bot.py flask run
|
| 89 |
+
```
|
| 90 |
+
|
| 91 |
+
Open http://127.0.0.1:5000/bot - if you see **WhatsApp Echo Bot is ready!** then
|
| 92 |
+
the bot is ready to receive message!
|
| 93 |
+
|
| 94 |
+
Send message to the WhatsApp (that you used to scan QR code) and it'll echo text
|
| 95 |
+
back to you!
|
| 96 |
+
|
| 97 |
+
## WhatsApp Download Files Bot
|
| 98 |
+
|
| 99 |
+
The WhatsApp Download Image Bot downloads all files people send to your WhatsApp
|
| 100 |
+
and log the path for the file.
|
| 101 |
+
|
| 102 |
+
**The bot works only with WAHA Plus version** available with donations. Visit
|
| 103 |
+
[read more about difference between Core and Plus versions](https://waha.devlike.pro/docs/how-to/plus-version/).
|
| 104 |
+
|
| 105 |
+
Download **WAHA Plus** version:
|
| 106 |
+
|
| 107 |
+
```bash
|
| 108 |
+
# Download the image
|
| 109 |
+
docker pull devlikeapro/waha-plus
|
| 110 |
+
# Run the docker container
|
| 111 |
+
docker run -it --rm --network=host -e WHATSAPP_HOOK_URL=http://localhost:5000/bot -e "WHATSAPP_HOOK_EVENTS=*" --name waha devlikeapro/waha-plus
|
| 112 |
+
```
|
| 113 |
+
|
| 114 |
+
Run the WhatsApp Download Files bot:
|
| 115 |
+
|
| 116 |
+
```bash
|
| 117 |
+
# Clone the git repository with example
|
| 118 |
+
git clone https://github.com/devlikeapro/waha.git
|
| 119 |
+
# Open python example folder
|
| 120 |
+
cd waha/examples/python
|
| 121 |
+
# Install requirements
|
| 122 |
+
python -mpip install -r requirements.txt
|
| 123 |
+
# Run the bot
|
| 124 |
+
FLASK_APP=whatsapp_download_files_bot.py flask run
|
| 125 |
+
```
|
| 126 |
+
|
| 127 |
+
Open http://127.0.0.1:5000/bot - if you see **WhatsApp Download Files Bot!**
|
| 128 |
+
then the bot is ready to receive message with files!
|
examples/python/requirements.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
flask~=1.0
|
| 2 |
+
requests~=2.0
|
| 3 |
+
markupsafe==2.0.1
|
examples/python/whatsapp_download_files_bot.py
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from os.path import abspath
|
| 2 |
+
from pprint import pprint
|
| 3 |
+
|
| 4 |
+
import requests
|
| 5 |
+
from flask import Flask
|
| 6 |
+
from flask import request
|
| 7 |
+
|
| 8 |
+
app = Flask(__name__)
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
def send_message(chat_id, text):
|
| 12 |
+
"""
|
| 13 |
+
Send message to chat_id.
|
| 14 |
+
:param chat_id: Phone number + "@c.us" suffix - 1231231231@c.us
|
| 15 |
+
:param text: Message for the recipient
|
| 16 |
+
"""
|
| 17 |
+
# Send a text back via WhatsApp HTTP API
|
| 18 |
+
response = requests.post(
|
| 19 |
+
"http://localhost:3000/api/sendText",
|
| 20 |
+
json={
|
| 21 |
+
"chatId": chat_id,
|
| 22 |
+
"text": text,
|
| 23 |
+
"session": "default",
|
| 24 |
+
},
|
| 25 |
+
)
|
| 26 |
+
response.raise_for_status()
|
| 27 |
+
|
| 28 |
+
def send_seen(chat_id, message_id, participant):
|
| 29 |
+
response = requests.post(
|
| 30 |
+
"http://localhost:3000/api/sendSeen",
|
| 31 |
+
json={
|
| 32 |
+
"session": "default",
|
| 33 |
+
"chatId": chat_id,
|
| 34 |
+
"messageId": message_id,
|
| 35 |
+
"participant": participant,
|
| 36 |
+
},
|
| 37 |
+
)
|
| 38 |
+
response.raise_for_status()
|
| 39 |
+
|
| 40 |
+
@app.route("/")
|
| 41 |
+
def whatsapp_echo():
|
| 42 |
+
return "WhatsApp Download Files Bot is ready!"
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
@app.route("/bot", methods=["GET", "POST"])
|
| 46 |
+
def whatsapp_webhook():
|
| 47 |
+
if request.method == "GET":
|
| 48 |
+
return "WhatsApp Download Files Bot is ready!"
|
| 49 |
+
|
| 50 |
+
data = request.get_json()
|
| 51 |
+
pprint(data)
|
| 52 |
+
if data["event"] != "message":
|
| 53 |
+
# We can't process other event yet
|
| 54 |
+
return f"Unknown event {data['event']}"
|
| 55 |
+
|
| 56 |
+
payload = data["payload"]
|
| 57 |
+
# Ignore messages without files
|
| 58 |
+
if not payload.get("mediaUrl", None):
|
| 59 |
+
return "No files in the message"
|
| 60 |
+
|
| 61 |
+
# Number in format 791111111@c.us
|
| 62 |
+
chat_id = payload["from"]
|
| 63 |
+
# Message ID - false_11111111111@c.us_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
| 64 |
+
message_id = payload['id']
|
| 65 |
+
# For groups - who sent the message
|
| 66 |
+
participant = payload.get('participant')
|
| 67 |
+
# IMPORTANT - Always send seen before sending new message
|
| 68 |
+
send_seen(chat_id=chat_id, message_id=message_id, participant=participant)
|
| 69 |
+
|
| 70 |
+
# Download the file and download it to the current folder
|
| 71 |
+
client_url = payload["mediaUrl"]
|
| 72 |
+
filename = client_url.split("/")[-1]
|
| 73 |
+
path = abspath("./" + filename)
|
| 74 |
+
r = requests.get(client_url)
|
| 75 |
+
with open(path, "wb") as f:
|
| 76 |
+
f.write(r.content)
|
| 77 |
+
|
| 78 |
+
# Send a text back via WhatsApp HTTP API
|
| 79 |
+
text = f"We have downloaded file here: {path}"
|
| 80 |
+
print(text)
|
| 81 |
+
send_message(chat_id=chat_id, text=text)
|
| 82 |
+
|
| 83 |
+
# Send OK back
|
| 84 |
+
return "OK"
|
examples/python/whatsapp_echo_bot.py
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import random
|
| 2 |
+
from pprint import pprint
|
| 3 |
+
from time import sleep
|
| 4 |
+
|
| 5 |
+
import requests
|
| 6 |
+
from flask import Flask
|
| 7 |
+
from flask import request
|
| 8 |
+
|
| 9 |
+
app = Flask(__name__)
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
def send_message(chat_id, text):
|
| 13 |
+
"""
|
| 14 |
+
Send message to chat_id.
|
| 15 |
+
:param chat_id: Phone number + "@c.us" suffix - 1231231231@c.us
|
| 16 |
+
:param text: Message for the recipient
|
| 17 |
+
"""
|
| 18 |
+
# Send a text back via WhatsApp HTTP API
|
| 19 |
+
response = requests.post(
|
| 20 |
+
"http://localhost:3000/api/sendText",
|
| 21 |
+
json={
|
| 22 |
+
"chatId": chat_id,
|
| 23 |
+
"text": text,
|
| 24 |
+
"session": "default",
|
| 25 |
+
},
|
| 26 |
+
)
|
| 27 |
+
response.raise_for_status()
|
| 28 |
+
|
| 29 |
+
def reply(chat_id, message_id, text):
|
| 30 |
+
response = requests.post(
|
| 31 |
+
"http://localhost:3000/api/reply",
|
| 32 |
+
json={
|
| 33 |
+
"chatId": chat_id,
|
| 34 |
+
"text": text,
|
| 35 |
+
"reply_to": message_id,
|
| 36 |
+
"session": "default",
|
| 37 |
+
},
|
| 38 |
+
)
|
| 39 |
+
response.raise_for_status()
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
def send_seen(chat_id, message_id, participant):
|
| 43 |
+
response = requests.post(
|
| 44 |
+
"http://localhost:3000/api/sendSeen",
|
| 45 |
+
json={
|
| 46 |
+
"session": "default",
|
| 47 |
+
"chatId": chat_id,
|
| 48 |
+
"messageId": message_id,
|
| 49 |
+
"participant": participant,
|
| 50 |
+
},
|
| 51 |
+
)
|
| 52 |
+
response.raise_for_status()
|
| 53 |
+
|
| 54 |
+
def start_typing(chat_id):
|
| 55 |
+
response = requests.post(
|
| 56 |
+
"http://localhost:3000/api/startTyping",
|
| 57 |
+
json={
|
| 58 |
+
"session": "default",
|
| 59 |
+
"chatId": chat_id,
|
| 60 |
+
},
|
| 61 |
+
)
|
| 62 |
+
response.raise_for_status()
|
| 63 |
+
|
| 64 |
+
def stop_typing(chat_id):
|
| 65 |
+
response = requests.post(
|
| 66 |
+
"http://localhost:3000/api/stopTyping",
|
| 67 |
+
json={
|
| 68 |
+
"session": "default",
|
| 69 |
+
"chatId": chat_id,
|
| 70 |
+
},
|
| 71 |
+
)
|
| 72 |
+
response.raise_for_status()
|
| 73 |
+
|
| 74 |
+
def typing(chat_id, seconds):
|
| 75 |
+
start_typing(chat_id=chat_id)
|
| 76 |
+
sleep(seconds)
|
| 77 |
+
stop_typing(chat_id=chat_id)
|
| 78 |
+
|
| 79 |
+
@app.route("/")
|
| 80 |
+
def whatsapp_echo():
|
| 81 |
+
return "WhatsApp Echo Bot is ready!"
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
@app.route("/bot", methods=["GET", "POST"])
|
| 85 |
+
def whatsapp_webhook():
|
| 86 |
+
if request.method == "GET":
|
| 87 |
+
return "WhatsApp Echo Bot is ready!"
|
| 88 |
+
|
| 89 |
+
data = request.get_json()
|
| 90 |
+
pprint(data)
|
| 91 |
+
if data["event"] != "message":
|
| 92 |
+
# We can't process other event yet
|
| 93 |
+
return f"Unknown event {data['event']}"
|
| 94 |
+
|
| 95 |
+
# Payload that we've got
|
| 96 |
+
payload = data["payload"]
|
| 97 |
+
# The text
|
| 98 |
+
text = payload.get("body")
|
| 99 |
+
if not text:
|
| 100 |
+
# We can't process non-text messages yet
|
| 101 |
+
print("No text in message")
|
| 102 |
+
print(payload)
|
| 103 |
+
return "OK"
|
| 104 |
+
# Number in format 1231231231@c.us or @g.us for group
|
| 105 |
+
chat_id = payload["from"]
|
| 106 |
+
# Message ID - false_11111111111@c.us_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
| 107 |
+
message_id = payload['id']
|
| 108 |
+
# For groups - who sent the message
|
| 109 |
+
participant = payload.get('participant')
|
| 110 |
+
# IMPORTANT - Always send seen before sending new message
|
| 111 |
+
send_seen(chat_id=chat_id, message_id=message_id, participant=participant)
|
| 112 |
+
|
| 113 |
+
|
| 114 |
+
# Send a text back via WhatsApp HTTP API
|
| 115 |
+
typing(chat_id=chat_id, seconds=random.random() * 3)
|
| 116 |
+
send_message(chat_id=chat_id, text=text)
|
| 117 |
+
|
| 118 |
+
# OR reply on the message
|
| 119 |
+
typing(chat_id=chat_id, seconds=random.random() * 3)
|
| 120 |
+
reply(chat_id=chat_id, message_id=message_id, text=text)
|
| 121 |
+
|
| 122 |
+
# Send OK back
|
| 123 |
+
return "OK"
|
examples/video.avi
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:50a48a3e5ac93a164c62179ca85d6891eba738807ab29a266122586459f80c10
|
| 3 |
+
size 1480958
|
examples/video.mp4
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:31b6bd76b7f1d23315d25223ecc0153bd794639626f8fd7bb2e8c11b9912237a
|
| 3 |
+
size 1846872
|
examples/voice.mp3
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:90ce3b7c9dfcce6aafcb2dcfc3fc496dab6ba8106b61531b05d2c57a4be1640e
|
| 3 |
+
size 1059386
|
examples/waha.jpg
ADDED
|
logo.png
ADDED
|
nest-cli.json
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"collection": "@nestjs/schematics",
|
| 3 |
+
"sourceRoot": "src",
|
| 4 |
+
"compilerOptions": {
|
| 5 |
+
"plugins": ["@nestjs/swagger"],
|
| 6 |
+
"assets": [
|
| 7 |
+
"dashboard/**",
|
| 8 |
+
"core/engines/webjs/*",
|
| 9 |
+
"plus/engines/webjs/*",
|
| 10 |
+
"apps/chatwoot/i18n/*.yaml"
|
| 11 |
+
],
|
| 12 |
+
"watchAssets": true
|
| 13 |
+
}
|
| 14 |
+
}
|
package.json
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "waha",
|
| 3 |
+
"version": "0.0.1",
|
| 4 |
+
"description": "",
|
| 5 |
+
"author": "",
|
| 6 |
+
"private": true,
|
| 7 |
+
"license": "UNLICENSED",
|
| 8 |
+
"scripts": {
|
| 9 |
+
"prebuild": "rimraf dist",
|
| 10 |
+
"build": "nest build",
|
| 11 |
+
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
| 12 |
+
"start": "nest start",
|
| 13 |
+
"start:dev": "nest start --watch",
|
| 14 |
+
"start:debug": "nest start --debug --watch",
|
| 15 |
+
"start:prod": "node dist/main",
|
| 16 |
+
"start:prod-exit": "node dist/main",
|
| 17 |
+
"lint": "oxlint --deny-warnings",
|
| 18 |
+
"lint-fix": "oxlint --fix --deny-warnings",
|
| 19 |
+
"test": "jest",
|
| 20 |
+
"test:watch": "jest --watch",
|
| 21 |
+
"test:cov": "jest --coverage",
|
| 22 |
+
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
|
| 23 |
+
"test:e2e": "jest --config ./test/jest-e2e.json",
|
| 24 |
+
"gows:proto:fetch": "node scripts/gows-proto.js fetch",
|
| 25 |
+
"gows:proto:build": "node scripts/gows-proto.js build",
|
| 26 |
+
"gows:proto": "yarn gows:proto:fetch && yarn gows:proto:build"
|
| 27 |
+
},
|
| 28 |
+
"dependencies": {
|
| 29 |
+
"@adiwajshing/baileys": "github:devlikeapro/Baileys#fork-master-2025-07-04",
|
| 30 |
+
"@adiwajshing/keyed-db": "^0.2.4",
|
| 31 |
+
"@aws-sdk/client-s3": "^3.633.0",
|
| 32 |
+
"@aws-sdk/s3-request-presigner": "^3.633.0",
|
| 33 |
+
"@bull-board/api": "^6.9.1",
|
| 34 |
+
"@bull-board/express": "^6.9.1",
|
| 35 |
+
"@bull-board/nestjs": "^6.9.1",
|
| 36 |
+
"@figuro/chatwoot-sdk": "^1.1.17",
|
| 37 |
+
"@liaoliaots/nestjs-redis": "^9",
|
| 38 |
+
"@nestjs/axios": "^3.0.2",
|
| 39 |
+
"@nestjs/bullmq": "^11.0.2",
|
| 40 |
+
"@nestjs/common": "^11.0.0",
|
| 41 |
+
"@nestjs/config": "^3.2.3",
|
| 42 |
+
"@nestjs/core": "^11.0.0",
|
| 43 |
+
"@nestjs/passport": "^11.0.0",
|
| 44 |
+
"@nestjs/platform-express": "^11.1.5",
|
| 45 |
+
"@nestjs/platform-ws": "^11.0.0",
|
| 46 |
+
"@nestjs/serve-static": "^5.0.0",
|
| 47 |
+
"@nestjs/swagger": "^7.1.11",
|
| 48 |
+
"@nestjs/terminus": "^10.2.3",
|
| 49 |
+
"@nestjs/websockets": "^11.0.0",
|
| 50 |
+
"@types/better-sqlite3": "^7.6.10",
|
| 51 |
+
"@types/lodash": "^4.14.194",
|
| 52 |
+
"@types/mustache": "^4.2.5",
|
| 53 |
+
"@types/passport": "^1.0.17",
|
| 54 |
+
"@types/sqlite3": "^5.1.0",
|
| 55 |
+
"@types/ws": "^8.5.4",
|
| 56 |
+
"adm-zip": "0.5.10",
|
| 57 |
+
"agentkeepalive": "^4.5.0",
|
| 58 |
+
"async-lock": "^1.4.1",
|
| 59 |
+
"audio-decode": "^2.2.2",
|
| 60 |
+
"axios": "^1.9.0",
|
| 61 |
+
"axios-retry": "^4.5.0",
|
| 62 |
+
"better-sqlite3": "11.3.0",
|
| 63 |
+
"bullmq": "^5.48.1",
|
| 64 |
+
"check-disk-space": "^3.4.0",
|
| 65 |
+
"chokidar": "^3.6.0",
|
| 66 |
+
"class-transformer": "^0.5.1",
|
| 67 |
+
"class-validator": "0.14.0",
|
| 68 |
+
"del": "^8.0.0",
|
| 69 |
+
"express-basic-auth": "^1.2.1",
|
| 70 |
+
"file-type": "16.5.4",
|
| 71 |
+
"fs-extra": "^11.2.0",
|
| 72 |
+
"google-protobuf": "^3.21.4",
|
| 73 |
+
"https-proxy-agent": "^7.0.0",
|
| 74 |
+
"ioredis": "^5",
|
| 75 |
+
"joi": "^17.13.3",
|
| 76 |
+
"knex": "^3.1.0",
|
| 77 |
+
"libphonenumber-js": "^1.10.36",
|
| 78 |
+
"libsignal": "github:devlikeapro/libsignal-node#fork-master",
|
| 79 |
+
"link-preview-js": "^3.0.4",
|
| 80 |
+
"lodash": "^4.17.21",
|
| 81 |
+
"mime-types": "^2.1.27",
|
| 82 |
+
"mongodb": "6.9.0",
|
| 83 |
+
"mustache": "^4.2.0",
|
| 84 |
+
"nestjs-pino": "^4.1.0",
|
| 85 |
+
"node-cache": "5.1.2",
|
| 86 |
+
"passport": "^0.7.0",
|
| 87 |
+
"passport-headerapikey": "^1.2.2",
|
| 88 |
+
"pg": "^8.13.1",
|
| 89 |
+
"pino-http": "^10.2.0",
|
| 90 |
+
"pino-pretty": "^11.2.1",
|
| 91 |
+
"pretty-bytes": "5.6.0",
|
| 92 |
+
"promise-retry": "^2.0.1",
|
| 93 |
+
"puppeteer": "^24.10.0",
|
| 94 |
+
"qrcode": "^1.5.1",
|
| 95 |
+
"qrcode-terminal": "^0.12.0",
|
| 96 |
+
"reflect-metadata": "^0.1.13",
|
| 97 |
+
"rimraf": "^4.3.0",
|
| 98 |
+
"rxjs": "^7.8.1",
|
| 99 |
+
"sharp": "^0.33.4",
|
| 100 |
+
"sqlite3": "^5.1.7",
|
| 101 |
+
"swagger-ui-express": "^4.1.4",
|
| 102 |
+
"ulid": "^2.3.0",
|
| 103 |
+
"whatsapp-web.js": "github:devlikeapro/whatsapp-web.js#fork-main-2025-06-09",
|
| 104 |
+
"write-file-atomic": "^6.0.0",
|
| 105 |
+
"yaml": "^2.7.1"
|
| 106 |
+
},
|
| 107 |
+
"optionalDependencies": {
|
| 108 |
+
"bufferutil": "^4.0.8"
|
| 109 |
+
},
|
| 110 |
+
"resolutions": {
|
| 111 |
+
"bufferutil": "^4.0.8",
|
| 112 |
+
"ws": "^8.18.0",
|
| 113 |
+
"puppeteer": "^24.10.0",
|
| 114 |
+
"whatwg-url": "13.0.0",
|
| 115 |
+
"libsignal": "github:devlikeapro/libsignal-node#fork-master",
|
| 116 |
+
"axios": "^1.9.0"
|
| 117 |
+
},
|
| 118 |
+
"devDependencies": {
|
| 119 |
+
"@grpc/grpc-js": "^1.13.4",
|
| 120 |
+
"@grpc/proto-loader": "^0.7.13",
|
| 121 |
+
"@nestjs/cli": "^11.0.0",
|
| 122 |
+
"@nestjs/schematics": "^11.0.0",
|
| 123 |
+
"@nestjs/testing": "^11.0.0",
|
| 124 |
+
"@types/express": "^4.17.3",
|
| 125 |
+
"@types/jest": "26.0.10",
|
| 126 |
+
"@types/node": "^18.14.2",
|
| 127 |
+
"@types/node-fetch": "^2.6.13",
|
| 128 |
+
"@types/semver": "^7.7.0",
|
| 129 |
+
"@types/supertest": "^2.0.8",
|
| 130 |
+
"grpc-tools": "^1.13.0",
|
| 131 |
+
"jest": "^29.7.0",
|
| 132 |
+
"oxlint": "^1.13.0",
|
| 133 |
+
"prettier": "^1.19.1",
|
| 134 |
+
"protoc-gen-ts": "^0.8.7",
|
| 135 |
+
"supertest": "^4.0.2",
|
| 136 |
+
"ts-jest": "^29.1.3",
|
| 137 |
+
"ts-loader": "^6.2.1",
|
| 138 |
+
"ts-node": "^10.9.1",
|
| 139 |
+
"tsconfig-paths": "^4.1.0",
|
| 140 |
+
"typescript": "^4.8.4",
|
| 141 |
+
"yargs": "^17.7.2"
|
| 142 |
+
},
|
| 143 |
+
"jest": {
|
| 144 |
+
"moduleFileExtensions": [
|
| 145 |
+
"js",
|
| 146 |
+
"json",
|
| 147 |
+
"ts"
|
| 148 |
+
],
|
| 149 |
+
"rootDir": "src",
|
| 150 |
+
"testRegex": ".test.ts$",
|
| 151 |
+
"transform": {
|
| 152 |
+
"^.+\\.(t|j)s$": "ts-jest"
|
| 153 |
+
},
|
| 154 |
+
"coverageDirectory": "../coverage",
|
| 155 |
+
"testEnvironment": "node"
|
| 156 |
+
},
|
| 157 |
+
"packageManager": "yarn@3.6.3"
|
| 158 |
+
}
|
prepare-chatgpt.sh
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
|
| 3 |
+
# Set source and output file
|
| 4 |
+
SOURCE_DIR="src"
|
| 5 |
+
OUTPUT_DIR="$HOME/Downloads/chatgpt"
|
| 6 |
+
OUTPUT_FILE="$OUTPUT_DIR/waha.ts"
|
| 7 |
+
|
| 8 |
+
# Create or clear the output file
|
| 9 |
+
rm -f "$OUTPUT_FILE"
|
| 10 |
+
touch "$OUTPUT_FILE"
|
| 11 |
+
|
| 12 |
+
# Find all .md files in the source directory and combine them
|
| 13 |
+
find "$SOURCE_DIR" -type f -name "*.ts" | while read -r file; do
|
| 14 |
+
# Add file name to OUTPUT_FILE
|
| 15 |
+
echo "\n-------" >> "$OUTPUT_FILE"
|
| 16 |
+
echo "File: $file" >> "$OUTPUT_FILE"
|
| 17 |
+
echo "-------\n" >> "$OUTPUT_FILE"
|
| 18 |
+
# Append the content of the file to the output file
|
| 19 |
+
cat "$file" >> "$OUTPUT_FILE"
|
| 20 |
+
done
|
| 21 |
+
|
| 22 |
+
echo "All .ts files combined into $OUTPUT_FILE with separators."
|
scripts/gows-proto.js
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
| 2 |
+
const fs = require('fs');
|
| 3 |
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
| 4 |
+
const path = require('path');
|
| 5 |
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
| 6 |
+
const axios = require('axios');
|
| 7 |
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
| 8 |
+
const { execSync } = require('child_process');
|
| 9 |
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
| 10 |
+
const yargs = require('yargs');
|
| 11 |
+
|
| 12 |
+
// Defaults
|
| 13 |
+
const CONFIG_FILE = 'waha.config.json';
|
| 14 |
+
// Load defaults from package.json
|
| 15 |
+
gows = (() => {
|
| 16 |
+
try {
|
| 17 |
+
const config = JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf8'));
|
| 18 |
+
return config.waha.gows || {};
|
| 19 |
+
} catch (error) {
|
| 20 |
+
return {};
|
| 21 |
+
}
|
| 22 |
+
})();
|
| 23 |
+
|
| 24 |
+
const DEFAULT_REPO = gows.repo;
|
| 25 |
+
if (!DEFAULT_REPO) {
|
| 26 |
+
throw new Error(`Missing default repo in ${CONFIG_FILE}`);
|
| 27 |
+
}
|
| 28 |
+
const DEFAULT_REF = gows.ref;
|
| 29 |
+
if (!DEFAULT_REF) {
|
| 30 |
+
throw new Error('Missing default ref in ${CONFIG_FILE}');
|
| 31 |
+
}
|
| 32 |
+
const DEFAULT_DIR = './src/core/engines/gows/proto';
|
| 33 |
+
|
| 34 |
+
const PROTO_FILES = ['gows.proto'];
|
| 35 |
+
const PROTO_OUTPUT = './src/core/engines/gows/grpc';
|
| 36 |
+
|
| 37 |
+
// Helper function to clean directory
|
| 38 |
+
function cleanDirectory(directory, suffix) {
|
| 39 |
+
if (!fs.existsSync(directory)) {
|
| 40 |
+
fs.mkdirSync(directory, { recursive: true });
|
| 41 |
+
return;
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
const files = fs.readdirSync(directory);
|
| 45 |
+
for (const file of files) {
|
| 46 |
+
const filePath = path.join(directory, file);
|
| 47 |
+
if (file.endsWith(suffix)) {
|
| 48 |
+
fs.unlinkSync(filePath);
|
| 49 |
+
}
|
| 50 |
+
}
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
// Helper function to download files
|
| 54 |
+
async function downloadFiles(repo, ref, directory) {
|
| 55 |
+
for (const file of PROTO_FILES) {
|
| 56 |
+
const url = `https://github.com/${repo}/releases/download/${ref}/${file}`;
|
| 57 |
+
const filePath = path.join(directory, file);
|
| 58 |
+
try {
|
| 59 |
+
const response = await axios.get(url, { responseType: 'arraybuffer' });
|
| 60 |
+
fs.writeFileSync(filePath, response.data);
|
| 61 |
+
console.log(`Downloaded: ${file}`);
|
| 62 |
+
} catch (error) {
|
| 63 |
+
console.error(`Failed to download ${file}: ${error.message}`);
|
| 64 |
+
}
|
| 65 |
+
}
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
// Handler for fetch command
|
| 69 |
+
async function handleFetch(repo, ref, dir) {
|
| 70 |
+
console.log(`Fetching .proto files from ${repo}@${ref} to ${dir}...`);
|
| 71 |
+
cleanDirectory(dir, '.proto');
|
| 72 |
+
await downloadFiles(repo, ref, dir);
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
// Handler for build command
|
| 76 |
+
function handleBuild(dir) {
|
| 77 |
+
console.log('Building gRPC files...');
|
| 78 |
+
cleanDirectory(PROTO_OUTPUT);
|
| 79 |
+
|
| 80 |
+
const command = `grpc_tools_node_protoc \
|
| 81 |
+
--plugin=protoc-gen-ts=node_modules/.bin/protoc-gen-ts \
|
| 82 |
+
--plugin=protoc-gen-grpc=node_modules/.bin/grpc_tools_node_protoc_plugin \
|
| 83 |
+
--js_out=import_style=commonjs,binary:${PROTO_OUTPUT} \
|
| 84 |
+
--grpc_out=grpc_js:${PROTO_OUTPUT} \
|
| 85 |
+
--ts_out=grpc_js:${PROTO_OUTPUT} \
|
| 86 |
+
-I ${dir} ${dir}/gows.proto`;
|
| 87 |
+
|
| 88 |
+
try {
|
| 89 |
+
execSync(command, { stdio: 'inherit' });
|
| 90 |
+
console.log('gRPC files built successfully.');
|
| 91 |
+
} catch (error) {
|
| 92 |
+
console.error(`Failed to build gRPC files: ${error.message}`);
|
| 93 |
+
}
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
//
|
| 97 |
+
// Commands
|
| 98 |
+
//
|
| 99 |
+
|
| 100 |
+
// fetch
|
| 101 |
+
yargs.command(
|
| 102 |
+
'fetch',
|
| 103 |
+
'Fetch .proto files from GitHub',
|
| 104 |
+
(yargs) => {
|
| 105 |
+
yargs
|
| 106 |
+
.option('repo', {
|
| 107 |
+
describe: 'GitHub repository (owner/repo)',
|
| 108 |
+
type: 'string',
|
| 109 |
+
default: DEFAULT_REPO,
|
| 110 |
+
})
|
| 111 |
+
.option('ref', {
|
| 112 |
+
describe: 'Git reference (branch or commit SHA)',
|
| 113 |
+
type: 'string',
|
| 114 |
+
default: DEFAULT_REF,
|
| 115 |
+
})
|
| 116 |
+
.option('dir', {
|
| 117 |
+
describe: 'Directory to output .proto files',
|
| 118 |
+
type: 'string',
|
| 119 |
+
default: DEFAULT_DIR,
|
| 120 |
+
});
|
| 121 |
+
},
|
| 122 |
+
async (argv) => {
|
| 123 |
+
await handleFetch(argv.repo, argv.ref, argv.dir);
|
| 124 |
+
},
|
| 125 |
+
);
|
| 126 |
+
|
| 127 |
+
// build
|
| 128 |
+
yargs.command(
|
| 129 |
+
'build',
|
| 130 |
+
'Build gRPC files from .proto files',
|
| 131 |
+
(yargs) => {
|
| 132 |
+
yargs.option('dir', {
|
| 133 |
+
describe: 'Directory containing .proto files',
|
| 134 |
+
type: 'string',
|
| 135 |
+
default: DEFAULT_DIR,
|
| 136 |
+
});
|
| 137 |
+
},
|
| 138 |
+
(argv) => {
|
| 139 |
+
handleBuild(argv.dir);
|
| 140 |
+
},
|
| 141 |
+
);
|
| 142 |
+
|
| 143 |
+
// Parse arguments
|
| 144 |
+
yargs.parse();
|
src/api/auth.controller.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import {
|
| 2 |
+
Body,
|
| 3 |
+
Controller,
|
| 4 |
+
Get,
|
| 5 |
+
Post,
|
| 6 |
+
Query,
|
| 7 |
+
UseInterceptors,
|
| 8 |
+
} from '@nestjs/common';
|
| 9 |
+
import { ApiOperation, ApiSecurity, ApiTags } from '@nestjs/swagger';
|
| 10 |
+
import { ApiFileAcceptHeader } from '@waha/nestjs/ApiFileAcceptHeader';
|
| 11 |
+
import {
|
| 12 |
+
QRCodeSessionParam,
|
| 13 |
+
SessionApiParam,
|
| 14 |
+
SessionParam,
|
| 15 |
+
} from '@waha/nestjs/params/SessionApiParam';
|
| 16 |
+
|
| 17 |
+
import { SessionManager } from '../core/abc/manager.abc';
|
| 18 |
+
import { WhatsappSession } from '../core/abc/session.abc';
|
| 19 |
+
import { BufferResponseInterceptor } from '../nestjs/BufferResponseInterceptor';
|
| 20 |
+
import {
|
| 21 |
+
QRCodeFormat,
|
| 22 |
+
QRCodeQuery,
|
| 23 |
+
QRCodeValue,
|
| 24 |
+
RequestCodeRequest,
|
| 25 |
+
} from '../structures/auth.dto';
|
| 26 |
+
import { Base64File } from '../structures/files.dto';
|
| 27 |
+
|
| 28 |
+
@ApiSecurity('api_key')
|
| 29 |
+
@Controller('api/:session/auth')
|
| 30 |
+
@ApiTags('🔑 Auth')
|
| 31 |
+
class AuthController {
|
| 32 |
+
constructor(private manager: SessionManager) {}
|
| 33 |
+
|
| 34 |
+
@Get('qr')
|
| 35 |
+
@ApiOperation({
|
| 36 |
+
summary: 'Get QR code for pairing WhatsApp API.',
|
| 37 |
+
})
|
| 38 |
+
@SessionApiParam
|
| 39 |
+
@ApiFileAcceptHeader('image/png', Base64File, QRCodeValue)
|
| 40 |
+
@UseInterceptors(new BufferResponseInterceptor('image/png'))
|
| 41 |
+
async getQR(
|
| 42 |
+
@QRCodeSessionParam session: WhatsappSession,
|
| 43 |
+
@Query() query: QRCodeQuery,
|
| 44 |
+
): Promise<Buffer | QRCodeValue> {
|
| 45 |
+
const qr = session.getQR();
|
| 46 |
+
if (query.format == QRCodeFormat.RAW) {
|
| 47 |
+
return { value: qr.raw };
|
| 48 |
+
}
|
| 49 |
+
return qr.get();
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
@Post('request-code')
|
| 53 |
+
@SessionApiParam
|
| 54 |
+
@ApiOperation({
|
| 55 |
+
summary: 'Request authentication code.',
|
| 56 |
+
})
|
| 57 |
+
requestCode(
|
| 58 |
+
@SessionParam session: WhatsappSession,
|
| 59 |
+
@Body() request: RequestCodeRequest,
|
| 60 |
+
) {
|
| 61 |
+
return session.requestCode(request.phoneNumber, request.method, request);
|
| 62 |
+
}
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
export { AuthController };
|