NitinBot002 commited on
Commit
4327358
·
verified ·
1 Parent(s): 48c4397

Upload 384 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .dockerignore +48 -0
  2. .env.example +120 -0
  3. .eslintignore +3 -0
  4. .gitattributes +3 -0
  5. .github/FUNDING.yml +14 -0
  6. .github/ISSUE_TEMPLATE/bug_report.md +59 -0
  7. .github/ISSUE_TEMPLATE/feature_request.md +25 -0
  8. .github/ISSUE_TEMPLATE/question.md +11 -0
  9. .github/clear-gh-runs.sh +18 -0
  10. .github/gh-team-labels.yml +10 -0
  11. .github/workflows/build.yaml +150 -0
  12. .gitignore +56 -0
  13. .nvmrc +1 -0
  14. .oxlintrc.json +15 -0
  15. .pre-commit-config.yaml +75 -0
  16. .precommit/validate_commit_message.py +38 -0
  17. .prettierrc +13 -0
  18. .yarn/releases/yarn-3.6.3.cjs +0 -0
  19. .yarnrc +1 -0
  20. .yarnrc.yml +3 -0
  21. CHANGELOG.md +4 -0
  22. CNAME +1 -0
  23. Dockerfile +202 -53
  24. LICENSE +201 -0
  25. Makefile +60 -0
  26. docker-compose.yaml +104 -0
  27. docker-compose/chatwoot/.chatwoot.env +260 -0
  28. docker-compose/chatwoot/.waha.env +115 -0
  29. docker-compose/chatwoot/docker-compose.yaml +97 -0
  30. docker-compose/docker-compose.workers.yaml +97 -0
  31. docker-compose/n8n/docker-compose.yaml +34 -0
  32. docker-compose/test/docker-compose.yaml +112 -0
  33. entrypoint.sh +87 -0
  34. examples/dev.likeapro.jpg +0 -0
  35. examples/dev.likeapro.opus +0 -0
  36. examples/example.pdf +0 -0
  37. examples/python/README.md +128 -0
  38. examples/python/requirements.txt +3 -0
  39. examples/python/whatsapp_download_files_bot.py +84 -0
  40. examples/python/whatsapp_echo_bot.py +123 -0
  41. examples/video.avi +3 -0
  42. examples/video.mp4 +3 -0
  43. examples/voice.mp3 +3 -0
  44. examples/waha.jpg +0 -0
  45. logo.png +0 -0
  46. nest-cli.json +14 -0
  47. package.json +158 -0
  48. prepare-chatgpt.sh +22 -0
  49. scripts/gows-proto.js +144 -0
  50. 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: '[![patron:PRO](https://img.shields.io/badge/patron-PRO-188a42)](https://waha.devlike.pro/docs/how-to/plus-version/#tiers)'
5
+ - team: waha-patrons-advanced
6
+ label: patron:ADVANCED
7
+ comment: '[![patron:ADVANCED](https://img.shields.io/badge/patron-ADVANCED-4cd07d)](https://waha.devlike.pro/docs/how-to/plus-version/#tiers)'
8
+ - team: waha-patrons-plus
9
+ label: patron:PLUS
10
+ comment: '[![patron:PLUS](https://img.shields.io/badge/patron-PLUS-a0e6ba)](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
- # Approach 1: Simple Dockerfile to run WAHA directly with permission fixes
2
- # This is the recommended approach for most use cases
3
 
4
- # FROM devlikeapro/waha:latest
 
 
 
 
5
 
6
- # # Switch to root to fix permissions
7
- # USER root
 
 
 
8
 
9
- # # Create necessary directories and set proper permissions
10
- # RUN mkdir -p /app/.sessions /app/data /tmp/whatsapp-files && \
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
- # # Create a non-root user if it doesn't exist and switch back
15
- # RUN id -u node &>/dev/null || useradd -r -s /bin/false node
16
- # USER node
17
 
18
- # # Expose port 3000
19
- # EXPOSE 3000
 
 
 
20
 
21
- # The base image already has the proper entrypoint
22
- # Just run the container with: docker build -t my-waha . && docker run -p 3000:3000 my-waha
 
 
23
 
24
- # =================================================================
25
- # Approach 2: Docker-in-Docker (if you specifically need this)
26
- # WARNING: This approach has security implications and complexity
27
- # =================================================================
28
 
29
- FROM docker:dind
 
30
 
31
- # Install git
32
- RUN apk add --no-cache git
 
 
 
 
 
 
 
 
33
 
34
- # Create a startup script
35
- RUN echo '#!/bin/sh' > /start.sh && \
36
- echo 'dockerd &' >> /start.sh && \
37
- echo 'sleep 10' >> /start.sh && \
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
- EXPOSE 3000
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
 
45
- CMD ["bash","start.sh"]
46
-
47
- # =================================================================
48
- # Approach 3: Using docker-compose (Recommended for development)
49
- # Create a docker-compose.yml file instead:
50
- # =================================================================
51
-
52
- # version: '3.8'
53
- # services:
54
- # waha:
55
- # image: devlikeapro/waha:latest
56
- # ports:
57
- # - "3000:3000"
58
- # restart: unless-stopped
59
- # environment:
60
- # - WHATSAPP_HOOK_URL=http://localhost:3000/webhook
61
- # volumes:
62
- # - waha_data:/app/data
63
- #
64
- # volumes:
65
- # waha_data:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ ![](/images/versions/core.png) 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 };