Compare commits

..
181 Commits
Author SHA1 Message Date
devlikepro 5cfb53c367 [core] 2025.10.1
Release / WEBJS - chrome - amd64 - chrome (push) Waiting to run
Release / WEBJS - chromium - amd64 - latest (push) Waiting to run
Release / WEBJS - chromium - linux/arm64 - arm (push) Waiting to run
Release / GOWS - none - amd64 - gows (push) Waiting to run
Release / GOWS - none - linux/arm64 - gows-arm (push) Waiting to run
Release / NOWEB - none - amd64 - noweb (push) Waiting to run
Release / NOWEB - none - linux/arm64 - noweb-arm (push) Waiting to run
2025-10-12 18:45:57 +07:00
devlikepro 9466407b8a [core] ChatWoot - update last seen (on message.ack)
closes #1436
fixes #1319
2025-10-12 18:45:56 +07:00
devlikepro 4b65f0c462 [core] ChatWoot - up to v4.6.0 2025-10-12 18:45:56 +07:00
devlikepro 23504b35c8 [core] ChatWoot - remove /n at the end of any templated 2025-10-12 18:45:55 +07:00
devlikepro dd6ec4ca3a [core] ChatWoot - Pix fixes 2025-10-12 18:45:55 +07:00
devlikepro 8235e5a111 [core] ChatWoot - i18n - pt enable timeZone Sao Paulo 2025-10-12 18:45:55 +07:00
devlikepro 55499a6144 [core] ChatWoot - i18n - datetime 2025-10-12 18:45:54 +07:00
devlikepro 9dbc4a6085 [core] ChatWoot - i18n - poll, event, pix 2025-10-12 18:45:54 +07:00
devlikepro f7c6ce847c [core] ChatWoot - i18n - poll no empty line 2025-10-12 18:45:53 +07:00
devlikepro 84eed00415 [core] ChatWoot - i18n - location url (not URL) 2025-10-12 18:45:53 +07:00
devlikepro 51aa0e3154 [core] ChatWoot - i18n - datetime 2025-10-12 18:45:52 +07:00
devlikepro 77893a0eb0 [core] ChatWoot - i18n - locale base 2025-10-12 18:45:52 +07:00
devlikepro 4a866d8a08 [core] ChatWoot - PIX
(cherry picked from bergpinheiro/waha@696de94859)

Thanks @bergpinheiro
Co-authored-by: bergpinheiro <berg.pinheiro2009@gmail.com>
2025-10-12 18:45:52 +07:00
devlikepro f912353a5c [core] ChatWoot - Event Message
(cherry picked from bergpinheiro/waha@696de94859)

Thanks @bergpinheiro
Co-authored-by: bergpinheiro <berg.pinheiro2009@gmail.com>
2025-10-12 18:45:51 +07:00
devlikepro a6a1d8dc28 [core] ChatWoot - Poll message
(cherry picked from bergpinheiro/waha@696de94859)

Thanks @bergpinheiro
Co-authored-by: bergpinheiro <berg.pinheiro2009@gmail.com>
2025-10-12 18:45:50 +07:00
devlikepro 150e73aa74 [core] ChatWoot - adjust location message
(cherry picked from bergpinheiro/waha@696de94859)

Thanks @bergpinheiro
Co-authored-by: bergpinheiro <berg.pinheiro2009@gmail.com>
2025-10-12 18:45:49 +07:00
devlikepro a9300b3134 [core] ChatWoot add URL test 2025-10-12 18:45:48 +07:00
devlikepro bbe3859085 [core] ChatWoot - Facebook Ads Message Template
closes #1461

(cherry picked from bergpinheiro/waha@5863590208)

Thanks @bergpinheiro
Co-authored-by: bergpinheiro <berg.pinheiro2009@gmail.com>
2025-10-12 18:45:48 +07:00
devlikepro b420548dd9 [core] export fetchBuffer 2025-10-12 18:45:47 +07:00
devlikepro 741483eec7 [core] ChatWoot - remove unused getAttachments in message.reaction 2025-10-12 18:45:47 +07:00
devlikepro 2acf7e4e17 [core] ChatWoot - add name for location message 2025-10-12 18:45:46 +07:00
devlikepro 9bca6d904d [core] ChatWoot - Refactor message.any 2025-10-12 18:45:45 +07:00
devlikepro 857c586df6 [core] AGENTS.md 2025-10-12 18:45:45 +07:00
devlikepro df8cb7cecb [core] NOWEB - fix ssl issue
fix #1474
2025-10-12 18:45:45 +07:00
devlikepro 9d0050adb8 [core] NOWEB - filter PEER_DATA_OPERATION_REQUEST_RESPONSE_MESSAGE
fix #1459
2025-10-12 18:45:44 +07:00
devlikepro df927ab04a [core] Remove + at the start
fix #1475
2025-10-12 18:45:43 +07:00
devlikepro 02e5934e8f [core] Up NOWEB 2025-10-10 - fixes 2025-10-12 18:45:42 +07:00
devlikepro 825a4152db [core] Up NOWEB 2025-10-10 2025-10-12 18:45:41 +07:00
devlikepro 81b10099af [core] Up WEBJS
fix #1469
fix #1468
2025-10-12 18:45:41 +07:00
devlikepro 3be5f328b0 [core] Up GOWS 2025-10-12 18:45:41 +07:00
devlikepro 5caa3b8b81 [core] do not rename title 2025-10-10 10:07:02 +07:00
devlikepro 8231bf7d8e [core] GitHub - en/pt by default 2025-10-06 18:30:15 +07:00
devlikepro 22d94808fb [core] Fix lint
Release / WEBJS - chrome - amd64 - chrome (push) Waiting to run
Release / WEBJS - chromium - amd64 - latest (push) Waiting to run
Release / WEBJS - chromium - linux/arm64 - arm (push) Waiting to run
Release / GOWS - none - amd64 - gows (push) Waiting to run
Release / GOWS - none - linux/arm64 - gows-arm (push) Waiting to run
Release / NOWEB - none - amd64 - noweb (push) Waiting to run
Release / NOWEB - none - linux/arm64 - noweb-arm (push) Waiting to run
2025-10-04 17:12:34 +07:00
devlikepro 57daefa680 [core] 2025.9.8 2025-10-04 17:00:06 +07:00
devlikepro 5cf8704973 [core] NOWEB - no await in start
fix #1397
2025-10-04 17:00:05 +07:00
devlikepro 28da9c34bb [core] Fix NOWEB Apps on start
fix #1397
2025-10-04 17:00:05 +07:00
devlikepro 51ba5e3266 [core] Up GOWS
fix #1293
fix #1412
fix #1406
2025-10-04 17:00:05 +07:00
devlikepro f696794ee1 [core] Up WEBJS
fix #1276
fix #1407
2025-10-04 17:00:04 +07:00
devlikepro c6eca9510b [core] NOWEB - 2025-10-03 2025-10-04 17:00:04 +07:00
devlikepro 9a2fd2fccd [core] make up* 2025-10-04 17:00:04 +07:00
devlikepro c0a2d02f0d [core] NOWEB - send poll to newsletters
fix #1270
fix #1415
2025-10-04 17:00:04 +07:00
devlikepro 6493d16fd2 [core] NOWEB - try to get message just by id for poll
fix #1396
2025-10-04 17:00:04 +07:00
devlikeapro 9f96c678dc [core] support CSAT messages in webhook processing
fix(chatwoot): support CSAT messages in webhook processing
2025-10-04 16:59:36 +07:00
Berg Pinheiro a81f2ab553 fix(chatwoot): support CSAT messages in webhook processing
- Add support for 'input_csat' content_type in MessageHandler
- Previously CSAT messages were being ignored due to strict content_type check
- CSAT messages now processed as text messages and sent to WhatsApp
- Fixes issue where Chatwoot CSAT surveys were not being delivered to users

Changes:
- Modified content_type validation in message_created.ts to accept both 'text' and 'input_csat'
- CSAT messages will now be sent to WhatsApp with their survey content and links
- Maintains existing behavior for all other message types
2025-10-01 22:23:36 -03:00
devlikepro 8fbf7fa0e5 [core] ChatWoot - brazil phone number
Release / WEBJS - chrome - amd64 - chrome (push) Waiting to run
Release / WEBJS - chromium - amd64 - latest (push) Waiting to run
Release / WEBJS - chromium - linux/arm64 - arm (push) Waiting to run
Release / GOWS - none - amd64 - gows (push) Waiting to run
Release / GOWS - none - linux/arm64 - gows-arm (push) Waiting to run
Release / NOWEB - none - amd64 - noweb (push) Waiting to run
Release / NOWEB - none - linux/arm64 - noweb-arm (push) Waiting to run
fix #1261
2025-09-29 12:10:09 +07:00
devlikepro af0bba313a [core] 2025.9.7 2025-09-29 12:10:09 +07:00
devlikepro 76307dec12 [core] 2025.9.6
Release / WEBJS - chrome - amd64 - chrome (push) Waiting to run
Release / WEBJS - chromium - amd64 - latest (push) Waiting to run
Release / WEBJS - chromium - linux/arm64 - arm (push) Waiting to run
Release / GOWS - none - amd64 - gows (push) Waiting to run
Release / GOWS - none - linux/arm64 - gows-arm (push) Waiting to run
Release / NOWEB - none - amd64 - noweb (push) Waiting to run
Release / NOWEB - none - linux/arm64 - noweb-arm (push) Waiting to run
2025-09-29 09:09:47 +07:00
devlikepro 0b441054ae [core] Up dashboard 2025-09-29 09:09:46 +07:00
devlikepro 2e8b78aebc [core] ChatWoot fix duplicating messages for transcribe feature
fix #1371
2025-09-29 09:09:45 +07:00
devlikepro d01b221a24 [core] Add ChatWootAppConfig to openapi
fix #1416
2025-09-29 09:09:44 +07:00
devlikepro 61bb111768 [core] ChatWoot - conversation selector
fix #1216
fix #1357
fix #1237
close #1343
close #1213
2025-09-29 09:09:43 +07:00
devlikepro de47d6e445 [core] ChatWoot - list custom attributes once on upsert 2025-09-29 09:09:41 +07:00
devlikepro 59fe4b30f0 [core] ChatWoot - use Service suffix 2025-09-29 09:09:40 +07:00
devlikepro 166dae8e27 [core] ChatWoot - fix brazil numbers
fix #1261
2025-09-29 09:09:39 +07:00
devlikepro 5ce64fd30d [core] ChatWoot - check JID format 2025-09-29 09:09:37 +07:00
devlikepro 1a4513f437 [core] GOWS - do not fail in case of wrong numbers
fix #1173
2025-09-29 09:09:37 +07:00
devlikepro 59be4a780f [core] ChatWoot - check attributes before updating
fix #1173
2025-09-29 09:09:37 +07:00
devlikepro 74001c2b49 [core] ChatWoot - get group name
fix #1245
2025-09-29 09:09:37 +07:00
devlikepro a9ce0fb2d9 [core] ChatWoot - fix /jobs auth
fix #1398
2025-09-29 09:09:36 +07:00
devlikepro 4c3fd1c214 [core] ChatWoot - do not send STOPPED if server restarts 2025-09-29 09:09:34 +07:00
devlikepro a9459fe746 [core] ChatWoot - logging 2025-09-29 09:09:32 +07:00
devlikepro 5a3228f05b [core] ChatWoot - safe get avatar from WhatsApp 2025-09-29 09:09:31 +07:00
devlikepro befc238db9 [core] ChatWoot - fix 500 Error - use Account API to fetch contact conversations list
fix #1389
2025-09-29 09:09:31 +07:00
devlikepro ae75a1f8d4 [core] ChatWoot - use JobLink for success 2025-09-29 09:09:30 +07:00
devlikepro d1c50bfd73 [core] ChatWoot - add WAHA_PUBLIC_URL 2025-09-29 09:09:30 +07:00
devlikepro 6f540366f4 [core] ChatWoot - add RACK_TIMEOUT_SERVICE_TIMEOUT 60s
mention #1389
2025-09-29 09:09:29 +07:00
devlikepro 151fc760fe [core] ChatWoot log additional errors 2025-09-29 09:09:29 +07:00
devlikepro be4391a4b6 [core] ChatWoot fix reply if not found 2025-09-29 09:09:29 +07:00
devlikepro 76ae3e0f6b [core] 2025.9.5
Release / WEBJS - chrome - amd64 - chrome (push) Waiting to run
Release / WEBJS - chromium - amd64 - latest (push) Waiting to run
Release / WEBJS - chromium - linux/arm64 - arm (push) Waiting to run
Release / GOWS - none - amd64 - gows (push) Waiting to run
Release / GOWS - none - linux/arm64 - gows-arm (push) Waiting to run
Release / NOWEB - none - amd64 - noweb (push) Waiting to run
Release / NOWEB - none - linux/arm64 - noweb-arm (push) Waiting to run
2025-09-23 15:51:01 +07:00
devlikepro f37b6edaa6 [core] Up Dashboard 2025-09-23 15:51:00 +07:00
devlikepro 7095f77f93 [core] GOWS - v1.0.15 2025-09-23 15:51:00 +07:00
devlikepro 5853b778f2 [core] GOWS - fix "typing" after message
fix #1364
2025-09-23 15:51:00 +07:00
devlikepro 6405725ce6 [core] WEBJS - send vcard
fix #1341
2025-09-23 15:50:59 +07:00
devlikepro 111d6141aa [core] WEBJS - fix login via code on new version 2025-09-23 15:50:58 +07:00
devlikepro 5560b3c8e6 [core] NOWEB - login via phone
fix #1385
2025-09-23 15:50:58 +07:00
devlikepro d528d541ea [core] NOWEB - fix fromMe in group messages
fix #1350
2025-09-23 15:50:57 +07:00
devlikepro ab6b51cc1f [core] NOWEB - normalized lid 2025-09-23 15:50:57 +07:00
devlikepro 35aa4f2658 [core] WEBJS - fix status messages 2025-09-23 15:50:56 +07:00
devlikepro 36db3c37e8 [core] WEBJS - fix channel role 2025-09-23 15:50:55 +07:00
devlikepro b0c9232153 [core] Update WEBJS 2025-09-23 15:50:55 +07:00
devlikepro 0070fb9e5c [core] Update NOWEB, use ESM wrapper 2025-09-23 15:50:53 +07:00
devlikepro aa33ac4b1d [core] NOWEB - handle lid-mapping.update 2025-09-23 15:50:52 +07:00
devlikepro 1c2bc5b395 [core] NOWEB - no clean storage on history sync 2025-09-23 15:50:51 +07:00
devlikepro f2fe18a4c5 [core] NOWEB Handle lottie stickers using .zip 2025-09-23 15:50:51 +07:00
devlikepro 87fdcbebf6 [core] NOWEB Use directPath for newsletters 2025-09-23 15:50:51 +07:00
devlikepro 68a4f651ea [core] pin postgres:17.6
fix #1380
2025-09-23 15:50:50 +07:00
devlikepro 243caa9626 [core] ChatWoot - group participant at the bottom
fix #1369
2025-09-23 15:50:50 +07:00
devlikepro 863684b916 [core] ChatWoot - fix statuses.at
Release / WEBJS - chrome - amd64 - chrome (push) Waiting to run
Release / WEBJS - chromium - amd64 - latest (push) Waiting to run
Release / WEBJS - chromium - linux/arm64 - arm (push) Waiting to run
Release / GOWS - none - amd64 - gows (push) Waiting to run
Release / GOWS - none - linux/arm64 - gows-arm (push) Waiting to run
Release / NOWEB - none - amd64 - noweb (push) Waiting to run
Release / NOWEB - none - linux/arm64 - noweb-arm (push) Waiting to run
2025-09-15 15:49:13 +07:00
devlikepro 2d543f3728 [core] Fix WAHA Dashboard /jobs creds 2025-09-15 15:49:13 +07:00
devlikepro 47088cfbee [core] 2025.9.4 2025-09-15 15:40:29 +07:00
devlikepro 66c75cbf79 [core] ChatWoot - add |- in yaml i18n - remove \n
fix #1161
2025-09-15 15:40:21 +07:00
devlikepro b2c68d88ae [core] ChatWoot - show attachments preview
fix #1340
2025-09-15 15:40:21 +07:00
devlikepro 675e998cba [core] ChatWoot - avoid WORKING => STARTING => WORKING status changes every N minutes
fix #1342
2025-09-15 15:40:20 +07:00
devlikepro db1d20ae36 [core] Add 'statuses' points to session.status event 2025-09-15 15:40:20 +07:00
devlikepro 59b40dda4e [core] ChatWoot - fix "TypeError: Cannot read properties of undefined (reading 'send')" error 2025-09-15 15:40:20 +07:00
devlikepro 317fab4dfe [core] 2025.9.3
Release / WEBJS - chrome - amd64 - chrome (push) Waiting to run
Release / WEBJS - chromium - amd64 - latest (push) Waiting to run
Release / WEBJS - chromium - linux/arm64 - arm (push) Waiting to run
Release / GOWS - none - amd64 - gows (push) Waiting to run
Release / GOWS - none - linux/arm64 - gows-arm (push) Waiting to run
Release / NOWEB - none - amd64 - noweb (push) Waiting to run
Release / NOWEB - none - linux/arm64 - noweb-arm (push) Waiting to run
2025-09-14 17:48:58 +07:00
devlikepro 6c83ab68b4 [core] Up Dashboard 2025-09-14 17:48:57 +07:00
devlikepro 2194465757 [core] Up GOWS 2025-09-14 17:48:57 +07:00
devlikepro a0e70f88ad [core] NOWEB - update proto to v1025985905 2025-09-14 17:48:56 +07:00
devlikepro 9102a3d852 [core] WEBJS - Add WAHA_WEBJS_PUPPETER_ARGS to test --single-process
fix #1348
2025-09-14 17:48:55 +07:00
devlikepro b05cba896e [core] WEBJS - Update Chrome, Puppeter
fix #1348
2025-09-14 17:48:55 +07:00
devlikepro 6716a31b6c [core] WEBJS - --disable-blink-features=AutomationControlled
fix #1348
2025-09-14 17:48:54 +07:00
devlikepro 2e42d0e7eb [core] ChatWoot - receive messages from broadcast list
fix #1321
2025-09-14 17:48:54 +07:00
devlikepro dee9864157 [core] ChatWoot API Error 2025-09-14 17:48:53 +07:00
devlikepro 0293fc8c6f [core] Fix cases when message.media constains _data when no media attached 2025-09-14 17:48:52 +07:00
devlikepro 725fdc03a6 [core] ChatWoot - i18n 2025-09-14 17:48:49 +07:00
devlikepro 4557cb695f [core] ChatWoot - refactoring 2025-09-14 17:48:49 +07:00
devlikepro 172403a061 [core] ChatWoot - share contacts
fix #1175
2025-09-14 17:48:48 +07:00
devlikepro d03c3c185e [core] ChatWoot - share location (current and live)
fix #1205
2025-09-14 17:48:47 +07:00
devlikepro 50a111343c [core] ChatWoot - fix audio and pdf preview
fix #1330
fix #1340
2025-09-14 17:48:46 +07:00
devlikepro f01693adc3 [core] ChatWoot - Unsupported messages from WhatsApp
fix #1267
2025-09-14 17:48:46 +07:00
devlikepro d2bbbb4448 [core] Apps - JobLink 2025-09-14 17:48:45 +07:00
devlikepro 38c0aadff2 [core] ChatWoot - ignore not set WAHA_DASHBOARD_ENABLED - treat as true 2025-09-14 17:48:44 +07:00
devlikepro 79d593b155 [core] ChatWoot - customize templates via API
fix #1160
fix #1161
2025-09-14 17:48:43 +07:00
devlikepro ddc84cfecc [core] ChatWoot - customize messages
fix #1161
2025-09-14 17:48:42 +07:00
devlikepro b620383d94 [core] ChatWoot - do not send empty text messages 2025-09-14 17:48:42 +07:00
devlikepro 2319dba68d [core] ChatWoot - load languages WAHA_APPS_CHATWOOT_LANGUAGES_FOLDER
fix #1160
2025-09-14 17:48:41 +07:00
devlikepro 0c388ee3a7 [core] ChatWoot - set link preview
fix #1162
fix #1274
2025-09-14 17:48:40 +07:00
devlikepro fb5b3e2964 [core] Use ChatWootConfig 2025-09-14 17:48:39 +07:00
devlikepro d44eaa5b41 [core] Disable commands.server
fix #1182
fix #1176
2025-09-14 17:48:38 +07:00
devlikepro 2eaf05df27 [core] Update i18n 2025-09-14 17:48:37 +07:00
devlikepro 9e5431e205 [core] Update typescript 2025-09-14 17:48:35 +07:00
devlikepro 26c3102af8 [core] ChatWoot - disable app
fix #1260
2025-09-14 17:48:34 +07:00
devlikepro 104f06ef2b [core] ChatWoot - docker compose extra_hosts 2025-09-14 17:48:34 +07:00
devlikepro 93c8654e84 [core] Up chatwoot 4.5.2 2025-09-14 17:48:34 +07:00
devlikepro a7261790bd [core] Add ignore.broadcast
fix #1346
2025-09-14 17:48:34 +07:00
devlikepro d8d6e521f6 [core] Add excel to examples 2025-09-14 16:57:51 +07:00
devlikepro 02497bcd40 [core] 2025.9.2
Release / WEBJS - chromium - linux/arm64 - arm (push) Waiting to run
Release / GOWS - none - amd64 - gows (push) Waiting to run
Release / GOWS - none - linux/arm64 - gows-arm (push) Waiting to run
Release / NOWEB - none - amd64 - noweb (push) Waiting to run
Release / NOWEB - none - linux/arm64 - noweb-arm (push) Waiting to run
Release / WEBJS - chrome - amd64 - chrome (push) Waiting to run
Release / WEBJS - chromium - amd64 - latest (push) Waiting to run
2025-09-05 11:19:04 +07:00
devlikepro b498e15620 [core] NOWEB - Fix message.any fromMe: 1
fix #1318
fix #1338
2025-09-05 11:19:04 +07:00
devlikepro 1288d312c0 [core] Update Dashboard - WAHA_API_KEY warning 2025-09-05 11:19:04 +07:00
devlikepro 84cd350c42 [core] 2025.9.1
Release / WEBJS - chrome - amd64 - chrome (push) Waiting to run
Release / WEBJS - chromium - amd64 - latest (push) Waiting to run
Release / WEBJS - chromium - linux/arm64 - arm (push) Waiting to run
Release / GOWS - none - amd64 - gows (push) Waiting to run
Release / GOWS - none - linux/arm64 - gows-arm (push) Waiting to run
Release / NOWEB - none - amd64 - noweb (push) Waiting to run
Release / NOWEB - none - linux/arm64 - noweb-arm (push) Waiting to run
2025-09-02 18:14:14 +07:00
devlikepro 100bf89074 [core] WEBJS - fix STARTING session
fix #1301
fix #1315
fix #1314
fix #1312
2025-09-02 18:14:14 +07:00
devlikepro d66c80f95a [core] 2025.8.3
Release / WEBJS - chrome - amd64 - chrome (push) Waiting to run
Release / WEBJS - chromium - amd64 - latest (push) Waiting to run
Release / WEBJS - chromium - linux/arm64 - arm (push) Waiting to run
Release / GOWS - none - amd64 - gows (push) Waiting to run
Release / GOWS - none - linux/arm64 - gows-arm (push) Waiting to run
Release / NOWEB - none - amd64 - noweb (push) Waiting to run
Release / NOWEB - none - linux/arm64 - noweb-arm (push) Waiting to run
2025-08-30 18:30:07 +07:00
devlikepro 26f04bbd94 [core] Up Dashboard 2025-08-30 18:30:06 +07:00
devlikepro 6582c03823 [core] Up GOWS 2025-08-30 18:30:06 +07:00
devlikepro abacaf2e02 [core] WEBJS - fix STARTING session
fix #1298
fix #1299
fix #1300
2025-08-30 18:30:05 +07:00
devlikepro c65d8b9856 [core] GOWS - chat /unread 2025-08-30 18:30:05 +07:00
devlikepro 8f94cf06de [core] WEBJS - add webjs.tagsEventsOn config 2025-08-30 18:30:04 +07:00
devlikepro 94c1c16de8 [core] Use oxlint instead of eslint 2025-08-30 18:30:03 +07:00
devlikepro e69d992725 [core] Ignore - Status, Groups, Broadcast
fix #1142
fix #1259
fix #1190
2025-08-30 18:30:03 +07:00
devlikepro e6c5dd6e22 [core] eslint - no project 2025-08-30 18:30:02 +07:00
devlikepro 5486d4874a [core] Refactor media and processIncomingMessage 2025-08-30 18:30:02 +07:00
devlikepro 9d9d8e03fe [core] Add @types 2025-08-30 18:30:02 +07:00
devlikepro 6ee50243a2 [core] 2025.8.2
Release / GOWS - none - linux/arm64 - gows-arm (push) Waiting to run
Release / NOWEB - none - amd64 - noweb (push) Waiting to run
Release / NOWEB - none - linux/arm64 - noweb-arm (push) Waiting to run
Release / WEBJS - chrome - amd64 - chrome (push) Waiting to run
Release / WEBJS - chromium - amd64 - latest (push) Waiting to run
Release / WEBJS - chromium - linux/arm64 - arm (push) Waiting to run
Release / GOWS - none - amd64 - gows (push) Waiting to run
2025-08-25 10:31:26 +07:00
devlikepro 3ec078f9c1 [core] Update Dashboard 2025-08-25 10:31:26 +07:00
devlikepro 4c3209be6d [core] GOWS v1.0.12 2025-08-25 10:31:26 +07:00
devlikepro 7fe8f9a8dc [core] put "stack" last in errors 2025-08-25 10:31:25 +07:00
devlikepro 7fa2b29418 [core] GOWS - /api/sendPollVote
fix #1077
2025-08-25 10:31:25 +07:00
devlikepro dd4edd5a85 [core] show the engine name in errors 2025-08-25 10:31:24 +07:00
devlikepro b85df5a0d3 [core] GOWS - /api/sendLocation
fix #1250
2025-08-25 10:31:24 +07:00
devlikepro 1a7bec3d4e [core] NOWEB - add title for location, convert to right jid 2025-08-25 10:31:23 +07:00
devlikepro 727c4b454f [core] GOWS - Fix poll key
fix #1028
2025-08-25 10:31:23 +07:00
devlikepro 4ba86b34a9 [core] Add me.lid - GOWS, NOWEB 2025-08-25 10:31:22 +07:00
devlikepro 277a35aed9 [core] Add /api/sendList - NOWEB, GOWS
fix #393
fix #482
fix #715
fix #938
2025-08-25 10:31:21 +07:00
devlikepro 28c1ffa09f [core] ChatWoot - fix link preview for big files issue
fix #1162
2025-08-25 10:31:21 +07:00
devlikepro 10595680a9 [core] Dashboard - add zh - Simplified Chinese
fix #1193
2025-08-25 10:31:21 +07:00
devlikepro 577298dbc5 [core] ChatWoot - add zh-CN - Simplified Chinese
fix #1193
2025-08-25 10:31:21 +07:00
devlikepro 49ca4dfbf7 [core] rm LocaleCode 2025-08-25 10:31:21 +07:00
devlikepro 89ec47deec [core] 2025.8.1
Release / WEBJS - chrome - amd64 - chrome (push) Waiting to run
Release / WEBJS - chromium - amd64 - latest (push) Waiting to run
Release / WEBJS - chromium - linux/arm64 - arm (push) Waiting to run
Release / GOWS - none - amd64 - gows (push) Waiting to run
Release / GOWS - none - linux/arm64 - gows-arm (push) Waiting to run
Release / NOWEB - none - amd64 - noweb (push) Waiting to run
Release / NOWEB - none - linux/arm64 - noweb-arm (push) Waiting to run
2025-08-05 15:53:42 +07:00
devlikepro a043a46457 [core] API - limited characters in the session name
fix #1163
2025-08-05 15:53:42 +07:00
devlikepro eb8e3a0fd1 [core] WEBJS - fix create group
fix #1145
2025-08-05 15:53:41 +07:00
devlikepro fc25df8104 [core] NOWEB - fix channel list
fix #1177
2025-08-05 15:53:41 +07:00
devlikepro d8ffd3e543 [core] 2025.7.11
Release / WEBJS - chrome - amd64 - chrome (push) Waiting to run
Release / WEBJS - chromium - amd64 - latest (push) Waiting to run
Release / WEBJS - chromium - linux/arm64 - arm (push) Waiting to run
Release / GOWS - none - amd64 - gows (push) Waiting to run
Release / GOWS - none - linux/arm64 - gows-arm (push) Waiting to run
Release / NOWEB - none - amd64 - noweb (push) Waiting to run
Release / NOWEB - none - linux/arm64 - noweb-arm (push) Waiting to run
2025-08-03 13:59:23 +07:00
devlikepro ea4ec9310d [core] WEBJS - fix Caught error, dropping value from, event: 'message.ack'
fix #1178
2025-08-03 13:59:22 +07:00
devlikepro 479ec85e0d [core] Dashboard - i18n 2025-08-03 13:59:22 +07:00
devlikepro 3e4b450260 [core] ChatWoot - find chat id - jid, lid, chat id 2025-08-03 13:59:22 +07:00
devlikepro f6a81949d0 [core] ChatWoot - Urdu 2025-08-03 13:59:21 +07:00
devlikepro 6896962606 [core] Always show list of chatwoot languages
fix #1138
2025-08-03 13:59:21 +07:00
devlikepro 9b6d6ab4b0 [core] Inline LOCALE_NAME in yaml 2025-08-03 13:59:21 +07:00
devlikepro d5f399f7d5 [core] 2025.7.10
Release / WEBJS - chrome - amd64 - chrome (push) Waiting to run
Release / WEBJS - chromium - amd64 - latest (push) Waiting to run
Release / WEBJS - chromium - linux/arm64 - arm (push) Waiting to run
Release / GOWS - none - amd64 - gows (push) Waiting to run
Release / GOWS - none - linux/arm64 - gows-arm (push) Waiting to run
Release / NOWEB - none - amd64 - noweb (push) Waiting to run
Release / NOWEB - none - linux/arm64 - noweb-arm (push) Waiting to run
2025-07-27 17:39:17 +07:00
devlikepro dbd3bd024c [core] Up GOWS
Fix #1100
2025-07-27 17:39:16 +07:00
devlikepro 9ba7e19da3 [core] Use sqlite3 instead of better-sqlite3
better-sqlite3 can freeze the whole system
2025-07-27 17:39:16 +07:00
devlikepro 5f6d1412cf [core] Add sqlite3 2025-07-27 17:39:15 +07:00
devlikepro 0b5af3145e [core] Always save config, not null 2025-07-27 17:39:15 +07:00
devlikepro ad10ea4e96 [core] 2025.7.9
Release / WEBJS - chrome - amd64 - chrome (push) Waiting to run
Release / WEBJS - chromium - amd64 - latest (push) Waiting to run
Release / WEBJS - chromium - linux/arm64 - arm (push) Waiting to run
Release / GOWS - none - amd64 - gows (push) Waiting to run
Release / GOWS - none - linux/arm64 - gows-arm (push) Waiting to run
Release / NOWEB - none - amd64 - noweb (push) Waiting to run
Release / NOWEB - none - linux/arm64 - noweb-arm (push) Waiting to run
2025-07-25 12:46:33 +07:00
devlikepro 9de53a972a [core] Up NOWEB
fix #1143
2025-07-25 12:46:33 +07:00
devlikepro 4043efbb9a [core] Up Dashboard 2025-07-25 12:46:33 +07:00
devlikepro 42019644f0 [core] cpus*2 for UV_THREADPOOL_SIZE 2025-07-25 12:46:33 +07:00
devlikepro bcc25ef42f [core] Adjust UV_THREADPOOL_SIZE logic 2025-07-25 12:46:33 +07:00
devlikepro 602bbf3b60 [core] WEBJS - WAHA_RUN_XVFB
fix #1151
2025-07-25 12:46:32 +07:00
devlikeaproandsnyk-bot 585ac6074f [core] fix: package.json to reduce vulnerabilities (#16)
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-JS-MULTER-10773732

Co-authored-by: snyk-bot <snyk-bot@snyk.io>
2025-07-24 10:37:37 +07:00
196 changed files with 13526 additions and 4564 deletions

No files matched your search

+1
View File
@@ -8,6 +8,7 @@
# ==================
# Base URL for the API (used for webhooks, file URLs, etc.)
WAHA_BASE_URL=http://localhost:3000
# WAHA_PUBLIC_URL=http://localhost:3000
# Server configuration (if you need to customize hostname/port)
# WHATSAPP_API_SCHEMA=http
+1
View File
@@ -1,2 +1,3 @@
src/core/engines/gows/grpc/*
src/core/engines/gows/proto/*
src/core/engines/webjs/_lodash.js
-36
View File
@@ -1,36 +0,0 @@
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
project: 'tsconfig.json',
sourceType: 'module',
},
plugins: ['@typescript-eslint/eslint-plugin', 'simple-import-sort'],
extends: [
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended',
'prettier',
'prettier/@typescript-eslint',
],
root: true,
env: {
node: true,
jest: true,
},
rules: {
'simple-import-sort/imports': 'error',
'simple-import-sort/exports': 'error',
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-inferrable-types': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/ban-ts-ignore': 'off',
'@typescript-eslint/ban-ts-comment': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'lines-between-class-members': [
'error',
'always',
{ exceptAfterSingleLine: true },
],
},
};
+51
View File
@@ -0,0 +1,51 @@
name: 'github-translate'
on:
issues:
types: [opened]
issue_comment:
types: [created]
discussion:
types: [created]
discussion_comment:
types: [created]
# pull_request_target:
# types: [opened, edited]
# pull_request_review_comment:
# types: [created, edited]
jobs:
en:
permissions:
issues: write
discussions: write
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: devlikeapro/github-translate-action@main
env:
# GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
IS_MODIFY_TITLE: true
CUSTOM_BOT_NOTE: 'English'
TARGET_LANGUAGE: 'eng'
TRANSLATED_LANGUAGE: 'en'
pt:
permissions:
issues: write
discussions: write
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: devlikeapro/github-translate-action@main
env:
# GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
IS_MODIFY_TITLE: false
CUSTOM_BOT_NOTE: 'Portuguese'
TARGET_LANGUAGE: 'por'
TRANSLATED_LANGUAGE: 'pt'
+15
View File
@@ -0,0 +1,15 @@
{
"$schema": "./node_modules/oxlint/configuration_schema.json",
"plugins": ["typescript"],
"env": {
"builtin": true
},
"rules": {
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/no-inferrable-types": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/ban-ts-comment": "off",
"no-unused-vars": "off"
}
}
+6 -11
View File
@@ -17,18 +17,12 @@ repos:
language: python
stages: [commit-msg]
- repo: local
hooks:
- id: lint
stages: [pre-commit]
name: lint
- id: oxlint
name: oxlint
entry: npx oxlint --fix --deny-warnings
language: system
entry: bash -c '$HOME/.nvm/nvm-exec npm run lint-cache'
pass_filenames: false
files: |
(?x)^(
src/.*|
)$
pass_filenames: true
files: \.(ts|tsx|js|jsx)$
- repo: https://github.com/pre-commit/mirrors-prettier
rev: 'v3.1.0'
@@ -73,6 +67,7 @@ repos:
exclude: |
(?x)^(
entrypoint.sh|
AGENTS.md|
.pre-commit-config.yaml|
^src/core/engines/webjs/session.webjs.core.ts|
^src/core/engines/webjs/_lodash.js|
+124
View File
@@ -0,0 +1,124 @@
# WAHA Agent Playbook
This guide summarizes how to explore, modify, and validate the WhatsApp HTTP API
(WAHA) codebase when assisting as an automation or coding agent.
## Product & Variants
- WAHA ships in **Core** and **Plus** editions. Core lives under `src/core` and
only supports the default session plus minimal media features. Plus extends
core via `src/plus` to add multi-session orchestration, richer media handling,
and external storage integrations.
- Core code must remain free from Plus-only references. A pre-commit hook
rejects the word `plus` inside core files; reuse abstractions exposed through
`@waha/core/**` instead of importing Plus modules from Core.
- Commit subjects are validated: changes that touch `src/plus` require a
`[PLUS] …` prefix and must not include non-Plus files; everything else must
use `[core] …`. Verify against `./.precommit/validate_commit_message.py` if
unsure.
## Tech Stack Snapshot
- **Runtime**: Node.js 22.x, Yarn 3.6 (Berry). Always install packages and run
scripts with Yarn.
- **Framework**: NestJS v11 with dependency injection, modular controllers in
`src/api`, and Pino-based logging via `nestjs-pino`.
- **Engines**: WhatsApp engines are abstracted (`WEBJS`, `GOWS`, `NOWEB`). Core
uses `SessionManagerCore`; Plus swaps to `SessionManagerPlus` with extra
storage backends (Mongo/Postgres/SQLite).
- **ESM Bridge**: ESM-only dependencies (Baileys) load through
`src/vendor/esm.ts`. Add new ESM modules there to ensure they load exactly
once.
- **Utilities**: RxJS streams (`SwitchObservable`, `DefaultMap`) drive webhook
event fan-out. Prefer existing helpers in `src/utils` and `src/core/utils`
before adding bespoke logic.
## Repository Landmarks
- `src/main.ts`: runtime entry point; dynamically loads the correct AppModule
(Core vs Plus) and configures global interceptors/filters.
- `src/api/**`: REST controllers and WebSocket gateway. Keep handlers thin;
delegate to managers/services. HTTP routes follow `/api/{sessionName}/…`;
always thread the session name through request DTOs and guards instead of
hardcoding `default`.
- `src/core/**`: shared abstractions (config services, engine bootstrap,
storage, session management). Core only allows the `default` session and
cleans up storage on boot.
- `src/plus/**`: multi-session orchestration, advanced media services, and
external persistence layers (Mongo, Postgres). Reuse this layer when adding
Plus-only capabilities.
- `src/apps/**`: integrations (e.g., ChatWoot) and application-specific
services.
- `src/structures/**` and `src/utils/**`: DTOs, enums (event names follow
`domain.action`), helper utilities. Maintain naming consistency when
introducing new events.
- `tests/**`: Jest-based suites; do not add new tests unless explicitly asked,
but keep existing tests working.
## Coding Expectations
- Favor composable, long-lived solutions. If a helper already exists (e.g.,
`parseBool`, `DefaultMap`, media factories), extend it instead of reinventing
logic. Lodash ships with the project—prefer its utilities over hand-rolled
helpers. Import lodash as a namespace (`import * as lodash from 'lodash';`) so
helpers like `lodash.camelCase` stay consistent across files. When a new
third-party library seems necessary, confirm with the user, especially if the
package looks stale.
- Stick to NestJS patterns: inject dependencies through constructors, expose
provider tokens from modules, and keep controllers free from business logic.
- Logging goes through injected `PinoLogger` or helpers in
`src/utils/logging.ts`. `console.log` is blocked by pre-commit.
- Respect path aliases (`@waha/...`) defined in `tsconfig.json`; keep imports
consistent (use absolute aliases, not relative `../../../`).
- Avoid naming unused variables with a leading underscore; if a parameter is
required by a signature, explicitly `void` it instead.
- For configs, prefer runtime configurability over constants. Environment keys
follow `WAHA_*` for global values and `WAHA_SESSION_CONFIG_*` /
`session.config.*` for per-session overrides. If both env and config are
supported, honor both (`WAHA_WEBJS_CONFIG_*` vs. `session.webjs.config.*`).
## Language & Localization
- Keep identifiers (classes, methods, variables) and code comments in English so
the codebase stays consistent for the global team.
- Route user-visible strings through the existing i18n structure rather than
hardcoding text. ChatWoot copy belongs in `src/apps/chatwoot/i18n` with
English as the source locale before adding translations.
## ChatWoot Integration Notes
- Avoid introducing synthetic events; map onto existing webhook or engine events
whenever plausible. Always use the official ChatWoot API client located in
`src/apps/chatwoot/client`.
- When adding events, align consumer names with webhook/event identifiers (e.g.,
`message.any`).
## Workflow Checklist
1. Identify whether work targets Core, Plus, or shared layers. If Plus-only,
isolate changes to `src/plus` and ensure the commit prefix matches.
2. Lean on existing services/managers; extend the appropriate session manager
rather than branching logic inline.
3. After edits run:
- `pre-commit run --all-files`
- `yarn build`
- `yarn test` Use Node 22. Address lint or formatting issues before
proceeding.
4. Do **not** start the application yourself; ask the user to run it if runtime
validation is required.
5. Capture any assumptions or open questions for the user, especially when
touching configs, introducing dependencies, or modifying public APIs.
## Additional Tips
- Concurrency-sensitive sections (session start/stop) rely on `async-lock`. When
adding async flows, reuse `SessionManager.withLock` or existing retry
utilities (`promiseTimeout`, `waitUntil`).
- Media features centralize through `MediaManager` and `MediaStorageFactory`.
When altering media behavior, update both Core and Plus variants where
applicable.
- Keep docs and code ASCII unless a file already uses other characters. When
updating documentation, mirror the concise, actionable tone used here.
Following this playbook keeps contributions aligned with WAHA’s structure,
automation hooks, and release process.
+1 -1
View File
@@ -162,7 +162,7 @@ RUN if [ "$USE_BROWSER" = "chromium" ]; then \
# Install Chrome
# Available versions:
# https://www.ubuntuupdates.org/package/google_chrome/stable/main/base/google-chrome-stable
ARG CHROME_VERSION="137.0.7151.103-1"
ARG CHROME_VERSION="140.0.7339.80-1"
RUN if [ "$USE_BROWSER" = "chrome" ]; then \
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 \
&& apt-get update \
+3 -3
View File
@@ -35,13 +35,13 @@ for-swagger:
WHATSAPP_SWAGGER_CONFIG_ADVANCED=true . ${NVM_DIR}/nvm.sh && nvm exec yarn start
up-noweb:
. ${NVM_DIR}/nvm.sh && nvm exec yarn up @adiwajshing/baileys@github:devlikeapro/Baileys#fork-master-2025-07-04
yarn up @adiwajshing/baileys@github:devlikeapro/Baileys#fork-master-2025-10-10
up-noweb-libsignal:
. ${NVM_DIR}/nvm.sh && nvm exec yarn up libsignal@github:devlikeapro/libsignal-node#fork-master
yarn up libsignal@github:devlikeapro/libsignal-node#fork-master
up-webjs:
. ${NVM_DIR}/nvm.sh && nvm exec yarn up whatsapp-web.js@github:devlikeapro/whatsapp-web.js#fork-main-2025-06-09
yarn up whatsapp-web.js@github:devlikeapro/whatsapp-web.js#fork-main-2025-09-10
start-proxy:
docker run --rm -d --name squid-container -e TZ=UTC -p 3128:3128 ubuntu/squid:5.2-22.04_beta
+1 -1
View File
@@ -36,7 +36,7 @@ services:
# NOTE: Only if you're using PostgreSQL to save sessions
# https://waha.devlike.pro/docs/how-to/storages/#media---postgresql
# postgres:
# image: postgres:17
# image: postgres:17.6
# restart: always
# environment:
# POSTGRES_USER: postgres
+4
View File
@@ -1,6 +1,10 @@
# Learn about the various environment variables at
# https://www.chatwoot.com/docs/self-hosted/configuration/environment-variables/#rails-production-variables
# Increase rack default timeout (30s) to avoid timeout errors
# Workaround for https://github.com/devlikeapro/waha/issues/1389
RACK_TIMEOUT_SERVICE_TIMEOUT=60
# Used to verify the integrity of signed cookies. so ensure a secure value is set
# SECRET_KEY_BASE should be alphanumeric. Avoid special characters or symbols.
# Use `rake secret` to generate this variable
+1
View File
@@ -8,6 +8,7 @@
# ==================
# Base URL for the API (used for webhooks, file URLs, etc.)
WAHA_BASE_URL=http://waha:3000
WAHA_PUBLIC_URL=http://localhost:3000
# Server configuration (if you need to customize hostname/port)
# WHATSAPP_API_SCHEMA=http
+3 -1
View File
@@ -24,10 +24,12 @@ services:
- 8.8.8.8
base: &base
image: chatwoot/chatwoot:v4.3.0
image: chatwoot/chatwoot:v4.6.0
env_file: .chatwoot.env ## Change this file for customized env variables
volumes:
- chatwoot_storage:/app/storage
extra_hosts:
- 'host.docker.internal:host-gateway'
logging:
driver: 'json-file'
options:
+30 -9
View File
@@ -4,8 +4,18 @@
#
# Calculate UV_THREADPOOL_SIZE based on number of CPUs
#
cpus=$(node -e "const os = require('os'); console.log(os.cpus().length);")
uv_threadpool_size=$(($cpus * 1))
# Try to get CPU count using Node.js, fallback to 1 if it fails
cpus=$(node -e "const os = require('os'); console.log(os.cpus().length);" 2>/dev/null) || cpus=1
# Make sure cpus is a number, default to 1 if not
case $cpus in
''|*[!0-9]*) cpus=1 ;;
esac
uv_threadpool_size=$(($cpus * 2))
# Check if uv_threadpool_size is less than 4 (default), set it to 4 if it is
if [ "$uv_threadpool_size" -lt 4 ]; then
uv_threadpool_size=4
fi
# Set UV_THREADPOOL_SIZE as an environment variable
export UV_THREADPOOL_SIZE="${UV_THREADPOOL_SIZE:-$uv_threadpool_size}"
@@ -46,13 +56,22 @@ fi
# xvfb-run
#
USE_XVFB=false
if [ -z "$WHATSAPP_DEFAULT_ENGINE" ] || [ "$WHATSAPP_DEFAULT_ENGINE" = "WEBJS" ]; then
# Try to run xvfb-run with a test command
if xvfb-run --auto-servernum echo "xvfb-run is working!"; then
USE_XVFB=true
else
echo "xvfb-run test failed, do not run it"
USE_XVFB=false
# Check WAHA_RUN_XVFB parameter - only test for "false" case, treat all others as True
if [ "$WAHA_RUN_XVFB" = "false" ] || [ "$WAHA_RUN_XVFB" = "False" ] || [ "$WAHA_RUN_XVFB" = "0" ]; then
# Explicitly disabled by user
echo "WAHA_RUN_XVFB value: $WAHA_RUN_XVFB - xvfb is disabled"
USE_XVFB=false
else
# Check engine and run test if it's WEBJS or not specified
if [ -z "$WHATSAPP_DEFAULT_ENGINE" ] || [ "$WHATSAPP_DEFAULT_ENGINE" = "WEBJS" ]; then
# Try to run xvfb-run with a test command
if xvfb-run --auto-servernum echo "xvfb-run is working!"; then
USE_XVFB=true
else
echo "xvfb-run test failed, do not run it"
USE_XVFB=false
fi
fi
fi
@@ -60,7 +79,9 @@ fi
# Start your application using node with exec to ensure proper signal handling
#
if [ "$USE_XVFB" = "true" ]; then
echo "Executing node with xvfb-run..."
exec xvfb-run --auto-servernum node dist/main
else
echo "Executing node without xvfb-run..."
exec node dist/main
fi
Binary file not shown.
+2 -1
View File
@@ -7,7 +7,8 @@
"dashboard/**",
"core/engines/webjs/*",
"plus/engines/webjs/*",
"apps/chatwoot/i18n/*.yaml"
"apps/chatwoot/i18n/locales/*.yaml",
"apps/chatwoot/i18n/locales/*.yml"
],
"watchAssets": true
}
+19 -15
View File
@@ -14,8 +14,8 @@
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
"start:prod-exit": "node dist/main",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix --max-warnings=0",
"lint-cache": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix --cache --max-warnings=0",
"lint": "oxlint --deny-warnings",
"lint-fix": "oxlint --fix --deny-warnings",
"test": "jest",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
@@ -26,7 +26,7 @@
"gows:proto": "yarn gows:proto:fetch && yarn gows:proto:build"
},
"dependencies": {
"@adiwajshing/baileys": "github:devlikeapro/Baileys#fork-master-2025-07-04",
"@adiwajshing/baileys": "github:devlikeapro/Baileys#fork-master-2025-10-10",
"@adiwajshing/keyed-db": "^0.2.4",
"@aws-sdk/client-s3": "^3.633.0",
"@aws-sdk/s3-request-presigner": "^3.633.0",
@@ -41,7 +41,7 @@
"@nestjs/config": "^3.2.3",
"@nestjs/core": "^11.0.0",
"@nestjs/passport": "^11.0.0",
"@nestjs/platform-express": "^11.0.0",
"@nestjs/platform-express": "^11.1.5",
"@nestjs/platform-ws": "^11.0.0",
"@nestjs/serve-static": "^5.0.0",
"@nestjs/swagger": "^7.1.11",
@@ -51,6 +51,7 @@
"@types/lodash": "^4.14.194",
"@types/mustache": "^4.2.5",
"@types/passport": "^1.0.17",
"@types/sqlite3": "^5.1.0",
"@types/ws": "^8.5.4",
"adm-zip": "0.5.10",
"agentkeepalive": "^4.5.0",
@@ -70,6 +71,7 @@
"fs-extra": "^11.2.0",
"google-protobuf": "^3.21.4",
"https-proxy-agent": "^7.0.0",
"ical.js": "^2.2.1",
"ioredis": "^5",
"joi": "^17.13.3",
"knex": "^3.1.0",
@@ -77,6 +79,7 @@
"libsignal": "github:devlikeapro/libsignal-node#fork-master",
"link-preview-js": "^3.0.4",
"lodash": "^4.17.21",
"long": "^5.3.2",
"mime-types": "^2.1.27",
"mongodb": "6.9.0",
"mustache": "^4.2.0",
@@ -89,16 +92,17 @@
"pino-pretty": "^11.2.1",
"pretty-bytes": "5.6.0",
"promise-retry": "^2.0.1",
"puppeteer": "^24.10.0",
"puppeteer": "^24.19.0",
"qrcode": "^1.5.1",
"qrcode-terminal": "^0.12.0",
"reflect-metadata": "^0.1.13",
"rimraf": "^4.3.0",
"rxjs": "^7.8.1",
"sharp": "^0.33.4",
"sqlite3": "^5.1.7",
"swagger-ui-express": "^4.1.4",
"ulid": "^2.3.0",
"whatsapp-web.js": "github:devlikeapro/whatsapp-web.js#fork-main-2025-06-09",
"whatsapp-web.js": "github:devlikeapro/whatsapp-web.js#fork-main-2025-09-10",
"write-file-atomic": "^6.0.0",
"yaml": "^2.7.1"
},
@@ -108,7 +112,7 @@
"resolutions": {
"bufferutil": "^4.0.8",
"ws": "^8.18.0",
"puppeteer": "^24.10.0",
"puppeteer": "^24.19.0",
"whatwg-url": "13.0.0",
"libsignal": "github:devlikeapro/libsignal-node#fork-master",
"axios": "^1.9.0"
@@ -122,23 +126,20 @@
"@types/express": "^4.17.3",
"@types/jest": "26.0.10",
"@types/node": "^18.14.2",
"@types/node-fetch": "^2.6.13",
"@types/semver": "^7.7.0",
"@types/supertest": "^2.0.8",
"@typescript-eslint/eslint-plugin": "3.9.1",
"@typescript-eslint/parser": "3.9.1",
"eslint": "7.7.0",
"eslint-config-prettier": "^6.10.0",
"eslint-plugin-import": "^2.20.1",
"eslint-plugin-simple-import-sort": "^10.0.0",
"grpc-tools": "^1.13.0",
"jest": "^29.7.0",
"oxlint": "^1.13.0",
"prettier": "^1.19.1",
"protoc-gen-ts": "^0.8.7",
"supertest": "^4.0.2",
"ts-jest": "^29.1.3",
"ts-loader": "^6.2.1",
"ts-node": "^10.9.1",
"ts-node": "^10.9.2",
"tsconfig-paths": "^4.1.0",
"typescript": "^4.8.4",
"typescript": "5.9.2",
"yargs": "^17.7.2"
},
"jest": {
@@ -148,6 +149,9 @@
"ts"
],
"rootDir": "src",
"moduleNameMapper": {
"^@waha/(.*)$": "<rootDir>/$1"
},
"testRegex": ".test.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
-1
View File
@@ -1,4 +1,3 @@
import { isJidGroup } from '@adiwajshing/baileys';
import {
Body,
Controller,
+26 -1
View File
@@ -16,6 +16,7 @@ import {
transformAck,
} from '@waha/structures/chats.dto';
import { SendButtonsRequest } from '@waha/structures/chatting.buttons.dto';
import { SendListRequest } from '@waha/structures/chatting.list.dto';
import { SessionManager } from '../core/abc/manager.abc';
import {
@@ -31,6 +32,7 @@ import {
MessageLinkPreviewRequest,
MessageLocationRequest,
MessagePollRequest,
MessagePollVoteRequest,
MessageReactionRequest,
MessageReplyRequest,
MessageStarRequest,
@@ -121,8 +123,9 @@ export class ChattingController {
@Post('/sendButtons')
@ApiOperation({
summary: 'Send buttons (interactive message)',
summary: 'Send buttons message (interactive)',
description: 'Send Buttons',
deprecated: true,
})
@UsePipes(new WAHAValidationPipe())
async sendButtons(@Body() request: SendButtonsRequest) {
@@ -130,6 +133,17 @@ export class ChattingController {
return whatsapp.sendButtons(request);
}
@Post('/sendList')
@ApiOperation({
summary: 'Send a list message (interactive)',
description: 'Send a List message with sections and rows',
})
@UsePipes(new WAHAValidationPipe())
async sendList(@Body() request: SendListRequest) {
const whatsapp = await this.manager.getWorkingSession(request.session);
return whatsapp.sendList(request);
}
@Post('/forwardMessage')
async forwardMessage(
@Body() request: MessageForwardRequest,
@@ -193,6 +207,17 @@ export class ChattingController {
return whatsapp.sendPoll(request);
}
@Post('/sendPollVote')
@ApiOperation({
summary: 'Vote on a poll',
description: 'Cast vote(s) on an existing poll message',
})
@UsePipes(new WAHAValidationPipe())
async sendPollVote(@Body() request: MessagePollVoteRequest) {
const whatsapp = await this.manager.getWorkingSession(request.session);
return whatsapp.sendPollVote(request);
}
@Post('/sendLocation')
async sendLocation(@Body() request: MessageLocationRequest) {
const whatsapp = await this.manager.getWorkingSession(request.session);
+1 -1
View File
@@ -1,4 +1,3 @@
import { isLidUser } from '@adiwajshing/baileys/lib/WABinary/jid-utils';
import {
Controller,
Get,
@@ -22,6 +21,7 @@ import {
import { PaginationParams, SortOrder } from '@waha/structures/pagination.dto';
import { SessionManager } from '../core/abc/manager.abc';
import { isLidUser } from '@waha/core/utils/jids';
@ApiSecurity('api_key')
@Controller('api/:session/lids')
+15
View File
@@ -50,3 +50,18 @@ export function HasBeenRetried(job: Job): boolean {
const attemptsMade = job.attemptsMade + 1;
return attemptsMade > 1;
}
let base =
process.env.WAHA_PUBLIC_URL ||
process.env.WAHA_BASE_URL ||
'http://localhost:3000';
// cut / at the end
base = base.replace(/\/+$/, '');
export function JobLink(job: Job): { text: string; url: string } {
const text = `${job.queueName} => ${job.id}`;
const url = `${base}/jobs/queue/${encodeURIComponent(job.queueName)}/${
job.id
}`;
return { text: text, url: url };
}
+9 -2
View File
@@ -48,10 +48,17 @@ export class AppsController {
return await this.appsService.create(this.manager, app);
}
@Get('/:id')
@ApiOperation({ summary: 'Get app by ID' })
@UsePipes(new WAHAValidationPipe())
async get(@Param('id') id: string): Promise<App> {
return await this.appsService.get(this.manager, id);
}
@Put('/:id')
@ApiOperation({ summary: 'Update an existing app' })
@UsePipes(new WAHAValidationPipe())
async update(@Param('id') id: string, @Body() app: App): Promise<void> {
async update(@Param('id') id: string, @Body() app: App): Promise<App> {
if (!app.id) {
app.id = id;
} else if (app.id !== id) {
@@ -60,7 +67,7 @@ export class AppsController {
);
}
await this.appsService.update(this.manager, app);
return await this.appsService.update(this.manager, app);
}
@Delete('/:id')
+10 -8
View File
@@ -4,19 +4,21 @@ import { parseBool } from '@waha/helpers';
import * as basicAuth from 'express-basic-auth';
export function BullAuthMiddleware() {
let username = process.env.WAHA_DASHBOARD_USERNAME;
let password = process.env.WAHA_DASHBOARD_PASSWORD;
const enabled = parseBool(process.env.WAHA_DASHBOARD_ENABLED);
if (!enabled) {
// Generate a random uuid4 username /password to prevent access
username = 'admin';
password = crypto.randomUUID();
let username = process.env.WAHA_DASHBOARD_USERNAME || '';
let password = process.env.WAHA_DASHBOARD_PASSWORD || '';
if (process.env.WAHA_DASHBOARD_ENABLED) {
const enabled = parseBool(process.env.WAHA_DASHBOARD_ENABLED);
if (!enabled) {
// Generate a random uuid4 username/password to effectively disable access
username = 'admin';
password = crypto.randomUUID();
}
}
return basicAuth({
challenge: true,
users: {
[username]: password,
[String(username)]: String(password),
},
});
}
+19 -1
View File
@@ -1,6 +1,13 @@
import { ChatWootAppConfig } from '@waha/apps/chatwoot/dto/config.dto';
import { Type } from 'class-transformer';
import { IsEnum, IsString, ValidateNested } from 'class-validator';
import {
IsBoolean,
IsEnum,
IsOptional,
IsString,
ValidateNested,
} from 'class-validator';
import { ApiExtraModels, ApiProperty } from '@nestjs/swagger';
export type AllowedAppConfig = ChatWootAppConfig;
@@ -8,6 +15,7 @@ export enum AppName {
chatwoot = 'chatwoot',
}
@ApiExtraModels(ChatWootAppConfig)
export class App<T extends AllowedAppConfig = any> {
@IsString()
id: string;
@@ -19,6 +27,16 @@ export class App<T extends AllowedAppConfig = any> {
@IsEnum(AppName)
app: AppName;
@ApiProperty({
description:
'Enable or disable this app without deleting it. If omitted, treated as enabled (true).',
required: false,
default: true,
})
@IsOptional()
@IsBoolean()
enabled?: boolean = true;
@ValidateNested()
@Type((options) => {
if (options && options.object && options.object.app) {
+12
View File
@@ -0,0 +1,12 @@
import { ILogger } from '@waha/apps/app_sdk/ILogger';
export function JestLogger(): ILogger {
return {
fatal: jest.fn(),
error: jest.fn(),
warn: jest.fn(),
info: jest.fn(),
debug: jest.fn(),
trace: jest.fn(),
};
}
@@ -0,0 +1,26 @@
import { Knex } from 'knex';
exports.up = async function (knex: Knex) {
// Add a boolean column 'enabled' defaulting to true and not nullable.
const hasColumn = await knex.schema.hasColumn('apps', 'enabled');
if (!hasColumn) {
await knex.schema.alterTable('apps', (table) => {
table.boolean('enabled').defaultTo(true);
});
// Ensure existing rows have enabled=true
await knex('apps').update({ enabled: true });
// Make the column NOT NULL
await knex.schema.alterTable('apps', (table) => {
table.boolean('enabled').notNullable().defaultTo(true).alter();
});
}
};
exports.down = async function (knex: Knex) {
const hasColumn = await knex.schema.hasColumn('apps', 'enabled');
if (hasColumn) {
await knex.schema.alterTable('apps', (table) => {
table.dropColumn('enabled');
});
}
};
@@ -21,11 +21,15 @@ export class AppsDisabledService implements IAppsService {
throw new AppsIsDisabledError();
}
async get(manager: SessionManager, appId: string): Promise<App> {
throw new AppsIsDisabledError();
}
async create(manager: SessionManager, app: App): Promise<App> {
throw new AppsIsDisabledError();
}
async update(manager: SessionManager, app: App) {
async update(manager: SessionManager, app: App): Promise<App> {
throw new AppsIsDisabledError();
}
@@ -40,4 +44,8 @@ export class AppsDisabledService implements IAppsService {
async beforeSessionStart(session: WhatsappSession, store: DataStore) {
return;
}
async afterSessionStart(session: WhatsappSession, store: DataStore) {
return;
}
}
@@ -58,15 +58,32 @@ export class AppsEnabledService implements IAppsService {
}
const service = this.getAppService(app);
await service.beforeCreated(app);
service.validate(app);
// Only run beforeCreated when app is enabled (default true if omitted)
if (app.enabled !== false) {
await service.beforeCreated(app);
}
const result = await repo.save(app);
await this.restartIfRunning(manager, app.session);
if (app.enabled) {
await this.restartIfRunning(manager, app.session);
}
delete result.pk;
return result;
}
async update(manager: SessionManager, app: App) {
async get(manager: SessionManager, appId: string): Promise<App> {
const knex = manager.store.getWAHADatabase();
const repo = new AppRepository(knex);
const app = await repo.getById(appId);
if (!app) {
throw new NotFoundException(`App '${appId}' not found`);
}
delete (app as any).pk;
return app;
}
async update(manager: SessionManager, app: App): Promise<App> {
await this.checkSessionExists(manager, app.session);
const knex = manager.store.getWAHADatabase();
const repo = new AppRepository(knex);
@@ -86,11 +103,26 @@ export class AppsEnabledService implements IAppsService {
}
const service = this.getAppService(app);
await service.beforeUpdated(savedApp, app);
service.validate(app);
const hasEnabledChange = savedApp.enabled !== app.enabled;
if (hasEnabledChange) {
if (app.enabled) {
await service.beforeEnabled(savedApp, app);
} else {
await service.beforeDisabled(savedApp, app);
}
} else {
await service.beforeUpdated(savedApp, app);
}
await repo.update(app.id, app);
await this.restartIfRunning(manager, app.session);
return;
const updated = await repo.getById(app.id);
delete (updated as any)?.pk;
return updated!;
}
async delete(manager: SessionManager, appId: string) {
@@ -110,10 +142,20 @@ export class AppsEnabledService implements IAppsService {
async beforeSessionStart(session: WhatsappSession, store: DataStore) {
const knex = store.getWAHADatabase();
const repo = new AppRepository(knex);
const apps = await repo.getAllBySession(session.name);
const apps = await repo.getEnabledBySession(session.name);
for (const app of apps) {
const service = this.getAppService(app);
await service.beforeSessionStart(app, session);
service.beforeSessionStart(app, session);
}
}
async afterSessionStart(session: WhatsappSession, store: DataStore) {
const knex = store.getWAHADatabase();
const repo = new AppRepository(knex);
const apps = await repo.getEnabledBySession(session.name);
for (const app of apps) {
const service = this.getAppService(app);
service.afterSessionStart(app, session);
}
}
+15 -1
View File
@@ -5,11 +5,25 @@ import { WhatsappSession } from '@waha/core/abc/session.abc';
* Exact App service
*/
export interface IAppService {
validate(app: App): void;
beforeCreated(app: App): Promise<void>;
/**
* Called only when the app transitions from disabled -> enabled.
*/
beforeEnabled(savedApp: App, newApp: App): Promise<void>;
/**
* Called only when the app transitions from enabled -> disabled.
*/
beforeDisabled(savedApp: App, newApp: App): Promise<void>;
beforeUpdated(savedApp: App, newApp: App): Promise<void>;
beforeDeleted(app: App): Promise<void>;
beforeSessionStart(app: App, session: WhatsappSession): Promise<void>;
beforeSessionStart(app: App, session: WhatsappSession): void;
afterSessionStart(app: App, session: WhatsappSession): void;
}
+5 -1
View File
@@ -7,14 +7,18 @@ import { Knex } from 'knex';
export interface IAppsService {
list(manager: SessionManager, session: string): Promise<App[]>;
get(manager: SessionManager, appId: string): Promise<App>;
create(manager: SessionManager, app: App): Promise<App>;
update(manager: SessionManager, app: App): Promise<void>;
update(manager: SessionManager, app: App): Promise<App>;
delete(manager: SessionManager, appId: string): Promise<void>;
beforeSessionStart(session: WhatsappSession, store: DataStore): Promise<void>;
afterSessionStart(session: WhatsappSession, store: DataStore): Promise<void>;
migrate(knex: Knex): Promise<void>;
}
+50 -3
View File
@@ -16,7 +16,7 @@ export class AppRepository {
* Saves an app to the database
*/
async save(app: Omit<App, 'pk'>): Promise<AppDB> {
const appToSave = { ...app };
const appToSave: any = { ...app };
if (appToSave.config && typeof appToSave.config === 'object') {
appToSave.config = JSON.stringify(appToSave.config);
}
@@ -29,7 +29,25 @@ export class AppRepository {
private deserialize(app: AppDB): AppDB {
const parsedConfig =
typeof app.config === 'string' ? JSON.parse(app.config) : app.config;
return { ...app, config: parsedConfig };
// Ensure 'enabled' is boolean (SQLite may return 0/1)
let enabled: boolean;
switch (app.enabled as any) {
case undefined:
case true:
case 1:
case '1':
enabled = true;
break;
case false:
case 0:
enabled = false;
break;
default:
enabled = true;
}
return { ...(app as any), enabled: enabled, config: parsedConfig } as AppDB;
}
private serialize<T extends Partial<App>>(app: T): T {
@@ -51,6 +69,20 @@ export class AppRepository {
return this.deserialize(app);
}
/**
* Gets an enabled app by id, or null if not found or disabled.
*/
async findEnabledAppById(id: string): Promise<AppDB | null> {
const app = await this.knex(this.tableName)
.where('id', id)
.andWhere('enabled', true)
.first();
if (!app) {
return null;
}
return this.deserialize(app);
}
/**
* Gets all apps
*/
@@ -62,11 +94,26 @@ export class AppRepository {
.then((apps) => apps.map((app) => this.deserialize(app)));
}
/**
* Gets only enabled apps for a session.
*/
async getEnabledBySession(session: string): Promise<AppDB[]> {
return this.knex(this.tableName)
.select('*')
.where('session', session)
.andWhere('enabled', true)
.orderBy('id', 'asc')
.then((apps) => apps.map((app) => this.deserialize(app)));
}
/**
* Updates an app
*/
async update(id: string, app: Partial<Omit<App, 'id'>>): Promise<void> {
const appToUpdate = this.serialize(app);
const appToUpdate: any = this.serialize(app);
if (appToUpdate.enabled === undefined) {
delete appToUpdate.enabled; // keep current value
}
await this.knex(this.tableName).where('id', id).update(appToUpdate);
}
+2 -1
View File
@@ -9,6 +9,7 @@ import { BullAuthMiddleware } from '@waha/apps/app_sdk/auth';
import { AppsDisabledService } from '@waha/apps/app_sdk/services/AppsDisabledService';
import { AppsEnabledService } from '@waha/apps/app_sdk/services/AppsEnabledService';
import { AppsService } from '@waha/apps/app_sdk/services/IAppsService';
import { ChatwootLocalesController } from '@waha/apps/chatwoot/api/chatwoot.locales.controller';
import { ChatWootExports } from '@waha/apps/chatwoot/chatwoot.module';
import { parseBool } from '@waha/helpers';
import { RMutexModule } from '@waha/modules/rmutex';
@@ -88,7 +89,7 @@ const AppsDisabled = {
},
],
imports: [],
controllers: [AppsController],
controllers: [AppsController, ChatwootLocalesController],
};
function checkApiKey() {
@@ -1,6 +1,7 @@
import { Controller, Get } from '@nestjs/common';
import { sortBy } from 'lodash';
import { ApiOperation, ApiSecurity, ApiTags } from '@nestjs/swagger';
import { LOCALE_NAMES } from '@waha/apps/chatwoot/locale';
import { i18n } from '@waha/apps/chatwoot/i18n';
interface LanguageResponse {
name: string;
@@ -17,9 +18,14 @@ export class ChatwootLocalesController {
description: 'Get available languages for Chatwoot app',
})
getLanguages(): LanguageResponse[] {
return Object.entries(LOCALE_NAMES).map(([locale, name]) => ({
name: name,
locale: locale,
}));
const locales = i18n.available();
const priority = ['en-US', 'pt-BR', 'es-ES'];
return sortBy(locales, [
(x) => {
const idx = priority.indexOf(x.locale);
return idx === -1 ? Number.MAX_SAFE_INTEGER : idx;
},
'locale',
]);
}
}
@@ -1,15 +1,26 @@
import { Body, Controller, Param, Post } from '@nestjs/common';
import {
Body,
Controller,
NotFoundException,
Param,
Post,
} from '@nestjs/common';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { GetChatID } from '@waha/apps/chatwoot/client/ids';
import { FindChatID } from '@waha/apps/chatwoot/client/ids';
import { EventName, MessageType } from '@waha/apps/chatwoot/client/types';
import { INBOX_CONTACT_CHAT_ID } from '@waha/apps/chatwoot/const';
import { InboxData } from '@waha/apps/chatwoot/consumers/types';
import { ChatWootQueueService } from '@waha/apps/chatwoot/services/ChatWootQueueService';
import { SessionManager } from '@waha/core/abc/manager.abc';
import { AppRepository } from '@waha/apps/app_sdk/storage/AppRepository';
@Controller('webhooks/chatwoot/')
@ApiTags('🧩 Apps')
export class ChatwootWebhookController {
constructor(private readonly chatWootQueueService: ChatWootQueueService) {}
constructor(
private readonly chatWootQueueService: ChatWootQueueService,
private readonly manager: SessionManager,
) {}
@Post(':session/:id')
@ApiOperation({
@@ -41,9 +52,17 @@ export class ChatwootWebhookController {
body: body,
};
// Skip if app is disabled or does not exist
const knex = this.manager.store.getWAHADatabase();
const repo = new AppRepository(knex);
const app = await repo.findEnabledAppById(id);
if (!app || app.session !== session) {
throw new NotFoundException(`App '${id}' not found`);
}
// Check if it's a command message (sent to the special inbox contact)
const sender = body?.conversation?.meta?.sender;
const chatId = GetChatID(sender);
const chatId = FindChatID(sender);
const isCommandsChat = chatId === INBOX_CONTACT_CHAT_ID;
// Check if it's a deleted message
@@ -62,6 +81,19 @@ export class ChatwootWebhookController {
}
return { success: true };
case EventName.MESSAGE_UPDATED:
// We handle only "retries" on message_update
// This is the attribute ChatWoot send
// There's NO other way to identify "status: read" updates right now
// There's no "body.status" in message_updated webhook :(
const isRetryNull = body.content_attributes?.external_error === null;
const isRetrySomething = Boolean(
body.content_attributes?.external_error,
);
const isRetry = isRetryNull || isRetrySomething;
if (!isRetry) {
return { success: true };
}
if (!isCommandsChat) {
await this.chatWootQueueService.addMessageUpdatedJob(data);
} else {
@@ -70,6 +102,7 @@ export class ChatwootWebhookController {
return { success: true };
default:
// Ignore other events
await this.chatWootQueueService.addJobToQueue(body.event, data);
return { success: true };
}
}
+4 -4
View File
@@ -1,8 +1,8 @@
import { public_conversation } from '@figuro/chatwoot-sdk';
import { ChatWootAPIConfig } from '@waha/apps/chatwoot/client/interfaces';
import * as NodeCache from 'node-cache';
import { IConversationCache } from './IConversationCache';
import { ContactIds } from '@waha/apps/chatwoot/client/ConversationService';
const cache: NodeCache = new NodeCache({
stdTTL: 24 * 60 * 60, // 1 day
@@ -16,7 +16,7 @@ export function CacheForConfig(config: ChatWootAPIConfig): ConversationCache {
class ConversationCache implements IConversationCache {
constructor(private prefix: string) {}
fullKey(key: string) {
private fullKey(key: string) {
return `${this.prefix}.${key}`;
}
@@ -25,7 +25,7 @@ class ConversationCache implements IConversationCache {
cache.del(fullKey);
}
get(key: string): public_conversation | null {
get(key: string): ContactIds | null {
const fullKey = this.fullKey(key);
return cache.get(fullKey) || null;
}
@@ -35,7 +35,7 @@ class ConversationCache implements IConversationCache {
return cache.has(fullKey);
}
set(key: string, value: public_conversation): void {
set(key: string, value: ContactIds): void {
const fullKey = this.fullKey(key);
cache.set(fullKey, value);
}
+3 -3
View File
@@ -1,8 +1,8 @@
import { public_conversation } from '@figuro/chatwoot-sdk';
import { ContactIds } from '@waha/apps/chatwoot/client/ConversationService';
export interface IConversationCache {
get(key: string): public_conversation | null;
set(key: string, value: public_conversation): void;
get(key: string): ContactIds | null;
set(key: string, value: ContactIds): void;
has(key: string): boolean;
delete(key: string): void;
clean(): void;
+19 -1
View File
@@ -1,4 +1,3 @@
import { Module } from '@nestjs/common';
import { RegisterAppQueue } from '@waha/apps/app_sdk/BullUtils';
import {
ExponentialRetriesJobOptions,
@@ -22,10 +21,13 @@ import { WAHAMessageAnyConsumer } from './consumers/waha/message.any';
import { WAHAMessageEditedConsumer } from './consumers/waha/message.edited';
import { WAHAMessageReactionConsumer } from './consumers/waha/message.reaction';
import { WAHAMessageRevokedConsumer } from './consumers/waha/message.revoked';
import { WAHAMessageAckConsumer } from './consumers/waha/message.ack';
import { WAHASessionStatusConsumer } from './consumers/waha/session.status';
import { ChatWootQueueService } from './services/ChatWootQueueService';
import { ChatWootScheduleService } from './services/ChatWootScheduleService';
import { ChatWootWAHAQueueService } from './services/ChatWootWAHAQueueService';
import { ChatWootConversationCreatedConsumer } from './consumers/inbox/conversation_created';
import { ChatWootConversationStatusChangedConsumer } from '@waha/apps/chatwoot/consumers/inbox/conversation_status_changed';
const CONTROLLERS = [ChatwootWebhookController, ChatwootLocalesController];
@@ -54,6 +56,10 @@ const IMPORTS = lodash.flatten([
name: QueueName.WAHA_MESSAGE_REVOKED,
defaultJobOptions: merge(ExponentialRetriesJobOptions, JobRemoveOptions),
}),
RegisterAppQueue({
name: QueueName.WAHA_MESSAGE_ACK,
defaultJobOptions: merge(ExponentialRetriesJobOptions, JobRemoveOptions),
}),
RegisterAppQueue({
name: QueueName.WAHA_SESSION_STATUS,
defaultJobOptions: merge(ExponentialRetriesJobOptions, JobRemoveOptions),
@@ -66,6 +72,14 @@ const IMPORTS = lodash.flatten([
name: QueueName.INBOX_MESSAGE_UPDATED,
defaultJobOptions: merge(ExponentialRetriesJobOptions, JobRemoveOptions),
}),
RegisterAppQueue({
name: QueueName.INBOX_CONVERSATION_CREATED,
defaultJobOptions: merge(NoRetriesJobOptions, JobRemoveOptions),
}),
RegisterAppQueue({
name: QueueName.INBOX_CONVERSATION_STATUS_CHANGED,
defaultJobOptions: merge(NoRetriesJobOptions, JobRemoveOptions),
}),
RegisterAppQueue({
name: QueueName.INBOX_MESSAGE_DELETED,
defaultJobOptions: merge(ExponentialRetriesJobOptions, JobRemoveOptions),
@@ -80,12 +94,16 @@ const PROVIDERS = [
ChatWootInboxMessageCreatedConsumer,
ChatWootInboxMessageUpdatedConsumer,
ChatWootInboxMessageDeletedConsumer,
// Conversation events
ChatWootConversationCreatedConsumer,
ChatWootConversationStatusChangedConsumer,
ChatWootInboxCommandsConsumer,
WAHASessionStatusConsumer,
WAHAMessageAnyConsumer,
WAHAMessageReactionConsumer,
WAHAMessageEditedConsumer,
WAHAMessageRevokedConsumer,
WAHAMessageAckConsumer,
MessageCleanupConsumer,
CheckVersionConsumer,
ChatWootWAHAQueueService,
@@ -0,0 +1,26 @@
import axios from 'axios';
export class ChatWootInboxNewAPI {
constructor(
private base: string,
private inboxIdentifier: string,
) {}
async updateLastSeen(sourceId: string, conversationId: number) {
// TODO: Move to the lib (fork?)
// Call the update_last_seen endpoint using a direct HTTP request
// since the SDK doesn't have this method
const path = `/public/api/v1/inboxes/${this.inboxIdentifier}/contacts/${sourceId}/conversations/${conversationId}/update_last_seen`;
const url = new URL(path, this.base).toString();
await axios.post(
url,
{},
{
headers: {
api_access_token: this.inboxIdentifier,
'Content-Type': 'application/json',
},
},
);
}
}
@@ -1,15 +1,17 @@
import ChatwootClient, {
ApiError,
ApiError as ChatWootAPIError,
public_contact_create_update_payload,
public_conversation,
} from '@figuro/chatwoot-sdk';
import { ILogger } from '@waha/apps/app_sdk/ILogger';
import { ContactAPI } from '@waha/apps/chatwoot/client/ContactAPI';
import { ContactService } from '@waha/apps/chatwoot/client/ContactService';
import { Conversation } from '@waha/apps/chatwoot/client/Conversation';
import { ConversationAPI } from '@waha/apps/chatwoot/client/ConversationAPI';
import {
ContactIds,
ConversationService,
} from '@waha/apps/chatwoot/client/ConversationService';
import { ChatWootAPIConfig } from '@waha/apps/chatwoot/client/interfaces';
import { InboxContactInfo } from '@waha/apps/chatwoot/contacts/InboxContactInfo';
import { Locale } from '@waha/apps/chatwoot/locale';
import { Locale } from '@waha/apps/chatwoot/i18n/locale';
import { CacheForConfig } from '../cache/ConversationCache';
import { IConversationCache } from '../cache/IConversationCache';
@@ -29,8 +31,8 @@ export class ContactConversationService {
constructor(
private config: ChatWootAPIConfig,
private contactAPI: ContactAPI,
private conversationAPI: ConversationAPI,
private contactService: ContactService,
private conversationService: ConversationService,
private accountAPI: ChatwootClient,
private logger: ILogger,
private l: Locale,
@@ -40,7 +42,7 @@ export class ContactConversationService {
private async upsertByContactInfo(
contactInfo: ContactInfo,
): Promise<public_conversation> {
): Promise<ContactIds> {
const chatId = contactInfo.ChatId();
// Check cache for chat id
@@ -51,61 +53,75 @@ export class ContactConversationService {
//
// Find or create contact
//
let contact = await this.contactAPI.searchByAnyID(chatId);
let contact = await this.contactService.searchByAnyID(chatId);
if (!contact) {
const request = await contactInfo.PublicContactCreate();
contact = await this.contactAPI.create(chatId, request);
contact = await this.contactService.create(chatId, request);
}
// Update custom attributes - always
const attributes = await contactInfo.Attributes();
this.logger.info(
`Updating contact custom attributes for chat.id: ${chatId}, contact.id: ${contact.data.id}`,
`Updating if required contact custom attributes for chat.id: ${chatId}, contact.id: ${contact.data.id}`,
);
await this.contactAPI.updateCustomAttributes(contact.data, attributes);
await this.contactService.upsertCustomAttributes(contact.data, attributes);
// Update Avatar if nothing, but keep the original one if any
if (!contact.data.thumbnail) {
const avatarUrl = await contactInfo.AvatarUrl();
const avatarUrl = await contactInfo.AvatarUrl().catch((err) => {
this.logger.warn(
`Error getting avatar for chat.id from WhatsApp: ${chatId}`,
);
this.logger.warn(err);
return null;
});
if (avatarUrl) {
this.contactAPI.updateAvatarUrlSafe(contact.data.id, avatarUrl);
this.contactService.updateAvatarUrlSafe(contact.data.id, avatarUrl);
}
}
this.logger.info(
`Using contact for chat.id: ${chatId}, contact.id: ${contact.sourceId}`,
`Using contact for chat.id: ${chatId}, contact.id: ${contact.data.id}, contact.sourceId: ${contact.sourceId}`,
);
//
// Get or create a conversation for this inbox
//
const conversation = await this.conversationAPI.upsert(contact.sourceId);
const conversation = await this.conversationService.upsert({
id: contact.data.id,
sourceId: contact.sourceId,
});
this.logger.info(
`Using conversation for chat.id: ${chatId}, conversation.id: ${conversation.id}, contact.id: ${contact.sourceId}`,
);
// Save to cache
this.cache.set(chatId, conversation);
return conversation;
const ids = {
id: conversation.id,
sourceId: contact.sourceId,
};
this.cache.set(chatId, ids);
return ids;
}
public async ConversationByContact(
contactInfo: ContactInfo,
): Promise<Conversation> {
const chatId = contactInfo.ChatId();
const publicConversation = await this.upsertByContactInfo(contactInfo);
const ids = await this.upsertByContactInfo(contactInfo);
const conversation = new Conversation(
this.accountAPI,
this.config.accountId,
publicConversation.id,
ids.id,
ids.sourceId,
);
conversation.onError = (err) => {
if (err instanceof ApiError) {
if (err instanceof ChatWootAPIError) {
// invalidate cache
this.cache.delete(chatId);
this.logger.error(`ApiError: ${err.message}`);
this.logger.error(
`ApiError occurred, invalidating cache for chat.id: ${chatId}, conversation.id: ${publicConversation.id}`,
`ApiError occurred, invalidating cache for chat.id: ${chatId}, conversation.id: ${ids.id}, source.id: ${ids.sourceId}`,
);
}
};
@@ -127,4 +143,33 @@ export class ContactConversationService {
public async InboxNotifications() {
return this.ConversationByContact(new InboxContactInfo(this.l));
}
public ResetCache(chatIds: Array<string>) {
this.logger.info(`Resetting cache chat ids: ${chatIds.join(', ')}`);
for (const chatId of chatIds) {
this.cache.delete(chatId);
}
}
public ResetMismatchedCache(chatIds: Array<string>, contactId: number) {
for (const chatId of chatIds) {
if (!this.cache.has(chatId)) {
continue;
}
const current = this.cache.get(chatId);
if (current.id !== contactId) {
this.logger.info(
`Resetting cache for chat id: ${chatId}, value changed from ${current} to ${contactId}`,
);
this.cache.delete(chatId);
}
}
}
public async markConversationAsRead(
conversationId: number,
sourceId: string,
): Promise<void> {
await this.conversationService.markAsRead(conversationId, sourceId);
}
}
@@ -13,13 +13,14 @@ import { isJidCusFormat } from '@waha/utils/wa';
import * as lodash from 'lodash';
import { AttributeKey } from '../const';
import { E164Parser } from '@waha/core/utils/PhoneJidNormalizer';
export interface ContactResponse {
data: generic_id & contact;
sourceId: string;
}
export class ContactAPI {
export class ContactService {
constructor(
private config: ChatWootAPIConfig,
private accountAPI: ChatwootClient,
@@ -64,8 +65,8 @@ export class ContactAPI {
if (isJidCusFormat(chatId)) {
// Search by phone
let phone_number = chatId.split('@')[0];
phone_number = phone_number.replace('+', '');
const phoneNumberE164 = E164Parser.fromJid(chatId);
const phone_number = phoneNumberE164.replace('+', '');
payload[payload.length - 1].query_operator = 'OR';
payload.push({
attribute_key: 'phone_number',
@@ -96,18 +97,22 @@ export class ContactAPI {
};
}
public updateCustomAttributes(
public async upsertCustomAttributes(
contact: generic_id & contact,
attributes: any,
) {
): Promise<boolean> {
if (lodash.isEqual(attributes, contact.custom_attributes)) {
return false;
}
const update: contact_update = {
custom_attributes: { ...contact.custom_attributes, ...attributes },
};
return this.accountAPI.contacts.update({
await this.accountAPI.contacts.update({
id: contact.id,
accountId: this.config.accountId,
data: update,
});
return true;
}
public async create(
@@ -142,7 +147,7 @@ export class ContactAPI {
})
.catch((e) => {
this.logger.warn(
'Error updating avatar_url for contact.id: ' + contactId,
`Error updating avatar_url for contact.id: ${contactId}`,
);
this.logger.warn(e);
});
+1
View File
@@ -9,6 +9,7 @@ export class Conversation {
private accountAPI: ChatwootClient,
private accountId: number,
public conversationId: number,
public sourceId: string | null = null,
) {}
public async send(data: conversation_message_create) {
@@ -1,52 +0,0 @@
import { public_conversation } from '@figuro/chatwoot-sdk';
import { ILogger } from '@waha/apps/app_sdk/ILogger';
import {
ChatWootAPIConfig,
ChatWootInboxAPI,
} from '@waha/apps/chatwoot/client/interfaces';
export class ConversationAPI {
constructor(
private config: ChatWootAPIConfig,
private inboxAPI: ChatWootInboxAPI,
private logger: ILogger,
) {}
private async find(
contactIdentifier: string,
): Promise<public_conversation | null> {
const request = {
inboxIdentifier: this.config.inboxIdentifier,
contactIdentifier: contactIdentifier,
};
const conversations = await this.inboxAPI.conversations.list(request);
if (conversations.length != 0) {
return conversations[0];
}
return null;
}
private async create(
contactIdentifier: string,
): Promise<public_conversation> {
const conversation = await this.inboxAPI.conversations.create({
inboxIdentifier: this.config.inboxIdentifier,
contactIdentifier: contactIdentifier,
});
this.logger.info(
`Created conversation.id: ${conversation.id} for contact.id: ${contactIdentifier}`,
);
return conversation;
}
async upsert(contactIdentifier: string): Promise<public_conversation> {
let conversation = await this.find(contactIdentifier);
if (!conversation) {
conversation = await this.create(contactIdentifier);
}
this.logger.info(
`Using conversation.id: ${conversation.id} for contact.id: ${contactIdentifier}`,
);
return conversation;
}
}
@@ -0,0 +1,78 @@
import ChatwootClient, { contact_conversations } from '@figuro/chatwoot-sdk';
import { ILogger } from '@waha/apps/app_sdk/ILogger';
import {
ChatWootAPIConfig,
ChatWootInboxAPI,
} from '@waha/apps/chatwoot/client/interfaces';
import type { conversation } from '@figuro/chatwoot-sdk/dist/models/conversation';
import { ConversationSelector } from '@waha/apps/chatwoot/services/ConversationSelector';
import axios from 'axios';
import { ChatWootInboxNewAPI } from '@waha/apps/chatwoot/client/ChatWootInboxNewAPI';
export type ConversationResult = Pick<conversation, 'id' | 'account_id'>;
export interface ContactIds {
id: number;
sourceId: string;
}
export class ConversationService {
constructor(
private config: ChatWootAPIConfig,
private accountAPI: ChatwootClient,
private inboxAPI: ChatWootInboxAPI,
private selector: ConversationSelector,
private logger: ILogger,
) {}
private async find(contact: ContactIds): Promise<ConversationResult | null> {
const result: { payload: contact_conversations } =
(await this.accountAPI.contacts.listConversations({
accountId: this.config.accountId,
id: contact.id,
})) as any;
const conversations = result.payload;
return this.selector.select(conversations);
}
private async create(contact: ContactIds): Promise<ConversationResult> {
const conversation = await this.inboxAPI.conversations.create({
inboxIdentifier: this.config.inboxIdentifier,
contactIdentifier: contact.sourceId,
});
this.logger.info(
`Created conversation.id: ${conversation.id} for contact.id: ${contact.id}, contact.sourceId: ${contact.sourceId}`,
);
return conversation;
}
async upsert(contact: ContactIds): Promise<ConversationResult> {
let conversation = await this.find(contact);
if (!conversation) {
conversation = await this.create(contact);
}
this.logger.info(
`Using conversation.id: ${conversation.id} for contact.id: ${contact.id}, contact.sourceId: ${contact.sourceId}`,
);
return conversation;
}
async markAsRead(conversationId: number, sourceId: string): Promise<void> {
try {
const inboxNewAPI = new ChatWootInboxNewAPI(
this.config.url,
this.config.inboxIdentifier,
);
await inboxNewAPI.updateLastSeen(sourceId, conversationId);
this.logger.info(
`Marked conversation.id: ${conversationId} as read in inbox: ${this.config.inboxIdentifier} for contact: ${sourceId}`,
);
} catch (error) {
const reason = error instanceof Error ? error.message : String(error);
this.logger.error(
`Error marking conversation.id: ${conversationId} as read: ${reason}`,
);
throw error;
}
}
}
@@ -1,53 +0,0 @@
import ChatwootClient from '@figuro/chatwoot-sdk';
import { ChatWootAccountAPIConfig } from '@waha/apps/chatwoot/client/interfaces';
import {
CustomAttributeModel,
CustomAttributeType,
} from '@waha/apps/chatwoot/client/types';
export interface CustomAttribute {
key: string;
name: string;
type: CustomAttributeType;
description: string;
model: CustomAttributeModel;
}
export class CustomAttributesAPI {
constructor(
private config: ChatWootAccountAPIConfig,
private accountAPI: ChatwootClient,
) {}
async upsert(attribute: CustomAttribute): Promise<void> {
const attributes = await this.accountAPI.customAttributes.list({
accountId: this.config.accountId,
attributeModel: String(attribute.model) as '0' | '1',
});
const existing = attributes.find((a) => a.attribute_key === attribute.key);
if (existing) {
await this.accountAPI.customAttributes.update({
accountId: this.config.accountId,
id: existing.id,
data: {
attribute_key: attribute.key,
attribute_display_name: attribute.name,
attribute_display_type: attribute.type,
attribute_description: attribute.description,
},
});
} else {
await this.accountAPI.customAttributes.create({
accountId: this.config.accountId,
data: {
attribute_key: attribute.key,
attribute_display_name: attribute.name,
attribute_display_type: attribute.type,
attribute_description: attribute.description,
attribute_model: attribute.model,
},
});
}
}
}
@@ -0,0 +1,68 @@
import ChatwootClient from '@figuro/chatwoot-sdk';
import { ChatWootAccountAPIConfig } from '@waha/apps/chatwoot/client/interfaces';
import {
CustomAttributeModel,
CustomAttributeType,
} from '@waha/apps/chatwoot/client/types';
import type { custom_attribute } from '@figuro/chatwoot-sdk/dist/models/custom_attribute';
export interface CustomAttribute {
key: string;
name: string;
type: CustomAttributeType;
description: string;
model: CustomAttributeModel;
}
export class CustomAttributesService {
constructor(
private config: ChatWootAccountAPIConfig,
private accountAPI: ChatwootClient,
) {}
async upsert(attributes: Array<CustomAttribute>): Promise<void> {
const current: Record<CustomAttributeModel, Array<custom_attribute>> = {
[CustomAttributeModel.CONVERSATION]: [],
[CustomAttributeModel.CONTACT]: [],
};
const models = [
CustomAttributeModel.CONVERSATION,
CustomAttributeModel.CONTACT,
];
for (const model of models) {
current[model] = await this.accountAPI.customAttributes.list({
accountId: this.config.accountId,
attributeModel: String(model) as '0' | '1',
});
}
for (const attribute of attributes) {
const existing = current[attribute.model].find(
(a) => a.attribute_key === attribute.key,
);
if (existing) {
await this.accountAPI.customAttributes.update({
accountId: this.config.accountId,
id: existing.id,
data: {
attribute_key: attribute.key,
attribute_display_name: attribute.name,
attribute_display_type: attribute.type,
attribute_description: attribute.description,
},
});
} else {
await this.accountAPI.customAttributes.create({
accountId: this.config.accountId,
data: {
attribute_key: attribute.key,
attribute_display_name: attribute.name,
attribute_display_type: attribute.type,
attribute_description: attribute.description,
attribute_model: attribute.model,
},
});
}
}
}
}
+24 -1
View File
@@ -1,7 +1,7 @@
import { isLidUser } from '@adiwajshing/baileys/lib/WABinary/jid-utils';
import { AttributeKey } from '@waha/apps/chatwoot/const';
import { WhatsAppMessage } from '@waha/apps/chatwoot/storage';
import { buildMessageId } from '@waha/core/engines/noweb/session.noweb.core';
import { isLidUser } from '@waha/core/utils/jids';
export function GetJID(contact: any): string | null {
return contact?.custom_attributes?.[AttributeKey.WA_JID];
@@ -15,6 +15,29 @@ export function GetChatID(contact: any): string | null {
return contact?.custom_attributes?.[AttributeKey.WA_CHAT_ID];
}
export function GetAllChatIDs(contact: any): Array<string> {
const attrs = contact?.custom_attributes || {};
const ids = [
attrs[AttributeKey.WA_CHAT_ID],
attrs[AttributeKey.WA_JID],
attrs[AttributeKey.WA_LID],
];
return ids.filter(Boolean);
}
export function FindChatID(contact: any): string | null {
if (GetJID(contact)) {
return GetJID(contact);
}
if (GetLID(contact)) {
return GetLID(contact);
}
if (GetChatID(contact)) {
return GetChatID(contact);
}
return null;
}
export function SerializeWhatsAppKey(message: WhatsAppMessage): string {
const key = {
id: message.message_id,
+7
View File
@@ -51,3 +51,10 @@ export enum CustomAttributeModel {
CONVERSATION = 0,
CONTACT = 1,
}
export enum ConversationStatus {
OPEN = 'open',
PENDING = 'pending',
SNOOZED = 'snoozed',
RESOLVED = 'resolved',
}
+1 -1
View File
@@ -1,4 +1,4 @@
import { CustomAttribute } from '@waha/apps/chatwoot/client/CustomAttributesAPI';
import { CustomAttribute } from '@waha/apps/chatwoot/client/CustomAttributesService';
import { CustomAttributeModel, CustomAttributeType } from './client/types';
+3
View File
@@ -13,11 +13,14 @@ export enum QueueName {
WAHA_MESSAGE_REACTION = 'chatwoot.waha | message.reaction',
WAHA_MESSAGE_EDITED = 'chatwoot.waha | message.edited',
WAHA_MESSAGE_REVOKED = 'chatwoot.waha | message.revoked',
WAHA_MESSAGE_ACK = 'chatwoot.waha | message.ack',
//
// ChatWoot Events - Real
//
INBOX_MESSAGE_CREATED = 'chatwoot.inbox | message_created',
INBOX_MESSAGE_UPDATED = 'chatwoot.inbox | message_updated',
INBOX_CONVERSATION_CREATED = 'chatwoot.inbox | conversation_created',
INBOX_CONVERSATION_STATUS_CHANGED = 'chatwoot.inbox | conversation_status_changed',
//
// ChatWoot Events - Artificial
//
+11 -4
View File
@@ -1,7 +1,7 @@
import { AppConsumer } from '@waha/apps/app_sdk/AppConsumer';
import { JobLoggerWrapper } from '@waha/apps/app_sdk/JobLoggerWrapper';
import { HasBeenRetried } from '@waha/apps/app_sdk/JobUtils';
import { GetChatID } from '@waha/apps/chatwoot/client/ids';
import { FindChatID } from '@waha/apps/chatwoot/client/ids';
import { EventName } from '@waha/apps/chatwoot/client/types';
import { ChatWootConversationKey } from '@waha/apps/chatwoot/consumers/mutex';
import { InboxData } from '@waha/apps/chatwoot/consumers/types';
@@ -10,7 +10,6 @@ import {
ChatIDNotFoundForContactError,
PhoneNumberNotFoundInWhatsAppError,
} from '@waha/apps/chatwoot/errors';
import { TKey } from '@waha/apps/chatwoot/locale';
import { WAHASessionAPI } from '@waha/apps/chatwoot/session/WAHASelf';
import { SessionManager } from '@waha/core/abc/manager.abc';
import { RMutexService } from '@waha/modules/rmutex/rmutex.service';
@@ -18,6 +17,7 @@ import { Job } from 'bullmq';
import { PinoLogger } from 'nestjs-pino';
import { AppRepository } from '../../storage';
import { TKey } from '@waha/apps/chatwoot/i18n/templates';
/**
* Base class for ChatWoot inbox consumers
@@ -58,13 +58,20 @@ export abstract class ChatWootInboxMessageConsumer extends AppConsumer {
job: Job,
): Promise<any>;
protected GetConversationID(body) {
return body.conversation.id;
}
/**
* Process the job
* This method is called by the queue processor
*/
async processJob(job: Job<InboxData, any, EventName>): Promise<any> {
const body = job.data.body;
const key = ChatWootConversationKey(job.data.app, body.conversation.id);
const key = ChatWootConversationKey(
job.data.app,
this.GetConversationID(body),
);
return await this.withMutex(job, key, () =>
this.ProcessAndReportStatus(job),
);
@@ -124,7 +131,7 @@ export async function LookupAndCheckChatId(
body: any,
): Promise<string> {
const sender = body.conversation.meta.sender;
let chatId = GetChatID(sender);
let chatId = FindChatID(sender);
if (!chatId && sender.phone_number) {
const existResult = await session.contactCheckExists(sender.phone_number);
if (!existResult.numberExists) {
+28 -10
View File
@@ -7,13 +7,15 @@ import { MessageType } from '@waha/apps/chatwoot/client/types';
import { ChatWootInboxMessageConsumer } from '@waha/apps/chatwoot/consumers/inbox/base';
import { QueueName } from '@waha/apps/chatwoot/consumers/QueueName';
import { DIContainer } from '@waha/apps/chatwoot/di/DIContainer';
import { Locale, TKey } from '@waha/apps/chatwoot/locale';
import { Locale } from '@waha/apps/chatwoot/i18n/locale';
import { WAHASelf } from '@waha/apps/chatwoot/session/WAHASelf';
import { SessionStatusEmoji } from '@waha/apps/chatwoot/SessionStatusEmoji';
import { SessionManager } from '@waha/core/abc/manager.abc';
import { RMutexService } from '@waha/modules/rmutex/rmutex.service';
import { Job } from 'bullmq';
import { PinoLogger } from 'nestjs-pino';
import { TKey } from '@waha/apps/chatwoot/i18n/templates';
import { ChatWootCommandsConfig } from '@waha/apps/chatwoot/dto/config.dto';
@Processor(QueueName.INBOX_COMMANDS, { concurrency: JOB_CONCURRENCY })
export class ChatWootInboxCommandsConsumer extends ChatWootInboxMessageConsumer {
@@ -36,11 +38,14 @@ export class ChatWootInboxCommandsConsumer extends ChatWootInboxMessageConsumer
job.data.session,
container.Locale(),
container.WAHASelf(),
container.ChatWootConfig().commands,
);
return await handler.handle(body);
}
}
const CommandServerPrefix = 'server ';
enum Command {
STATUS = 'status',
RESTART = 'restart',
@@ -99,6 +104,7 @@ class SessionCommandHandler {
private session: string,
private l: Locale,
private waha: WAHASelf,
private commands: ChatWootCommandsConfig,
) {}
async handle(message: any) {
@@ -107,6 +113,13 @@ class SessionCommandHandler {
this.logger.info(
`Executing command ${command} for session ${this.session}`,
);
const warning = this.commandDisabledWarning(command);
const conversation = await this.repo.InboxNotifications();
if (warning) {
const text = this.l.key(warning).render();
await conversation.incoming(text);
return;
}
switch (command) {
case Command.RESTART:
await this.waha.restart(this.session);
@@ -117,7 +130,6 @@ class SessionCommandHandler {
case Command.LOGOUT:
this.logger.info(`Logging out session ${this.session}`);
await this.waha.logout(this.session);
const conversation = await this.repo.InboxNotifications();
const text = this.l.key(TKey.APP_LOGOUT_SUCCESS).render();
await conversation.incoming(text);
break;
@@ -128,7 +140,6 @@ class SessionCommandHandler {
case Command.STATUS: {
this.logger.info(`Getting status for session ${this.session}`);
const session = await this.waha.get(this.session);
const conversation = await this.repo.InboxNotifications();
const emoji = SessionStatusEmoji(session.status);
const text = this.l.key(TKey.APP_SESSION_CURRENT_STATUS).render({
emoji: emoji,
@@ -144,7 +155,6 @@ class SessionCommandHandler {
this.logger.info('Getting server version and status');
const version = await this.waha.serverVersion();
const status = await this.waha.serverStatus();
const conversation = await this.repo.InboxNotifications();
const text = this.l.key(TKey.APP_SERVER_VERSION_AND_STATUS).render({
version: JSON.stringify(version, null, 2),
status: JSON.stringify(status, null, 2),
@@ -154,7 +164,6 @@ class SessionCommandHandler {
}
case Command.SERVER_REBOOT: {
this.logger.info('Rebooting server (graceful)');
const conversation = await this.repo.InboxNotifications();
const text = this.l.key(TKey.APP_SERVER_REBOOT).render();
await conversation.incoming(text);
await this.waha.serverReboot(false);
@@ -162,14 +171,12 @@ class SessionCommandHandler {
}
case Command.SERVER_REBOOT_FORCE: {
this.logger.info('Rebooting server (force)');
const conversation = await this.repo.InboxNotifications();
const text = this.l.key(TKey.APP_SERVER_REBOOT_FORCE).render();
await conversation.incoming(text);
await this.waha.serverReboot(true);
break;
}
case Command.QR: {
const conversation = await this.repo.InboxNotifications();
const content = await this.waha.qr(this.session);
const message = AttachmentFromBuffer(content, 'qr.jpg');
message.message_type = MessageType.INCOMING;
@@ -178,7 +185,6 @@ class SessionCommandHandler {
}
case Command.SCREENSHOT: {
this.logger.info(`Getting screenshot for session ${this.session}`);
const conversation = await this.repo.InboxNotifications();
const content = await this.waha.screenshot(this.session);
const message = AttachmentFromBuffer(content, 'screenshot.jpg');
message.message_type = MessageType.INCOMING;
@@ -186,8 +192,9 @@ class SessionCommandHandler {
break;
}
case Command.HELP: {
const conversation = await this.repo.InboxNotifications();
const text = this.l.key(TKey.APP_COMMANDS_LIST).render();
const text = this.l
.key(TKey.APP_COMMANDS_LIST)
.render({ commands: this.commands });
await conversation.incoming(text);
break;
}
@@ -196,6 +203,17 @@ class SessionCommandHandler {
}
}
/**
* Check if the command allowed for this session
* Returns `null` if allowed or the message key to show as an error
*/
commandDisabledWarning(command: Command): TKey | null {
if (!this.commands.server && command.startsWith(CommandServerPrefix)) {
return TKey.APP_COMMANDS_SERVER_DISABLED;
}
return null;
}
findCommand(text: string): Command {
// Remove empty from end
text = text.trim();
@@ -0,0 +1,57 @@
import { Processor } from '@nestjs/bullmq';
import { JOB_CONCURRENCY } from '@waha/apps/app_sdk/constants';
import { QueueName } from '@waha/apps/chatwoot/consumers/QueueName';
import { ChatWootConversationKey } from '@waha/apps/chatwoot/consumers/mutex';
import { ChatWootInboxMessageConsumer } from '@waha/apps/chatwoot/consumers/inbox/base';
import { InboxData } from '@waha/apps/chatwoot/consumers/types';
import { Job } from 'bullmq';
import { GetAllChatIDs } from '@waha/apps/chatwoot/client/ids';
import { DIContainer } from '@waha/apps/chatwoot/di/DIContainer';
import { TKey } from '@waha/apps/chatwoot/i18n/templates';
import { ContactConversationService } from '@waha/apps/chatwoot/client/ContactConversationService';
import { SessionManager } from '@waha/core/abc/manager.abc';
import { PinoLogger } from 'nestjs-pino';
import { RMutexService } from '@waha/modules/rmutex';
@Processor(QueueName.INBOX_CONVERSATION_CREATED, {
concurrency: JOB_CONCURRENCY,
})
export class ChatWootConversationCreatedConsumer extends ChatWootInboxMessageConsumer {
constructor(
protected readonly manager: SessionManager,
log: PinoLogger,
rmutex: RMutexService,
) {
super(manager, log, rmutex, 'ChatWootConversationCreatedConsumer');
}
protected ErrorHeaderKey(): TKey | null {
return null;
}
protected GetConversationID(body) {
return body.id;
}
protected async Process(
container: DIContainer,
body: any,
job: Job,
): Promise<any> {
const handler = new ConversationCreatedHandler(
container.ContactConversationService(),
);
return handler.handle(body);
}
}
class ConversationCreatedHandler {
constructor(private service: ContactConversationService) {}
async handle(body: any) {
const ids = GetAllChatIDs(body?.meta?.sender);
if (!ids || ids.length === 0) {
return;
}
this.service.ResetMismatchedCache(ids, body.id);
}
}
@@ -0,0 +1,62 @@
import { Processor } from '@nestjs/bullmq';
import { JOB_CONCURRENCY } from '@waha/apps/app_sdk/constants';
import { QueueName } from '@waha/apps/chatwoot/consumers/QueueName';
import { ChatWootInboxMessageConsumer } from '@waha/apps/chatwoot/consumers/inbox/base';
import { Job } from 'bullmq';
import { DIContainer } from '../../di/DIContainer';
import { TKey } from '../../i18n/templates';
import { ContactConversationService } from '@waha/apps/chatwoot/client/ContactConversationService';
import { AttributeKey } from '@waha/apps/chatwoot/const';
import { ConversationSelector } from '@waha/apps/chatwoot/services/ConversationSelector';
import { GetAllChatIDs } from '@waha/apps/chatwoot/client/ids';
import { SessionManager } from '@waha/core/abc/manager.abc';
import { PinoLogger } from 'nestjs-pino';
import { RMutexService } from '@waha/modules/rmutex';
@Processor(QueueName.INBOX_CONVERSATION_STATUS_CHANGED, {
concurrency: JOB_CONCURRENCY,
})
export class ChatWootConversationStatusChangedConsumer extends ChatWootInboxMessageConsumer {
constructor(
protected readonly manager: SessionManager,
log: PinoLogger,
rmutex: RMutexService,
) {
super(manager, log, rmutex, 'ChatWootConversationStatusChangedConsumer');
}
protected ErrorHeaderKey(): TKey | null {
return null;
}
protected GetConversationID(body) {
return body.id;
}
protected async Process(
container: DIContainer,
body: any,
job: Job,
): Promise<any> {
const handler = new ConversationStatusChangedHandler(
container.ContactConversationService(),
container.ConversationSelector(),
);
return await handler.handle(body);
}
}
class ConversationStatusChangedHandler {
constructor(
private service: ContactConversationService,
private selector: ConversationSelector,
) {}
async handle(body) {
if (!this.selector.hasStatusFilter()) {
return;
}
const ids = GetAllChatIDs(body.meta?.sender);
this.service.ResetCache(ids);
}
}
@@ -8,14 +8,14 @@ import {
} from '@waha/apps/chatwoot/consumers/inbox/base';
import { QueueName } from '@waha/apps/chatwoot/consumers/QueueName';
import { DIContainer } from '@waha/apps/chatwoot/di/DIContainer';
import { TKey } from '@waha/apps/chatwoot/locale';
import { EngineHelper } from '@waha/apps/chatwoot/session';
import { WAHASessionAPI } from '@waha/apps/chatwoot/session/WAHASelf';
import {
ChatwootMessage,
MessageMapping,
MessageMappingService,
} from '@waha/apps/chatwoot/storage';
import { MarkdownToWhatsApp } from '@waha/apps/chatwoot/text';
import { MarkdownToWhatsApp } from '@waha/apps/chatwoot/messages/to/whatsapp/markdown';
import { SessionManager } from '@waha/core/abc/manager.abc';
import { RMutexService } from '@waha/modules/rmutex/rmutex.service';
import {
@@ -30,6 +30,12 @@ import { Job } from 'bullmq';
import { PinoLogger } from 'nestjs-pino';
import { SerializeWhatsAppKey } from '../../client/ids';
import { TKey } from '@waha/apps/chatwoot/i18n/templates';
import {
ChatWootConfig,
LinkPreview,
} from '@waha/apps/chatwoot/dto/config.dto';
import { Locale } from '@waha/apps/chatwoot/i18n/locale';
// eslint-disable-next-line @typescript-eslint/no-var-requires
const mime = require('mime-types');
@@ -45,7 +51,7 @@ export class ChatWootInboxMessageCreatedConsumer extends ChatWootInboxMessageCon
}
ErrorHeaderKey(): TKey | null {
return TKey.WHATSAPP_ERROR_SENDING_MESSAGE;
return TKey.WHATSAPP_MESSAGE_SENDING_ERROR;
}
protected async Process(container: DIContainer, body, job: Job) {
@@ -55,6 +61,8 @@ export class ChatWootInboxMessageCreatedConsumer extends ChatWootInboxMessageCon
container.MessageMappingService(),
container.Logger(),
session,
container.ChatWootConfig(),
container.Locale(),
);
return await handler.handle(body);
}
@@ -65,12 +73,17 @@ export class MessageHandler {
private mappingService: MessageMappingService,
private logger: ILogger,
private session: WAHASessionAPI,
private config: ChatWootConfig,
private l: Locale,
) {}
async handle(body: any) {
const chatId = await LookupAndCheckChatId(this.session, body);
const message = body;
if (message.content_type != 'text') {
if (
message.content_type != 'text' &&
message.content_type != 'input_csat'
) {
this.logger.info(
`Message content type not supported. Content type: ${message.content_type}`,
);
@@ -78,37 +91,60 @@ export class MessageHandler {
}
const content = MarkdownToWhatsApp(message.content);
const attachments = message.attachments || [];
const results = [];
const multipleAttachments = attachments.length > 1;
let part = 1;
let part = 0; // Start from 0 and increment before each send/check
const replyTo = await this.getReplyTo(message).catch((err) => {
this.logger.error(`Error getting reply to message ID: ${err}`);
this.logger.error(
`ChatWoot => WhatsApp: error getting reply to message ID: ${err}`,
);
return undefined;
});
// Send text
if (attachments.length == 0 || multipleAttachments) {
const msg = await this.sendTextMessage(chatId, content, replyTo);
results.push(msg);
part = await this.saveMapping(message, msg, part);
this.logger.info(`Text message sent: ${msg.id}`);
// Send text (Part 1 if present)
const attachments = message.attachments || [];
const sendText = content && attachments.length !== 1;
if (sendText) {
part += 1; // Text is the first possible part
const exists = await this.getMapping(message, part);
if (exists) {
this.logger.warn(
`Skip part ${part}: mapping exists for Chatwoot message ${message.id}`,
);
} else {
const textTemplate = this.l.key(TKey.CW_TO_WA_MESSAGE_TEXT);
const text = textTemplate.render({
content: content,
chatwoot: body,
});
const msg = await this.sendTextMessage(chatId, text, replyTo);
results.push(msg);
await this.saveMapping(message, msg, part);
this.logger.info(`Text message sent: ${msg.id}`);
}
}
// Send files
const fileMessageContent = multipleAttachments ? '' : content;
const captionTemplate = this.l.key(TKey.CW_TO_WA_MESSAGE_MEDIA_CAPTION);
for (const file of attachments) {
const msg = await this.sendFile(
chatId,
fileMessageContent,
file,
replyTo,
);
part += 1; // Increment before each attachment send/check
const exists = await this.getMapping(message, part);
if (exists) {
this.logger.warn(
`Skip part ${part}: mapping exists for Chatwoot message ${message.id}`,
);
continue;
}
const caption = captionTemplate.render({
content: content,
chatwoot: body,
singleAttachment: attachments.length == 1,
});
const msg = await this.sendFile(chatId, caption, file, replyTo);
this.logger.info(
`File message sent: ${msg.id} - ${file.data_url} - ${file.file_type}`,
);
results.push(msg);
part = await this.saveMapping(message, msg, part);
await this.saveMapping(message, msg, part);
}
return results;
}
@@ -117,15 +153,27 @@ export class MessageHandler {
chatwootMessage: any,
whatsappMessage: any,
part: number,
): Promise<number> {
): Promise<void> {
const chatwoot: Omit<ChatwootMessage, 'id'> = {
timestamp: new Date(chatwootMessage.created_at),
conversation_id: chatwootMessage.conversation.id,
message_id: chatwootMessage.id,
};
const whatsapp = EngineHelper.WhatsAppMessageKeys(whatsappMessage);
await this.mappingService.map(chatwoot, whatsapp, 1);
return part + 1;
await this.mappingService.map(chatwoot, whatsapp, part);
}
private async getMapping(
message: any,
part: number,
): Promise<MessageMapping | null> {
return this.mappingService.getMappingByChatwootCombinedKeyAndPart(
{
conversation_id: message.conversation.id,
message_id: message.id,
},
part,
);
}
async getReplyTo(message): Promise<string | undefined> {
@@ -154,6 +202,10 @@ export class MessageHandler {
chatId: chatId,
text: content,
reply_to: replyTo,
linkPreview: [LinkPreview.LQ, LinkPreview.HQ].includes(
this.config.linkPreview,
),
linkPreviewHighQuality: this.config.linkPreview == LinkPreview.HQ,
};
const session = this.session;
await session.readMessages(chatId);
@@ -8,13 +8,13 @@ import {
} from '@waha/apps/chatwoot/consumers/inbox/base';
import { QueueName } from '@waha/apps/chatwoot/consumers/QueueName';
import { DIContainer } from '@waha/apps/chatwoot/di/DIContainer';
import { TKey } from '@waha/apps/chatwoot/locale';
import { WAHASessionAPI } from '@waha/apps/chatwoot/session/WAHASelf';
import { MessageMappingService } from '@waha/apps/chatwoot/storage';
import { SessionManager } from '@waha/core/abc/manager.abc';
import { RMutexService } from '@waha/modules/rmutex/rmutex.service';
import { Job } from 'bullmq';
import { PinoLogger } from 'nestjs-pino';
import { TKey } from '@waha/apps/chatwoot/i18n/templates';
@Processor(QueueName.INBOX_MESSAGE_DELETED, { concurrency: JOB_CONCURRENCY })
export class ChatWootInboxMessageDeletedConsumer extends ChatWootInboxMessageConsumer {
@@ -27,7 +27,7 @@ export class ChatWootInboxMessageDeletedConsumer extends ChatWootInboxMessageCon
}
ErrorHeaderKey(): TKey | null {
return TKey.WHATSAPP_ERROR_REMOVING_MESSAGE;
return TKey.WHATSAPP_MESSAGE_REMOVING_ERROR;
}
protected async Process(container: DIContainer, body, job: Job) {
@@ -4,13 +4,13 @@ import { ChatWootInboxMessageConsumer } from '@waha/apps/chatwoot/consumers/inbo
import { MessageHandler } from '@waha/apps/chatwoot/consumers/inbox/message_created';
import { QueueName } from '@waha/apps/chatwoot/consumers/QueueName';
import { DIContainer } from '@waha/apps/chatwoot/di/DIContainer';
import { TKey } from '@waha/apps/chatwoot/locale';
import { SessionManager } from '@waha/core/abc/manager.abc';
import { RMutexService } from '@waha/modules/rmutex/rmutex.service';
import { Job } from 'bullmq';
import { PinoLogger } from 'nestjs-pino';
import { WAHASessionAPI } from '../../session/WAHASelf';
import { TKey } from '@waha/apps/chatwoot/i18n/templates';
@Processor(QueueName.INBOX_MESSAGE_UPDATED, { concurrency: JOB_CONCURRENCY })
export class ChatWootInboxMessageUpdatedConsumer extends ChatWootInboxMessageConsumer {
@@ -23,7 +23,7 @@ export class ChatWootInboxMessageUpdatedConsumer extends ChatWootInboxMessageCon
}
ErrorHeaderKey(): TKey | null {
return TKey.WHATSAPP_ERROR_SENDING_MESSAGE;
return TKey.WHATSAPP_MESSAGE_SENDING_ERROR;
}
protected async Process(container: DIContainer, body, job: Job) {
@@ -33,6 +33,8 @@ export class ChatWootInboxMessageUpdatedConsumer extends ChatWootInboxMessageCon
container.MessageMappingService(),
container.Logger(),
session,
container.ChatWootConfig(),
container.Locale(),
);
return await handler.handle(body);
}
@@ -5,13 +5,13 @@ import { MessageType } from '@waha/apps/chatwoot/client/types';
import { ScheduledData } from '@waha/apps/chatwoot/consumers/types';
import { DIContainer } from '@waha/apps/chatwoot/di/DIContainer';
import { ChatWootAppConfig } from '@waha/apps/chatwoot/dto/config.dto';
import { TKey } from '@waha/apps/chatwoot/locale';
import { SessionManager } from '@waha/core/abc/manager.abc';
import { RMutexService } from '@waha/modules/rmutex/rmutex.service';
import { Job } from 'bullmq';
import { PinoLogger } from 'nestjs-pino';
import { AppRepository } from '../../storage';
import { TKey } from '@waha/apps/chatwoot/i18n/templates';
/**
* Base class for ChatWoot scheduled consumers
@@ -4,7 +4,6 @@ import { JOB_CONCURRENCY } from '@waha/apps/app_sdk/constants';
import { ILogger } from '@waha/apps/app_sdk/ILogger';
import { QueueName } from '@waha/apps/chatwoot/consumers/QueueName';
import { DIContainer } from '@waha/apps/chatwoot/di/DIContainer';
import { TKey } from '@waha/apps/chatwoot/locale';
import { SessionManager } from '@waha/core/abc/manager.abc';
import { CHANGELOG_URL, SUPPORT_US_URL } from '@waha/core/constants';
import { RMutexService } from '@waha/modules/rmutex/rmutex.service';
@@ -14,6 +13,7 @@ import { Job } from 'bullmq';
import { PinoLogger } from 'nestjs-pino';
import { ChatWootScheduledConsumer } from './base';
import { TKey } from '@waha/apps/chatwoot/i18n/templates';
/**
* Scheduled consumer for version checking
@@ -26,7 +26,7 @@ export class CheckVersionConsumer extends ChatWootScheduledConsumer {
}
protected ErrorHeaderKey(): TKey {
return TKey.APP_SCHEDULED_JOB_ERROR;
return TKey.JOB_SCHEDULED_ERROR_HEADER;
}
/**
@@ -50,7 +50,7 @@ export class CheckVersionConsumer extends ChatWootScheduledConsumer {
return;
}
logger.info('WAHA is using the CORE version');
const supportMessage = locale.key(TKey.APP_CORE_VERSION_USED).render({
const supportMessage = locale.key(TKey.WAHA_CORE_VERSION_USED).render({
supportUrl: SUPPORT_US_URL,
});
await conversation.incoming(supportMessage);
@@ -74,7 +74,7 @@ export class CheckVersionConsumer extends ChatWootScheduledConsumer {
// Send a message to Chatwoot conversation about a new version
const locale = container.Locale();
const message = locale.key(TKey.APP_NEW_VERSION_AVAILABLE).render({
const message = locale.key(TKey.WAHA_NEW_VERSION_AVAILABLE).render({
currentVersion: currentVersion,
newVersion: latestVersion,
changelogUrl: CHANGELOG_URL,
@@ -3,13 +3,13 @@ import { Injectable } from '@nestjs/common';
import { JOB_CONCURRENCY } from '@waha/apps/app_sdk/constants';
import { QueueName } from '@waha/apps/chatwoot/consumers/QueueName';
import { DIContainer } from '@waha/apps/chatwoot/di/DIContainer';
import { TKey } from '@waha/apps/chatwoot/locale';
import { SessionManager } from '@waha/core/abc/manager.abc';
import { RMutexService } from '@waha/modules/rmutex/rmutex.service';
import { Job } from 'bullmq';
import { PinoLogger } from 'nestjs-pino';
import { ChatWootScheduledConsumer } from './base';
import { TKey } from '@waha/apps/chatwoot/i18n/templates';
/**
* Scheduled consumer for message cleanup tasks
@@ -26,7 +26,7 @@ export class MessageCleanupConsumer extends ChatWootScheduledConsumer {
}
protected ErrorHeaderKey(): TKey {
return TKey.APP_SCHEDULED_JOB_ERROR;
return TKey.JOB_SCHEDULED_ERROR_HEADER;
}
/**
+33 -21
View File
@@ -1,4 +1,3 @@
import { isJidGroup, isJidStatusBroadcast } from '@adiwajshing/baileys';
import { conversation_message_create } from '@figuro/chatwoot-sdk';
import type { generic_id } from '@figuro/chatwoot-sdk/dist/models/generic_id';
import type { message } from '@figuro/chatwoot-sdk/dist/models/message';
@@ -13,7 +12,7 @@ import { WhatsAppChatIdKey } from '@waha/apps/chatwoot/consumers/mutex';
import { EventData } from '@waha/apps/chatwoot/consumers/types';
import { WhatsAppContactInfo } from '@waha/apps/chatwoot/contacts/WhatsAppContactInfo';
import { DIContainer } from '@waha/apps/chatwoot/di/DIContainer';
import { Locale, TKey } from '@waha/apps/chatwoot/locale';
import { Locale } from '@waha/apps/chatwoot/i18n/locale';
import { WAHASelf, WAHASessionAPI } from '@waha/apps/chatwoot/session/WAHASelf';
import {
AppRepository,
@@ -22,7 +21,6 @@ import {
WhatsAppMessage,
} from '@waha/apps/chatwoot/storage';
import { SessionManager } from '@waha/core/abc/manager.abc';
import { toCusFormat } from '@waha/core/engines/noweb/session.noweb.core';
import { parseMessageIdSerialized } from '@waha/core/utils/ids';
import { RMutexService } from '@waha/modules/rmutex/rmutex.service';
import { WAHAEvents } from '@waha/structures/enums.dto';
@@ -35,7 +33,8 @@ import { sleep } from '@waha/utils/promiseTimeout';
import { Job } from 'bullmq';
import { PinoLogger } from 'nestjs-pino';
import { ChatWootAppConfig } from '../../dto/config.dto';
import { TKey } from '@waha/apps/chatwoot/i18n/templates';
import { isJidBroadcast, isJidGroup, toCusFormat } from '@waha/core/utils/jids';
export function ListenEventsForChatWoot() {
return [
@@ -43,6 +42,7 @@ export function ListenEventsForChatWoot() {
WAHAEvents.MESSAGE_REACTION,
WAHAEvents.MESSAGE_EDITED,
WAHAEvents.MESSAGE_REVOKED,
WAHAEvents.MESSAGE_ACK,
WAHAEvents.SESSION_STATUS,
];
}
@@ -64,7 +64,7 @@ export abstract class ChatWootWAHABaseConsumer extends AppConsumer {
}
protected ErrorHeaderKey(): TKey | null {
return TKey.WHATSAPP_ERROR_RECEIVING_MESSAGE;
return TKey.WHATSAPP_MESSAGE_RECEIVING_ERROR;
}
private async ProcessAndReportErrors(job) {
@@ -97,8 +97,15 @@ export abstract class ChatWootWAHABaseConsumer extends AppConsumer {
messageInfo: IMessageInfo,
): Promise<any>;
ShouldProcess(event: any): boolean {
return true;
}
async processJob(job: Job<EventData, any, WAHAEvents>): Promise<any> {
const event: WAHAWebhookMessageRevoked = job.data.event as any;
const event = job.data.event as any;
if (!this.ShouldProcess(event)) {
return;
}
const key = WhatsAppChatIdKey(job.data.app, this.GetChatId(event));
return await this.withMutex(job, key, () =>
this.ProcessAndReportErrors(job),
@@ -151,7 +158,7 @@ export abstract class ChatWootWAHABaseConsumer extends AppConsumer {
.ContactConversationService()
.ConversationById(info.conversationId);
} else {
const conversation = await container
conversation = await container
.ContactConversationService()
.InboxNotifications();
}
@@ -183,8 +190,15 @@ class MessageReportInfo implements IMessageInfo {
}
}
export interface ChatWootMessagePartial {
content: string;
attachments: SendAttachment[];
private?: boolean;
}
export abstract class MessageBaseHandler<Payload extends WAMessageBase> {
constructor(
protected job: Job,
protected mappingService: MessageMappingService,
protected repo: ContactConversationService,
protected logger: ILogger,
@@ -194,12 +208,12 @@ export abstract class MessageBaseHandler<Payload extends WAMessageBase> {
protected waha: WAHASelf,
) {}
abstract getContent(payload: Payload): string;
protected abstract getMessage(
payload: Payload,
): Promise<ChatWootMessagePartial>;
abstract getReplyToWhatsAppID(payload: Payload): string | undefined;
abstract getAttachments(payload: Payload): Promise<SendAttachment[]>;
async handle(data: WAHAWebhook<Payload>) {
const payload = data.payload;
// Find the type as soon as possible for error reporting
@@ -262,7 +276,8 @@ export abstract class MessageBaseHandler<Payload extends WAMessageBase> {
private async buildChatWootMessage(
payload: Payload,
): Promise<conversation_message_create> {
let content: string = this.getContent(payload);
const message = await this.getMessage(payload);
let content = message.content;
// Format the content if the message from me
if (payload.fromMe && payload.source === MessageSource.APP) {
@@ -276,7 +291,7 @@ export abstract class MessageBaseHandler<Payload extends WAMessageBase> {
const chatId = payload.from;
// Add participant name to group messages
const manyParticipants = isJidGroup(chatId) || isJidStatusBroadcast(chatId);
const manyParticipants = isJidGroup(chatId) || isJidBroadcast(chatId);
if (!payload.fromMe && manyParticipants) {
const key = parseMessageIdSerialized(payload.id, true);
let participant = toCusFormat(key.participant);
@@ -290,14 +305,11 @@ export abstract class MessageBaseHandler<Payload extends WAMessageBase> {
participant: participant,
});
}
const attachments: SendAttachment[] = await this.getAttachments(payload);
if (!content && attachments.length > 0) {
// With no content ChatWoot render the message as an ugly big attachment
content = ' ';
}
const replyTo = await this.getReplyToChatWootMessageID(payload).catch(
(err) => {
this.logger.error(`Error getting reply to message ID: ${err}`);
this.logger.error(
`WhatsApp => ChatWoot - error getting reply to message ID: ${err}`,
);
return undefined;
},
);
@@ -306,8 +318,8 @@ export abstract class MessageBaseHandler<Payload extends WAMessageBase> {
return {
content: content,
message_type: type,
private: payload.fromMe,
attachments: attachments as any,
private: message.private ?? payload.fromMe,
attachments: message.attachments as any,
content_attributes: {
in_reply_to: replyTo,
},
@@ -325,6 +337,6 @@ export abstract class MessageBaseHandler<Payload extends WAMessageBase> {
chat_id: payload.from,
message_id: replyToWhatsAppID,
});
return chatwoot.message_id;
return chatwoot?.message_id;
}
}
@@ -0,0 +1,113 @@
import { Processor } from '@nestjs/bullmq';
import { ILogger } from '@waha/apps/app_sdk/ILogger';
import { JOB_CONCURRENCY } from '@waha/apps/app_sdk/constants';
import { ContactConversationService } from '@waha/apps/chatwoot/client/ContactConversationService';
import { QueueName } from '@waha/apps/chatwoot/consumers/QueueName';
import { EventData } from '@waha/apps/chatwoot/consumers/types';
import {
ChatWootWAHABaseConsumer,
IMessageInfo,
} from '@waha/apps/chatwoot/consumers/waha/base';
import { WhatsAppContactInfo } from '@waha/apps/chatwoot/contacts/WhatsAppContactInfo';
import { Locale } from '@waha/apps/chatwoot/i18n/locale';
import { WAHASessionAPI } from '@waha/apps/chatwoot/session/WAHASelf';
import { SessionManager } from '@waha/core/abc/manager.abc';
import { RMutexService } from '@waha/modules/rmutex/rmutex.service';
import { WAHAEvents, WAMessageAck } from '@waha/structures/enums.dto';
import { WAHAWebhookMessageAck } from '@waha/structures/webhooks.dto';
import { Job } from 'bullmq';
import { PinoLogger } from 'nestjs-pino';
import { isJidCusFormat } from '@waha/utils/wa';
import { isLidUser } from '@adiwajshing/baileys/lib/WABinary/jid-utils';
@Processor(QueueName.WAHA_MESSAGE_ACK, { concurrency: JOB_CONCURRENCY })
export class WAHAMessageAckConsumer extends ChatWootWAHABaseConsumer {
constructor(
protected readonly manager: SessionManager,
log: PinoLogger,
rmutex: RMutexService,
) {
super(manager, log, rmutex, 'WAHAMessageAckConsumer');
}
ShouldProcess(event: WAHAWebhookMessageAck): boolean {
// Mark as seen only if it's DM
// Ignore groups and other multiple participants chats
const chatId = this.GetChatId(event);
if (!isJidCusFormat(chatId) && !isLidUser(chatId)) {
return false;
}
// Only READ and PLAYED
const payload = event.payload;
return (
payload.ack === WAMessageAck.READ || payload.ack == WAMessageAck.PLAYED
);
}
GetChatId(event: WAHAWebhookMessageAck): string {
return event.payload.from;
}
async Process(
job: Job<EventData, any, WAHAEvents>,
info: IMessageInfo,
): Promise<void> {
const container = await this.DIContainer(job, job.data.app);
const event = job.data.event as WAHAWebhookMessageAck;
const session = new WAHASessionAPI(event.session, container.WAHASelf());
const handler = new MessageAckHandler(
container.ContactConversationService(),
container.Logger(),
info,
session,
container.Locale(),
);
await handler.handle(event);
}
}
class MessageAckHandler {
constructor(
private readonly contactConversationService: ContactConversationService,
private readonly logger: ILogger,
private readonly info: IMessageInfo,
private readonly session: WAHASessionAPI,
private readonly locale: Locale,
) {}
async handle(event: WAHAWebhookMessageAck): Promise<void> {
const payload = event.payload;
const contactInfo = WhatsAppContactInfo(
this.session,
payload.from,
this.locale,
);
const conversation =
await this.contactConversationService.ConversationByContact(contactInfo);
this.info.onConversationId(conversation.conversationId);
const sourceId = conversation.sourceId;
if (!sourceId) {
this.logger.warn(
`Contact not found for chat.id: ${payload.from}. Skipping read update for message ${payload.id}`,
);
return;
}
try {
await this.contactConversationService.markConversationAsRead(
conversation.conversationId,
sourceId,
);
this.logger.info(
`Marked conversation ${conversation.conversationId} as read for chat.id: ${payload.from} (message: ${payload.id}, sourceId: ${sourceId})`,
);
} catch (error) {
const reason = error instanceof Error ? error.message : String(error);
this.logger.error(
`Error marking conversation ${conversation.conversationId} as read for chat.id: ${payload.from}. Reason: ${reason}`,
);
throw error;
}
}
}
+68 -36
View File
@@ -1,15 +1,14 @@
import { Processor } from '@nestjs/bullmq';
import { JOB_CONCURRENCY } from '@waha/apps/app_sdk/constants';
import { SendAttachment } from '@waha/apps/chatwoot/client/types';
import { QueueName } from '@waha/apps/chatwoot/consumers/QueueName';
import { EventData } from '@waha/apps/chatwoot/consumers/types';
import {
ChatWootMessagePartial,
ChatWootWAHABaseConsumer,
IMessageInfo,
MessageBaseHandler,
} from '@waha/apps/chatwoot/consumers/waha/base';
import { MessageBaseHandler } from '@waha/apps/chatwoot/consumers/waha/base';
import { WAHASessionAPI } from '@waha/apps/chatwoot/session/WAHASelf';
import { WhatsappToMarkdown } from '@waha/apps/chatwoot/text';
import { SessionManager } from '@waha/core/abc/manager.abc';
import { parseMessageIdSerialized } from '@waha/core/utils/ids';
import { RMutexService } from '@waha/modules/rmutex/rmutex.service';
@@ -18,9 +17,18 @@ import { WAMessage } from '@waha/structures/responses.dto';
import { WAHAWebhookMessageAny } from '@waha/structures/webhooks.dto';
import { Job } from 'bullmq';
import { PinoLogger } from 'nestjs-pino';
// eslint-disable-next-line @typescript-eslint/no-var-requires
const mime = require('mime-types');
import {
FacebookAdMessage,
EventMessage,
PixMessage,
LocationMessage,
MessageToChatWootConverter,
PollMessage,
ShareContactMessage,
TextMessage,
UnsupportedMessage,
resolveProtoMessage,
} from '@waha/apps/chatwoot/messages/to/chatwoot';
@Processor(QueueName.WAHA_MESSAGE_ANY, { concurrency: JOB_CONCURRENCY })
export class WAHAMessageAnyConsumer extends ChatWootWAHABaseConsumer {
@@ -44,6 +52,7 @@ export class WAHAMessageAnyConsumer extends ChatWootWAHABaseConsumer {
const event: WAHAWebhookMessageAny = job.data.event as any;
const session = new WAHASessionAPI(event.session, container.WAHASelf());
const handler = new MessageAnyHandler(
job,
container.MessageMappingService(),
container.ContactConversationService(),
container.Logger(),
@@ -57,9 +66,59 @@ export class WAHAMessageAnyConsumer extends ChatWootWAHABaseConsumer {
}
class MessageAnyHandler extends MessageBaseHandler<WAMessage> {
getContent(payload: WAMessage): string {
const body = payload.body;
return WhatsappToMarkdown(body);
protected async getMessage(
payload: WAMessage,
): Promise<ChatWootMessagePartial> {
let converter: MessageToChatWootConverter;
let msg: ChatWootMessagePartial;
const protoMessage = resolveProtoMessage(payload);
// Check for Facebook Ad first - but let it use the normal flow later
converter = new FacebookAdMessage(this.l, this.logger);
msg = await converter.convert(payload, protoMessage);
if (msg) {
return msg;
}
converter = new TextMessage(this.l, this.logger, this.waha);
msg = await converter.convert(payload, null);
if (msg) {
return msg;
}
converter = new LocationMessage(this.l);
msg = await converter.convert(payload, protoMessage);
if (msg) {
return msg;
}
converter = new ShareContactMessage(this.l, this.logger);
msg = await converter.convert(payload, protoMessage);
if (msg) {
return msg;
}
converter = new PollMessage(this.l);
msg = await converter.convert(payload, protoMessage);
if (msg) {
return msg;
}
converter = new EventMessage(this.l);
msg = await converter.convert(payload, protoMessage);
if (msg) {
return msg;
}
converter = new PixMessage(this.l, this.logger);
msg = await converter.convert(payload, protoMessage);
if (msg) {
return msg;
}
converter = new UnsupportedMessage(this.l, this.job);
msg = await converter.convert(payload, protoMessage);
return msg;
}
getReplyToWhatsAppID(payload: WAMessage): string {
@@ -70,31 +129,4 @@ class MessageAnyHandler extends MessageBaseHandler<WAMessage> {
const key = parseMessageIdSerialized(replyTo.id, true);
return key.id;
}
async getAttachments(payload: WAMessage): Promise<SendAttachment[]> {
const hasMedia = payload.media?.url;
if (!hasMedia) {
return [];
}
const attachments: SendAttachment[] = [];
const media = payload.media;
this.logger.info(`Downloading media from '${media.url}'...`);
const buffer = await this.waha.fetch(media.url);
const fileContent = buffer.toString('base64');
let filename = media.filename;
if (!filename) {
const extension = mime.extension(media.mimetype);
filename = `no-filename.${extension}`;
}
const attachment: SendAttachment = {
content: fileContent,
filename: filename,
encoding: 'base64',
};
attachments.push(attachment);
this.logger.info(`Downloaded media from '${media.url}' as '${filename}'`);
return attachments;
}
}
@@ -3,12 +3,11 @@ import { JOB_CONCURRENCY } from '@waha/apps/app_sdk/constants';
import { QueueName } from '@waha/apps/chatwoot/consumers/QueueName';
import { EventData } from '@waha/apps/chatwoot/consumers/types';
import {
ChatWootMessagePartial,
ChatWootWAHABaseConsumer,
IMessageInfo,
MessageBaseHandler,
} from '@waha/apps/chatwoot/consumers/waha/base';
import { MessageBaseHandler } from '@waha/apps/chatwoot/consumers/waha/base';
import { TKey } from '@waha/apps/chatwoot/locale';
import { WhatsappToMarkdown } from '@waha/apps/chatwoot/text';
import { SessionManager } from '@waha/core/abc/manager.abc';
import { RMutexService } from '@waha/modules/rmutex/rmutex.service';
import { WAHAEvents } from '@waha/structures/enums.dto';
@@ -19,8 +18,12 @@ import {
import { Job } from 'bullmq';
import { PinoLogger } from 'nestjs-pino';
import { SendAttachment } from '../../client/types';
import { WAHASessionAPI } from '../../session/WAHASelf';
import {
MessageEdited,
MessageToChatWootConverter,
resolveProtoMessage,
} from '@waha/apps/chatwoot/messages/to/chatwoot';
@Processor(QueueName.WAHA_MESSAGE_EDITED, { concurrency: JOB_CONCURRENCY })
export class WAHAMessageEditedConsumer extends ChatWootWAHABaseConsumer {
@@ -44,6 +47,7 @@ export class WAHAMessageEditedConsumer extends ChatWootWAHABaseConsumer {
const event: WAHAWebhookMessageEdited = job.data.event as any;
const session = new WAHASessionAPI(event.session, container.WAHASelf());
const handler = new MessageEditedHandler(
job,
container.MessageMappingService(),
container.ContactConversationService(),
container.Logger(),
@@ -57,21 +61,15 @@ export class WAHAMessageEditedConsumer extends ChatWootWAHABaseConsumer {
}
class MessageEditedHandler extends MessageBaseHandler<WAMessageEditedBody> {
getContent(payload: WAMessageEditedBody): string {
const body = payload.body;
const formatted = WhatsappToMarkdown(body);
return this.l
.key(TKey.MESSAGE_EDITED_IN_WHATSAPP)
.render({ text: formatted });
protected async getMessage(
payload: WAMessageEditedBody,
): Promise<ChatWootMessagePartial> {
const protoMessage = resolveProtoMessage(payload);
const converter: MessageToChatWootConverter = new MessageEdited(this.l);
return converter.convert(payload, protoMessage);
}
getReplyToWhatsAppID(payload: WAMessageEditedBody): string {
return payload.editedMessageId;
}
async getAttachments(
payload: WAMessageEditedBody,
): Promise<SendAttachment[]> {
return [];
}
}
@@ -4,11 +4,11 @@ import { SendAttachment } from '@waha/apps/chatwoot/client/types';
import { QueueName } from '@waha/apps/chatwoot/consumers/QueueName';
import { EventData } from '@waha/apps/chatwoot/consumers/types';
import {
ChatWootMessagePartial,
ChatWootWAHABaseConsumer,
IMessageInfo,
} from '@waha/apps/chatwoot/consumers/waha/base';
import { MessageBaseHandler } from '@waha/apps/chatwoot/consumers/waha/base';
import { TKey } from '@waha/apps/chatwoot/locale';
import { WAHASessionAPI } from '@waha/apps/chatwoot/session/WAHASelf';
import { SessionManager } from '@waha/core/abc/manager.abc';
import { parseMessageIdSerialized } from '@waha/core/utils/ids';
@@ -18,6 +18,7 @@ import { WAMessageReaction, WAReaction } from '@waha/structures/responses.dto';
import { WAHAWebhookMessageReaction } from '@waha/structures/webhooks.dto';
import { Job } from 'bullmq';
import { PinoLogger } from 'nestjs-pino';
import { TKey } from '@waha/apps/chatwoot/i18n/templates';
@Processor(QueueName.WAHA_MESSAGE_REACTION, { concurrency: JOB_CONCURRENCY })
export class WAHAMessageReactionConsumer extends ChatWootWAHABaseConsumer {
@@ -41,6 +42,7 @@ export class WAHAMessageReactionConsumer extends ChatWootWAHABaseConsumer {
const event: WAHAWebhookMessageReaction = job.data.event as any;
const session = new WAHASessionAPI(event.session, container.WAHASelf());
const handler = new MessageReactionHandler(
job,
container.MessageMappingService(),
container.ContactConversationService(),
container.Logger(),
@@ -54,15 +56,24 @@ export class WAHAMessageReactionConsumer extends ChatWootWAHABaseConsumer {
}
export class MessageReactionHandler extends MessageBaseHandler<WAMessageReaction> {
getContent(payload: WAMessageReaction) {
protected async getMessage(
payload: WAMessageReaction,
): Promise<ChatWootMessagePartial> {
const reaction = payload.reaction as WAReaction;
const emoji = reaction.text;
if (!emoji) {
return this.l.key(TKey.WHATSAPP_REACTION_REMOVED).render();
let content: string;
if (emoji) {
content = this.l.key(TKey.WHATSAPP_REACTION_ADDED).render({
emoji: emoji,
});
} else {
content = this.l.key(TKey.WHATSAPP_REACTION_REMOVED).render();
}
return this.l.key(TKey.WHATSAPP_REACTION_ADDED).render({
emoji: emoji,
});
return {
content: content,
attachments: [],
private: undefined,
};
}
getReplyToWhatsAppID(payload: WAMessageReaction) {
@@ -71,8 +82,4 @@ export class MessageReactionHandler extends MessageBaseHandler<WAMessageReaction
const key = parseMessageIdSerialized(messageId, false);
return key.id;
}
async getAttachments(payload: WAMessageReaction): Promise<SendAttachment[]> {
return [];
}
}
@@ -10,18 +10,19 @@ import {
ChatWootWAHABaseConsumer,
IMessageInfo,
} from '@waha/apps/chatwoot/consumers/waha/base';
import { Locale, TKey } from '@waha/apps/chatwoot/locale';
import { Locale } from '@waha/apps/chatwoot/i18n/locale';
import {
ChatwootMessage,
MessageMappingService,
} from '@waha/apps/chatwoot/storage';
import { SessionManager } from '@waha/core/abc/manager.abc';
import { toCusFormat } from '@waha/core/engines/noweb/session.noweb.core';
import { RMutexService } from '@waha/modules/rmutex/rmutex.service';
import { WAHAEvents } from '@waha/structures/enums.dto';
import { WAHAWebhookMessageRevoked } from '@waha/structures/webhooks.dto';
import { Job } from 'bullmq';
import { PinoLogger } from 'nestjs-pino';
import { TKey } from '@waha/apps/chatwoot/i18n/templates';
import { toCusFormat } from '@waha/core/utils/jids';
@Processor(QueueName.WAHA_MESSAGE_REVOKED, { concurrency: JOB_CONCURRENCY })
export class WAHAMessageRevokedConsumer extends ChatWootWAHABaseConsumer {
@@ -10,7 +10,7 @@ import {
ChatWootWAHABaseConsumer,
IMessageInfo,
} from '@waha/apps/chatwoot/consumers/waha/base';
import { Locale, TKey } from '@waha/apps/chatwoot/locale';
import { Locale } from '@waha/apps/chatwoot/i18n/locale';
import { WAHASelf } from '@waha/apps/chatwoot/session/WAHASelf';
import { SessionStatusEmoji } from '@waha/apps/chatwoot/SessionStatusEmoji';
import { SessionManager } from '@waha/core/abc/manager.abc';
@@ -19,6 +19,8 @@ import { WAHAEvents, WAHASessionStatus } from '@waha/structures/enums.dto';
import { WAHAWebhookSessionStatus } from '@waha/structures/webhooks.dto';
import { Job } from 'bullmq';
import { PinoLogger } from 'nestjs-pino';
import { TKey } from '@waha/apps/chatwoot/i18n/templates';
import { waitUntil } from '@waha/utils/promiseTimeout';
@Processor(QueueName.WAHA_SESSION_STATUS, { concurrency: JOB_CONCURRENCY })
export class WAHASessionStatusConsumer extends ChatWootWAHABaseConsumer {
@@ -48,6 +50,9 @@ export class WAHASessionStatusConsumer extends ChatWootWAHABaseConsumer {
}
}
const RECOVER_TIME_MS = 10_000;
const CHECK_STATUS_INTERVAL_MS = 2_000;
export class SessionStatusHandler {
constructor(
private repo: ContactConversationService,
@@ -56,28 +61,61 @@ export class SessionStatusHandler {
) {}
async handle(data: WAHAWebhookSessionStatus) {
const conversation = await this.repo.InboxNotifications();
// Report session status
const emoji = SessionStatusEmoji(data.payload.status);
const activity = this.l.key(TKey.APP_SESSION_STATUS_CHANGE).r({
emoji: emoji,
session: data.session,
status: data.payload.status,
});
await conversation.activity(activity);
const payload = data.payload;
let text = '';
const current = payload.statuses?.at(-1);
const previous = payload.statuses?.at(-2);
const older = payload.statuses?.at(-3);
switch (payload.status) {
case WAHASessionStatus.STARTING:
// WORKING => STARTING [=> WORKING]
if (previous?.status == WAHASessionStatus.WORKING) {
// if previous is WORKING - wait, give time to recover
const recovered = await waitUntil(
async () => {
const response = await this.waha.get(data.session);
return response.status == WAHASessionStatus.WORKING;
},
CHECK_STATUS_INTERVAL_MS,
RECOVER_TIME_MS,
);
if (recovered) {
// Current status is WORKING, no needs for an alert
return;
}
}
break;
case WAHASessionStatus.WORKING:
// WORKING => STARTING => WORKING
if (
previous?.status == WAHASessionStatus.STARTING &&
older?.status == WAHASessionStatus.WORKING
) {
if (current?.timestamp - previous?.timestamp < RECOVER_TIME_MS) {
// Session got recovered fast, no needs to notify about that
return;
}
}
text = this.l.key(TKey.APP_SESSION_STATUS_WORKING).r({
name: data.me?.pushName || 'Unknown',
id: data.me?.id || 'No phone number',
});
break;
case WAHASessionStatus.STOPPED:
try {
// Check the session is yet in STOPPED status.
// In case of server restarts,
// the consumer can process STOPPED after STARTING/WORKING
const response = await this.waha.get(data.session);
if (response.status != WAHASessionStatus.STOPPED) {
return;
}
} catch (_) {}
text = this.l.key(TKey.APP_SESSION_STATUS_ERROR).r();
text += '\n\n';
text += this.l.key(TKey.APP_HELP_REMINDER).r();
text += '\n\n';
break;
case WAHASessionStatus.FAILED:
text = this.l.key(TKey.APP_SESSION_STATUS_ERROR).r();
text += '\n\n';
@@ -87,6 +125,18 @@ export class SessionStatusHandler {
case WAHASessionStatus.SCAN_QR_CODE:
text = this.l.key(TKey.APP_SESSION_SCAN_QR_CODE).r();
}
//
// Report Status Change if required
//
const conversation = await this.repo.InboxNotifications();
const emoji = SessionStatusEmoji(data.payload.status);
const activity = this.l.key(TKey.APP_SESSION_STATUS_CHANGE).r({
emoji: emoji,
session: data.session,
status: data.payload.status,
});
await conversation.activity(activity);
if (text) {
const message: conversation_message_create = {
content: text,
@@ -1,7 +1,8 @@
import { public_contact_create_update_payload } from '@figuro/chatwoot-sdk';
import { ContactInfo } from '@waha/apps/chatwoot/client/ContactConversationService';
import { AttributeKey, INBOX_CONTACT_CHAT_ID } from '@waha/apps/chatwoot/const';
import { Locale, TKey } from '@waha/apps/chatwoot/locale';
import { Locale } from '@waha/apps/chatwoot/i18n/locale';
import { TKey } from '@waha/apps/chatwoot/i18n/templates';
/**
* Inbox Notifications Contact
@@ -1,16 +1,21 @@
import {
isJidGroup,
isJidNewsletter,
isJidStatusBroadcast,
} from '@adiwajshing/baileys';
import { isLidUser } from '@adiwajshing/baileys/lib/WABinary/jid-utils';
import { public_contact_create_update_payload as Contact } from '@figuro/chatwoot-sdk';
import { ContactInfo } from '@waha/apps/chatwoot/client/ContactConversationService';
import { AttributeKey } from '@waha/apps/chatwoot/const';
import { Locale, TKey } from '@waha/apps/chatwoot/locale';
import { Locale } from '@waha/apps/chatwoot/i18n/locale';
import { WAHASessionAPI } from '@waha/apps/chatwoot/session/WAHASelf';
import { Channel } from '@waha/structures/channels.dto';
import { CacheAsync } from '@waha/utils/Cache';
import { TKey } from '@waha/apps/chatwoot/i18n/templates';
import {
isJidBroadcast,
isJidGroup,
isJidNewsletter,
isJidStatusBroadcast,
isLidUser,
isPnUser,
} from '@waha/core/utils/jids';
import { UnknownJIDFormat } from '@waha/apps/chatwoot/errors';
import { E164Parser } from '@waha/core/utils/PhoneJidNormalizer';
/**
* Base WhatsApp contact info class
@@ -64,8 +69,7 @@ class JidContactInfo extends ChatContactInfo {
const contact: any = await this.session.getContact(this.chatId);
const name =
contact?.name || contact?.pushName || contact?.pushname || this.chatId;
const phoneNumber = this.chatId.split('@')[0];
const phoneNumberE164 = '+' + phoneNumber;
const phoneNumberE164 = E164Parser.fromJid(this.chatId);
const result: Contact = {
name: name,
@@ -147,6 +151,7 @@ class GroupContactInfo extends ChatContactInfo {
const group: any = await this.session?.getGroup(this.chatId);
if (group) {
name = group.subject || group.name || group.topic || name;
name = group.Name || name;
const suffix = this.locale
.key(TKey.WHATSAPP_CONTACT_GROUP_SUFFIX)
.render();
@@ -220,6 +225,31 @@ class StatusContactInfo extends ChatContactInfo {
}
}
class BroadcastContactInfo extends ChatContactInfo {
async Attributes() {
return {
[AttributeKey.WA_CHAT_ID]: this.chatId,
};
}
@CacheAsync()
async AvatarUrl(): Promise<string | null> {
return null;
}
async PublicContactCreate(): Promise<Contact> {
const name = this.locale
.key(TKey.WHATSAPP_CONTACT_BROADCAST_SUFFIX)
.render();
return {
identifier: this.chatId,
name: `${name} (${this.chatId})`,
custom_attributes: await this.Attributes(),
};
}
}
/**
* Factory function to get the appropriate ContactInfo implementation
* based on the chat ID type
@@ -235,8 +265,13 @@ export function WhatsAppContactInfo(
return new ChannelContactInfo(session, chatId, locale);
} else if (isJidStatusBroadcast(chatId)) {
return new StatusContactInfo(session, chatId, locale);
} else if (isJidBroadcast(chatId)) {
return new BroadcastContactInfo(session, chatId, locale);
} else if (isLidUser(chatId)) {
return new LidContactInfo(session, chatId, locale);
} else if (isPnUser(chatId)) {
return new JidContactInfo(session, chatId, locale);
} else {
throw new UnknownJIDFormat(chatId);
}
return new JidContactInfo(session, chatId, locale);
}
+114 -92
View File
@@ -1,14 +1,20 @@
import ChatwootClient from '@figuro/chatwoot-sdk';
import * as lodash from 'lodash';
import { AxiosLogging } from '@waha/apps/app_sdk/AxiosLogging';
import { ILogger } from '@waha/apps/app_sdk/ILogger';
import { ContactAPI } from '@waha/apps/chatwoot/client/ContactAPI';
import { ContactService } from '@waha/apps/chatwoot/client/ContactService';
import { ContactConversationService } from '@waha/apps/chatwoot/client/ContactConversationService';
import { ConversationAPI } from '@waha/apps/chatwoot/client/ConversationAPI';
import { CustomAttributesAPI } from '@waha/apps/chatwoot/client/CustomAttributesAPI';
import { ConversationService } from '@waha/apps/chatwoot/client/ConversationService';
import { CustomAttributesService } from '@waha/apps/chatwoot/client/CustomAttributesService';
import { ChatWootInboxAPI } from '@waha/apps/chatwoot/client/interfaces';
import { ChatWootAppConfig } from '@waha/apps/chatwoot/dto/config.dto';
import {
ChatWootAppConfig,
ChatWootConfig,
DEFAULT_LOCALE,
LinkPreview,
} from '@waha/apps/chatwoot/dto/config.dto';
import { ChatWootErrorReporter } from '@waha/apps/chatwoot/error/ChatWootErrorReporter';
import { Locale } from '@waha/apps/chatwoot/locale';
import { Locale } from '@waha/apps/chatwoot/i18n/locale';
import { WAHASelf } from '@waha/apps/chatwoot/session/WAHASelf';
import {
ChatwootMessageRepository,
@@ -18,21 +24,18 @@ import {
} from '@waha/apps/chatwoot/storage';
import { Job } from 'bullmq';
import { Knex } from 'knex';
import { i18n } from '@waha/apps/chatwoot/i18n';
import { CacheSync } from '@waha/utils/Cache';
import {
ConversationSelector,
ConversationSort,
} from '@waha/apps/chatwoot/services/ConversationSelector';
/**
* Dependency Injection Container for ChatWoot
* Manages the creation and caching of various clients and repositories
*/
export class DIContainer {
private accountAPI: ChatwootClient;
private inboxAPI: ChatWootInboxAPI;
private contactAPI: ContactAPI;
private conversationAPI: ConversationAPI;
private contactConversationService: ContactConversationService;
private locale: Locale;
private messageMappingService: MessageMappingService;
private wahaSelf: WAHASelf;
/**
* Creates a new DIContainer with the given configuration
*/
@@ -61,121 +64,124 @@ export class DIContainer {
return this.knex;
}
@CacheSync()
public Locale(): Locale {
if (!this.locale) {
this.locale = new Locale(this.config.locale);
}
return this.locale;
let locale = i18n.locale(this.config.locale || DEFAULT_LOCALE);
locale = locale.override(this.ChatWootConfig().templates);
return locale;
}
/**
* Gets the AccountAPI client
* @returns ChatwootClient instance
*/
@CacheSync()
public AccountAPI(): ChatwootClient {
if (!this.accountAPI) {
this.accountAPI = new ChatwootClient({
config: {
basePath: this.config.url,
with_credentials: true,
credentials: 'include',
token: this.config.accountToken,
},
});
}
return this.accountAPI;
return new ChatwootClient({
config: {
basePath: this.config.url,
with_credentials: true,
credentials: 'include',
token: this.config.accountToken,
},
});
}
/**
* Gets the InboxAPI client
* @returns ChatWootInboxAPI instance
*/
@CacheSync()
public InboxAPI(): ChatWootInboxAPI {
if (!this.inboxAPI) {
const chatwootClientAPI = new ChatwootClient({
config: {
basePath: this.config.url,
with_credentials: true,
credentials: 'include',
token: this.config.inboxIdentifier,
},
});
this.inboxAPI = chatwootClientAPI.client as ChatWootInboxAPI;
}
return this.inboxAPI;
const chatwootClientAPI = new ChatwootClient({
config: {
basePath: this.config.url,
with_credentials: true,
credentials: 'include',
token: this.config.inboxIdentifier,
},
});
return chatwootClientAPI.client as ChatWootInboxAPI;
}
/**
* Gets the ContactAPI
* @returns ContactAPI instance
* Gets the ContactService
* @returns ContactService instance
*/
private ContactAPI(): ContactAPI {
if (!this.contactAPI) {
this.contactAPI = new ContactAPI(
this.config,
this.AccountAPI(),
this.InboxAPI(),
this.logger,
);
}
return this.contactAPI;
@CacheSync()
private ContactService(): ContactService {
return new ContactService(
this.config,
this.AccountAPI(),
this.InboxAPI(),
this.logger,
);
}
@CacheSync()
public ConversationSelector() {
const config = this.ChatWootConfig();
return new ConversationSelector({
sort: config.conversations.sort,
status: config.conversations.status,
inboxId: this.config.inboxId,
});
}
/**
* Gets the ConversationAPI
* @returns ConversationAPI instance
* Gets the ConversationService
* @returns ConversationService instance
*/
private ConversationAPI(): ConversationAPI {
if (!this.conversationAPI) {
this.conversationAPI = new ConversationAPI(
this.config,
this.InboxAPI(),
this.logger,
);
}
return this.conversationAPI;
@CacheSync()
private ConversationService(): ConversationService {
return new ConversationService(
this.config,
this.AccountAPI(),
this.InboxAPI(),
this.ConversationSelector(),
this.logger,
);
}
/**
* Gets the ContactConversationService
* @returns ContactConversationService instance
*/
@CacheSync()
public ContactConversationService(): ContactConversationService {
if (!this.contactConversationService) {
this.contactConversationService = new ContactConversationService(
this.config,
this.ContactAPI(),
this.ConversationAPI(),
this.AccountAPI(),
this.logger,
this.Locale(),
);
}
return this.contactConversationService;
return new ContactConversationService(
this.config,
this.ContactService(),
this.ConversationService(),
this.AccountAPI(),
this.logger,
this.Locale(),
);
}
@CacheSync()
private ChatwootMessageRepository(): ChatwootMessageRepository {
return new ChatwootMessageRepository(this.Knex(), this.AppPk());
}
@CacheSync()
private WhatsAppMessageRepository(): WhatsAppMessageRepository {
return new WhatsAppMessageRepository(this.Knex(), this.AppPk());
}
@CacheSync()
private MessageMappingRepository(): MessageMappingRepository {
return new MessageMappingRepository(this.Knex(), this.AppPk());
}
@CacheSync()
public MessageMappingService(): MessageMappingService {
if (!this.messageMappingService) {
this.messageMappingService = new MessageMappingService(
this.Knex(),
this.WhatsAppMessageRepository(),
this.ChatwootMessageRepository(),
this.MessageMappingRepository(),
);
}
return this.messageMappingService;
return new MessageMappingService(
this.Knex(),
this.WhatsAppMessageRepository(),
this.ChatwootMessageRepository(),
this.MessageMappingRepository(),
);
}
public ChatWootErrorReporter(job: Job): ChatWootErrorReporter {
@@ -186,16 +192,32 @@ export class DIContainer {
* Gets the WAHASelf instance
* @returns WAHASelf instance
*/
@CacheSync()
public WAHASelf(): WAHASelf {
if (!this.wahaSelf) {
this.wahaSelf = new WAHASelf();
const logging = new AxiosLogging(this.Logger());
logging.applyTo(this.wahaSelf.client);
}
return this.wahaSelf;
const self = new WAHASelf();
const logging = new AxiosLogging(this.Logger());
logging.applyTo(self.client);
return self;
}
public CustomAttributesAPI() {
return new CustomAttributesAPI(this.config, this.AccountAPI());
@CacheSync()
public CustomAttributesService() {
return new CustomAttributesService(this.config, this.AccountAPI());
}
@CacheSync()
public ChatWootConfig(): ChatWootConfig {
const defaults: ChatWootConfig = {
templates: {},
linkPreview: LinkPreview.OFF,
commands: {
server: true,
},
conversations: {
sort: ConversationSort.created_newest,
status: null,
},
};
return lodash.defaults({}, this.config, defaults);
}
}
+62 -3
View File
@@ -1,6 +1,48 @@
import { ChatWootAPIConfig } from '@waha/apps/chatwoot/client/interfaces';
import { DEFAULT_LOCALE, LOCALES } from '@waha/apps/chatwoot/locale';
import { IsIn, IsNumber, IsString } from 'class-validator';
import {
IsBoolean,
IsEnum,
IsNumber,
IsOptional,
IsString,
ValidateNested,
} from 'class-validator';
import { Type } from 'class-transformer';
import { IsDynamicObject } from '@waha/nestjs/validation/IsDynamicObject';
import {
ConversationSelectorConfig,
ConversationSort,
} from '@waha/apps/chatwoot/services/ConversationSelector';
import { ConversationStatus } from '@waha/apps/chatwoot/client/types';
export const DEFAULT_LOCALE = 'en-US';
export class ChatWootCommandsConfig {
@IsBoolean()
server: boolean = true;
}
export enum LinkPreview {
OFF = 'OFF',
LQ = 'LG',
HQ = 'HG',
}
export class ChatWootConversationsConfig {
@IsEnum(ConversationSort)
sort: ConversationSort;
@IsOptional()
@IsEnum(ConversationStatus, { each: true })
status: Array<ConversationStatus> | null;
}
export interface ChatWootConfig {
templates: Record<string, string>;
linkPreview: LinkPreview;
commands: ChatWootCommandsConfig;
conversations: ChatWootConversationsConfig;
}
export class ChatWootAppConfig implements ChatWootAPIConfig {
@IsString()
@@ -18,7 +60,24 @@ export class ChatWootAppConfig implements ChatWootAPIConfig {
@IsString()
inboxIdentifier: string;
@IsEnum(LinkPreview)
@IsOptional()
linkPreview?: LinkPreview = LinkPreview.OFF;
@IsString()
@IsIn(LOCALES)
locale: string = DEFAULT_LOCALE;
@IsOptional()
@IsDynamicObject()
templates?: Record<string, string>;
@IsOptional()
@ValidateNested()
@Type(() => ChatWootCommandsConfig)
commands?: ChatWootCommandsConfig;
@IsOptional()
@ValidateNested()
@Type(() => ChatWootConversationsConfig)
conversations?: ChatWootConversationsConfig;
}
@@ -1,14 +1,20 @@
import type { conversation_message_create } from '@figuro/chatwoot-sdk/dist/models/conversation_message_create';
import { ILogger } from '@waha/apps/app_sdk/ILogger';
import { NextAttemptDelayInWholeSeconds } from '@waha/apps/app_sdk/JobUtils';
import {
JobLink,
NextAttemptDelayInWholeSeconds,
} from '@waha/apps/app_sdk/JobUtils';
import { Conversation } from '@waha/apps/chatwoot/client/Conversation';
import { MessageType } from '@waha/apps/chatwoot/client/types';
import { ErrorRenderer } from '@waha/apps/chatwoot/error/ErrorRenderer';
import { Locale, TKey } from '@waha/apps/chatwoot/locale';
import { Locale } from '@waha/apps/chatwoot/i18n/locale';
import { Job } from 'bullmq';
import { TKey } from '@waha/apps/chatwoot/i18n/templates';
const renderer: ErrorRenderer = new ErrorRenderer();
export class ChatWootErrorReporter {
private errorRenderer: ErrorRenderer = new ErrorRenderer();
private errorRenderer: ErrorRenderer = renderer;
constructor(
private logger: ILogger,
@@ -23,12 +29,15 @@ export class ChatWootErrorReporter {
error: any,
replyTo?: number,
) {
const errorText = this.errorRenderer.renderError(error);
const errorText = this.errorRenderer.text(error);
this.logger.error(errorText);
const errorUrl = `http://localhost:3000/jobs/queue/${encodeURIComponent(
this.job.queueName,
)}/${this.job.id}`;
const template = this.l.key(TKey.JOB_ERROR_REPORT);
try {
const data = this.errorRenderer.data(error);
this.logger.error(JSON.stringify(data, null, 2));
} catch (err) {
this.logger.error(`Error occurred while login details for error: ${err}`);
}
const template = this.l.key(TKey.JOB_REPORT_ERROR);
const nextDelay = NextAttemptDelayInWholeSeconds(this.job);
const attempts = {
current: this.job.attemptsMade + 1,
@@ -38,10 +47,7 @@ export class ChatWootErrorReporter {
const content = template.render({
header: header,
error: nextDelay != null ? null : errorText,
details: {
text: `${this.job.queueName} => ${this.job.id}`,
url: errorUrl,
},
details: JobLink(this.job),
attempts: attempts,
});
const request: conversation_message_create = {
@@ -71,20 +77,14 @@ export class ChatWootErrorReporter {
type: MessageType,
replyTo?: number,
): Promise<void> {
const jobUrl = `http://localhost:3000/jobs/queue/${encodeURIComponent(
this.job.queueName,
)}/${this.job.id}`;
const template = this.l.key(TKey.JOB_SUCCEEDED_REPORT);
const template = this.l.key(TKey.JOB_REPORT_SUCCEEDED);
const attempts = {
current: this.job.attemptsMade + 1,
max: this.job.opts?.attempts || 1,
};
const content = template.render({
details: {
text: `${this.job.queueName} => ${this.job.id}`,
url: jobUrl,
},
details: JobLink(this.job),
attempts: attempts,
});
+106 -41
View File
@@ -1,45 +1,28 @@
import { ApiError } from '@figuro/chatwoot-sdk/dist/core/ApiError';
import { AxiosError } from 'axios';
import { ApiError as ChatWootAPIError } from '@figuro/chatwoot-sdk/dist/core/ApiError';
import type { AxiosError } from 'axios';
/**
* Class responsible for rendering error information based on error type
*/
export class ErrorRenderer {
interface IErrorRender<T> {
/**
* Renders error information based on error type
* @param error The error to render
* @returns Formatted error text
* Get an error text to show to the user
*/
public renderError(error: any): string {
// Handle Axios errors
if (error.isAxiosError) {
return this.renderAxiosError(error as AxiosError);
}
// Handle Chatwoot SDK ApiError
if (error instanceof ApiError) {
return this.renderApiError(error);
}
// For all other errors
return this.renderGenericError(error);
}
text(error: T): string;
/**
* Renders Axios error information
* @param error The Axios error to render
* @returns Formatted error text
* Structured error data for logging/inspection
*/
private renderAxiosError(error: AxiosError): string {
let errorText = `Axios Error: ${error.message}`;
data(error: T): Record<string, any>;
}
class AxiosErrorRenderer implements IErrorRender<AxiosError> {
text(error: AxiosError): string {
let errorText = `API Error: ${error.message}`;
if (!error.response?.data) {
return errorText;
}
// Add response data if it exists and is JSON
try {
const data = error.response.data as any;
let json: undefined;
let json: any;
if (Buffer.isBuffer(data)) {
json = JSON.parse(data.toString());
} else if (typeof data === 'object') {
@@ -55,16 +38,35 @@ export class ErrorRenderer {
return errorText;
}
/**
* Renders Chatwoot SDK ApiError information
* @param error The ApiError to render
* @returns Formatted error text
*/
private renderApiError(error: ApiError): string {
let errorText = `API Error: ${error.message}`;
data(error: AxiosError): Record<string, any> {
const { config, response, request } = error as any;
return {
class: 'APIError',
request: {
method: request?.method || config?.method,
url: request?.path || config?.url,
params: config?.params,
body: request?.body || config?.data,
},
response: {
status: response?.status,
statusText: response?.statusText,
headers: response?.headers,
body: response?.data,
},
message: error.message,
code: (error as any)?.code,
stack: error.stack,
};
}
}
class ChatWootAPIErrorRenderer implements IErrorRender<ChatWootAPIError> {
text(error: ChatWootAPIError): string {
let errorText = `ChatWoot API Error: ${error.message}`;
errorText += `\nStatus: ${error.status}`;
// Add body if it exists
if (error.body) {
try {
const body =
@@ -78,12 +80,75 @@ export class ErrorRenderer {
return errorText;
}
data(error: ChatWootAPIError): Record<string, any> {
return {
class: 'ChatWootAPIError',
request: {
method: error.request?.method,
url: error.request?.url,
query: error.request?.query,
path: error.request?.path,
body: error.request?.body,
},
response: {
status: error.status,
statusText: error.statusText,
body: error.body,
},
message: error.message,
stack: error.stack,
};
}
}
class GenericErrorRenderer implements IErrorRender<any> {
text(error: any): string {
return error?.toString?.() ?? String(error);
}
data(error: any): Record<string, any> {
return {
class: error?.name ?? error?.constructor?.name ?? typeof error,
message: error?.message ?? String(error),
stack: error.stack,
};
}
}
/**
* Class responsible for rendering error information based on error type
*/
export class ErrorRenderer implements IErrorRender<any> {
private readonly axiosRenderer = new AxiosErrorRenderer();
private readonly chatwootRenderer = new ChatWootAPIErrorRenderer();
private readonly genericRenderer = new GenericErrorRenderer();
/**
* Renders generic error information
* Renders error information based on error type
* @param error The error to render
* @returns Formatted error text
*/
private renderGenericError(error: any): string {
return error.toString();
public text(error: any): string {
if (error?.isAxiosError) {
return this.axiosRenderer.text(error as AxiosError);
}
if (error instanceof ChatWootAPIError) {
return this.chatwootRenderer.text(error);
}
return this.genericRenderer.text(error);
}
public data(error: any): Record<string, any> {
if (error?.isAxiosError) {
return this.axiosRenderer.data(error as AxiosError);
}
if (error instanceof ChatWootAPIError) {
return this.chatwootRenderer.data(error);
}
return this.genericRenderer.data(error);
}
}
+6
View File
@@ -9,3 +9,9 @@ export class PhoneNumberNotFoundInWhatsAppError extends Error {
super(`Phone number not found in WhatsApp: ${phone}`);
}
}
export class UnknownJIDFormat extends Error {
constructor(public jid: string) {
super(`WhatsApp Chat ID is not recognized: ${jid}`);
}
}
-183
View File
@@ -1,183 +0,0 @@
# German translations for ChatWoot integration
APP_INBOX_CONTACT_NAME: 'WhatsApp Integration (WAHA)'
JOB_ERROR_REPORT: |
⚠️ **{{{header}}}**
{{#attempts.nextDelay}}
🔄 Wiederholung in {{attempts.nextDelay}} Sekunden...
{{/attempts.nextDelay}}
{{^attempts.nextDelay}}
❌ Keine weiteren Versuche übrig. Bitte versuchen Sie es später erneut.
{{/attempts.nextDelay}}
Versuch: {{{attempts.current}}} / {{{attempts.max}}}
Details: [{{{details.text}}}]({{{details.url}}})
{{#error}}
```
{{{error}}}
```
{{/error}}
JOB_SUCCEEDED_REPORT: |
✅ **Erfolgreich**
Versuch: {{{attempts.current}}} / {{{attempts.max}}}
Details: [{{{details.text}}}]({{{details.url}}})
WHATSAPP_ERROR_SENDING_MESSAGE:
Nachricht konnte nicht über WhatsApp gesendet werden.
WHATSAPP_ERROR_RECEIVING_MESSAGE:
Nachricht konnte nicht von WhatsApp empfangen werden
WHATSAPP_ERROR_REMOVING_MESSAGE:
Nachricht konnte nicht von WhatsApp entfernt werden
APP_SCHEDULED_JOB_ERROR: Geplante Aufgabe konnte nicht ausgeführt werden
MESSAGE_FROM_WHATSAPP: |
{{{text}}}
📱 *Von WhatsApp gesendet*
MESSAGE_FROM_API: |
{{{text}}}
📱 *Über API gesendet*
MESSAGE_REMOVED_IN_WHATSAPP: |
❌ *Diese Nachricht wurde in WhatsApp gelöscht*
MESSAGE_EDITED_IN_WHATSAPP: |
{{{text}}}
✏️ *In WhatsApp bearbeitet*
WHATSAPP_GROUP_MESSAGE: |
{{{text}}}
👥 *{{{participant}}}*
WHATSAPP_REACTION_ADDED: |
*Reagiert mit* {{{emoji}}}
WHATSAPP_REACTION_REMOVED: |
*Reaktion entfernt*
WHATSAPP_CONTACT_GROUP_SUFFIX: 'Gruppe'
WHATSAPP_CONTACT_CHANNEL_SUFFIX: 'Kanal'
# Aka Stories
WHATSAPP_CONTACT_STATUS_NAME: 'Status'
APP_CONNECTED_MESSAGE: |
🔗 **VERBUNDEN: WhatsApp-Sitzung mit ChatWoot Inbox**
✅ WhatsApp-Sitzung **{{{name}}}** wurde erfolgreich mit dieser ChatWoot Inbox verbunden.
Diese Inbox ist jetzt mit Ihrem **WhatsApp-Konto** verknüpft. Sie können Nachrichten direkt von hier senden und empfangen — genau wie bei WhatsApp, aber innerhalb von ChatWoot.
Sie können auch die mit dieser Inbox verknüpfte WhatsApp-Sitzung verwalten. Um verfügbare Aktionen anzuzeigen, senden Sie **help** an diesen Chat.
📋 Häufige Aktionen, die Sie durchführen können:
- Überprüfen, ob die WhatsApp-Sitzung aktiv ist
- Die WhatsApp-Sitzung neu starten oder stoppen
- Abmelden und durch Scannen eines neuen QR-Codes wieder verbinden
Wenn alles funktioniert, können Sie frei chatten. Wenn Sie Warnungen sehen, müssen Sie möglicherweise Ihr WhatsApp-Konto neu verbinden.
Lassen Sie uns beginnen! 🚀
APP_DISCONNECTED_MESSAGE: |
🔌 **GETRENNT: WhatsApp-Sitzung von ChatWoot Inbox**
❌ WhatsApp-Sitzung **{{{name}}}** wurde von dieser ChatWoot Inbox getrennt.
Sie können keine Nachrichten mehr von WhatsApp senden oder empfangen.
Um eine erneute Verbindung herzustellen, wenden Sie sich bitte an Ihren Administrator.
APP_UPDATED_MESSAGE: |
🔄 **AKTUALISIERT: WhatsApp-Sitzungseinstellungen**
✅ Einstellungen für WhatsApp-Sitzung **{{{name}}}** wurden aktualisiert.
APP_COMMANDS_LIST: |
Sie können die **WhatsApp Integration** verwalten, indem Sie einen der folgenden Befehle senden:
🖥️ Sitzungen:
1. **status** - den aktuellen Sitzungsstatus abrufen.
2. **restart** - die Sitzung neu starten - dies versucht, Ihr WhatsApp-Konto neu zu verbinden.
3. **start** - die Sitzung starten.
4. **stop** - die Sitzung stoppen.
5. **logout** - von der Sitzung abmelden, damit Sie den QR-Code scannen und die Sitzung reparieren können.
6. **qr** - den QR-Code für die Sitzung abrufen.
7. **screenshot** - einen Screenshot der Sitzung erhalten (nur in der **WEBJS**-Engine verfügbar).
8. **help** - verfügbare Befehle.
⚙️ Server:
- **server status** - Serverversion und Statusinformationen abrufen.
- **server reboot** - Server ordnungsgemäß neu starten.
- **server reboot force** - Server erzwungen neu starten.
Senden Sie einen **Befehl** (Groß-/Kleinschreibung wird nicht beachtet) oder eine **Befehlsnummer** an diese Konversation.
APP_HELP_REMINDER: |
Senden Sie **help**, um die Liste der verfügbaren Befehle zu erhalten.
APP_SESSION_STATUS_CHANGE: |
{{{emoji}}} Sitzung "{{{session}}}" hat den Status zu {{{status}}} gewechselt
APP_SESSION_CURRENT_STATUS: |
{{{emoji}}} **{{{session}}}** Sitzungsstatus ist **{{{status}}}**
**WhatsApp-Konto:**
📱 **{{{name}}} ({{{id}}})**
APP_DASHBOARD_LINK: |
Besuchen Sie das [WAHA Dashboard]({{{url}}}) für weitere Details.
APP_SESSION_STATUS_WORKING: |
✅ Diese ChatWoot Inbox ist mit dem **WhatsApp-Konto** verknüpft und bereit zum Senden und Empfangen von Nachrichten!
📱 **{{{name}}} ({{{id}}})**
APP_SESSION_STATUS_ERROR: |
⚠️ **Diese ChatWoot Inbox ist mit dem WhatsApp-Konto verknüpft, aber NICHT bereit zum Senden und Empfangen von Nachrichten!**
Bitte überprüfen Sie den Sitzungsstatus und versuchen Sie, sie neu zu starten oder melden Sie sich ab und scannen Sie den QR-Code erneut.
APP_SESSION_SCAN_QR_CODE: |
⚠️ **Scannen Sie den QR-Code auf Ihrem Telefon, um das WhatsApp-Konto mit dieser ChatWoot Inbox zu verknüpfen!**
APP_SERVER_VERSION_AND_STATUS: |
**Version:**
```
{{{version}}}
```
**Status:**
```
{{{status}}}
```
APP_SERVER_REBOOT: |
Server wird ordnungsgemäß neu gestartet...
APP_SERVER_REBOOT_FORCE: |
Server wird erzwungen neu gestartet...
APP_LOGOUT_SUCCESS: |
✅ Konto erfolgreich abgemeldet!
APP_NEW_VERSION_AVAILABLE: |
🔄 **Neue Version verfügbar!**
Aktuelle Version: **{{{currentVersion}}}**
Neue Version: **{{{newVersion}}}**
👉 Sehen Sie, was neu ist im [**🆕 Änderungsprotokoll**]({{{changelogUrl}}})
APP_CORE_VERSION_USED: |
❤️ **Unterstützen Sie WAHA!**
Sie verwenden die kostenlose **WAHA Core** Version. Wenn Sie dieses Projekt nützlich finden, erwägen Sie bitte, seine Entwicklung zu unterstützen.
Ihre Unterstützung ist der einzige Weg, wie wir weiterhin an Updates, Fehlerbehebungen und neuen Funktionen arbeiten können.
[**🎁 Unterstützen Sie uns**]({{{supportUrl}}})
-181
View File
@@ -1,181 +0,0 @@
# English translations for ChatWoot integration
APP_INBOX_CONTACT_NAME: 'WhatsApp Integration (WAHA)'
APP_INBOX_CONTACT_AVATAR_URL: 'https://raw.githubusercontent.com/devlikeapro/waha/core/logo.png'
JOB_ERROR_REPORT: |
⚠️ **{{{header}}}**
{{#attempts.nextDelay}}
🔄 Retrying in {{attempts.nextDelay}} seconds...
{{/attempts.nextDelay}}
{{^attempts.nextDelay}}
❌ No more retries left. Please try again later.
{{/attempts.nextDelay}}
Attempt: {{{attempts.current}}} / {{{attempts.max}}}
Details: [{{{details.text}}}]({{{details.url}}})
{{#error}}
```
{{{error}}}
```
{{/error}}
JOB_SUCCEEDED_REPORT: |
✅ **Succeeded**
Attempt: {{{attempts.current}}} / {{{attempts.max}}}
Details: [{{{details.text}}}]({{{details.url}}})
WHATSAPP_ERROR_SENDING_MESSAGE: Couldn't send a message on WhatsApp.
WHATSAPP_ERROR_RECEIVING_MESSAGE: Couldn't receive a message from WhatsApp
WHATSAPP_ERROR_REMOVING_MESSAGE: Couldn't remove a message from WhatsApp
APP_SCHEDULED_JOB_ERROR: Scheduled job failed to execute
MESSAGE_FROM_WHATSAPP: |
{{{text}}}
📱 *Sent from WhatsApp*
MESSAGE_FROM_API: |
{{{text}}}
📱 *Sent via API*
MESSAGE_REMOVED_IN_WHATSAPP: |
❌ *This message was deleted in WhatsApp*
MESSAGE_EDITED_IN_WHATSAPP: |
{{{text}}}
✏️ *Edited in WhatsApp*
WHATSAPP_GROUP_MESSAGE: |
{{{text}}}
👥 *{{{participant}}}*
WHATSAPP_REACTION_ADDED: |
*Reacted* {{{emoji}}}
WHATSAPP_REACTION_REMOVED: |
*Reaction removed*
WHATSAPP_CONTACT_GROUP_SUFFIX: 'Group'
WHATSAPP_CONTACT_CHANNEL_SUFFIX: 'Channel'
# Aka Stories
WHATSAPP_CONTACT_STATUS_NAME: 'Status'
APP_CONNECTED_MESSAGE: |
🔗 **CONNECTED: WhatsApp Session to ChatWoot Inbox**
✅ WhatsApp session **{{{name}}}** has been successfully connected to this ChatWoot Inbox.
This inbox is now linked to your **WhatsApp Account**. You can send and receive messages directly from here — just like using WhatsApp, but inside ChatWoot.
You can also manage the WhatsApp session linked to this inbox. To view available actions, send **help** to this chat.
📋 Common actions you can do:
- Check if the WhatsApp session is active
- Restart or Stop the WhatsApp session
- Log out and reconnect by scanning a new QR code
If everything is working, you'll be able to chat freely. If you see warnings, you might need to reconnect your WhatsApp account.
Let's get started! 🚀
APP_DISCONNECTED_MESSAGE: |
🔌 **DISCONNECTED: WhatsApp Session from ChatWoot Inbox**
❌ WhatsApp session **{{{name}}}** has been disconnected from this ChatWoot Inbox.
You will no longer be able to send or receive messages from WhatsApp.
To reconnect, please contact your administrator.
APP_UPDATED_MESSAGE: |
🔄 **UPDATED: WhatsApp Session Settings**
✅ Settings for WhatsApp session **{{{name}}}** have been updated.
APP_COMMANDS_LIST: |
You can manage **WhatsApp Integration** by sending one of the following commands:
🖥️ Sessions:
1. **status** - get the current session status.
2. **restart** - restart the session - this will try to reconnect your WhatsApp account.
3. **start** - start the session.
4. **stop** - stop the session.
5. **logout** - logout from the session, so you can scan QR code and repair the session.
6. **qr** - get the QR code for the session.
7. **screenshot** - get a screenshot of the session (only available in **WEBJS** engine).
8. **help** - available commands.
⚙️ Server:
- **server status** - get the server version and status information.
- **server reboot** - reboot the server gracefully.
- **server reboot force** - force reboot the server.
Send a **command** (case insensitive) or a **command number** to this conversation.
APP_HELP_REMINDER: |
Send **help** to get the list of available commands.
APP_SESSION_STATUS_CHANGE: |
{{{emoji}}} "{{{session}}}" session switched to {{{status}}} status
APP_SESSION_CURRENT_STATUS: |
{{{emoji}}} **{{{session}}}** session status is in **{{{status}}}**
**WhatsApp Account:**
📱 **{{{name}}} ({{{id}}})**
APP_DASHBOARD_LINK: |
Visit [WAHA Dashboard]({{{url}}}) for more details.
APP_SESSION_STATUS_WORKING: |
✅ This ChatWoot Inbox is linked to **WhatsApp Account** and ready to send and receive messages!
📱 **{{{name}}} ({{{id}}})**
APP_SESSION_STATUS_ERROR: |
⚠️ **This ChatWoot Inbox is linked to WhatsApp Account but NOT ready to send and receive messages!**
Please check the session status and try restarting it or logout and scan the QR code again.
APP_SESSION_SCAN_QR_CODE: |
⚠️ **Scan the QR code on your phone to link WhatsApp Account with this ChatWoot Inbox!**
APP_SERVER_VERSION_AND_STATUS: |
**Version:**
```
{{{version}}}
```
**Status:**
```
{{{status}}}
```
APP_SERVER_REBOOT: |
Server is rebooting gracefully...
APP_SERVER_REBOOT_FORCE: |
Server is force rebooting...
APP_LOGOUT_SUCCESS: |
✅ Account unauthorized successfully!
APP_NEW_VERSION_AVAILABLE: |
🔄 **New Version Available!**
Current version: **{{{currentVersion}}}**
New version: **{{{newVersion}}}**
👉 Check out what's new in the [**🆕 Changelog**]({{{changelogUrl}}})
APP_CORE_VERSION_USED: |
❤️ **Support WAHA!**
You're using the free **WAHA Core** version. If you find this project useful, please consider supporting its development.
Your support is the only way we can continue working on updates, fixes, and new features.
[**🎁 Support Us**]({{{supportUrl}}})
-180
View File
@@ -1,180 +0,0 @@
# Spanish translations for ChatWoot integration
APP_INBOX_CONTACT_NAME: 'Integración de WhatsApp (WAHA)'
JOB_ERROR_REPORT: |
⚠️ **{{{header}}}**
{{#attempts.nextDelay}}
🔄 Reintentando en {{attempts.nextDelay}} segundos...
{{/attempts.nextDelay}}
{{^attempts.nextDelay}}
❌ No quedan más intentos. Por favor, inténtelo de nuevo más tarde.
{{/attempts.nextDelay}}
Intento: {{{attempts.current}}} / {{{attempts.max}}}
Detalles: [{{{details.text}}}]({{{details.url}}})
{{#error}}
```
{{{error}}}
```
{{/error}}
JOB_SUCCEEDED_REPORT: |
✅ **Éxito**
Intento: {{{attempts.current}}} / {{{attempts.max}}}
Detalles: [{{{details.text}}}]({{{details.url}}})
WHATSAPP_ERROR_SENDING_MESSAGE: No se pudo enviar un mensaje en WhatsApp.
WHATSAPP_ERROR_RECEIVING_MESSAGE: No se pudo recibir un mensaje de WhatsApp
WHATSAPP_ERROR_REMOVING_MESSAGE: No se pudo eliminar un mensaje de WhatsApp
APP_SCHEDULED_JOB_ERROR: La tarea programada no se pudo ejecutar
MESSAGE_FROM_WHATSAPP: |
{{{text}}}
📱 *Enviado desde WhatsApp*
MESSAGE_FROM_API: |
{{{text}}}
📱 *Enviado a través de API*
MESSAGE_REMOVED_IN_WHATSAPP: |
❌ *Este mensaje fue eliminado en WhatsApp*
MESSAGE_EDITED_IN_WHATSAPP: |
{{{text}}}
✏️ *Editado en WhatsApp*
WHATSAPP_GROUP_MESSAGE: |
{{{text}}}
👥 *{{{participant}}}*
WHATSAPP_REACTION_ADDED: |
*Reaccionó con* {{{emoji}}}
WHATSAPP_REACTION_REMOVED: |
*Reacción eliminada*
WHATSAPP_CONTACT_GROUP_SUFFIX: 'Grupo'
WHATSAPP_CONTACT_CHANNEL_SUFFIX: 'Canal'
# Aka Stories
WHATSAPP_CONTACT_STATUS_NAME: 'Estado'
APP_CONNECTED_MESSAGE: |
🔗 **CONECTADO: Sesión de WhatsApp a Bandeja de Entrada de ChatWoot**
✅ La sesión de WhatsApp **{{{name}}}** ha sido conectada exitosamente a esta Bandeja de Entrada de ChatWoot.
Esta bandeja de entrada ahora está vinculada a tu **Cuenta de WhatsApp**. Puedes enviar y recibir mensajes directamente desde aquí — justo como usar WhatsApp, pero dentro de ChatWoot.
También puedes gestionar la sesión de WhatsApp vinculada a esta bandeja de entrada. Para ver las acciones disponibles, envía **help** a este chat.
📋 Acciones comunes que puedes realizar:
- Comprobar si la sesión de WhatsApp está activa
- Reiniciar o Detener la sesión de WhatsApp
- Cerrar sesión y reconectar escaneando un nuevo código QR
Si todo funciona, podrás chatear libremente. Si ves advertencias, es posible que necesites reconectar tu cuenta de WhatsApp.
¡Comencemos! 🚀
APP_DISCONNECTED_MESSAGE: |
🔌 **DESCONECTADO: Sesión de WhatsApp de Bandeja de Entrada de ChatWoot**
❌ La sesión de WhatsApp **{{{name}}}** ha sido desconectada de esta Bandeja de Entrada de ChatWoot.
Ya no podrás enviar o recibir mensajes desde WhatsApp.
Para reconectar, por favor contacta a tu administrador.
APP_UPDATED_MESSAGE: |
🔄 **ACTUALIZADO: Configuración de Sesión de WhatsApp**
✅ La configuración para la sesión de WhatsApp **{{{name}}}** ha sido actualizada.
APP_COMMANDS_LIST: |
Puedes gestionar la **Integración de WhatsApp** enviando uno de los siguientes comandos:
🖥️ Sesiones:
1. **status** - obtener el estado actual de la sesión.
2. **restart** - reiniciar la sesión - esto intentará reconectar tu cuenta de WhatsApp.
3. **start** - iniciar la sesión.
4. **stop** - detener la sesión.
5. **logout** - cerrar sesión, para que puedas escanear el código QR y reparar la sesión.
6. **qr** - obtener el código QR para la sesión.
7. **screenshot** - obtener una captura de pantalla de la sesión (solo disponible en el motor **WEBJS**).
8. **help** - comandos disponibles.
⚙️ Servidor:
- **server status** - obtener información de versión y estado del servidor.
- **server reboot** - reiniciar el servidor de forma segura.
- **server reboot force** - forzar el reinicio del servidor.
Envía un **comando** (no sensible a mayúsculas/minúsculas) o un **número de comando** a esta conversación.
APP_HELP_REMINDER: |
Envía **help** para obtener la lista de comandos disponibles.
APP_SESSION_STATUS_CHANGE: |
{{{emoji}}} La sesión "{{{session}}}" cambió al estado {{{status}}}
APP_SESSION_CURRENT_STATUS: |
{{{emoji}}} El estado de la sesión **{{{session}}}** es **{{{status}}}**
**Cuenta de WhatsApp:**
📱 **{{{name}}} ({{{id}}})**
APP_DASHBOARD_LINK: |
Visita el [Panel de WAHA]({{{url}}}) para más detalles.
APP_SESSION_STATUS_WORKING: |
✅ ¡Esta Bandeja de Entrada de ChatWoot está vinculada a la **Cuenta de WhatsApp** y lista para enviar y recibir mensajes!
📱 **{{{name}}} ({{{id}}})**
APP_SESSION_STATUS_ERROR: |
⚠️ **¡Esta Bandeja de Entrada de ChatWoot está vinculada a la Cuenta de WhatsApp pero NO está lista para enviar y recibir mensajes!**
Por favor, comprueba el estado de la sesión e intenta reiniciarla o cierra sesión y escanea el código QR de nuevo.
APP_SESSION_SCAN_QR_CODE: |
⚠️ **¡Escanea el código QR en tu teléfono para vincular la Cuenta de WhatsApp con esta Bandeja de Entrada de ChatWoot!**
APP_SERVER_VERSION_AND_STATUS: |
**Versión:**
```
{{{version}}}
```
**Estado:**
```
{{{status}}}
```
APP_SERVER_REBOOT: |
El servidor se está reiniciando de forma segura...
APP_SERVER_REBOOT_FORCE: |
El servidor se está reiniciando forzadamente...
APP_LOGOUT_SUCCESS: |
✅ ¡Cuenta desautorizada con éxito!
APP_NEW_VERSION_AVAILABLE: |
🔄 **¡Nueva Versión Disponible!**
Versión actual: **{{{currentVersion}}}**
Nueva versión: **{{{newVersion}}}**
👉 Mira qué hay de nuevo en el [**🆕 Registro de Cambios**]({{{changelogUrl}}})
APP_CORE_VERSION_USED: |
❤️ **¡Apoya a WAHA!**
Estás usando la versión gratuita **WAHA Core**. Si encuentras útil este proyecto, por favor considera apoyar su desarrollo.
Tu apoyo es la única forma en que podemos seguir trabajando en actualizaciones, correcciones y nuevas funciones.
[**🎁 Apóyanos**]({{{supportUrl}}})
-180
View File
@@ -1,180 +0,0 @@
# French translations for ChatWoot integration
APP_INBOX_CONTACT_NAME: 'Intégration WhatsApp (WAHA)'
JOB_ERROR_REPORT: |
⚠️ **{{{header}}}**
{{#attempts.nextDelay}}
🔄 Nouvelle tentative dans {{attempts.nextDelay}} secondes...
{{/attempts.nextDelay}}
{{^attempts.nextDelay}}
❌ Plus de tentatives restantes. Veuillez réessayer plus tard.
{{/attempts.nextDelay}}
Tentative : {{{attempts.current}}} / {{{attempts.max}}}
Détails : [{{{details.text}}}]({{{details.url}}})
{{#error}}
```
{{{error}}}
```
{{/error}}
JOB_SUCCEEDED_REPORT: |
✅ **Réussi**
Tentative : {{{attempts.current}}} / {{{attempts.max}}}
Détails : [{{{details.text}}}]({{{details.url}}})
WHATSAPP_ERROR_SENDING_MESSAGE: Impossible d'envoyer un message sur WhatsApp.
WHATSAPP_ERROR_RECEIVING_MESSAGE: Impossible de recevoir un message de WhatsApp
WHATSAPP_ERROR_REMOVING_MESSAGE: Impossible de supprimer un message de WhatsApp
APP_SCHEDULED_JOB_ERROR: La tâche planifiée n'a pas pu être exécutée
MESSAGE_FROM_WHATSAPP: |
{{{text}}}
📱 *Envoyé depuis WhatsApp*
MESSAGE_FROM_API: |
{{{text}}}
📱 *Envoyé via API*
MESSAGE_REMOVED_IN_WHATSAPP: |
❌ *Ce message a été supprimé dans WhatsApp*
MESSAGE_EDITED_IN_WHATSAPP: |
{{{text}}}
✏️ *Modifié dans WhatsApp*
WHATSAPP_GROUP_MESSAGE: |
{{{text}}}
👥 *{{{participant}}}*
WHATSAPP_REACTION_ADDED: |
*A réagi avec* {{{emoji}}}
WHATSAPP_REACTION_REMOVED: |
*Réaction supprimée*
WHATSAPP_CONTACT_GROUP_SUFFIX: 'Groupe'
WHATSAPP_CONTACT_CHANNEL_SUFFIX: 'Canal'
# Aka Stories
WHATSAPP_CONTACT_STATUS_NAME: 'Statut'
APP_CONNECTED_MESSAGE: |
🔗 **CONNECTÉ : Session WhatsApp à la Boîte de Réception ChatWoot**
✅ La session WhatsApp **{{{name}}}** a été connectée avec succès à cette Boîte de Réception ChatWoot.
Cette boîte de réception est maintenant liée à votre **Compte WhatsApp**. Vous pouvez envoyer et recevoir des messages directement d'ici — tout comme utiliser WhatsApp, mais à l'intérieur de ChatWoot.
Vous pouvez également gérer la session WhatsApp liée à cette boîte de réception. Pour voir les actions disponibles, envoyez **help** à ce chat.
📋 Actions courantes que vous pouvez effectuer :
- Vérifier si la session WhatsApp est active
- Redémarrer ou Arrêter la session WhatsApp
- Se déconnecter et se reconnecter en scannant un nouveau code QR
Si tout fonctionne, vous pourrez discuter librement. Si vous voyez des avertissements, vous devrez peut-être reconnecter votre compte WhatsApp.
Commençons ! 🚀
APP_DISCONNECTED_MESSAGE: |
🔌 **DÉCONNECTÉ : Session WhatsApp de la Boîte de Réception ChatWoot**
❌ La session WhatsApp **{{{name}}}** a été déconnectée de cette Boîte de Réception ChatWoot.
Vous ne pourrez plus envoyer ou recevoir de messages depuis WhatsApp.
Pour vous reconnecter, veuillez contacter votre administrateur.
APP_UPDATED_MESSAGE: |
🔄 **MIS À JOUR : Paramètres de Session WhatsApp**
✅ Les paramètres de la session WhatsApp **{{{name}}}** ont été mis à jour.
APP_COMMANDS_LIST: |
Vous pouvez gérer l'**Intégration WhatsApp** en envoyant l'une des commandes suivantes :
🖥️ Sessions :
1. **status** - obtenir l'état actuel de la session.
2. **restart** - redémarrer la session - cela tentera de reconnecter votre compte WhatsApp.
3. **start** - démarrer la session.
4. **stop** - arrêter la session.
5. **logout** - se déconnecter de la session, pour pouvoir scanner le code QR et réparer la session.
6. **qr** - obtenir le code QR pour la session.
7. **screenshot** - obtenir une capture d'écran de la session (disponible uniquement dans le moteur **WEBJS**).
8. **help** - commandes disponibles.
⚙️ Serveur :
- **server status** - obtenir les informations de version et d'état du serveur.
- **server reboot** - redémarrer le serveur en douceur.
- **server reboot force** - forcer le redémarrage du serveur.
Envoyez une **commande** (insensible à la casse) ou un **numéro de commande** à cette conversation.
APP_HELP_REMINDER: |
Envoyez **help** pour obtenir la liste des commandes disponibles.
APP_SESSION_STATUS_CHANGE: |
{{{emoji}}} La session "{{{session}}}" est passée au statut {{{status}}}
APP_SESSION_CURRENT_STATUS: |
{{{emoji}}} Le statut de la session **{{{session}}}** est **{{{status}}}**
**Compte WhatsApp :**
📱 **{{{name}}} ({{{id}}})**
APP_DASHBOARD_LINK: |
Visitez le [Tableau de bord WAHA]({{{url}}}) pour plus de détails.
APP_SESSION_STATUS_WORKING: |
✅ Cette Boîte de Réception ChatWoot est liée au **Compte WhatsApp** et prête à envoyer et recevoir des messages !
📱 **{{{name}}} ({{{id}}})**
APP_SESSION_STATUS_ERROR: |
⚠️ **Cette Boîte de Réception ChatWoot est liée au Compte WhatsApp mais N'EST PAS prête à envoyer et recevoir des messages !**
Veuillez vérifier l'état de la session et essayer de la redémarrer ou déconnectez-vous et scannez à nouveau le code QR.
APP_SESSION_SCAN_QR_CODE: |
⚠️ **Scannez le code QR sur votre téléphone pour lier le Compte WhatsApp à cette Boîte de Réception ChatWoot !**
APP_SERVER_VERSION_AND_STATUS: |
**Version :**
```
{{{version}}}
```
**Statut :**
```
{{{status}}}
```
APP_SERVER_REBOOT: |
Le serveur redémarre en douceur...
APP_SERVER_REBOOT_FORCE: |
Le serveur redémarre de force...
APP_LOGOUT_SUCCESS: |
✅ Compte déconnecté avec succès !
APP_NEW_VERSION_AVAILABLE: |
🔄 **Nouvelle Version Disponible !**
Version actuelle : **{{{currentVersion}}}**
Nouvelle version : **{{{newVersion}}}**
👉 Découvrez les nouveautés dans le [**🆕 Journal des modifications**]({{{changelogUrl}}})
APP_CORE_VERSION_USED: |
❤️ **Soutenez WAHA !**
Vous utilisez la version gratuite **WAHA Core**. Si vous trouvez ce projet utile, veuillez envisager de soutenir son développement.
Votre soutien est le seul moyen pour nous de continuer à travailler sur les mises à jour, les corrections et les nouvelles fonctionnalités.
[**🎁 Soutenez-nous**]({{{supportUrl}}})
-180
View File
@@ -1,180 +0,0 @@
# Hebrew translations for ChatWoot integration
APP_INBOX_CONTACT_NAME: 'אינטגרציית וואטסאפ (WAHA)'
JOB_ERROR_REPORT: |
⚠️ **{{{header}}}**
{{#attempts.nextDelay}}
🔄 מנסה שוב בעוד {{attempts.nextDelay}} שניות...
{{/attempts.nextDelay}}
{{^attempts.nextDelay}}
❌ לא נותרו ניסיונות נוספים. אנא נסה שוב מאוחר יותר.
{{/attempts.nextDelay}}
ניסיון: {{{attempts.current}}} / {{{attempts.max}}}
פרטים: [{{{details.text}}}]({{{details.url}}})
{{#error}}
```
{{{error}}}
```
{{/error}}
JOB_SUCCEEDED_REPORT: |
✅ **הצליח**
ניסיון: {{{attempts.current}}} / {{{attempts.max}}}
פרטים: [{{{details.text}}}]({{{details.url}}})
WHATSAPP_ERROR_SENDING_MESSAGE: לא ניתן לשלוח הודעה בוואטסאפ.
WHATSAPP_ERROR_RECEIVING_MESSAGE: לא ניתן לקבל הודעה מוואטסאפ
WHATSAPP_ERROR_REMOVING_MESSAGE: לא ניתן להסיר הודעה מוואטסאפ
APP_SCHEDULED_JOB_ERROR: המשימה המתוזמנת נכשלה בביצוע
MESSAGE_FROM_WHATSAPP: |
{{{text}}}
📱 *נשלח מוואטסאפ*
MESSAGE_FROM_API: |
{{{text}}}
📱 *נשלח דרך API*
MESSAGE_REMOVED_IN_WHATSAPP: |
❌ *הודעה זו נמחקה בוואטסאפ*
MESSAGE_EDITED_IN_WHATSAPP: |
{{{text}}}
✏️ *נערך בוואטסאפ*
WHATSAPP_GROUP_MESSAGE: |
{{{text}}}
👥 *{{{participant}}}*
WHATSAPP_REACTION_ADDED: |
*הגיב* {{{emoji}}}
WHATSAPP_REACTION_REMOVED: |
*התגובה הוסרה*
WHATSAPP_CONTACT_GROUP_SUFFIX: 'קבוצה'
WHATSAPP_CONTACT_CHANNEL_SUFFIX: 'ערוץ'
# Aka Stories
WHATSAPP_CONTACT_STATUS_NAME: 'סטטוס'
APP_CONNECTED_MESSAGE: |
🔗 **מחובר: הפעלת וואטסאפ לתיבת הדואר הנכנס של ChatWoot**
✅ הפעלת וואטסאפ **{{{name}}}** חוברה בהצלחה לתיבת הדואר הנכנס של ChatWoot.
תיבת דואר נכנס זו מקושרת כעת ל**חשבון הוואטסאפ** שלך. אתה יכול לשלוח ולקבל הודעות ישירות מכאן — בדיוק כמו שימוש בוואטסאפ, אבל בתוך ChatWoot.
אתה יכול גם לנהל את הפעלת הוואטסאפ המקושרת לתיבת דואר נכנס זו. כדי לראות פעולות זמינות, שלח **help** לצ'אט זה.
📋 פעולות נפוצות שאתה יכול לעשות:
- בדוק אם הפעלת הוואטסאפ פעילה
- הפעל מחדש או עצור את הפעלת הוואטסאפ
- התנתק והתחבר מחדש על ידי סריקת קוד QR חדש
אם הכל עובד, תוכל לשוחח בחופשיות. אם אתה רואה אזהרות, ייתכן שתצטרך לחבר מחדש את חשבון הוואטסאפ שלך.
בוא נתחיל! 🚀
APP_DISCONNECTED_MESSAGE: |
🔌 **מנותק: הפעלת וואטסאפ מתיבת הדואר הנכנס של ChatWoot**
❌ הפעלת וואטסאפ **{{{name}}}** נותקה מתיבת הדואר הנכנס של ChatWoot.
לא תוכל יותר לשלוח או לקבל הודעות מוואטסאפ.
כדי להתחבר מחדש, אנא פנה למנהל המערכת שלך.
APP_UPDATED_MESSAGE: |
🔄 **עודכן: הגדרות הפעלת וואטסאפ**
✅ ההגדרות עבור הפעלת וואטסאפ **{{{name}}}** עודכנו.
APP_COMMANDS_LIST: |
אתה יכול לנהל **אינטגרציית וואטסאפ** על ידי שליחת אחת מהפקודות הבאות:
🖥️ הפעלות:
1. **status** - קבל את סטטוס ההפעלה הנוכחי.
2. **restart** - הפעל מחדש את ההפעלה - זה ינסה לחבר מחדש את חשבון הוואטסאפ שלך.
3. **start** - התחל את ההפעלה.
4. **stop** - עצור את ההפעלה.
5. **logout** - התנתק מההפעלה, כך שתוכל לסרוק קוד QR ולתקן את ההפעלה.
6. **qr** - קבל את קוד ה-QR עבור ההפעלה.
7. **screenshot** - קבל צילום מסך של ההפעלה (זמין רק במנוע **WEBJS**).
8. **help** - פקודות זמינות.
⚙️ שרת:
- **server status** - קבל מידע על גרסת השרת והסטטוס.
- **server reboot** - הפעל מחדש את השרת בצורה חלקה.
- **server reboot force** - אלץ הפעלה מחדש של השרת.
שלח **פקודה** (לא תלוי רישיות) או **מספר פקודה** לשיחה זו.
APP_HELP_REMINDER: |
שלח **help** כדי לקבל את רשימת הפקודות הזמינות.
APP_SESSION_STATUS_CHANGE: |
{{{emoji}}} הפעלה "{{{session}}}" עברה לסטטוס {{{status}}}
APP_SESSION_CURRENT_STATUS: |
{{{emoji}}} סטטוס ההפעלה **{{{session}}}** הוא **{{{status}}}**
**חשבון וואטסאפ:**
📱 **{{{name}}} ({{{id}}})**
APP_DASHBOARD_LINK: |
בקר ב[לוח הבקרה של WAHA]({{{url}}}) לפרטים נוספים.
APP_SESSION_STATUS_WORKING: |
✅ תיבת הדואר הנכנס של ChatWoot מקושרת ל**חשבון וואטסאפ** ומוכנה לשלוח ולקבל הודעות!
📱 **{{{name}}} ({{{id}}})**
APP_SESSION_STATUS_ERROR: |
⚠️ **תיבת הדואר הנכנס של ChatWoot מקושרת לחשבון וואטסאפ אך אינה מוכנה לשלוח ולקבל הודעות!**
אנא בדוק את סטטוס ההפעלה ונסה להפעיל אותה מחדש או התנתק וסרוק את קוד ה-QR שוב.
APP_SESSION_SCAN_QR_CODE: |
⚠️ **סרוק את קוד ה-QR בטלפון שלך כדי לקשר את חשבון הוואטסאפ לתיבת הדואר הנכנס של ChatWoot!**
APP_SERVER_VERSION_AND_STATUS: |
**גרסה:**
```
{{{version}}}
```
**סטטוס:**
```
{{{status}}}
```
APP_SERVER_REBOOT: |
השרת מופעל מחדש בצורה חלקה...
APP_SERVER_REBOOT_FORCE: |
השרת מופעל מחדש בכוח...
APP_LOGOUT_SUCCESS: |
✅ החשבון בוטל בהצלחה!
APP_NEW_VERSION_AVAILABLE: |
🔄 **גרסה חדשה זמינה!**
גרסה נוכחית: **{{{currentVersion}}}**
גרסה חדשה: **{{{newVersion}}}**
👉 בדוק מה חדש ב[**🆕 יומן שינויים**]({{{changelogUrl}}})
APP_CORE_VERSION_USED: |
❤️ **תמוך ב-WAHA!**
אתה משתמש בגרסת **WAHA Core** החינמית. אם אתה מוצא פרויקט זה שימושי, אנא שקול לתמוך בפיתוח שלו.
התמיכה שלך היא הדרך היחידה שבה אנחנו יכולים להמשיך לעבוד על עדכונים, תיקונים ותכונות חדשות.
[**🎁 תמוך בנו**]({{{supportUrl}}})
+43
View File
@@ -0,0 +1,43 @@
import { Locale } from '@waha/apps/chatwoot/i18n/locale';
import { TKey } from '@waha/apps/chatwoot/i18n/templates';
export class I18N {
private readonly locales: Record<string, Locale>;
constructor() {
this.locales = {};
}
available(): Array<{ name: string; locale: string }> {
const result = [];
for (const [key, template] of Object.entries(this.locales)) {
result.push({ locale: key, name: template.key(TKey.LOCALE_NAME).r() });
}
return result;
}
load(locales: Record<string, Record<string, string>>) {
for (const [locale, strings] of Object.entries(locales)) {
this.add(locale, strings);
}
}
add(locale: string, strings: Record<string, string>) {
if (!this.locales[locale]) {
this.locales[locale] = new Locale(strings);
} else {
this.locales[locale] = this.locales[locale].override(strings);
}
}
locale(locale: string) {
if (!this.has(locale)) {
throw new Error(`Locale ${locale} not found`);
}
return this.locales[locale];
}
has(locale: string) {
return !!this.locales[locale];
}
}
-180
View File
@@ -1,180 +0,0 @@
# Indonesian translations for ChatWoot integration
APP_INBOX_CONTACT_NAME: 'Integrasi WhatsApp (WAHA)'
JOB_ERROR_REPORT: |
⚠️ **{{{header}}}**
{{#attempts.nextDelay}}
🔄 Mencoba lagi dalam {{attempts.nextDelay}} detik...
{{/attempts.nextDelay}}
{{^attempts.nextDelay}}
❌ Tidak ada percobaan lagi. Silakan coba lagi nanti.
{{/attempts.nextDelay}}
Percobaan: {{{attempts.current}}} / {{{attempts.max}}}
Detail: [{{{details.text}}}]({{{details.url}}})
{{#error}}
```
{{{error}}}
```
{{/error}}
JOB_SUCCEEDED_REPORT: |
✅ **Berhasil**
Percobaan: {{{attempts.current}}} / {{{attempts.max}}}
Detail: [{{{details.text}}}]({{{details.url}}})
WHATSAPP_ERROR_SENDING_MESSAGE: Tidak dapat mengirim pesan di WhatsApp.
WHATSAPP_ERROR_RECEIVING_MESSAGE: Tidak dapat menerima pesan dari WhatsApp
WHATSAPP_ERROR_REMOVING_MESSAGE: Tidak dapat menghapus pesan dari WhatsApp
APP_SCHEDULED_JOB_ERROR: Tugas terjadwal gagal dijalankan
MESSAGE_FROM_WHATSAPP: |
{{{text}}}
📱 *Dikirim dari WhatsApp*
MESSAGE_FROM_API: |
{{{text}}}
📱 *Dikirim melalui API*
MESSAGE_REMOVED_IN_WHATSAPP: |
❌ *Pesan ini telah dihapus di WhatsApp*
MESSAGE_EDITED_IN_WHATSAPP: |
{{{text}}}
✏️ *Diedit di WhatsApp*
WHATSAPP_GROUP_MESSAGE: |
{{{text}}}
👥 *{{{participant}}}*
WHATSAPP_REACTION_ADDED: |
*Bereaksi* {{{emoji}}}
WHATSAPP_REACTION_REMOVED: |
*Reaksi dihapus*
WHATSAPP_CONTACT_GROUP_SUFFIX: 'Grup'
WHATSAPP_CONTACT_CHANNEL_SUFFIX: 'Saluran'
# Aka Stories
WHATSAPP_CONTACT_STATUS_NAME: 'Status'
APP_CONNECTED_MESSAGE: |
🔗 **TERHUBUNG: Sesi WhatsApp ke Kotak Masuk ChatWoot**
✅ Sesi WhatsApp **{{{name}}}** telah berhasil terhubung ke Kotak Masuk ChatWoot ini.
Kotak masuk ini sekarang terhubung ke **Akun WhatsApp** Anda. Anda dapat mengirim dan menerima pesan langsung dari sini — seperti menggunakan WhatsApp, tetapi di dalam ChatWoot.
Anda juga dapat mengelola sesi WhatsApp yang terhubung ke kotak masuk ini. Untuk melihat tindakan yang tersedia, kirim **help** ke obrolan ini.
📋 Tindakan umum yang dapat Anda lakukan:
- Periksa apakah sesi WhatsApp aktif
- Mulai ulang atau Hentikan sesi WhatsApp
- Keluar dan hubungkan kembali dengan memindai kode QR baru
Jika semuanya berfungsi, Anda akan dapat mengobrol dengan bebas. Jika Anda melihat peringatan, Anda mungkin perlu menghubungkan kembali akun WhatsApp Anda.
Mari kita mulai! 🚀
APP_DISCONNECTED_MESSAGE: |
🔌 **TERPUTUS: Sesi WhatsApp dari Kotak Masuk ChatWoot**
❌ Sesi WhatsApp **{{{name}}}** telah terputus dari Kotak Masuk ChatWoot ini.
Anda tidak akan dapat lagi mengirim atau menerima pesan dari WhatsApp.
Untuk menghubungkan kembali, silakan hubungi administrator Anda.
APP_UPDATED_MESSAGE: |
🔄 **DIPERBARUI: Pengaturan Sesi WhatsApp**
✅ Pengaturan untuk sesi WhatsApp **{{{name}}}** telah diperbarui.
APP_COMMANDS_LIST: |
Anda dapat mengelola **Integrasi WhatsApp** dengan mengirimkan salah satu perintah berikut:
🖥️ Sesi:
1. **status** - dapatkan status sesi saat ini.
2. **restart** - mulai ulang sesi - ini akan mencoba menghubungkan kembali akun WhatsApp Anda.
3. **start** - mulai sesi.
4. **stop** - hentikan sesi.
5. **logout** - keluar dari sesi, sehingga Anda dapat memindai kode QR dan memperbaiki sesi.
6. **qr** - dapatkan kode QR untuk sesi.
7. **screenshot** - dapatkan tangkapan layar sesi (hanya tersedia di mesin **WEBJS**).
8. **help** - perintah yang tersedia.
⚙️ Server:
- **server status** - dapatkan informasi versi dan status server.
- **server reboot** - mulai ulang server dengan anggun.
- **server reboot force** - paksa mulai ulang server.
Kirim **perintah** (tidak peka huruf besar/kecil) atau **nomor perintah** ke percakapan ini.
APP_HELP_REMINDER: |
Kirim **help** untuk mendapatkan daftar perintah yang tersedia.
APP_SESSION_STATUS_CHANGE: |
{{{emoji}}} Sesi "{{{session}}}" beralih ke status {{{status}}}
APP_SESSION_CURRENT_STATUS: |
{{{emoji}}} Status sesi **{{{session}}}** adalah **{{{status}}}**
**Akun WhatsApp:**
📱 **{{{name}}} ({{{id}}})**
APP_DASHBOARD_LINK: |
Kunjungi [Dasbor WAHA]({{{url}}}) untuk detail lebih lanjut.
APP_SESSION_STATUS_WORKING: |
✅ Kotak Masuk ChatWoot ini terhubung ke **Akun WhatsApp** dan siap untuk mengirim dan menerima pesan!
📱 **{{{name}}} ({{{id}}})**
APP_SESSION_STATUS_ERROR: |
⚠️ **Kotak Masuk ChatWoot ini terhubung ke Akun WhatsApp tetapi TIDAK siap untuk mengirim dan menerima pesan!**
Silakan periksa status sesi dan coba mulai ulang atau keluar dan pindai kode QR lagi.
APP_SESSION_SCAN_QR_CODE: |
⚠️ **Pindai kode QR di ponsel Anda untuk menghubungkan Akun WhatsApp dengan Kotak Masuk ChatWoot ini!**
APP_SERVER_VERSION_AND_STATUS: |
**Versi:**
```
{{{version}}}
```
**Status:**
```
{{{status}}}
```
APP_SERVER_REBOOT: |
Server sedang dimulai ulang dengan anggun...
APP_SERVER_REBOOT_FORCE: |
Server sedang dipaksa untuk dimulai ulang...
APP_LOGOUT_SUCCESS: |
✅ Akun berhasil tidak diotorisasi!
APP_NEW_VERSION_AVAILABLE: |
🔄 **Versi Baru Tersedia!**
Versi saat ini: **{{{currentVersion}}}**
Versi baru: **{{{newVersion}}}**
👉 Lihat apa yang baru di [**🆕 Changelog**]({{{changelogUrl}}})
APP_CORE_VERSION_USED: |
❤️ **Dukung WAHA!**
Anda menggunakan versi **WAHA Core** gratis. Jika Anda merasa proyek ini bermanfaat, harap pertimbangkan untuk mendukung pengembangannya.
Dukungan Anda adalah satu-satunya cara kami dapat terus bekerja pada pembaruan, perbaikan, dan fitur baru.
[**🎁 Dukung Kami**]({{{supportUrl}}})
+19
View File
@@ -0,0 +1,19 @@
import * as path from 'path';
import { YamlLocaleLoader } from '@waha/apps/chatwoot/i18n/loader';
import { I18N } from '@waha/apps/chatwoot/i18n/i18n';
const i18n = new I18N();
const localesDir = path.join(__dirname, 'locales');
// Load both .yml and .yaml files from locales directory (non-recursive)
i18n.load(new YamlLocaleLoader(localesDir, 'yml').load());
i18n.load(new YamlLocaleLoader(localesDir, 'yaml').load());
// Resolve env var (supports '.' and '~'); fallback to default
const additional = process.env.WAHA_APPS_CHATWOOT_LANGUAGES_FOLDER?.trim();
if (additional) {
const resolved = path.resolve(additional);
i18n.load(new YamlLocaleLoader(resolved, 'yml').load());
i18n.load(new YamlLocaleLoader(resolved, 'yaml').load());
}
export { i18n };
+33
View File
@@ -0,0 +1,33 @@
import * as fs from 'fs-extra';
import * as path from 'path';
import * as yaml from 'yaml';
export class YamlLocaleLoader {
constructor(
private readonly dir: string,
private readonly ext: string,
) {}
load(): Record<string, Record<string, string>> {
const result: Record<string, Record<string, string>> = {};
const files = fs.readdirSync(this.dir, { withFileTypes: true });
for (const entry of files) {
if (!entry.isFile()) continue;
const filename = entry.name;
if (!filename.endsWith(`.${this.ext}`)) continue;
const locale = path.basename(filename, `.${this.ext}`);
const filePath = path.join(this.dir, filename);
const content = fs.readFileSync(filePath, 'utf-8');
const parsed = yaml.parse(content) as Record<string, string> | undefined;
if (parsed && typeof parsed === 'object') {
result[locale] = parsed as Record<string, string>;
}
}
return result;
}
}
+91
View File
@@ -0,0 +1,91 @@
import * as Mustache from 'mustache';
import { TemplatePayloads, TKey } from '@waha/apps/chatwoot/i18n/templates';
import Long from 'long';
import { ensureNumber } from '@waha/core/engines/noweb/utils';
export class Locale {
constructor(private readonly strings: Record<string, string>) {}
/**
* Return Base Locale
* For number, datetime, currency formats
*/
get locale(): string {
return this.strings['locale.base'] || 'en';
}
key<K extends TKey>(key: K): Template<K> {
return new Template(this.strings[key] || key);
}
/**
* Overrides the existing strings with the provided strings for the locale.
* Merges the new strings with the current strings.
*/
override(strings: Record<string, string>): Locale {
return new Locale({ ...this.strings, ...strings });
}
FormatCurrency(
currency: string,
value: number | null,
offset: number = 1,
): string | null {
if (value == null) {
return null;
}
if (!currency) {
return null;
}
offset = offset || 1;
try {
const fmt = new Intl.NumberFormat(this.locale, {
style: 'currency',
currency: currency,
});
return fmt.format(value / offset);
} catch (err) {
return `${currency} ${value}`;
}
}
FormatDatetime(date: Date | null): string | null {
if (!date) {
return null;
}
const options: any = this.strings['datetime'] || {};
options.timeZone = options.timeZone || options.timezone || process.env.TZ;
return date.toLocaleString(this.locale, options);
}
FormatTimestamp(timestamp: Long | string | number | null): string | null {
const value = ensureNumber(timestamp);
if (!value) {
return undefined;
}
if (!Number.isFinite(value)) {
return undefined;
}
const milliseconds = value >= 1e12 ? value : value * 1000;
const date = new Date(milliseconds);
if (Number.isNaN(date.getTime())) {
return undefined;
}
return this.FormatDatetime(date);
}
}
export class Template<K extends TKey> {
constructor(private readonly template: string) {}
render(data: TemplatePayloads[K]): string {
const text = Mustache.render(this.template, data);
// Remove /n at the end if any
return text.replace(/\n$/, '');
}
r(data: TemplatePayloads[K]): string {
return this.render(data);
}
}
@@ -1,7 +1,29 @@
# Arabic translations for ChatWoot integration
APP_INBOX_CONTACT_NAME: 'تكامل واتساب (WAHA)'
locale.name: '🇦🇪 العربية (Arabic)'
JOB_ERROR_REPORT: |
# رمز اللغة الأساسي - يجب أن يكون محليًا صالحًا وفق BCP 47
# https://en.wikipedia.org/wiki/IETF_language_tag
# تستخدمه WAHA لعرض الأرقام والعملات والتاريخ/الوقت
locale.base: 'ar-AE'
app.inbox.contact.name: 'تكامل واتساب (WAHA)'
app.inbox.contact.avatar.url: 'https://raw.githubusercontent.com/devlikeapro/waha/core/logo.png'
# "options" من date.toLocaleString
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#options
datetime:
locales: ar-AE
day: 2-digit
month: 2-digit
year: numeric
hour: 2-digit
minute: 2-digit
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#timezonename
timeZoneName: shortGeneric
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
# timeZone: 'Asia/Dubai'
job.report.error: |-
⚠️ **{{{header}}}**
{{#attempts.nextDelay}}
🔄 إعادة المحاولة في {{attempts.nextDelay}} ثانية...
@@ -18,51 +40,52 @@ JOB_ERROR_REPORT: |
```
{{/error}}
JOB_SUCCEEDED_REPORT: |
job.report.succeeded: |-
✅ **نجاح**
المحاولة: {{{attempts.current}}} / {{{attempts.max}}}
التفاصيل: [{{{details.text}}}]({{{details.url}}})
WHATSAPP_ERROR_SENDING_MESSAGE: تعذر إرسال رسالة على واتساب.
WHATSAPP_ERROR_RECEIVING_MESSAGE: تعذر استلام رسالة من واتساب
WHATSAPP_ERROR_REMOVING_MESSAGE: تعذر إزالة رسالة من واتساب
APP_SCHEDULED_JOB_ERROR: فشل تنفيذ المهمة المجدولة
whatsapp.message.sending.error: تعذر إرسال رسالة على واتساب.
whatsapp.message.receiving.error: تعذر استلام رسالة من واتساب
whatsapp.message.removing.error: تعذر إزالة رسالة من واتساب
job.scheduled.error.header: فشل تنفيذ المهمة المجدولة
MESSAGE_FROM_WHATSAPP: |
message.from.whatsapp: |-
{{{text}}}
📱 *أرسلت من واتساب*
MESSAGE_FROM_API: |
message.from.api: |-
{{{text}}}
📱 *أرسلت عبر API*
MESSAGE_REMOVED_IN_WHATSAPP: |
message.removed.in.whatsapp: |-
❌ *تم حذف هذه الرسالة في واتساب*
MESSAGE_EDITED_IN_WHATSAPP: |
message.edited.in.whatsapp: |-
{{{text}}}
✏️ *تم تعديلها في واتساب*
WHATSAPP_GROUP_MESSAGE: |
{{{text}}}
whatsapp.group.message: |-
👥 *{{{participant}}}*
WHATSAPP_REACTION_ADDED: |
{{{text}}}
whatsapp.reaction.added: |-
*تفاعل* {{{emoji}}}
WHATSAPP_REACTION_REMOVED: |
whatsapp.reaction.removed: |-
*تمت إزالة التفاعل*
WHATSAPP_CONTACT_GROUP_SUFFIX: 'مجموعة'
WHATSAPP_CONTACT_CHANNEL_SUFFIX: 'قناة'
whatsapp.contact.group.suffix: 'مجموعة'
whatsapp.contact.channel.suffix: 'قناة'
whatsapp.contact.broadcast.suffix: 'قائمة البث'
# Aka Stories
WHATSAPP_CONTACT_STATUS_NAME: 'الحالة'
whatsapp.contact.status.name: 'الحالة'
APP_CONNECTED_MESSAGE: |
app.connected.message: |-
🔗 **متصل: جلسة واتساب إلى صندوق وارد ChatWoot**
✅ تم توصيل جلسة واتساب **{{{name}}}** بنجاح بصندوق وارد ChatWoot هذا.
@@ -80,7 +103,7 @@ APP_CONNECTED_MESSAGE: |
لنبدأ! 🚀
APP_DISCONNECTED_MESSAGE: |
app.disconnected.message: |-
🔌 **غير متصل: جلسة واتساب من صندوق وارد ChatWoot**
❌ تم قطع اتصال جلسة واتساب **{{{name}}}** من صندوق وارد ChatWoot هذا.
@@ -89,15 +112,15 @@ APP_DISCONNECTED_MESSAGE: |
لإعادة الاتصال، يرجى الاتصال بالمسؤول الخاص بك.
APP_UPDATED_MESSAGE: |
app.updated.message: |-
🔄 **تم التحديث: إعدادات جلسة واتساب**
✅ تم تحديث إعدادات جلسة واتساب **{{{name}}}**.
APP_COMMANDS_LIST: |
app.commands.list: |-
يمكنك إدارة **تكامل واتساب** عن طريق إرسال أحد الأوامر التالية:
🖥️ الجلسات:
🖥️ **الجلسة**:
1. **status** - الحصول على حالة الجلسة الحالية.
2. **restart** - إعادة تشغيل الجلسة - سيحاول هذا إعادة توصيل حساب واتساب الخاص بك.
3. **start** - بدء الجلسة.
@@ -107,42 +130,47 @@ APP_COMMANDS_LIST: |
7. **screenshot** - الحصول على لقطة شاشة للجلسة (متاح فقط في محرك **WEBJS**).
8. **help** - الأوامر المتاحة.
{{#commands.server}}
⚙️ الخادم:
- **server status** - الحصول على معلومات إصدار الخادم وحالته.
- **server reboot** - إعادة تشغيل الخادم بسلاسة.
- **server reboot force** - إعادة تشغيل الخادم بالقوة.
{{/commands.server}}
أرسل **أمرًا** (غير حساس لحالة الأحرف) أو **رقم أمر** إلى هذه المحادثة.
APP_HELP_REMINDER: |
app.commands.server.disabled: ⛔ **تم تعطيل أوامر الخادم**.
يرجى التواصل مع مسؤول النظام لديك.
أرسل **help** للحصول على قائمة الأوامر المتاحة.
APP_SESSION_STATUS_CHANGE: |
app.help.reminder: |-
أرسل **help** للحصول على قائمة الأوامر المتاحة.
app.session.status.change: |-
{{{emoji}}} تم تغيير حالة جلسة "{{{session}}}" إلى {{{status}}}
APP_SESSION_CURRENT_STATUS: |
app.session.current.status: |-
{{{emoji}}} حالة جلسة **{{{session}}}** هي **{{{status}}}**
**حساب واتساب:**
📱 **{{{name}}} ({{{id}}})**
APP_DASHBOARD_LINK: |
قم بزيارة [لوحة تحكم WAHA]({{{url}}}) لمزيد من التفاصيل.
APP_SESSION_STATUS_WORKING: |
app.session.status.working: |-
✅ صندوق وارد ChatWoot هذا مرتبط بـ **حساب واتساب** وجاهز لإرسال واستقبال الرسائل!
📱 **{{{name}}} ({{{id}}})**
APP_SESSION_STATUS_ERROR: |
app.session.status.error: |-
⚠️ **صندوق وارد ChatWoot هذا مرتبط بحساب واتساب ولكنه غير جاهز لإرسال واستقبال الرسائل!**
يرجى التحقق من حالة الجلسة ومحاولة إعادة تشغيلها أو تسجيل الخروج ومسح رمز QR مرة أخرى.
APP_SESSION_SCAN_QR_CODE: |
app.session.scan.qr.code: |-
⚠️ **امسح رمز QR على هاتفك لربط حساب واتساب بصندوق وارد ChatWoot هذا!**
APP_SERVER_VERSION_AND_STATUS: |
app.server.version.and.status: |-
**الإصدار:**
```
{{{version}}}
@@ -153,16 +181,16 @@ APP_SERVER_VERSION_AND_STATUS: |
{{{status}}}
```
APP_SERVER_REBOOT: |
app.server.reboot: |-
يتم إعادة تشغيل الخادم بسلاسة...
APP_SERVER_REBOOT_FORCE: |
app.server.reboot.force: |-
يتم إعادة تشغيل الخادم بالقوة...
APP_LOGOUT_SUCCESS: |
app.logout.success: |-
✅ تم إلغاء تفويض الحساب بنجاح!
APP_NEW_VERSION_AVAILABLE: |
waha.new.version.available: |-
🔄 **إصدار جديد متاح!**
الإصدار الحالي: **{{{currentVersion}}}**
@@ -170,7 +198,7 @@ APP_NEW_VERSION_AVAILABLE: |
👉 تحقق مما هو جديد في [**🆕 سجل التغييرات**]({{{changelogUrl}}})
APP_CORE_VERSION_USED: |
waha.core.version.used: |-
❤️ **ادعم WAHA!**
أنت تستخدم إصدار **WAHA Core** المجاني. إذا وجدت هذا المشروع مفيدًا، فيرجى التفكير في دعم تطويره.
@@ -178,3 +206,149 @@ APP_CORE_VERSION_USED: |
دعمك هو الطريقة الوحيدة التي يمكننا من خلالها الاستمرار في العمل على التحديثات والإصلاحات والميزات الجديدة.
[**🎁 ادعمنا**]({{{supportUrl}}})
chatwoot.to.whatsapp.message.text: |-
{{{ content }}}
chatwoot.to.whatsapp.message.media.caption: |-
{{#singleAttachment}}
{{#content}}
{{{ content }}}
{{/content}}
{{/singleAttachment}}
whatsapp.to.chatwoot.message: |-
{{{payload.body}}}
whatsapp.to.chatwoot.message.contacts: |-
👤 **جهات الاتصال المشتركة**
{{#contacts}}
🪪 الاسم: **{{fullName}}**
{{#phoneNumbers}}
- 📞 الهاتف: **{{.}}**
{{/phoneNumbers}}
{{/contacts}}
whatsapp.to.chatwoot.message.location: |-
{{#message}}
{{#locationMessage}}
📍 **الموقع المشترك**
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **العنوان:** {{address}}
{{/address}}
{{#url}}
🌐 **الموقع الإلكتروني:** {{url}}
{{/url}}
🔗 **عرض على الخريطة:** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/locationMessage}}
{{#liveLocationMessage}}
📍📡 **مشاركة الموقع المباشر**
افتح **WhatsApp** لعرض التحديثات اللحظية.
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **العنوان:** {{address}}
{{/address}}
{{#url}}
🌐 **الموقع الإلكتروني:** {{url}}
{{/url}}
🔗 **عرض على الخريطة:** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/liveLocationMessage}}
{{/message}}
whatsapp.to.chatwoot.message.poll: |-
{{#poll}}
📊 **استطلاع**
**{{name}}**
{{#options}}
- {{optionName}}
{{/options}}
{{/poll}}
whatsapp.to.chatwoot.message.event: |-
{{#message}}
{{#eventMessage}}
📅 **حدث**
**{{name}}**
{{#description}}
{{description}}
{{/description}}
{{#location.name}}
📍 **الموقع:** {{location.name}}
{{/location.name}}
{{#startTime}}
🕐 **البدء:** {{startTime}}
{{/startTime}}
{{#endTime}}
🕐 **الانتهاء:** {{endTime}}
{{/endTime}}
{{#joinLink}}
🔗 **رابط الانضمام:** [{{joinLink}}]({{joinLink}})
{{/joinLink}}
{{/eventMessage}}
{{/message}}
whatsapp.to.chatwoot.message.pix: |-
💳 **PIX - نسخ ولصق**
{{#pixData}}
{{#merchantName}}
**{{merchantName}}**
{{/merchantName}}
{{#key}}
**مفتاح PIX:** {{key}}
{{/key}}
{{#keyType}}
**النوع:** {{keyType}}
{{/keyType}}
{{#totalAmount}}
**المبلغ:** {{totalAmountFormatted}}
{{/totalAmount}}
{{#referenceId}}
**المرجع:** {{referenceId}}
{{/referenceId}}
💳 **تم إرسال PIX نسخ ولصق**
{{/pixData}}
whatsapp.to.chatwoot.message.unsupported: |-
⚠️ **هذا النوع من الرسائل غير مدعوم في ChatWoot.**
📱 يرجى فتح **WhatsApp** لعرضه.
التفاصيل: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **إعلان فيسبوك**
**العنوان:** {{{adData.title}}}
**الوصف:**
{{{adData.body}}}
**رابط الإعلان:** [عرض على فيسبوك]({{{adData.sourceUrl}}})
**معرّف الإعلان:** {{{adData.sourceId}}}
---
💬 **رسالة العميل:**
{{{payload.body}}}
@@ -1,7 +1,29 @@
# Bengali translations for ChatWoot integration
APP_INBOX_CONTACT_NAME: 'হোয়াটসঅ্যাপ ইন্টিগ্রেশন (WAHA)'
locale.name: '🇧🇩 বাংলা (Bengali)'
JOB_ERROR_REPORT: |
# বেস লোকেল কোড - এটি একটি বৈধ BCP 47 লোকেল হতে হবে
# https://en.wikipedia.org/wiki/IETF_language_tag
# WAHA এটি সংখ্যা, মুদ্রা এবং তারিখ/সময়ের ফরম্যাটিংয়ে ব্যবহার করে।
locale.base: 'bn-BD'
app.inbox.contact.name: 'হোয়াটসঅ্যাপ ইন্টিগ্রেশন (WAHA)'
app.inbox.contact.avatar.url: 'https://raw.githubusercontent.com/devlikeapro/waha/core/logo.png'
# date.toLocaleString এর "options"
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#options
datetime:
locales: bn-BD
day: 2-digit
month: 2-digit
year: numeric
hour: 2-digit
minute: 2-digit
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#timezonename
timeZoneName: shortGeneric
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
# timeZone: 'Asia/Dhaka'
job.report.error: |-
⚠️ **{{{header}}}**
{{#attempts.nextDelay}}
🔄 {{attempts.nextDelay}} সেকেন্ডের মধ্যে পুনরায় চেষ্টা করা হচ্ছে...
@@ -18,51 +40,52 @@ JOB_ERROR_REPORT: |
```
{{/error}}
JOB_SUCCEEDED_REPORT: |
job.report.succeeded: |-
✅ **সফল হয়েছে**
প্রচেষ্টা: {{{attempts.current}}} / {{{attempts.max}}}
বিবরণ: [{{{details.text}}}]({{{details.url}}})
WHATSAPP_ERROR_SENDING_MESSAGE: হোয়াটসঅ্যাপে বার্তা পাঠাতে পারেনি।
WHATSAPP_ERROR_RECEIVING_MESSAGE: হোয়াটসঅ্যাপ থেকে বার্তা পেতে পারেনি
WHATSAPP_ERROR_REMOVING_MESSAGE: হোয়াটসঅ্যাপ থেকে বার্তা সরাতে পারেনি
APP_SCHEDULED_JOB_ERROR: নির্ধারিত কাজ সম্পাদন করতে ব্যর্থ হয়েছে
whatsapp.message.sending.error: হোয়াটসঅ্যাপে বার্তা পাঠাতে পারেনি।
whatsapp.message.receiving.error: হোয়াটসঅ্যাপ থেকে বার্তা পেতে পারেনি
whatsapp.message.removing.error: হোয়াটসঅ্যাপ থেকে বার্তা সরাতে পারেনি
job.scheduled.error.header: নির্ধারিত কাজ সম্পাদন করতে ব্যর্থ হয়েছে
MESSAGE_FROM_WHATSAPP: |
message.from.whatsapp: |-
{{{text}}}
📱 *হোয়াটসঅ্যাপ থেকে পাঠানো হয়েছে*
MESSAGE_FROM_API: |
message.from.api: |-
{{{text}}}
📱 *API এর মাধ্যমে পাঠানো হয়েছে*
MESSAGE_REMOVED_IN_WHATSAPP: |
message.removed.in.whatsapp: |-
❌ *এই বার্তাটি হোয়াটসঅ্যাপে মুছে ফেলা হয়েছে*
MESSAGE_EDITED_IN_WHATSAPP: |
message.edited.in.whatsapp: |-
{{{text}}}
✏️ *হোয়াটসঅ্যাপে সম্পাদিত*
WHATSAPP_GROUP_MESSAGE: |
{{{text}}}
whatsapp.group.message: |-
👥 *{{{participant}}}*
WHATSAPP_REACTION_ADDED: |
{{{text}}}
whatsapp.reaction.added: |-
*প্রতিক্রিয়া দিয়েছেন* {{{emoji}}}
WHATSAPP_REACTION_REMOVED: |
whatsapp.reaction.removed: |-
*প্রতিক্রিয়া সরানো হয়েছে*
WHATSAPP_CONTACT_GROUP_SUFFIX: 'গ্রুপ'
WHATSAPP_CONTACT_CHANNEL_SUFFIX: 'চ্যানেল'
whatsapp.contact.group.suffix: 'গ্রুপ'
whatsapp.contact.channel.suffix: 'চ্যানেল'
whatsapp.contact.broadcast.suffix: 'প্রচার তালিকা'
# Aka Stories
WHATSAPP_CONTACT_STATUS_NAME: 'স্ট্যাটাস'
whatsapp.contact.status.name: 'স্ট্যাটাস'
APP_CONNECTED_MESSAGE: |
app.connected.message: |-
🔗 **সংযুক্ত: হোয়াটসঅ্যাপ সেশন থেকে ChatWoot ইনবক্স**
✅ হোয়াটসঅ্যাপ সেশন **{{{name}}}** সফলভাবে এই ChatWoot ইনবক্সের সাথে সংযুক্ত করা হয়েছে।
@@ -80,7 +103,7 @@ APP_CONNECTED_MESSAGE: |
চলুন শুরু করা যাক! 🚀
APP_DISCONNECTED_MESSAGE: |
app.disconnected.message: |-
🔌 **সংযোগ বিচ্ছিন্ন: হোয়াটসঅ্যাপ সেশন থেকে ChatWoot ইনবক্স**
❌ হোয়াটসঅ্যাপ সেশন **{{{name}}}** এই ChatWoot ইনবক্স থেকে সংযোগ বিচ্ছিন্ন করা হয়েছে।
@@ -89,15 +112,15 @@ APP_DISCONNECTED_MESSAGE: |
পুনরায় সংযোগ করতে, অনুগ্রহ করে আপনার প্রশাসকের সাথে যোগাযোগ করুন।
APP_UPDATED_MESSAGE: |
app.updated.message: |-
🔄 **আপডেট করা হয়েছে: হোয়াটসঅ্যাপ সেশন সেটিংস**
✅ হোয়াটসঅ্যাপ সেশন **{{{name}}}** এর সেটিংস আপডেট করা হয়েছে।
APP_COMMANDS_LIST: |
app.commands.list: |-
আপনি নিম্নলিখিত কমান্ডগুলির একটি পাঠিয়ে **হোয়াটসঅ্যাপ ইন্টিগ্রেশন** পরিচালনা করতে পারেন:
🖥️ সেশন:
🖥️ **সেশন**:
1. **status** - বর্তমান সেশনের স্ট্যাটাস পান।
2. **restart** - সেশন পুনরায় চালু করুন - এটি আপনার হোয়াটসঅ্যাপ অ্যাকাউন্ট পুনরায় সংযোগ করার চেষ্টা করবে।
3. **start** - সেশন শুরু করুন।
@@ -107,42 +130,47 @@ APP_COMMANDS_LIST: |
7. **screenshot** - সেশনের স্ক্রিনশট পান (শুধুমাত্র **WEBJS** ইঞ্জিনে উপলব্ধ)।
8. **help** - উপলব্ধ কমান্ডগুলি।
{{#commands.server}}
⚙️ সার্ভার:
- **server status** - সার্ভারের সংস্করণ এবং স্ট্যাটাস তথ্য পান।
- **server reboot** - সার্ভার সুন্দরভাবে পুনরায় চালু করুন।
- **server reboot force** - সার্ভার জোর করে পুনরায় চালু করুন।
{{/commands.server}}
এই কথোপকথনে একটি **কমান্ড** (কেস সংবেদনশীল নয়) বা **কমান্ড নম্বর** পাঠান।
APP_HELP_REMINDER: |
app.commands.server.disabled: ⛔ **সার্ভার কমান্ড নিষ্ক্রিয় করা হয়েছে**।
দয়া করে আপনার প্রশাসকের সাথে যোগাযোগ করুন।
উপলব্ধ কমান্ডের তালিকা পেতে **help** পাঠান।
app.help.reminder: |-
উপলব্ধ কমান্ডগুলির তালিকা পেতে **help** পাঠান।
APP_SESSION_STATUS_CHANGE: |
app.session.status.change: |-
{{{emoji}}} "{{{session}}}" সেশন {{{status}}} স্ট্যাটাসে পরিবর্তিত হয়েছে
APP_SESSION_CURRENT_STATUS: |
app.session.current.status: |-
{{{emoji}}} **{{{session}}}** সেশনের স্ট্যাটাস **{{{status}}}**
**হোয়াটসঅ্যাপ অ্যাকাউন্ট:**
📱 **{{{name}}} ({{{id}}})**
APP_DASHBOARD_LINK: |
আরও বিবরণের জন্য [WAHA ড্যাশবোর্ড]({{{url}}}) দেখুন।
APP_SESSION_STATUS_WORKING: |
app.session.status.working: |-
✅ এই ChatWoot ইনবক্স **হোয়াটসঅ্যাপ অ্যাকাউন্টের** সাথে সংযুক্ত এবং বার্তা পাঠাতে ও গ্রহণ করতে প্রস্তুত!
📱 **{{{name}}} ({{{id}}})**
APP_SESSION_STATUS_ERROR: |
app.session.status.error: |-
⚠️ **এই ChatWoot ইনবক্স হোয়াটসঅ্যাপ অ্যাকাউন্টের সাথে সংযুক্ত কিন্তু বার্তা পাঠাতে ও গ্রহণ করতে প্রস্তুত নয়!**
অনুগ্রহ করে সেশনের স্ট্যাটাস পরীক্ষা করুন এবং এটি পুনরায় চালু করার চেষ্টা করুন অথবা লগআউট করুন এবং QR কোড আবার স্ক্যান করুন।
APP_SESSION_SCAN_QR_CODE: |
app.session.scan.qr.code: |-
⚠️ **এই ChatWoot ইনবক্সের সাথে হোয়াটসঅ্যাপ অ্যাকাউন্ট লিঙ্ক করতে আপনার ফোনে QR কোড স্ক্যান করুন!**
APP_SERVER_VERSION_AND_STATUS: |
app.server.version.and.status: |-
**সংস্করণ:**
```
{{{version}}}
@@ -153,16 +181,16 @@ APP_SERVER_VERSION_AND_STATUS: |
{{{status}}}
```
APP_SERVER_REBOOT: |
app.server.reboot: |-
সার্ভার সুন্দরভাবে পুনরায় চালু হচ্ছে...
APP_SERVER_REBOOT_FORCE: |
app.server.reboot.force: |-
সার্ভার জোর করে পুনরায় চালু হচ্ছে...
APP_LOGOUT_SUCCESS: |
app.logout.success: |-
✅ অ্যাকাউন্ট সফলভাবে অননুমোদিত করা হয়েছে!
APP_NEW_VERSION_AVAILABLE: |
waha.new.version.available: |-
🔄 **নতুন সংস্করণ উপলব্ধ!**
বর্তমান সংস্করণ: **{{{currentVersion}}}**
@@ -170,7 +198,7 @@ APP_NEW_VERSION_AVAILABLE: |
👉 [**🆕 পরিবর্তন লগ**]({{{changelogUrl}}}) এ নতুন কি আছে তা দেখুন
APP_CORE_VERSION_USED: |
waha.core.version.used: |-
❤️ **WAHA সমর্থন করুন!**
আপনি বিনামূল্যের **WAHA Core** সংস্করণ ব্যবহার করছেন। যদি আপনি এই প্রকল্পটি উপযোগী মনে করেন, তবে এর বিকাশকে সমর্থন করার কথা বিবেচনা করুন।
@@ -178,3 +206,149 @@ APP_CORE_VERSION_USED: |
আপনার সমর্থন হল একমাত্র উপায় যা দিয়ে আমরা আপডেট, ফিক্স এবং নতুন বৈশিষ্ট্যগুলিতে কাজ চালিয়ে যেতে পারি।
[**🎁 আমাদের সমর্থন করুন**]({{{supportUrl}}})
chatwoot.to.whatsapp.message.text: |-
{{{ content }}}
chatwoot.to.whatsapp.message.media.caption: |-
{{#singleAttachment}}
{{#content}}
{{{ content }}}
{{/content}}
{{/singleAttachment}}
whatsapp.to.chatwoot.message: |-
{{{payload.body}}}
whatsapp.to.chatwoot.message.contacts: |-
👤 **শেয়ার করা যোগাযোগ**
{{#contacts}}
🪪 নাম: **{{fullName}}**
{{#phoneNumbers}}
- 📞 ফোন: **{{.}}**
{{/phoneNumbers}}
{{/contacts}}
whatsapp.to.chatwoot.message.location: |-
{{#message}}
{{#locationMessage}}
📍 **শেয়ার করা লোকেশন**
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **ঠিকানা:** {{address}}
{{/address}}
{{#url}}
🌐 **ওয়েবসাইট:** {{url}}
{{/url}}
🔗 **মানচিত্রে দেখুন:** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/locationMessage}}
{{#liveLocationMessage}}
📍📡 **লাইভ লোকেশন শেয়ার করা হচ্ছে**
রিয়েল-টাইম আপডেট দেখতে **WhatsApp** খুলুন।
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **ঠিকানা:** {{address}}
{{/address}}
{{#url}}
🌐 **ওয়েবসাইট:** {{url}}
{{/url}}
🔗 **মানচিত্রে দেখুন:** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/liveLocationMessage}}
{{/message}}
whatsapp.to.chatwoot.message.poll: |-
{{#poll}}
📊 **জরিপ**
**{{name}}**
{{#options}}
- {{optionName}}
{{/options}}
{{/poll}}
whatsapp.to.chatwoot.message.event: |-
{{#message}}
{{#eventMessage}}
📅 **ইভেন্ট**
**{{name}}**
{{#description}}
{{description}}
{{/description}}
{{#location.name}}
📍 **স্থান:** {{location.name}}
{{/location.name}}
{{#startTime}}
🕐 **শুরুর সময়:** {{startTime}}
{{/startTime}}
{{#endTime}}
🕐 **শেষের সময়:** {{endTime}}
{{/endTime}}
{{#joinLink}}
🔗 **যোগদানের লিঙ্ক:** [{{joinLink}}]({{joinLink}})
{{/joinLink}}
{{/eventMessage}}
{{/message}}
whatsapp.to.chatwoot.message.pix: |-
💳 **PIX - কপি এবং পেস্ট**
{{#pixData}}
{{#merchantName}}
**{{merchantName}}**
{{/merchantName}}
{{#key}}
**PIX কী:** {{key}}
{{/key}}
{{#keyType}}
**ধরন:** {{keyType}}
{{/keyType}}
{{#totalAmount}}
**পরিমাণ:** {{totalAmountFormatted}}
{{/totalAmount}}
{{#referenceId}}
**রেফারেন্স:** {{referenceId}}
{{/referenceId}}
💳 **PIX কপি এবং পেস্ট পাঠানো হয়েছে**
{{/pixData}}
whatsapp.to.chatwoot.message.unsupported: |-
⚠️ **এই ধরনের বার্তা ChatWoot-এ সমর্থিত নয়।**
📱 এটি দেখতে অনুগ্রহ করে **WhatsApp** খুলুন।
বিস্তারিত: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **ফেসবুক বিজ্ঞাপন**
**শিরোনাম:** {{{adData.title}}}
**বর্ণনা:**
{{{adData.body}}}
**বিজ্ঞাপনের লিংক:** [ফেসবুকে দেখুন]({{{adData.sourceUrl}}})
**বিজ্ঞাপনের আইডি:** {{{adData.sourceId}}}
---
💬 **গ্রাহকের বার্তা:**
{{{payload.body}}}
+357
View File
@@ -0,0 +1,357 @@
# German translations for ChatWoot integration
locale.name: '🇩🇪 Deutsch (German)'
# Basis-Gebietsschema-Code - muss eine gültige BCP 47 Locale sein
# https://en.wikipedia.org/wiki/IETF_language_tag
# WAHA nutzt ihn zur Darstellung von Zahlen, Währungen sowie Datum und Uhrzeit
locale.base: 'de-DE'
app.inbox.contact.name: 'WhatsApp Integration (WAHA)'
app.inbox.contact.avatar.url: 'https://raw.githubusercontent.com/devlikeapro/waha/core/logo.png'
# "Optionen" von date.toLocaleString
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#options
datetime:
locales: de-DE
day: 2-digit
month: 2-digit
year: numeric
hour: 2-digit
minute: 2-digit
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#timezonename
timeZoneName: shortGeneric
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
# timeZone: 'Europe/Berlin'
job.report.error: |-
⚠️ **{{{header}}}**
{{#attempts.nextDelay}}
🔄 Wiederholung in {{attempts.nextDelay}} Sekunden...
{{/attempts.nextDelay}}
{{^attempts.nextDelay}}
❌ Keine weiteren Versuche übrig. Bitte versuchen Sie es später erneut.
{{/attempts.nextDelay}}
Versuch: {{{attempts.current}}} / {{{attempts.max}}}
Details: [{{{details.text}}}]({{{details.url}}})
{{#error}}
```
{{{error}}}
```
{{/error}}
job.report.succeeded: |-
✅ **Erfolgreich**
Versuch: {{{attempts.current}}} / {{{attempts.max}}}
Details: [{{{details.text}}}]({{{details.url}}})
whatsapp.message.sending.error:
Nachricht konnte nicht über WhatsApp gesendet werden.
whatsapp.message.receiving.error:
Nachricht konnte nicht von WhatsApp empfangen werden
whatsapp.message.removing.error:
Nachricht konnte nicht von WhatsApp entfernt werden
job.scheduled.error.header: Geplante Aufgabe konnte nicht ausgeführt werden
message.from.whatsapp: |-
{{{text}}}
📱 *Von WhatsApp gesendet*
message.from.api: |-
{{{text}}}
📱 *Über API gesendet*
message.removed.in.whatsapp: |-
❌ *Diese Nachricht wurde in WhatsApp gelöscht*
message.edited.in.whatsapp: |-
{{{text}}}
✏️ *In WhatsApp bearbeitet*
whatsapp.group.message: |-
👥 *{{{participant}}}*
{{{text}}}
whatsapp.reaction.added: |-
*Reagiert mit* {{{emoji}}}
whatsapp.reaction.removed: |-
*Reaktion entfernt*
whatsapp.contact.group.suffix: 'Gruppe'
whatsapp.contact.channel.suffix: 'Kanal'
whatsapp.contact.broadcast.suffix: 'Broadcast-Liste'
# Aka Stories
whatsapp.contact.status.name: 'Status'
app.connected.message: |-
🔗 **VERBUNDEN: WhatsApp-Sitzung mit ChatWoot Inbox**
✅ WhatsApp-Sitzung **{{{name}}}** wurde erfolgreich mit dieser ChatWoot Inbox verbunden.
Diese Inbox ist jetzt mit Ihrem **WhatsApp-Konto** verknüpft. Sie können Nachrichten direkt von hier senden und empfangen — genau wie bei WhatsApp, aber innerhalb von ChatWoot.
Sie können auch die mit dieser Inbox verknüpfte WhatsApp-Sitzung verwalten. Um verfügbare Aktionen anzuzeigen, senden Sie **help** an diesen Chat.
📋 Häufige Aktionen, die Sie durchführen können:
- Überprüfen, ob die WhatsApp-Sitzung aktiv ist
- Die WhatsApp-Sitzung neu starten oder stoppen
- Abmelden und durch Scannen eines neuen QR-Codes wieder verbinden
Wenn alles funktioniert, können Sie frei chatten. Wenn Sie Warnungen sehen, müssen Sie möglicherweise Ihr WhatsApp-Konto neu verbinden.
Lassen Sie uns beginnen! 🚀
app.disconnected.message: |-
🔌 **GETRENNT: WhatsApp-Sitzung von ChatWoot Inbox**
❌ WhatsApp-Sitzung **{{{name}}}** wurde von dieser ChatWoot Inbox getrennt.
Sie können keine Nachrichten mehr von WhatsApp senden oder empfangen.
Um eine erneute Verbindung herzustellen, wenden Sie sich bitte an Ihren Administrator.
app.updated.message: |-
🔄 **AKTUALISIERT: WhatsApp-Sitzungseinstellungen**
✅ Einstellungen für WhatsApp-Sitzung **{{{name}}}** wurden aktualisiert.
app.commands.list: |-
Sie können die **WhatsApp Integration** verwalten, indem Sie einen der folgenden Befehle senden:
🖥️ **Sitzung**:
1. **status** - den aktuellen Sitzungsstatus abrufen.
2. **restart** - die Sitzung neu starten - dies versucht, Ihr WhatsApp-Konto neu zu verbinden.
3. **start** - die Sitzung starten.
4. **stop** - die Sitzung stoppen.
5. **logout** - von der Sitzung abmelden, damit Sie den QR-Code scannen und die Sitzung reparieren können.
6. **qr** - den QR-Code für die Sitzung abrufen.
7. **screenshot** - einen Screenshot der Sitzung erhalten (nur in der **WEBJS**-Engine verfügbar).
8. **help** - verfügbare Befehle.
{{#commands.server}}
⚙️ Server:
- **server status** - Serverversion und Statusinformationen abrufen.
- **server reboot** - Server ordnungsgemäß neu starten.
- **server reboot force** - Server erzwungen neu starten.
{{/commands.server}}
Senden Sie einen **Befehl** (Groß-/Kleinschreibung wird nicht beachtet) oder eine **Befehlsnummer** an diese Konversation.
app.commands.server.disabled: ⛔ **Serverbefehle sind deaktiviert**.
Bitte wenden Sie sich an Ihren Administrator.
Senden Sie **help**, um die Liste der verfügbaren Befehle zu erhalten.
app.help.reminder: |-
Senden Sie **help**, um die Liste der verfügbaren Befehle zu erhalten.
app.session.status.change: |-
{{{emoji}}} Sitzung "{{{session}}}" hat den Status zu {{{status}}} gewechselt
app.session.current.status: |-
{{{emoji}}} **{{{session}}}** Sitzungsstatus ist **{{{status}}}**
**WhatsApp-Konto:**
📱 **{{{name}}} ({{{id}}})**
app.session.status.working: |-
✅ Diese ChatWoot Inbox ist mit dem **WhatsApp-Konto** verknüpft und bereit zum Senden und Empfangen von Nachrichten!
📱 **{{{name}}} ({{{id}}})**
app.session.status.error: |-
⚠️ **Diese ChatWoot Inbox ist mit dem WhatsApp-Konto verknüpft, aber NICHT bereit zum Senden und Empfangen von Nachrichten!**
Bitte überprüfen Sie den Sitzungsstatus und versuchen Sie, sie neu zu starten oder melden Sie sich ab und scannen Sie den QR-Code erneut.
app.session.scan.qr.code: |-
⚠️ **Scannen Sie den QR-Code auf Ihrem Telefon, um das WhatsApp-Konto mit dieser ChatWoot Inbox zu verknüpfen!**
app.server.version.and.status: |-
**Version:**
```
{{{version}}}
```
**Status:**
```
{{{status}}}
```
app.server.reboot: |-
Server wird ordnungsgemäß neu gestartet...
app.server.reboot.force: |-
Server wird erzwungen neu gestartet...
app.logout.success: |-
✅ Konto erfolgreich abgemeldet!
waha.new.version.available: |-
🔄 **Neue Version verfügbar!**
Aktuelle Version: **{{{currentVersion}}}**
Neue Version: **{{{newVersion}}}**
👉 Sehen Sie, was neu ist im [**🆕 Änderungsprotokoll**]({{{changelogUrl}}})
waha.core.version.used: |-
❤️ **Unterstützen Sie WAHA!**
Sie verwenden die kostenlose **WAHA Core** Version. Wenn Sie dieses Projekt nützlich finden, erwägen Sie bitte, seine Entwicklung zu unterstützen.
Ihre Unterstützung ist der einzige Weg, wie wir weiterhin an Updates, Fehlerbehebungen und neuen Funktionen arbeiten können.
[**🎁 Unterstützen Sie uns**]({{{supportUrl}}})
chatwoot.to.whatsapp.message.text: |-
{{{ content }}}
chatwoot.to.whatsapp.message.media.caption: |-
{{#singleAttachment}}
{{#content}}
{{{ content }}}
{{/content}}
{{/singleAttachment}}
whatsapp.to.chatwoot.message: |-
{{{payload.body}}}
whatsapp.to.chatwoot.message.contacts: |-
👤 **Geteilte Kontakte**
{{#contacts}}
🪪 Name: **{{fullName}}**
{{#phoneNumbers}}
- 📞 Telefon: **{{.}}**
{{/phoneNumbers}}
{{/contacts}}
whatsapp.to.chatwoot.message.location: |-
{{#message}}
{{#locationMessage}}
📍 **Geteilter Standort**
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **Adresse:** {{address}}
{{/address}}
{{#url}}
🌐 **Webseite:** {{url}}
{{/url}}
🔗 **Auf Karte ansehen:** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/locationMessage}}
{{#liveLocationMessage}}
📍📡 **Live-Standort wird geteilt**
Öffne **WhatsApp**, um Aktualisierungen in Echtzeit zu sehen.
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **Adresse:** {{address}}
{{/address}}
{{#url}}
🌐 **Webseite:** {{url}}
{{/url}}
🔗 **Auf Karte ansehen:** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/liveLocationMessage}}
{{/message}}
whatsapp.to.chatwoot.message.poll: |-
{{#poll}}
📊 **Umfrage**
**{{name}}**
{{#options}}
- {{optionName}}
{{/options}}
{{/poll}}
whatsapp.to.chatwoot.message.event: |-
{{#message}}
{{#eventMessage}}
📅 **Veranstaltung**
**{{name}}**
{{#description}}
{{description}}
{{/description}}
{{#location.name}}
📍 **Ort:** {{location.name}}
{{/location.name}}
{{#startTime}}
🕐 **Beginn:** {{startTime}}
{{/startTime}}
{{#endTime}}
🕐 **Ende:** {{endTime}}
{{/endTime}}
{{#joinLink}}
🔗 **Teilnahmelink:** [{{joinLink}}]({{joinLink}})
{{/joinLink}}
{{/eventMessage}}
{{/message}}
whatsapp.to.chatwoot.message.pix: |-
💳 **PIX - Kopieren und Einfügen**
{{#pixData}}
{{#merchantName}}
**{{merchantName}}**
{{/merchantName}}
{{#key}}
**PIX-Schlüssel:** {{key}}
{{/key}}
{{#keyType}}
**Typ:** {{keyType}}
{{/keyType}}
{{#totalAmount}}
**Betrag:** {{totalAmountFormatted}}
{{/totalAmount}}
{{#referenceId}}
**Referenz:** {{referenceId}}
{{/referenceId}}
💳 **PIX Kopieren und Einfügen gesendet**
{{/pixData}}
whatsapp.to.chatwoot.message.unsupported: |-
⚠️ **Dieser Nachrichtentyp wird in ChatWoot nicht unterstützt.**
📱 Bitte öffne **WhatsApp**, um ihn anzusehen.
Details: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **FACEBOOK-ANZEIGE**
**Titel:** {{{adData.title}}}
**Beschreibung:**
{{{adData.body}}}
**Anzeigenlink:** [Auf Facebook ansehen]({{{adData.sourceUrl}}})
**Anzeigen-ID:** {{{adData.sourceId}}}
---
💬 **Kundennachricht:**
{{{payload.body}}}
+353
View File
@@ -0,0 +1,353 @@
# English translations for ChatWoot integration
locale.name: '🇺🇸 English (English)'
# Base locale code - must be a valid BCP 47 locale
# https://en.wikipedia.org/wiki/IETF_language_tag
# WAHA uses it for number, currency and datetime representation
locale.base: 'en-US'
app.inbox.contact.name: 'WhatsApp Integration (WAHA)'
app.inbox.contact.avatar.url: 'https://raw.githubusercontent.com/devlikeapro/waha/core/logo.png'
# "options" from date.toLocaleString
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#options
datetime:
day: 2-digit
month: 2-digit
year: numeric
hour: 2-digit
minute: 2-digit
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#timezonename
timeZoneName: shortGeneric
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
# timeZone: 'America/New_York'
job.report.error: |-
⚠️ **{{{header}}}**
{{#attempts.nextDelay}}
🔄 Retrying in {{attempts.nextDelay}} seconds...
{{/attempts.nextDelay}}
{{^attempts.nextDelay}}
❌ No more retries left. Please try again later.
{{/attempts.nextDelay}}
Attempt: {{{attempts.current}}} / {{{attempts.max}}}
Details: [{{{details.text}}}]({{{details.url}}})
{{#error}}
```
{{{error}}}
```
{{/error}}
job.report.succeeded: |-
✅ **Succeeded**
Attempt: {{{attempts.current}}} / {{{attempts.max}}}
Details: [{{{details.text}}}]({{{details.url}}})
whatsapp.message.sending.error: Couldn't send a message on WhatsApp.
whatsapp.message.receiving.error: Couldn't receive a message from WhatsApp
whatsapp.message.removing.error: Couldn't remove a message from WhatsApp
job.scheduled.error.header: Scheduled job failed to execute
message.from.whatsapp: |-
{{{text}}}
📱 *Sent from WhatsApp*
message.from.api: |-
{{{text}}}
📱 *Sent via API*
message.removed.in.whatsapp: |-
❌ *This message was deleted in WhatsApp*
message.edited.in.whatsapp: |-
{{{text}}}
✏️ *Edited in WhatsApp*
whatsapp.group.message: |-
👥 *{{{participant}}}*
{{{text}}}
whatsapp.reaction.added: |-
*Reacted* {{{emoji}}}
whatsapp.reaction.removed: |-
*Reaction removed*
whatsapp.contact.group.suffix: 'Group'
whatsapp.contact.channel.suffix: 'Channel'
whatsapp.contact.broadcast.suffix: 'Broadcast List'
# Aka Stories
whatsapp.contact.status.name: 'Status'
chatwoot.to.whatsapp.message.text: |-
{{{ content }}}
chatwoot.to.whatsapp.message.media.caption: |-
{{#singleAttachment}}
{{#content}}
{{{ content }}}
{{/content}}
{{/singleAttachment}}
whatsapp.to.chatwoot.message: |-
{{{payload.body}}}
whatsapp.to.chatwoot.message.contacts: |-
👤 **Shared Contact(s)**
{{#contacts}}
🪪 Name: **{{fullName}}**
{{#phoneNumbers}}
- 📞 Phone: **{{.}}**
{{/phoneNumbers}}
{{/contacts}}
whatsapp.to.chatwoot.message.location: |-
{{#message}}
{{#locationMessage}}
📍 **Shared Location**
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **Address:** {{address}}
{{/address}}
{{#url}}
🌐 **Website:** {{url}}
{{/url}}
🔗 **View on map:** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/locationMessage}}
{{#liveLocationMessage}}
📍📡 **Sharing Live Location**
Open **WhatsApp** to see real-time updates.
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **Address:** {{address}}
{{/address}}
{{#url}}
🌐 **Website:** {{url}}
{{/url}}
🔗 **View on map:** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/liveLocationMessage}}
{{/message}}
whatsapp.to.chatwoot.message.poll: |-
{{#poll}}
📊 **Poll**
**{{name}}**
{{#options}}
- {{optionName}}
{{/options}}
{{/poll}}
whatsapp.to.chatwoot.message.event: |-
{{#message}}
{{#eventMessage}}
📅 **Event**
**{{name}}**
{{#description}}
{{description}}
{{/description}}
{{#location.name}}
📍 **Location:** {{location.name}}
{{/location.name}}
{{#startTime}}
🕐 **Start:** {{startTime}}
{{/startTime}}
{{#endTime}}
🕐 **End:** {{endTime}}
{{/endTime}}
{{#joinLink}}
🔗 **Join Link:** [{{joinLink}}]({{joinLink}})
{{/joinLink}}
{{/eventMessage}}
{{/message}}
whatsapp.to.chatwoot.message.pix: |-
💳 **PIX - Copy and Paste**
{{#pixData}}
{{#merchantName}}
**{{merchantName}}**
{{/merchantName}}
{{#key}}
**PIX Key:** {{key}}
{{/key}}
{{#keyType}}
**Type:** {{keyType}}
{{/keyType}}
{{#totalAmount}}
**Amount:** {{totalAmountFormatted}}
{{/totalAmount}}
{{#referenceId}}
**Reference:** {{referenceId}}
{{/referenceId}}
💳 **PIX Copy and Paste sent**
{{/pixData}}
whatsapp.to.chatwoot.message.unsupported: |-
⚠️ **This message type is not supported in ChatWoot.**
📱 Please open **WhatsApp** to view it.
Details: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **FACEBOOK AD**
**Title:** {{{adData.title}}}
**Description:**
{{{adData.body}}}
**Ad Link:** [View on Facebook]({{{adData.sourceUrl}}})
**Ad ID:** {{{adData.sourceId}}}
---
💬 **CUSTOMER MESSAGE:**
{{{payload.body}}}
app.connected.message: |-
🔗 **CONNECTED: WhatsApp Session to ChatWoot Inbox**
✅ WhatsApp session **{{{name}}}** has been successfully connected to this ChatWoot Inbox.
This inbox is now linked to your **WhatsApp Account**. You can send and receive messages directly from here — just like using WhatsApp, but inside ChatWoot.
You can also manage the WhatsApp session linked to this inbox. To view available actions, send **help** to this chat.
📋 Common actions you can do:
- Check if the WhatsApp session is active
- Restart or Stop the WhatsApp session
- Log out and reconnect by scanning a new QR code
If everything is working, you'll be able to chat freely. If you see warnings, you might need to reconnect your WhatsApp account.
Let's get started! 🚀
app.disconnected.message: |-
🔌 **DISCONNECTED: WhatsApp Session from ChatWoot Inbox**
❌ WhatsApp session **{{{name}}}** has been disconnected from this ChatWoot Inbox.
You will no longer be able to send or receive messages from WhatsApp.
To reconnect, please contact your administrator.
app.updated.message: |-
🔄 **UPDATED: WhatsApp Session Settings**
✅ Settings for WhatsApp session **{{{name}}}** have been updated.
app.commands.list: |-
You can manage **WhatsApp Integration** by sending one of the following commands:
🖥️ **Session**:
1. **status** - get the current session status.
2. **restart** - restart the session - this will try to reconnect your WhatsApp account.
3. **start** - start the session.
4. **stop** - stop the session.
5. **logout** - logout from the session, so you can scan QR code and repair the session.
6. **qr** - get the QR code for the session.
7. **screenshot** - get a screenshot of the session (only available in **WEBJS** engine).
8. **help** - available commands.
{{#commands.server}}
🛠️ **Server**:
- **server status** - get the server version and status information.
- **server reboot** - reboot the server gracefully.
- **server reboot force** - force reboot the server.
{{/commands.server}}
Send a **command** (case insensitive) or a **command number** to this conversation.
app.commands.server.disabled: ⛔ **Server commands are disabled**.
Please contact your administrator.
Send **help** to get the list of available commands.
app.help.reminder: |-
Send **help** to get the list of available commands.
app.session.status.change: |-
{{{emoji}}} "{{{session}}}" session switched to {{{status}}} status
app.session.current.status: |-
{{{emoji}}} **{{{session}}}** session status is in **{{{status}}}**
**WhatsApp Account:**
📱 **{{{name}}} ({{{id}}})**
app.session.status.working: |-
✅ This ChatWoot Inbox is linked to **WhatsApp Account** and ready to send and receive messages!
📱 **{{{name}}} ({{{id}}})**
app.session.status.error: |-
⚠️ **This ChatWoot Inbox is linked to WhatsApp Account but NOT ready to send and receive messages!**
Please check the session status and try restarting it or logout and scan the QR code again.
app.session.scan.qr.code: |-
⚠️ **Scan the QR code on your phone to link WhatsApp Account with this ChatWoot Inbox!**
app.server.version.and.status: |-
**Version:**
```
{{{version}}}
```
**Status:**
```
{{{status}}}
```
app.server.reboot: |-
Server is rebooting gracefully...
app.server.reboot.force: |-
Server is force rebooting...
app.logout.success: |-
✅ Account unauthorized successfully!
waha.new.version.available: |-
🔄 **New Version Available!**
Current version: **{{{currentVersion}}}**
New version: **{{{newVersion}}}**
👉 Check out what's new in the [**🆕 Changelog**]({{{changelogUrl}}})
waha.core.version.used: |-
❤️ **Support WAHA!**
You're using the free **WAHA Core** version. If you find this project useful, please consider supporting its development.
Your support is the only way we can continue working on updates, fixes, and new features.
[**🎁 Support Us**]({{{supportUrl}}})
+357
View File
@@ -0,0 +1,357 @@
# Spanish translations for ChatWoot integration
locale.name: '🇪🇸 Español (Spanish)'
# Código de locale base - debe ser un locale BCP 47 válido
# https://en.wikipedia.org/wiki/IETF_language_tag
# WAHA lo utiliza para formatear números, moneda y fecha/hora
locale.base: 'es-ES'
app.inbox.contact.name: 'Integración de WhatsApp (WAHA)'
app.inbox.contact.avatar.url: 'https://raw.githubusercontent.com/devlikeapro/waha/core/logo.png'
# "opciones" de date.toLocaleString
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#options
datetime:
locales: es-ES
day: 2-digit
month: 2-digit
year: numeric
hour: 2-digit
minute: 2-digit
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#timezonename
timeZoneName: shortGeneric
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
# timeZone: 'Europe/Madrid'
job.report.error: |-
⚠️ **{{{header}}}**
{{#attempts.nextDelay}}
🔄 Reintentando en {{attempts.nextDelay}} segundos...
{{/attempts.nextDelay}}
{{^attempts.nextDelay}}
❌ No quedan más intentos. Por favor, inténtelo de nuevo más tarde.
{{/attempts.nextDelay}}
Intento: {{{attempts.current}}} / {{{attempts.max}}}
Detalles: [{{{details.text}}}]({{{details.url}}})
{{#error}}
```
{{{error}}}
```
{{/error}}
job.report.succeeded: |-
✅ **Éxito**
Intento: {{{attempts.current}}} / {{{attempts.max}}}
Detalles: [{{{details.text}}}]({{{details.url}}})
whatsapp.message.sending.error: No se pudo enviar un mensaje en WhatsApp.
whatsapp.message.receiving.error: No se pudo recibir un mensaje de WhatsApp
whatsapp.message.removing.error: No se pudo eliminar un mensaje de WhatsApp
job.scheduled.error.header: La tarea programada no se pudo ejecutar
message.from.whatsapp: |-
{{{text}}}
📱 *Enviado desde WhatsApp*
message.from.api: |-
{{{text}}}
📱 *Enviado a través de API*
message.removed.in.whatsapp: |-
❌ *Este mensaje fue eliminado en WhatsApp*
message.edited.in.whatsapp: |-
{{{text}}}
✏️ *Editado en WhatsApp*
whatsapp.group.message: |-
👥 *{{{participant}}}*
{{{text}}}
whatsapp.reaction.added: |-
*Reaccionó con* {{{emoji}}}
whatsapp.reaction.removed: |-
*Reacción eliminada*
whatsapp.contact.group.suffix: 'Grupo'
whatsapp.contact.channel.suffix: 'Canal'
whatsapp.contact.broadcast.suffix: 'Lista de difusión'
# Aka Stories
whatsapp.contact.status.name: 'Estado'
app.connected.message: |-
🔗 **CONECTADO: Sesión de WhatsApp a Bandeja de Entrada de ChatWoot**
✅ La sesión de WhatsApp **{{{name}}}** ha sido conectada exitosamente a esta Bandeja de Entrada de ChatWoot.
Esta bandeja de entrada ahora está vinculada a tu **Cuenta de WhatsApp**. Puedes enviar y recibir mensajes directamente desde aquí — justo como usar WhatsApp, pero dentro de ChatWoot.
También puedes gestionar la sesión de WhatsApp vinculada a esta bandeja de entrada. Para ver las acciones disponibles, envía **help** a este chat.
📋 Acciones comunes que puedes realizar:
- Comprobar si la sesión de WhatsApp está activa
- Reiniciar o Detener la sesión de WhatsApp
- Cerrar sesión y reconectar escaneando un nuevo código QR
Si todo funciona, podrás chatear libremente. Si ves advertencias, es posible que necesites reconectar tu cuenta de WhatsApp.
¡Comencemos! 🚀
app.disconnected.message: |-
🔌 **DESCONECTADO: Sesión de WhatsApp de Bandeja de Entrada de ChatWoot**
❌ La sesión de WhatsApp **{{{name}}}** ha sido desconectada de esta Bandeja de Entrada de ChatWoot.
Ya no podrás enviar o recibir mensajes desde WhatsApp.
Para reconectar, por favor contacta a tu administrador.
app.updated.message: |-
🔄 **ACTUALIZADO: Configuración de Sesión de WhatsApp**
✅ La configuración para la sesión de WhatsApp **{{{name}}}** ha sido actualizada.
app.commands.list: |-
Puedes gestionar la **Integración de WhatsApp** enviando uno de los siguientes comandos:
🖥️ **Sesión**:
1. **status** - obtener el estado actual de la sesión.
2. **restart** - reiniciar la sesión - esto intentará reconectar tu cuenta de WhatsApp.
3. **start** - iniciar la sesión.
4. **stop** - detener la sesión.
5. **logout** - cerrar sesión, para que puedas escanear el código QR y reparar la sesión.
6. **qr** - obtener el código QR para la sesión.
7. **screenshot** - obtener una captura de pantalla de la sesión (solo disponible en el motor **WEBJS**).
8. **help** - comandos disponibles.
{{#commands.server}}
{{#commands.server}}
⚙️ Servidor:
- **server status** - obtener información de versión y estado del servidor.
- **server reboot** - reiniciar el servidor de forma segura.
- **server reboot force** - forzar el reinicio del servidor.
{{/commands.server}}
{{/commands.server}}
Envía un **comando** (no sensible a mayúsculas/minúsculas) o un **número de comando** a esta conversación.
app.commands.server.disabled: ⛔ **Los comandos del servidor están
deshabilitados**.
Por favor, contacta a tu administrador.
Envía **help** para obtener la lista de comandos disponibles.
app.help.reminder: |-
Envía **help** para obtener la lista de comandos disponibles.
app.session.status.change: |-
{{{emoji}}} La sesión "{{{session}}}" cambió al estado {{{status}}}
app.session.current.status: |-
{{{emoji}}} El estado de la sesión **{{{session}}}** es **{{{status}}}**
**Cuenta de WhatsApp:**
📱 **{{{name}}} ({{{id}}})**
app.session.status.working: |-
✅ ¡Esta Bandeja de Entrada de ChatWoot está vinculada a la **Cuenta de WhatsApp** y lista para enviar y recibir mensajes!
📱 **{{{name}}} ({{{id}}})**
app.session.status.error: |-
⚠️ **¡Esta Bandeja de Entrada de ChatWoot está vinculada a la Cuenta de WhatsApp pero NO está lista para enviar y recibir mensajes!**
Por favor, comprueba el estado de la sesión e intenta reiniciarla o cierra sesión y escanea el código QR de nuevo.
app.session.scan.qr.code: |-
⚠️ **¡Escanea el código QR en tu teléfono para vincular la Cuenta de WhatsApp con esta Bandeja de Entrada de ChatWoot!**
app.server.version.and.status: |-
**Versión:**
```
{{{version}}}
```
**Estado:**
```
{{{status}}}
```
app.server.reboot: |-
El servidor se está reiniciando de forma segura...
app.server.reboot.force: |-
El servidor se está reiniciando forzadamente...
app.logout.success: |-
✅ ¡Cuenta desautorizada con éxito!
waha.new.version.available: |-
🔄 **¡Nueva Versión Disponible!**
Versión actual: **{{{currentVersion}}}**
Nueva versión: **{{{newVersion}}}**
👉 Mira qué hay de nuevo en el [**🆕 Registro de Cambios**]({{{changelogUrl}}})
waha.core.version.used: |-
❤️ **¡Apoya a WAHA!**
Estás usando la versión gratuita **WAHA Core**. Si encuentras útil este proyecto, por favor considera apoyar su desarrollo.
Tu apoyo es la única forma en que podemos seguir trabajando en actualizaciones, correcciones y nuevas funciones.
[**🎁 Apóyanos**]({{{supportUrl}}})
chatwoot.to.whatsapp.message.text: |-
{{{ content }}}
chatwoot.to.whatsapp.message.media.caption: |-
{{#singleAttachment}}
{{#content}}
{{{ content }}}
{{/content}}
{{/singleAttachment}}
whatsapp.to.chatwoot.message: |-
{{{payload.body}}}
whatsapp.to.chatwoot.message.contacts: |-
👤 **Contacto(s) compartido(s)**
{{#contacts}}
🪪 Nombre: **{{fullName}}**
{{#phoneNumbers}}
- 📞 Teléfono: **{{.}}**
{{/phoneNumbers}}
{{/contacts}}
whatsapp.to.chatwoot.message.location: |-
{{#message}}
{{#locationMessage}}
📍 **Ubicación compartida**
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **Dirección:** {{address}}
{{/address}}
{{#url}}
🌐 **Sitio web:** {{url}}
{{/url}}
🔗 **Ver en el mapa:** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/locationMessage}}
{{#liveLocationMessage}}
📍📡 **Compartiendo ubicación en tiempo real**
Abre **WhatsApp** para ver las actualizaciones en tiempo real.
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **Dirección:** {{address}}
{{/address}}
{{#url}}
🌐 **Sitio web:** {{url}}
{{/url}}
🔗 **Ver en el mapa:** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/liveLocationMessage}}
{{/message}}
whatsapp.to.chatwoot.message.poll: |-
{{#poll}}
📊 **Encuesta**
**{{name}}**
{{#options}}
- {{optionName}}
{{/options}}
{{/poll}}
whatsapp.to.chatwoot.message.event: |-
{{#message}}
{{#eventMessage}}
📅 **Evento**
**{{name}}**
{{#description}}
{{description}}
{{/description}}
{{#location.name}}
📍 **Ubicación:** {{location.name}}
{{/location.name}}
{{#startTime}}
🕐 **Inicio:** {{startTime}}
{{/startTime}}
{{#endTime}}
🕐 **Fin:** {{endTime}}
{{/endTime}}
{{#joinLink}}
🔗 **Enlace para unirse:** [{{joinLink}}]({{joinLink}})
{{/joinLink}}
{{/eventMessage}}
{{/message}}
whatsapp.to.chatwoot.message.pix: |-
💳 **PIX - Copiar y Pegar**
{{#pixData}}
{{#merchantName}}
**{{merchantName}}**
{{/merchantName}}
{{#key}}
**Clave PIX:** {{key}}
{{/key}}
{{#keyType}}
**Tipo:** {{keyType}}
{{/keyType}}
{{#totalAmount}}
**Importe:** {{totalAmountFormatted}}
{{/totalAmount}}
{{#referenceId}}
**Referencia:** {{referenceId}}
{{/referenceId}}
💳 **PIX Copiar y Pegar enviado**
{{/pixData}}
whatsapp.to.chatwoot.message.unsupported: |-
⚠️ **Este tipo de mensaje no es compatible con ChatWoot.**
📱 Por favor, abre **WhatsApp** para verlo.
Detalles: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **ANUNCIO DE FACEBOOK**
**Título:** {{{adData.title}}}
**Descripción:**
{{{adData.body}}}
**Enlace del anuncio:** [Ver en Facebook]({{{adData.sourceUrl}}})
**ID del anuncio:** {{{adData.sourceId}}}
---
💬 **Mensaje del cliente:**
{{{payload.body}}}
@@ -1,7 +1,29 @@
# Persian translations for ChatWoot integration
APP_INBOX_CONTACT_NAME: 'ادغام واتساپ (WAHA)'
locale.name: '🇮🇷 فارسی (Persian)'
JOB_ERROR_REPORT: |
# کد محلی پایه - باید یک محلی معتبر BCP 47 باشد
# https://en.wikipedia.org/wiki/IETF_language_tag
# WAHA از آن برای نمایش اعداد، ارز و تاریخ/زمان استفاده می‌کند
locale.base: 'fa-IR'
app.inbox.contact.name: 'ادغام واتساپ (WAHA)'
app.inbox.contact.avatar.url: 'https://raw.githubusercontent.com/devlikeapro/waha/core/logo.png'
# گزینه‌های "options" از date.toLocaleString
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#options
datetime:
locales: fa-IR
day: 2-digit
month: 2-digit
year: numeric
hour: 2-digit
minute: 2-digit
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#timezonename
timeZoneName: shortGeneric
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
# timeZone: 'Asia/Tehran'
job.report.error: |-
⚠️ **{{{header}}}**
{{#attempts.nextDelay}}
🔄 تلاش مجدد در {{attempts.nextDelay}} ثانیه...
@@ -18,51 +40,52 @@ JOB_ERROR_REPORT: |
```
{{/error}}
JOB_SUCCEEDED_REPORT: |
job.report.succeeded: |-
✅ **موفقیت‌آمیز**
تلاش: {{{attempts.current}}} / {{{attempts.max}}}
جزئیات: [{{{details.text}}}]({{{details.url}}})
WHATSAPP_ERROR_SENDING_MESSAGE: ارسال پیام در واتساپ امکان‌پذیر نبود.
WHATSAPP_ERROR_RECEIVING_MESSAGE: دریافت پیام از واتساپ امکان‌پذیر نبود
WHATSAPP_ERROR_REMOVING_MESSAGE: حذف پیام از واتساپ امکان‌پذیر نبود
APP_SCHEDULED_JOB_ERROR: اجرای کار زمان‌بندی شده ناموفق بود
whatsapp.message.sending.error: ارسال پیام در واتساپ امکان‌پذیر نبود.
whatsapp.message.receiving.error: دریافت پیام از واتساپ امکان‌پذیر نبود
whatsapp.message.removing.error: حذف پیام از واتساپ امکان‌پذیر نبود
job.scheduled.error.header: اجرای کار زمان‌بندی شده ناموفق بود
MESSAGE_FROM_WHATSAPP: |
message.from.whatsapp: |-
{{{text}}}
📱 *ارسال شده از واتساپ*
MESSAGE_FROM_API: |
message.from.api: |-
{{{text}}}
📱 *ارسال شده از طریق API*
MESSAGE_REMOVED_IN_WHATSAPP: |
message.removed.in.whatsapp: |-
❌ *این پیام در واتساپ حذف شده است*
MESSAGE_EDITED_IN_WHATSAPP: |
message.edited.in.whatsapp: |-
{{{text}}}
✏️ *ویرایش شده در واتساپ*
WHATSAPP_GROUP_MESSAGE: |
{{{text}}}
whatsapp.group.message: |-
👥 *{{{participant}}}*
WHATSAPP_REACTION_ADDED: |
{{{text}}}
whatsapp.reaction.added: |-
*واکنش* {{{emoji}}}
WHATSAPP_REACTION_REMOVED: |
whatsapp.reaction.removed: |-
*واکنش حذف شد*
WHATSAPP_CONTACT_GROUP_SUFFIX: 'گروه'
WHATSAPP_CONTACT_CHANNEL_SUFFIX: 'کانال'
whatsapp.contact.group.suffix: 'گروه'
whatsapp.contact.channel.suffix: 'کانال'
whatsapp.contact.broadcast.suffix: 'فهرست انتشار'
# Aka Stories
WHATSAPP_CONTACT_STATUS_NAME: 'وضعیت'
whatsapp.contact.status.name: 'وضعیت'
APP_CONNECTED_MESSAGE: |
app.connected.message: |-
🔗 **متصل: جلسه واتساپ به صندوق ورودی ChatWoot**
✅ جلسه واتساپ **{{{name}}}** با موفقیت به این صندوق ورودی ChatWoot متصل شده است.
@@ -80,7 +103,7 @@ APP_CONNECTED_MESSAGE: |
بیایید شروع کنیم! 🚀
APP_DISCONNECTED_MESSAGE: |
app.disconnected.message: |-
🔌 **قطع اتصال: جلسه واتساپ از صندوق ورودی ChatWoot**
❌ جلسه واتساپ **{{{name}}}** از این صندوق ورودی ChatWoot قطع شده است.
@@ -89,15 +112,15 @@ APP_DISCONNECTED_MESSAGE: |
برای اتصال مجدد، لطفاً با مدیر خود تماس بگیرید.
APP_UPDATED_MESSAGE: |
app.updated.message: |-
🔄 **به‌روزرسانی: تنظیمات جلسه واتساپ**
✅ تنظیمات جلسه واتساپ **{{{name}}}** به‌روزرسانی شده است.
APP_COMMANDS_LIST: |
app.commands.list: |-
شما می‌توانید **ادغام واتساپ** را با ارسال یکی از دستورات زیر مدیریت کنید:
🖥️ جلسات:
🖥️ **جلسه**:
1. **status** - دریافت وضعیت فعلی جلسه.
2. **restart** - راه‌اندازی مجدد جلسه - این تلاش خواهد کرد حساب واتساپ شما را مجدداً متصل کند.
3. **start** - شروع جلسه.
@@ -107,42 +130,47 @@ APP_COMMANDS_LIST: |
7. **screenshot** - دریافت اسکرین‌شات از جلسه (فقط در موتور **WEBJS** در دسترس است).
8. **help** - دستورات موجود.
{{#commands.server}}
⚙️ سرور:
- **server status** - دریافت اطلاعات نسخه و وضعیت سرور.
- **server reboot** - راه‌اندازی مجدد سرور به صورت نرم.
- **server reboot force** - راه‌اندازی مجدد اجباری سرور.
{{/commands.server}}
یک **دستور** (بدون حساسیت به بزرگی و کوچکی حروف) یا **شماره دستور** را به این گفتگو ارسال کنید.
APP_HELP_REMINDER: |
app.commands.server.disabled: ⛔ **دستورات سرور غیرفعال است**.
لطفاً با مدیر سیستم خود تماس بگیرید.
برای دریافت فهرست دستورات، **help** را ارسال کنید.
app.help.reminder: |-
برای دریافت لیست دستورات موجود، **help** را ارسال کنید.
APP_SESSION_STATUS_CHANGE: |
app.session.status.change: |-
{{{emoji}}} جلسه "{{{session}}}" به وضعیت {{{status}}} تغییر کرد
APP_SESSION_CURRENT_STATUS: |
app.session.current.status: |-
{{{emoji}}} وضعیت جلسه **{{{session}}}** در **{{{status}}}** است
**حساب واتساپ:**
📱 **{{{name}}} ({{{id}}})**
APP_DASHBOARD_LINK: |
برای جزئیات بیشتر به [داشبورد WAHA]({{{url}}}) مراجعه کنید.
APP_SESSION_STATUS_WORKING: |
app.session.status.working: |-
✅ این صندوق ورودی ChatWoot به **حساب واتساپ** متصل است و آماده ارسال و دریافت پیام است!
📱 **{{{name}}} ({{{id}}})**
APP_SESSION_STATUS_ERROR: |
app.session.status.error: |-
⚠️ **این صندوق ورودی ChatWoot به حساب واتساپ متصل است اما آماده ارسال و دریافت پیام نیست!**
لطفاً وضعیت جلسه را بررسی کنید و سعی کنید آن را مجدداً راه‌اندازی کنید یا خارج شوید و کد QR را دوباره اسکن کنید.
APP_SESSION_SCAN_QR_CODE: |
app.session.scan.qr.code: |-
⚠️ **کد QR را در تلفن خود اسکن کنید تا حساب واتساپ را با این صندوق ورودی ChatWoot پیوند دهید!**
APP_SERVER_VERSION_AND_STATUS: |
app.server.version.and.status: |-
**نسخه:**
```
{{{version}}}
@@ -153,16 +181,16 @@ APP_SERVER_VERSION_AND_STATUS: |
{{{status}}}
```
APP_SERVER_REBOOT: |
app.server.reboot: |-
سرور در حال راه‌اندازی مجدد نرم است...
APP_SERVER_REBOOT_FORCE: |
app.server.reboot.force: |-
سرور در حال راه‌اندازی مجدد اجباری است...
APP_LOGOUT_SUCCESS: |
app.logout.success: |-
✅ حساب با موفقیت غیرمجاز شد!
APP_NEW_VERSION_AVAILABLE: |
waha.new.version.available: |-
🔄 **نسخه جدید در دسترس است!**
نسخه فعلی: **{{{currentVersion}}}**
@@ -170,7 +198,7 @@ APP_NEW_VERSION_AVAILABLE: |
👉 موارد جدید را در [**🆕 تغییرات**]({{{changelogUrl}}}) مشاهده کنید
APP_CORE_VERSION_USED: |
waha.core.version.used: |-
❤️ **از WAHA پشتیبانی کنید!**
شما از نسخه رایگان **WAHA Core** استفاده می‌کنید. اگر این پروژه را مفید می‌دانید، لطفاً حمایت از توسعه آن را در نظر بگیرید.
@@ -178,3 +206,149 @@ APP_CORE_VERSION_USED: |
حمایت شما تنها راهی است که ما می‌توانیم به کار بر روی به‌روزرسانی‌ها، رفع اشکالات و ویژگی‌های جدید ادامه دهیم.
[**🎁 از ما حمایت کنید**]({{{supportUrl}}})
chatwoot.to.whatsapp.message.text: |-
{{{ content }}}
chatwoot.to.whatsapp.message.media.caption: |-
{{#singleAttachment}}
{{#content}}
{{{ content }}}
{{/content}}
{{/singleAttachment}}
whatsapp.to.chatwoot.message: |-
{{{payload.body}}}
whatsapp.to.chatwoot.message.contacts: |-
👤 **مخاطب(ها)ی به‌اشتراک‌گذاشته‌شده**
{{#contacts}}
🪪 نام: **{{fullName}}**
{{#phoneNumbers}}
- 📞 تلفن: **{{.}}**
{{/phoneNumbers}}
{{/contacts}}
whatsapp.to.chatwoot.message.location: |-
{{#message}}
{{#locationMessage}}
📍 **موقعیت مکانی به‌اشتراک‌گذاشته‌شده**
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **آدرس:** {{address}}
{{/address}}
{{#url}}
🌐 **وب‌سایت:** {{url}}
{{/url}}
🔗 **مشاهده روی نقشه:** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/locationMessage}}
{{#liveLocationMessage}}
📍📡 **اشتراک‌گذاری موقعیت مکانی زنده**
برای دیدن به‌روزرسانی‌های لحظه‌ای **WhatsApp** را باز کنید.
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **آدرس:** {{address}}
{{/address}}
{{#url}}
🌐 **وب‌سایت:** {{url}}
{{/url}}
🔗 **مشاهده روی نقشه:** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/liveLocationMessage}}
{{/message}}
whatsapp.to.chatwoot.message.poll: |-
{{#poll}}
📊 **نظرسنجی**
**{{name}}**
{{#options}}
- {{optionName}}
{{/options}}
{{/poll}}
whatsapp.to.chatwoot.message.event: |-
{{#message}}
{{#eventMessage}}
📅 **رویداد**
**{{name}}**
{{#description}}
{{description}}
{{/description}}
{{#location.name}}
📍 **مکان:** {{location.name}}
{{/location.name}}
{{#startTime}}
🕐 **شروع:** {{startTime}}
{{/startTime}}
{{#endTime}}
🕐 **پایان:** {{endTime}}
{{/endTime}}
{{#joinLink}}
🔗 **لینک پیوستن:** [{{joinLink}}]({{joinLink}})
{{/joinLink}}
{{/eventMessage}}
{{/message}}
whatsapp.to.chatwoot.message.pix: |-
💳 **PIX - کپی و چسباندن**
{{#pixData}}
{{#merchantName}}
**{{merchantName}}**
{{/merchantName}}
{{#key}}
**کلید PIX:** {{key}}
{{/key}}
{{#keyType}}
**نوع:** {{keyType}}
{{/keyType}}
{{#totalAmount}}
**مبلغ:** {{totalAmountFormatted}}
{{/totalAmount}}
{{#referenceId}}
**شناسه مرجع:** {{referenceId}}
{{/referenceId}}
💳 **PIX کپی و چسباندن ارسال شد**
{{/pixData}}
whatsapp.to.chatwoot.message.unsupported: |-
⚠️ **این نوع پیام در ChatWoot پشتیبانی نمی‌شود.**
📱 لطفاً برای مشاهده آن **WhatsApp** را باز کنید.
جزئیات: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **آگهی فیس‌بوک**
**عنوان:** {{{adData.title}}}
**توضیحات:**
{{{adData.body}}}
**لینک آگهی:** [مشاهده در فیس‌بوک]({{{adData.sourceUrl}}})
**شناسه آگهی:** {{{adData.sourceId}}}
---
💬 **پیام مشتری:**
{{{payload.body}}}
+354
View File
@@ -0,0 +1,354 @@
# French translations for ChatWoot integration
locale.name: '🇫🇷 Français (French)'
# Code de locale de base - doit être une locale BCP 47 valide
# https://en.wikipedia.org/wiki/IETF_language_tag
# WAHA l'utilise pour le formatage des nombres, devises et dates/heures
locale.base: 'fr-FR'
app.inbox.contact.name: 'Intégration WhatsApp (WAHA)'
app.inbox.contact.avatar.url: 'https://raw.githubusercontent.com/devlikeapro/waha/core/logo.png'
# "options" de date.toLocaleString
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#options
datetime:
locales: fr-FR
day: 2-digit
month: 2-digit
year: numeric
hour: 2-digit
minute: 2-digit
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#timezonename
timeZoneName: shortGeneric
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
# timeZone: 'Europe/Paris'
job.report.error: |-
⚠️ **{{{header}}}**
{{#attempts.nextDelay}}
🔄 Nouvelle tentative dans {{attempts.nextDelay}} secondes...
{{/attempts.nextDelay}}
{{^attempts.nextDelay}}
❌ Plus de tentatives restantes. Veuillez réessayer plus tard.
{{/attempts.nextDelay}}
Tentative : {{{attempts.current}}} / {{{attempts.max}}}
Détails : [{{{details.text}}}]({{{details.url}}})
{{#error}}
```
{{{error}}}
```
{{/error}}
job.report.succeeded: |-
✅ **Réussi**
Tentative : {{{attempts.current}}} / {{{attempts.max}}}
Détails : [{{{details.text}}}]({{{details.url}}})
whatsapp.message.sending.error: Impossible d'envoyer un message sur WhatsApp.
whatsapp.message.receiving.error: Impossible de recevoir un message de WhatsApp
whatsapp.message.removing.error: Impossible de supprimer un message de WhatsApp
job.scheduled.error.header: La tâche planifiée n'a pas pu être exécutée
message.from.whatsapp: |-
{{{text}}}
📱 *Envoyé depuis WhatsApp*
message.from.api: |-
{{{text}}}
📱 *Envoyé via API*
message.removed.in.whatsapp: |-
❌ *Ce message a été supprimé dans WhatsApp*
message.edited.in.whatsapp: |-
{{{text}}}
✏️ *Modifié dans WhatsApp*
whatsapp.group.message: |-
👥 *{{{participant}}}*
{{{text}}}
whatsapp.reaction.added: |-
*A réagi avec* {{{emoji}}}
whatsapp.reaction.removed: |-
*Réaction supprimée*
whatsapp.contact.group.suffix: 'Groupe'
whatsapp.contact.channel.suffix: 'Canal'
whatsapp.contact.broadcast.suffix: 'Liste de diffusion'
# Aka Stories
whatsapp.contact.status.name: 'Statut'
app.connected.message: |-
🔗 **CONNECTÉ : Session WhatsApp à la Boîte de Réception ChatWoot**
✅ La session WhatsApp **{{{name}}}** a été connectée avec succès à cette Boîte de Réception ChatWoot.
Cette boîte de réception est maintenant liée à votre **Compte WhatsApp**. Vous pouvez envoyer et recevoir des messages directement d'ici — tout comme utiliser WhatsApp, mais à l'intérieur de ChatWoot.
Vous pouvez également gérer la session WhatsApp liée à cette boîte de réception. Pour voir les actions disponibles, envoyez **help** à ce chat.
📋 Actions courantes que vous pouvez effectuer :
- Vérifier si la session WhatsApp est active
- Redémarrer ou Arrêter la session WhatsApp
- Se déconnecter et se reconnecter en scannant un nouveau code QR
Si tout fonctionne, vous pourrez discuter librement. Si vous voyez des avertissements, vous devrez peut-être reconnecter votre compte WhatsApp.
Commençons ! 🚀
app.disconnected.message: |-
🔌 **DÉCONNECTÉ : Session WhatsApp de la Boîte de Réception ChatWoot**
❌ La session WhatsApp **{{{name}}}** a été déconnectée de cette Boîte de Réception ChatWoot.
Vous ne pourrez plus envoyer ou recevoir de messages depuis WhatsApp.
Pour vous reconnecter, veuillez contacter votre administrateur.
app.updated.message: |-
🔄 **MIS À JOUR : Paramètres de Session WhatsApp**
✅ Les paramètres de la session WhatsApp **{{{name}}}** ont été mis à jour.
app.commands.list: |-
Vous pouvez gérer l'**Intégration WhatsApp** en envoyant l'une des commandes suivantes :
🖥️ **Session** :
1. **status** - obtenir l'état actuel de la session.
2. **restart** - redémarrer la session - cela tentera de reconnecter votre compte WhatsApp.
3. **start** - démarrer la session.
4. **stop** - arrêter la session.
5. **logout** - se déconnecter de la session, pour pouvoir scanner le code QR et réparer la session.
6. **qr** - obtenir le code QR pour la session.
7. **screenshot** - obtenir une capture d'écran de la session (disponible uniquement dans le moteur **WEBJS**).
8. **help** - commandes disponibles.
{{#commands.server}}
⚙️ Serveur :
- **server status** - obtenir les informations de version et d'état du serveur.
- **server reboot** - redémarrer le serveur en douceur.
- **server reboot force** - forcer le redémarrage du serveur.
{{/commands.server}}
Envoyez une **commande** (insensible à la casse) ou un **numéro de commande** à cette conversation.
app.commands.server.disabled: ⛔ **Les commandes serveur sont désactivées**.
Veuillez contacter votre administrateur.
Envoyez **help** pour obtenir la liste des commandes disponibles.
app.help.reminder: |-
Envoyez **help** pour obtenir la liste des commandes disponibles.
app.session.status.change: |-
{{{emoji}}} La session "{{{session}}}" est passée au statut {{{status}}}
app.session.current.status: |-
{{{emoji}}} Le statut de la session **{{{session}}}** est **{{{status}}}**
**Compte WhatsApp :**
📱 **{{{name}}} ({{{id}}})**
app.session.status.working: |-
✅ Cette Boîte de Réception ChatWoot est liée au **Compte WhatsApp** et prête à envoyer et recevoir des messages !
📱 **{{{name}}} ({{{id}}})**
app.session.status.error: |-
⚠️ **Cette Boîte de Réception ChatWoot est liée au Compte WhatsApp mais N'EST PAS prête à envoyer et recevoir des messages !**
Veuillez vérifier l'état de la session et essayer de la redémarrer ou déconnectez-vous et scannez à nouveau le code QR.
app.session.scan.qr.code: |-
⚠️ **Scannez le code QR sur votre téléphone pour lier le Compte WhatsApp à cette Boîte de Réception ChatWoot !**
app.server.version.and.status: |-
**Version :**
```
{{{version}}}
```
**Statut :**
```
{{{status}}}
```
app.server.reboot: |-
Le serveur redémarre en douceur...
app.server.reboot.force: |-
Le serveur redémarre de force...
app.logout.success: |-
✅ Compte déconnecté avec succès !
waha.new.version.available: |-
🔄 **Nouvelle Version Disponible !**
Version actuelle : **{{{currentVersion}}}**
Nouvelle version : **{{{newVersion}}}**
👉 Découvrez les nouveautés dans le [**🆕 Journal des modifications**]({{{changelogUrl}}})
waha.core.version.used: |-
❤️ **Soutenez WAHA !**
Vous utilisez la version gratuite **WAHA Core**. Si vous trouvez ce projet utile, veuillez envisager de soutenir son développement.
Votre soutien est le seul moyen pour nous de continuer à travailler sur les mises à jour, les corrections et les nouvelles fonctionnalités.
[**🎁 Soutenez-nous**]({{{supportUrl}}})
chatwoot.to.whatsapp.message.text: |-
{{{ content }}}
chatwoot.to.whatsapp.message.media.caption: |-
{{#singleAttachment}}
{{#content}}
{{{ content }}}
{{/content}}
{{/singleAttachment}}
whatsapp.to.chatwoot.message: |-
{{{payload.body}}}
whatsapp.to.chatwoot.message.contacts: |-
👤 **Contact(s) partagé(s)**
{{#contacts}}
🪪 Nom: **{{fullName}}**
{{#phoneNumbers}}
- 📞 Téléphone: **{{.}}**
{{/phoneNumbers}}
{{/contacts}}
whatsapp.to.chatwoot.message.location: |-
{{#message}}
{{#locationMessage}}
📍 **Position partagée**
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **Adresse :** {{address}}
{{/address}}
{{#url}}
🌐 **Site web :** {{url}}
{{/url}}
🔗 **Voir sur la carte :** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/locationMessage}}
{{#liveLocationMessage}}
📍📡 **Partage de position en direct**
Ouvrez **WhatsApp** pour voir les mises à jour en temps réel.
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **Adresse :** {{address}}
{{/address}}
{{#url}}
🌐 **Site web :** {{url}}
{{/url}}
🔗 **Voir sur la carte :** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/liveLocationMessage}}
{{/message}}
whatsapp.to.chatwoot.message.poll: |-
{{#poll}}
📊 **Sondage**
**{{name}}**
{{#options}}
- {{optionName}}
{{/options}}
{{/poll}}
whatsapp.to.chatwoot.message.event: |-
{{#message}}
{{#eventMessage}}
📅 **Événement**
**{{name}}**
{{#description}}
{{description}}
{{/description}}
{{#location.name}}
📍 **Lieu :** {{location.name}}
{{/location.name}}
{{#startTime}}
🕐 **Début :** {{startTime}}
{{/startTime}}
{{#endTime}}
🕐 **Fin :** {{endTime}}
{{/endTime}}
{{#joinLink}}
🔗 **Lien de participation :** [{{joinLink}}]({{joinLink}})
{{/joinLink}}
{{/eventMessage}}
{{/message}}
whatsapp.to.chatwoot.message.pix: |-
💳 **PIX - Copier et Coller**
{{#pixData}}
{{#merchantName}}
**{{merchantName}}**
{{/merchantName}}
{{#key}}
**Clé PIX :** {{key}}
{{/key}}
{{#keyType}}
**Type :** {{keyType}}
{{/keyType}}
{{#totalAmount}}
**Montant :** {{totalAmountFormatted}}
{{/totalAmount}}
{{#referenceId}}
**Référence :** {{referenceId}}
{{/referenceId}}
💳 **PIX Copier et Coller envoyé**
{{/pixData}}
whatsapp.to.chatwoot.message.unsupported: |-
⚠️ **Ce type de message n’est pas pris en charge dans ChatWoot.**
📱 Veuillez ouvrir **WhatsApp** pour l’afficher.
Détails: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **PUBLICITÉ FACEBOOK**
**Titre:** {{{adData.title}}}
**Description:**
{{{adData.body}}}
**Lien de l'annonce :** [Voir sur Facebook]({{{adData.sourceUrl}}})
**ID de l'annonce :** {{{adData.sourceId}}}
---
💬 **Message du client :**
{{{payload.body}}}
+354
View File
@@ -0,0 +1,354 @@
# Hebrew translations for ChatWoot integration
locale.name: '🇮🇱 עברית (Hebrew)'
# קוד הלוקאל הבסיסי - חייב להיות לוקאל תקין לפי BCP 47
# https://en.wikipedia.org/wiki/IETF_language_tag
# WAHA משתמש בכך להצגת מספרים, מטבע ותאריך/שעה
locale.base: 'he-IL'
app.inbox.contact.name: 'אינטגרציית וואטסאפ (WAHA)'
app.inbox.contact.avatar.url: 'https://raw.githubusercontent.com/devlikeapro/waha/core/logo.png'
# "אפשרויות" של date.toLocaleString
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#options
datetime:
locales: he-IL
day: 2-digit
month: 2-digit
year: numeric
hour: 2-digit
minute: 2-digit
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#timezonename
timeZoneName: shortGeneric
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
# timeZone: 'Asia/Jerusalem'
job.report.error: |-
⚠️ **{{{header}}}**
{{#attempts.nextDelay}}
🔄 מנסה שוב בעוד {{attempts.nextDelay}} שניות...
{{/attempts.nextDelay}}
{{^attempts.nextDelay}}
❌ לא נותרו ניסיונות נוספים. אנא נסה שוב מאוחר יותר.
{{/attempts.nextDelay}}
ניסיון: {{{attempts.current}}} / {{{attempts.max}}}
פרטים: [{{{details.text}}}]({{{details.url}}})
{{#error}}
```
{{{error}}}
```
{{/error}}
job.report.succeeded: |-
✅ **הצליח**
ניסיון: {{{attempts.current}}} / {{{attempts.max}}}
פרטים: [{{{details.text}}}]({{{details.url}}})
whatsapp.message.sending.error: לא ניתן לשלוח הודעה בוואטסאפ.
whatsapp.message.receiving.error: לא ניתן לקבל הודעה מוואטסאפ
whatsapp.message.removing.error: לא ניתן להסיר הודעה מוואטסאפ
job.scheduled.error.header: המשימה המתוזמנת נכשלה בביצוע
message.from.whatsapp: |-
{{{text}}}
📱 *נשלח מוואטסאפ*
message.from.api: |-
{{{text}}}
📱 *נשלח דרך API*
message.removed.in.whatsapp: |-
❌ *הודעה זו נמחקה בוואטסאפ*
message.edited.in.whatsapp: |-
{{{text}}}
✏️ *נערך בוואטסאפ*
whatsapp.group.message: |-
👥 *{{{participant}}}*
{{{text}}}
whatsapp.reaction.added: |-
*הגיב* {{{emoji}}}
whatsapp.reaction.removed: |-
*התגובה הוסרה*
whatsapp.contact.group.suffix: 'קבוצה'
whatsapp.contact.channel.suffix: 'ערוץ'
whatsapp.contact.broadcast.suffix: 'רשימת שידור'
# Aka Stories
whatsapp.contact.status.name: 'סטטוס'
app.connected.message: |-
🔗 **מחובר: הפעלת וואטסאפ לתיבת הדואר הנכנס של ChatWoot**
✅ הפעלת וואטסאפ **{{{name}}}** חוברה בהצלחה לתיבת הדואר הנכנס של ChatWoot.
תיבת דואר נכנס זו מקושרת כעת ל**חשבון הוואטסאפ** שלך. אתה יכול לשלוח ולקבל הודעות ישירות מכאן — בדיוק כמו שימוש בוואטסאפ, אבל בתוך ChatWoot.
אתה יכול גם לנהל את הפעלת הוואטסאפ המקושרת לתיבת דואר נכנס זו. כדי לראות פעולות זמינות, שלח **help** לצ'אט זה.
📋 פעולות נפוצות שאתה יכול לעשות:
- בדוק אם הפעלת הוואטסאפ פעילה
- הפעל מחדש או עצור את הפעלת הוואטסאפ
- התנתק והתחבר מחדש על ידי סריקת קוד QR חדש
אם הכל עובד, תוכל לשוחח בחופשיות. אם אתה רואה אזהרות, ייתכן שתצטרך לחבר מחדש את חשבון הוואטסאפ שלך.
בוא נתחיל! 🚀
app.disconnected.message: |-
🔌 **מנותק: הפעלת וואטסאפ מתיבת הדואר הנכנס של ChatWoot**
❌ הפעלת וואטסאפ **{{{name}}}** נותקה מתיבת הדואר הנכנס של ChatWoot.
לא תוכל יותר לשלוח או לקבל הודעות מוואטסאפ.
כדי להתחבר מחדש, אנא פנה למנהל המערכת שלך.
app.updated.message: |-
🔄 **עודכן: הגדרות הפעלת וואטסאפ**
✅ ההגדרות עבור הפעלת וואטסאפ **{{{name}}}** עודכנו.
app.commands.list: |-
אתה יכול לנהל **אינטגרציית וואטסאפ** על ידי שליחת אחת מהפקודות הבאות:
🖥️ **הפעלה**:
1. **status** - קבל את סטטוס ההפעלה הנוכחי.
2. **restart** - הפעל מחדש את ההפעלה - זה ינסה לחבר מחדש את חשבון הוואטסאפ שלך.
3. **start** - התחל את ההפעלה.
4. **stop** - עצור את ההפעלה.
5. **logout** - התנתק מההפעלה, כך שתוכל לסרוק קוד QR ולתקן את ההפעלה.
6. **qr** - קבל את קוד ה-QR עבור ההפעלה.
7. **screenshot** - קבל צילום מסך של ההפעלה (זמין רק במנוע **WEBJS**).
8. **help** - פקודות זמינות.
{{#commands.server}}
⚙️ שרת:
- **server status** - קבל מידע על גרסת השרת והסטטוס.
- **server reboot** - הפעל מחדש את השרת בצורה חלקה.
- **server reboot force** - אלץ הפעלה מחדש של השרת.
{{/commands.server}}
שלח **פקודה** (לא תלוי רישיות) או **מספר פקודה** לשיחה זו.
app.commands.server.disabled: ⛔ **פקודות השרת מושבתות**.
אנא פנו למנהל המערכת שלכם.
שלחו **help** כדי לקבל את רשימת הפקודות הזמינות.
app.help.reminder: |-
שלח **help** כדי לקבל את רשימת הפקודות הזמינות.
app.session.status.change: |-
{{{emoji}}} הפעלה "{{{session}}}" עברה לסטטוס {{{status}}}
app.session.current.status: |-
{{{emoji}}} סטטוס ההפעלה **{{{session}}}** הוא **{{{status}}}**
**חשבון וואטסאפ:**
📱 **{{{name}}} ({{{id}}})**
app.session.status.working: |-
✅ תיבת הדואר הנכנס של ChatWoot מקושרת ל**חשבון וואטסאפ** ומוכנה לשלוח ולקבל הודעות!
📱 **{{{name}}} ({{{id}}})**
app.session.status.error: |-
⚠️ **תיבת הדואר הנכנס של ChatWoot מקושרת לחשבון וואטסאפ אך אינה מוכנה לשלוח ולקבל הודעות!**
אנא בדוק את סטטוס ההפעלה ונסה להפעיל אותה מחדש או התנתק וסרוק את קוד ה-QR שוב.
app.session.scan.qr.code: |-
⚠️ **סרוק את קוד ה-QR בטלפון שלך כדי לקשר את חשבון הוואטסאפ לתיבת הדואר הנכנס של ChatWoot!**
app.server.version.and.status: |-
**גרסה:**
```
{{{version}}}
```
**סטטוס:**
```
{{{status}}}
```
app.server.reboot: |-
השרת מופעל מחדש בצורה חלקה...
app.server.reboot.force: |-
השרת מופעל מחדש בכוח...
app.logout.success: |-
✅ החשבון בוטל בהצלחה!
waha.new.version.available: |-
🔄 **גרסה חדשה זמינה!**
גרסה נוכחית: **{{{currentVersion}}}**
גרסה חדשה: **{{{newVersion}}}**
👉 בדוק מה חדש ב[**🆕 יומן שינויים**]({{{changelogUrl}}})
waha.core.version.used: |-
❤️ **תמוך ב-WAHA!**
אתה משתמש בגרסת **WAHA Core** החינמית. אם אתה מוצא פרויקט זה שימושי, אנא שקול לתמוך בפיתוח שלו.
התמיכה שלך היא הדרך היחידה שבה אנחנו יכולים להמשיך לעבוד על עדכונים, תיקונים ותכונות חדשות.
[**🎁 תמוך בנו**]({{{supportUrl}}})
chatwoot.to.whatsapp.message.text: |-
{{{ content }}}
chatwoot.to.whatsapp.message.media.caption: |-
{{#singleAttachment}}
{{#content}}
{{{ content }}}
{{/content}}
{{/singleAttachment}}
whatsapp.to.chatwoot.message: |-
{{{payload.body}}}
whatsapp.to.chatwoot.message.contacts: |-
👤 **אנשי קשר משותפים**
{{#contacts}}
🪪 שם: **{{fullName}}**
{{#phoneNumbers}}
- 📞 טלפון: **{{.}}**
{{/phoneNumbers}}
{{/contacts}}
whatsapp.to.chatwoot.message.location: |-
{{#message}}
{{#locationMessage}}
📍 **מיקום משותף**
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **כתובת:** {{address}}
{{/address}}
{{#url}}
🌐 **אתר אינטרנט:** {{url}}
{{/url}}
🔗 **הצג במפה:** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/locationMessage}}
{{#liveLocationMessage}}
📍📡 **משתף מיקום חי**
פתח/י את **WhatsApp** כדי לראות עדכונים בזמן אמת.
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **כתובת:** {{address}}
{{/address}}
{{#url}}
🌐 **אתר אינטרנט:** {{url}}
{{/url}}
🔗 **הצג במפה:** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/liveLocationMessage}}
{{/message}}
whatsapp.to.chatwoot.message.poll: |-
{{#poll}}
📊 **סקר**
**{{name}}**
{{#options}}
- {{optionName}}
{{/options}}
{{/poll}}
whatsapp.to.chatwoot.message.event: |-
{{#message}}
{{#eventMessage}}
📅 **אירוע**
**{{name}}**
{{#description}}
{{description}}
{{/description}}
{{#location.name}}
📍 **מיקום:** {{location.name}}
{{/location.name}}
{{#startTime}}
🕐 **התחלה:** {{startTime}}
{{/startTime}}
{{#endTime}}
🕐 **סיום:** {{endTime}}
{{/endTime}}
{{#joinLink}}
🔗 **קישור הצטרפות:** [{{joinLink}}]({{joinLink}})
{{/joinLink}}
{{/eventMessage}}
{{/message}}
whatsapp.to.chatwoot.message.pix: |-
💳 **PIX - העתק והדבק**
{{#pixData}}
{{#merchantName}}
**{{merchantName}}**
{{/merchantName}}
{{#key}}
**מפתח PIX:** {{key}}
{{/key}}
{{#keyType}}
**סוג:** {{keyType}}
{{/keyType}}
{{#totalAmount}}
**סכום:** {{totalAmountFormatted}}
{{/totalAmount}}
{{#referenceId}}
**אסמכתא:** {{referenceId}}
{{/referenceId}}
💳 **PIX העתק והדבק נשלח**
{{/pixData}}
whatsapp.to.chatwoot.message.unsupported: |-
⚠️ **סוג הודעה זה אינו נתמך ב-ChatWoot.**
📱 אנא פתח/י את **WhatsApp** כדי לצפות בזה.
פרטים: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **מודעת פייסבוק**
**כותרת:** {{{adData.title}}}
**תיאור:**
{{{adData.body}}}
**קישור למודעה:** [לצפייה בפייסבוק]({{{adData.sourceUrl}}})
**מזהה המודעה:** {{{adData.sourceId}}}
---
💬 **הודעת הלקוח:**
{{{payload.body}}}
@@ -1,7 +1,29 @@
# Hindi translations for ChatWoot integration
APP_INBOX_CONTACT_NAME: 'व्हाट्सएप इंटीग्रेशन (WAHA)'
locale.name: '🇮🇳 हिंदी (Hindi)'
JOB_ERROR_REPORT: |
# बेस लोकैल कोड - यह एक मान्य BCP 47 लोकैल होना चाहिए
# https://en.wikipedia.org/wiki/IETF_language_tag
# WAHA इसे संख्याएँ, मुद्रा और दिनांक/समय प्रदर्शित करने के लिए उपयोग करता है।
locale.base: 'hi-IN'
app.inbox.contact.name: 'व्हाट्सएप इंटीग्रेशन (WAHA)'
app.inbox.contact.avatar.url: 'https://raw.githubusercontent.com/devlikeapro/waha/core/logo.png'
# date.toLocaleString की "options"
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#options
datetime:
locales: hi-IN
day: 2-digit
month: 2-digit
year: numeric
hour: 2-digit
minute: 2-digit
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#timezonename
timeZoneName: shortGeneric
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
# timeZone: 'Asia/Kolkata'
job.report.error: |-
⚠️ **{{{header}}}**
{{#attempts.nextDelay}}
🔄 {{attempts.nextDelay}} सेकंड में पुनः प्रयास कर रहा है...
@@ -18,51 +40,52 @@ JOB_ERROR_REPORT: |
```
{{/error}}
JOB_SUCCEEDED_REPORT: |
job.report.succeeded: |-
✅ **सफल**
प्रयास: {{{attempts.current}}} / {{{attempts.max}}}
विवरण: [{{{details.text}}}]({{{details.url}}})
WHATSAPP_ERROR_SENDING_MESSAGE: व्हाट्सएप पर संदेश नहीं भेज सका।
WHATSAPP_ERROR_RECEIVING_MESSAGE: व्हाट्सएप से संदेश प्राप्त नहीं कर सका
WHATSAPP_ERROR_REMOVING_MESSAGE: व्हाट्सएप से संदेश हटा नहीं सका
APP_SCHEDULED_JOB_ERROR: निर्धारित कार्य निष्पादित करने में विफल रहा
whatsapp.message.sending.error: व्हाट्सएप पर संदेश नहीं भेज सका।
whatsapp.message.receiving.error: व्हाट्सएप से संदेश प्राप्त नहीं कर सका
whatsapp.message.removing.error: व्हाट्सएप से संदेश हटा नहीं सका
job.scheduled.error.header: निर्धारित कार्य निष्पादित करने में विफल रहा
MESSAGE_FROM_WHATSAPP: |
message.from.whatsapp: |-
{{{text}}}
📱 *व्हाट्सएप से भेजा गया*
MESSAGE_FROM_API: |
message.from.api: |-
{{{text}}}
📱 *API के माध्यम से भेजा गया*
MESSAGE_REMOVED_IN_WHATSAPP: |
message.removed.in.whatsapp: |-
❌ *यह संदेश व्हाट्सएप में हटा दिया गया था*
MESSAGE_EDITED_IN_WHATSAPP: |
message.edited.in.whatsapp: |-
{{{text}}}
✏️ *व्हाट्सएप में संपादित*
WHATSAPP_GROUP_MESSAGE: |
{{{text}}}
whatsapp.group.message: |-
👥 *{{{participant}}}*
WHATSAPP_REACTION_ADDED: |
{{{text}}}
whatsapp.reaction.added: |-
*प्रतिक्रिया दी* {{{emoji}}}
WHATSAPP_REACTION_REMOVED: |
whatsapp.reaction.removed: |-
*प्रतिक्रिया हटा दी गई*
WHATSAPP_CONTACT_GROUP_SUFFIX: 'समूह'
WHATSAPP_CONTACT_CHANNEL_SUFFIX: 'चैनल'
whatsapp.contact.group.suffix: 'समूह'
whatsapp.contact.channel.suffix: 'चैनल'
whatsapp.contact.broadcast.suffix: 'प्रसारण सूची'
# Aka Stories
WHATSAPP_CONTACT_STATUS_NAME: 'स्थिति'
whatsapp.contact.status.name: 'स्थिति'
APP_CONNECTED_MESSAGE: |
app.connected.message: |-
🔗 **कनेक्टेड: व्हाट्सएप सत्र से ChatWoot इनबॉक्स**
✅ व्हाट्सएप सत्र **{{{name}}}** सफलतापूर्वक इस ChatWoot इनबॉक्स से जुड़ गया है।
@@ -80,7 +103,7 @@ APP_CONNECTED_MESSAGE: |
चलिए शुरू करते हैं! 🚀
APP_DISCONNECTED_MESSAGE: |
app.disconnected.message: |-
🔌 **डिस्कनेक्टेड: व्हाट्सएप सत्र से ChatWoot इनबॉक्स**
❌ व्हाट्सएप सत्र **{{{name}}}** इस ChatWoot इनबॉक्स से डिस्कनेक्ट हो गया है।
@@ -89,15 +112,15 @@ APP_DISCONNECTED_MESSAGE: |
फिर से कनेक्ट करने के लिए, कृपया अपने प्रशासक से संपर्क करें।
APP_UPDATED_MESSAGE: |
app.updated.message: |-
🔄 **अपडेटेड: व्हाट्सएप सत्र सेटिंग्स**
✅ व्हाट्सएप सत्र **{{{name}}}** की सेटिंग्स अपडेट की गई हैं।
APP_COMMANDS_LIST: |
app.commands.list: |-
आप निम्न कमांड में से एक भेजकर **व्हाट्सएप इंटीग्रेशन** का प्रबंधन कर सकते हैं:
🖥️ सत्र:
🖥️ **सेशन**:
1. **status** - वर्तमान सत्र स्थिति प्राप्त करें।
2. **restart** - सत्र को पुनरारंभ करें - यह आपके व्हाट्सएप खाते को फिर से कनेक्ट करने का प्रयास करेगा।
3. **start** - सत्र शुरू करें।
@@ -107,42 +130,47 @@ APP_COMMANDS_LIST: |
7. **screenshot** - सत्र का स्क्रीनशॉट प्राप्त करें (केवल **WEBJS** इंजन में उपलब्ध)।
8. **help** - उपलब्ध कमांड।
{{#commands.server}}
⚙️ सर्वर:
- **server status** - सर्वर संस्करण और स्थिति जानकारी प्राप्त करें।
- **server reboot** - सर्वर को सुचारू रूप से पुनरारंभ करें।
- **server reboot force** - सर्वर को जबरदस्ती पुनरारंभ करें।
{{/commands.server}}
इस वार्तालाप में **कमांड** (केस इनसेंसिटिव) या **कमांड नंबर** भेजें।
APP_HELP_REMINDER: |
app.commands.server.disabled: ⛔ **सर्वर कमांड अक्षम हैं**।
कृपया अपने व्यवस्थापक से संपर्क करें।
उपलब्ध कमांड की सूची पाने के लिए **help** भेजें।
app.help.reminder: |-
उपलब्ध कमांड की सूची प्राप्त करने के लिए **help** भेजें।
APP_SESSION_STATUS_CHANGE: |
app.session.status.change: |-
{{{emoji}}} "{{{session}}}" सत्र {{{status}}} स्थिति में बदल गया
APP_SESSION_CURRENT_STATUS: |
app.session.current.status: |-
{{{emoji}}} **{{{session}}}** सत्र की स्थिति **{{{status}}}** में है
**व्हाट्सएप खाता:**
📱 **{{{name}}} ({{{id}}})**
APP_DASHBOARD_LINK: |
अधिक जानकारी के लिए [WAHA डैशबोर्ड]({{{url}}}) पर जाएं।
APP_SESSION_STATUS_WORKING: |
app.session.status.working: |-
✅ यह ChatWoot इनबॉक्स **व्हाट्सएप खाते** से जुड़ा हुआ है और संदेश भेजने और प्राप्त करने के लिए तैयार है!
📱 **{{{name}}} ({{{id}}})**
APP_SESSION_STATUS_ERROR: |
app.session.status.error: |-
⚠️ **यह ChatWoot इनबॉक्स व्हाट्सएप खाते से जुड़ा हुआ है लेकिन संदेश भेजने और प्राप्त करने के लिए तैयार नहीं है!**
कृपया सत्र की स्थिति जांचें और इसे पुनरारंभ करने का प्रयास करें या लॉग आउट करें और QR कोड फिर से स्कैन करें।
APP_SESSION_SCAN_QR_CODE: |
app.session.scan.qr.code: |-
⚠️ **इस ChatWoot इनबॉक्स के साथ व्हाट्सएप खाता जोड़ने के लिए अपने फोन पर QR कोड स्कैन करें!**
APP_SERVER_VERSION_AND_STATUS: |
app.server.version.and.status: |-
**संस्करण:**
```
{{{version}}}
@@ -153,16 +181,16 @@ APP_SERVER_VERSION_AND_STATUS: |
{{{status}}}
```
APP_SERVER_REBOOT: |
app.server.reboot: |-
सर्वर सुचारू रूप से पुनरारंभ हो रहा है...
APP_SERVER_REBOOT_FORCE: |
app.server.reboot.force: |-
सर्वर जबरदस्ती पुनरारंभ हो रहा है...
APP_LOGOUT_SUCCESS: |
app.logout.success: |-
✅ खाता सफलतापूर्वक अनधिकृत किया गया!
APP_NEW_VERSION_AVAILABLE: |
waha.new.version.available: |-
🔄 **नया संस्करण उपलब्ध!**
वर्तमान संस्करण: **{{{currentVersion}}}**
@@ -170,7 +198,7 @@ APP_NEW_VERSION_AVAILABLE: |
👉 [**🆕 चेंजलॉग**]({{{changelogUrl}}}) में क्या नया है देखें
APP_CORE_VERSION_USED: |
waha.core.version.used: |-
❤️ **WAHA का समर्थन करें!**
आप मुफ्त **WAHA Core** संस्करण का उपयोग कर रहे हैं। यदि आपको यह प्रोजेक्ट उपयोगी लगता है, तो कृपया इसके विकास का समर्थन करने पर विचार करें।
@@ -178,3 +206,149 @@ APP_CORE_VERSION_USED: |
आपका समर्थन ही एकमात्र तरीका है जिससे हम अपडेट, फिक्स और नई सुविधाओं पर काम करना जारी रख सकते हैं।
[**🎁 हमें समर्थन दें**]({{{supportUrl}}})
chatwoot.to.whatsapp.message.text: |-
{{{ content }}}
chatwoot.to.whatsapp.message.media.caption: |-
{{#singleAttachment}}
{{#content}}
{{{ content }}}
{{/content}}
{{/singleAttachment}}
whatsapp.to.chatwoot.message: |-
{{{payload.body}}}
whatsapp.to.chatwoot.message.contacts: |-
👤 **साझा संपर्क**
{{#contacts}}
🪪 नाम: **{{fullName}}**
{{#phoneNumbers}}
- 📞 फ़ोन: **{{.}}**
{{/phoneNumbers}}
{{/contacts}}
whatsapp.to.chatwoot.message.location: |-
{{#message}}
{{#locationMessage}}
📍 **साझा स्थान**
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **पता:** {{address}}
{{/address}}
{{#url}}
🌐 **वेबसाइट:** {{url}}
{{/url}}
🔗 **मानचित्र पर देखें:** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/locationMessage}}
{{#liveLocationMessage}}
📍📡 **लाइव लोकेशन साझा की जा रही है**
रीयल-टाइम अपडेट देखने के लिए **WhatsApp** खोलें।
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **पता:** {{address}}
{{/address}}
{{#url}}
🌐 **वेबसाइट:** {{url}}
{{/url}}
🔗 **मानचित्र पर देखें:** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/liveLocationMessage}}
{{/message}}
whatsapp.to.chatwoot.message.poll: |-
{{#poll}}
📊 **मतदान**
**{{name}}**
{{#options}}
- {{optionName}}
{{/options}}
{{/poll}}
whatsapp.to.chatwoot.message.event: |-
{{#message}}
{{#eventMessage}}
📅 **कार्यक्रम**
**{{name}}**
{{#description}}
{{description}}
{{/description}}
{{#location.name}}
📍 **स्थान:** {{location.name}}
{{/location.name}}
{{#startTime}}
🕐 **आरंभ:** {{startTime}}
{{/startTime}}
{{#endTime}}
🕐 **समाप्ति:** {{endTime}}
{{/endTime}}
{{#joinLink}}
🔗 **जुड़ने का लिंक:** [{{joinLink}}]({{joinLink}})
{{/joinLink}}
{{/eventMessage}}
{{/message}}
whatsapp.to.chatwoot.message.pix: |-
💳 **PIX - कॉपी और पेस्ट**
{{#pixData}}
{{#merchantName}}
**{{merchantName}}**
{{/merchantName}}
{{#key}}
**PIX कुंजी:** {{key}}
{{/key}}
{{#keyType}}
**प्रकार:** {{keyType}}
{{/keyType}}
{{#totalAmount}}
**राशि:** {{totalAmountFormatted}}
{{/totalAmount}}
{{#referenceId}}
**संदर्भ:** {{referenceId}}
{{/referenceId}}
💳 **PIX कॉपी और पेस्ट भेजा गया**
{{/pixData}}
whatsapp.to.chatwoot.message.unsupported: |-
⚠️ **इस प्रकार का संदेश ChatWoot में समर्थित नहीं है।**
📱 इसे देखने के लिए कृपया **WhatsApp** खोलें।
विवरण: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **फेसबुक विज्ञापन**
**शीर्षक:** {{{adData.title}}}
**विवरण:**
{{{adData.body}}}
**विज्ञापन लिंक:** [फेसबुक पर देखें]({{{adData.sourceUrl}}})
**विज्ञापन आईडी:** {{{adData.sourceId}}}
---
💬 **ग्राहक संदेश:**
{{{payload.body}}}
+354
View File
@@ -0,0 +1,354 @@
# Indonesian translations for ChatWoot integration
locale.name: '🇮🇩 Bahasa Indonesia (Indonesian)'
# Kode locale dasar - harus berupa locale BCP 47 yang valid
# https://en.wikipedia.org/wiki/IETF_language_tag
# WAHA menggunakannya untuk format angka, mata uang, dan tanggal/waktu
locale.base: 'id-ID'
app.inbox.contact.name: 'Integrasi WhatsApp (WAHA)'
app.inbox.contact.avatar.url: 'https://raw.githubusercontent.com/devlikeapro/waha/core/logo.png'
# "opsi" dari date.toLocaleString
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#options
datetime:
locales: id-ID
day: 2-digit
month: 2-digit
year: numeric
hour: 2-digit
minute: 2-digit
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#timezonename
timeZoneName: shortGeneric
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
# timeZone: 'Asia/Jakarta'
job.report.error: |-
⚠️ **{{{header}}}**
{{#attempts.nextDelay}}
🔄 Mencoba lagi dalam {{attempts.nextDelay}} detik...
{{/attempts.nextDelay}}
{{^attempts.nextDelay}}
❌ Tidak ada percobaan lagi. Silakan coba lagi nanti.
{{/attempts.nextDelay}}
Percobaan: {{{attempts.current}}} / {{{attempts.max}}}
Detail: [{{{details.text}}}]({{{details.url}}})
{{#error}}
```
{{{error}}}
```
{{/error}}
job.report.succeeded: |-
✅ **Berhasil**
Percobaan: {{{attempts.current}}} / {{{attempts.max}}}
Detail: [{{{details.text}}}]({{{details.url}}})
whatsapp.message.sending.error: Tidak dapat mengirim pesan di WhatsApp.
whatsapp.message.receiving.error: Tidak dapat menerima pesan dari WhatsApp
whatsapp.message.removing.error: Tidak dapat menghapus pesan dari WhatsApp
job.scheduled.error.header: Tugas terjadwal gagal dijalankan
message.from.whatsapp: |-
{{{text}}}
📱 *Dikirim dari WhatsApp*
message.from.api: |-
{{{text}}}
📱 *Dikirim melalui API*
message.removed.in.whatsapp: |-
❌ *Pesan ini telah dihapus di WhatsApp*
message.edited.in.whatsapp: |-
{{{text}}}
✏️ *Diedit di WhatsApp*
whatsapp.group.message: |-
👥 *{{{participant}}}*
{{{text}}}
whatsapp.reaction.added: |-
*Bereaksi* {{{emoji}}}
whatsapp.reaction.removed: |-
*Reaksi dihapus*
whatsapp.contact.group.suffix: 'Grup'
whatsapp.contact.channel.suffix: 'Saluran'
whatsapp.contact.broadcast.suffix: 'Daftar Siaran'
# Aka Stories
whatsapp.contact.status.name: 'Status'
app.connected.message: |-
🔗 **TERHUBUNG: Sesi WhatsApp ke Kotak Masuk ChatWoot**
✅ Sesi WhatsApp **{{{name}}}** telah berhasil terhubung ke Kotak Masuk ChatWoot ini.
Kotak masuk ini sekarang terhubung ke **Akun WhatsApp** Anda. Anda dapat mengirim dan menerima pesan langsung dari sini — seperti menggunakan WhatsApp, tetapi di dalam ChatWoot.
Anda juga dapat mengelola sesi WhatsApp yang terhubung ke kotak masuk ini. Untuk melihat tindakan yang tersedia, kirim **help** ke obrolan ini.
📋 Tindakan umum yang dapat Anda lakukan:
- Periksa apakah sesi WhatsApp aktif
- Mulai ulang atau Hentikan sesi WhatsApp
- Keluar dan hubungkan kembali dengan memindai kode QR baru
Jika semuanya berfungsi, Anda akan dapat mengobrol dengan bebas. Jika Anda melihat peringatan, Anda mungkin perlu menghubungkan kembali akun WhatsApp Anda.
Mari kita mulai! 🚀
app.disconnected.message: |-
🔌 **TERPUTUS: Sesi WhatsApp dari Kotak Masuk ChatWoot**
❌ Sesi WhatsApp **{{{name}}}** telah terputus dari Kotak Masuk ChatWoot ini.
Anda tidak akan dapat lagi mengirim atau menerima pesan dari WhatsApp.
Untuk menghubungkan kembali, silakan hubungi administrator Anda.
app.updated.message: |-
🔄 **DIPERBARUI: Pengaturan Sesi WhatsApp**
✅ Pengaturan untuk sesi WhatsApp **{{{name}}}** telah diperbarui.
app.commands.list: |-
Anda dapat mengelola **Integrasi WhatsApp** dengan mengirimkan salah satu perintah berikut:
🖥️ **Sesi**:
1. **status** - dapatkan status sesi saat ini.
2. **restart** - mulai ulang sesi - ini akan mencoba menghubungkan kembali akun WhatsApp Anda.
3. **start** - mulai sesi.
4. **stop** - hentikan sesi.
5. **logout** - keluar dari sesi, sehingga Anda dapat memindai kode QR dan memperbaiki sesi.
6. **qr** - dapatkan kode QR untuk sesi.
7. **screenshot** - dapatkan tangkapan layar sesi (hanya tersedia di mesin **WEBJS**).
8. **help** - perintah yang tersedia.
{{#commands.server}}
⚙️ Server:
- **server status** - dapatkan informasi versi dan status server.
- **server reboot** - mulai ulang server dengan anggun.
- **server reboot force** - paksa mulai ulang server.
{{/commands.server}}
Kirim **perintah** (tidak peka huruf besar/kecil) atau **nomor perintah** ke percakapan ini.
app.commands.server.disabled: ⛔ **Perintah server dinonaktifkan**.
Silakan hubungi administrator Anda.
Kirim **help** untuk melihat daftar perintah yang tersedia.
app.help.reminder: |-
Kirim **help** untuk mendapatkan daftar perintah yang tersedia.
app.session.status.change: |-
{{{emoji}}} Sesi "{{{session}}}" beralih ke status {{{status}}}
app.session.current.status: |-
{{{emoji}}} Status sesi **{{{session}}}** adalah **{{{status}}}**
**Akun WhatsApp:**
📱 **{{{name}}} ({{{id}}})**
app.session.status.working: |-
✅ Kotak Masuk ChatWoot ini terhubung ke **Akun WhatsApp** dan siap untuk mengirim dan menerima pesan!
📱 **{{{name}}} ({{{id}}})**
app.session.status.error: |-
⚠️ **Kotak Masuk ChatWoot ini terhubung ke Akun WhatsApp tetapi TIDAK siap untuk mengirim dan menerima pesan!**
Silakan periksa status sesi dan coba mulai ulang atau keluar dan pindai kode QR lagi.
app.session.scan.qr.code: |-
⚠️ **Pindai kode QR di ponsel Anda untuk menghubungkan Akun WhatsApp dengan Kotak Masuk ChatWoot ini!**
app.server.version.and.status: |-
**Versi:**
```
{{{version}}}
```
**Status:**
```
{{{status}}}
```
app.server.reboot: |-
Server sedang dimulai ulang dengan anggun...
app.server.reboot.force: |-
Server sedang dipaksa untuk dimulai ulang...
app.logout.success: |-
✅ Akun berhasil tidak diotorisasi!
waha.new.version.available: |-
🔄 **Versi Baru Tersedia!**
Versi saat ini: **{{{currentVersion}}}**
Versi baru: **{{{newVersion}}}**
👉 Lihat apa yang baru di [**🆕 Changelog**]({{{changelogUrl}}})
waha.core.version.used: |-
❤️ **Dukung WAHA!**
Anda menggunakan versi **WAHA Core** gratis. Jika Anda merasa proyek ini bermanfaat, harap pertimbangkan untuk mendukung pengembangannya.
Dukungan Anda adalah satu-satunya cara kami dapat terus bekerja pada pembaruan, perbaikan, dan fitur baru.
[**🎁 Dukung Kami**]({{{supportUrl}}})
chatwoot.to.whatsapp.message.text: |-
{{{ content }}}
chatwoot.to.whatsapp.message.media.caption: |-
{{#singleAttachment}}
{{#content}}
{{{ content }}}
{{/content}}
{{/singleAttachment}}
whatsapp.to.chatwoot.message: |-
{{{payload.body}}}
whatsapp.to.chatwoot.message.contacts: |-
👤 **Kontak yang dibagikan**
{{#contacts}}
🪪 Nama: **{{fullName}}**
{{#phoneNumbers}}
- 📞 Telepon: **{{.}}**
{{/phoneNumbers}}
{{/contacts}}
whatsapp.to.chatwoot.message.location: |-
{{#message}}
{{#locationMessage}}
📍 **Lokasi yang dibagikan**
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **Alamat:** {{address}}
{{/address}}
{{#url}}
🌐 **Situs web:** {{url}}
{{/url}}
🔗 **Lihat di peta:** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/locationMessage}}
{{#liveLocationMessage}}
📍📡 **Berbagi Lokasi Langsung**
Buka **WhatsApp** untuk melihat pembaruan waktu nyata.
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **Alamat:** {{address}}
{{/address}}
{{#url}}
🌐 **Situs web:** {{url}}
{{/url}}
🔗 **Lihat di peta:** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/liveLocationMessage}}
{{/message}}
whatsapp.to.chatwoot.message.poll: |-
{{#poll}}
📊 **Jajak Pendapat**
**{{name}}**
{{#options}}
- {{optionName}}
{{/options}}
{{/poll}}
whatsapp.to.chatwoot.message.event: |-
{{#message}}
{{#eventMessage}}
📅 **Acara**
**{{name}}**
{{#description}}
{{description}}
{{/description}}
{{#location.name}}
📍 **Lokasi:** {{location.name}}
{{/location.name}}
{{#startTime}}
🕐 **Mulai:** {{startTime}}
{{/startTime}}
{{#endTime}}
🕐 **Selesai:** {{endTime}}
{{/endTime}}
{{#joinLink}}
🔗 **Tautan bergabung:** [{{joinLink}}]({{joinLink}})
{{/joinLink}}
{{/eventMessage}}
{{/message}}
whatsapp.to.chatwoot.message.pix: |-
💳 **PIX - Salin dan Tempel**
{{#pixData}}
{{#merchantName}}
**{{merchantName}}**
{{/merchantName}}
{{#key}}
**Kunci PIX:** {{key}}
{{/key}}
{{#keyType}}
**Jenis:** {{keyType}}
{{/keyType}}
{{#totalAmount}}
**Jumlah:** {{totalAmountFormatted}}
{{/totalAmount}}
{{#referenceId}}
**Referensi:** {{referenceId}}
{{/referenceId}}
💳 **PIX Salin dan Tempel terkirim**
{{/pixData}}
whatsapp.to.chatwoot.message.unsupported: |-
⚠️ **Jenis pesan ini tidak didukung di ChatWoot.**
📱 Silakan buka **WhatsApp** untuk melihatnya.
Detail: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **IKLAN FACEBOOK**
**Judul:** {{{adData.title}}}
**Deskripsi:**
{{{adData.body}}}
**Tautan Iklan:** [Lihat di Facebook]({{{adData.sourceUrl}}})
**ID Iklan:** {{{adData.sourceId}}}
---
💬 **Pesan Pelanggan:**
{{{payload.body}}}
@@ -1,7 +1,29 @@
# Punjabi translations for ChatWoot integration
APP_INBOX_CONTACT_NAME: 'ਵਟਸਐਪ ਇੰਟੀਗ੍ਰੇਸ਼ਨ (WAHA)'
locale.name: '🇵🇰 ਪੰਜਾਬੀ (Punjabi)'
JOB_ERROR_REPORT: |
# ਅਧਾਰਭੂਤ ਲੋਕੇਲ ਕੋਡ - ਇਹ ਇੱਕ ਵੈਧ BCP 47 ਲੋਕੇਲ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ
# https://en.wikipedia.org/wiki/IETF_language_tag
# WAHA ਇਸਨੂੰ ਅੰਕ, ਕਰੰਸੀ ਅਤੇ ਤਾਰੀਖ/ਸਮੇਂ ਦੀ ਨਮਾਇਸ਼ ਲਈ ਵਰਤਦਾ ਹੈ
locale.base: 'pa-PK'
app.inbox.contact.name: 'ਵਟਸਐਪ ਇੰਟੀਗ੍ਰੇਸ਼ਨ (WAHA)'
app.inbox.contact.avatar.url: 'https://raw.githubusercontent.com/devlikeapro/waha/core/logo.png'
# date.toLocaleString ਦੀਆਂ "options"
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#options
datetime:
locales: pa-PK
day: 2-digit
month: 2-digit
year: numeric
hour: 2-digit
minute: 2-digit
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#timezonename
timeZoneName: shortGeneric
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
# timeZone: 'Asia/Karachi'
job.report.error: |-
⚠️ **{{{header}}}**
{{#attempts.nextDelay}}
🔄 {{attempts.nextDelay}} ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰ ਰਿਹਾ ਹੈ...
@@ -18,51 +40,52 @@ JOB_ERROR_REPORT: |
```
{{/error}}
JOB_SUCCEEDED_REPORT: |
job.report.succeeded: |-
✅ **ਸਫਲ**
ਕੋਸ਼ਿਸ਼: {{{attempts.current}}} / {{{attempts.max}}}
ਵੇਰਵੇ: [{{{details.text}}}]({{{details.url}}})
WHATSAPP_ERROR_SENDING_MESSAGE: ਵਟਸਐਪ 'ਤੇ ਸੁਨੇਹਾ ਭੇਜ ਨਹੀਂ ਸਕਿਆ।
WHATSAPP_ERROR_RECEIVING_MESSAGE: ਵਟਸਐਪ ਤੋਂ ਸੁਨੇਹਾ ਪ੍ਰਾਪਤ ਨਹੀਂ ਕਰ ਸਕਿਆ
WHATSAPP_ERROR_REMOVING_MESSAGE: ਵਟਸਐਪ ਤੋਂ ਸੁਨੇਹਾ ਹਟਾ ਨਹੀਂ ਸਕਿਆ
APP_SCHEDULED_JOB_ERROR: ਨਿਰਧਾਰਿਤ ਕੰਮ ਚਲਾਉਣ ਵਿੱਚ ਅਸਫਲ ਰਿਹਾ
whatsapp.message.sending.error: ਵਟਸਐਪ 'ਤੇ ਸੁਨੇਹਾ ਭੇਜ ਨਹੀਂ ਸਕਿਆ।
whatsapp.message.receiving.error: ਵਟਸਐਪ ਤੋਂ ਸੁਨੇਹਾ ਪ੍ਰਾਪਤ ਨਹੀਂ ਕਰ ਸਕਿਆ
whatsapp.message.removing.error: ਵਟਸਐਪ ਤੋਂ ਸੁਨੇਹਾ ਹਟਾ ਨਹੀਂ ਸਕਿਆ
job.scheduled.error.header: ਨਿਰਧਾਰਿਤ ਕੰਮ ਚਲਾਉਣ ਵਿੱਚ ਅਸਫਲ ਰਿਹਾ
MESSAGE_FROM_WHATSAPP: |
message.from.whatsapp: |-
{{{text}}}
📱 *ਵਟਸਐਪ ਤੋਂ ਭੇਜਿਆ ਗਿਆ*
MESSAGE_FROM_API: |
message.from.api: |-
{{{text}}}
📱 *API ਰਾਹੀਂ ਭੇਜਿਆ ਗਿਆ*
MESSAGE_REMOVED_IN_WHATSAPP: |
message.removed.in.whatsapp: |-
❌ *ਇਹ ਸੁਨੇਹਾ ਵਟਸਐਪ ਵਿੱਚ ਮਿਟਾ ਦਿੱਤਾ ਗਿਆ ਸੀ*
MESSAGE_EDITED_IN_WHATSAPP: |
message.edited.in.whatsapp: |-
{{{text}}}
✏️ *ਵਟਸਐਪ ਵਿੱਚ ਸੰਪਾਦਿਤ ਕੀਤਾ ਗਿਆ*
WHATSAPP_GROUP_MESSAGE: |
{{{text}}}
whatsapp.group.message: |-
👥 *{{{participant}}}*
WHATSAPP_REACTION_ADDED: |
{{{text}}}
whatsapp.reaction.added: |-
*ਪ੍ਰਤੀਕਿਰਿਆ ਕੀਤੀ* {{{emoji}}}
WHATSAPP_REACTION_REMOVED: |
whatsapp.reaction.removed: |-
*ਪ੍ਰਤੀਕਿਰਿਆ ਹਟਾਈ ਗਈ*
WHATSAPP_CONTACT_GROUP_SUFFIX: 'ਗਰੁੱਪ'
WHATSAPP_CONTACT_CHANNEL_SUFFIX: 'ਚੈਨਲ'
whatsapp.contact.group.suffix: 'ਗਰੁੱਪ'
whatsapp.contact.channel.suffix: 'ਚੈਨਲ'
whatsapp.contact.broadcast.suffix: 'ਪ੍ਰਸਾਰਣ ਸੂਚੀ'
# Aka Stories
WHATSAPP_CONTACT_STATUS_NAME: 'ਸਥਿਤੀ'
whatsapp.contact.status.name: 'ਸਥਿਤੀ'
APP_CONNECTED_MESSAGE: |
app.connected.message: |-
🔗 **ਕਨੈਕਟ ਕੀਤਾ: ਵਟਸਐਪ ਸੈਸ਼ਨ ਤੋਂ ChatWoot ਇਨਬਾਕਸ**
✅ ਵਟਸਐਪ ਸੈਸ਼ਨ **{{{name}}}** ਨੂੰ ਸਫਲਤਾਪੂਰਵਕ ਇਸ ChatWoot ਇਨਬਾਕਸ ਨਾਲ ਜੋੜਿਆ ਗਿਆ ਹੈ।
@@ -80,7 +103,7 @@ APP_CONNECTED_MESSAGE: |
ਆਓ ਸ਼ੁਰੂ ਕਰੀਏ! 🚀
APP_DISCONNECTED_MESSAGE: |
app.disconnected.message: |-
🔌 **ਡਿਸਕਨੈਕਟ ਕੀਤਾ: ਵਟਸਐਪ ਸੈਸ਼ਨ ਤੋਂ ChatWoot ਇਨਬਾਕਸ**
❌ ਵਟਸਐਪ ਸੈਸ਼ਨ **{{{name}}}** ਇਸ ChatWoot ਇਨਬਾਕਸ ਤੋਂ ਡਿਸਕਨੈਕਟ ਕੀਤਾ ਗਿਆ ਹੈ।
@@ -89,15 +112,15 @@ APP_DISCONNECTED_MESSAGE: |
ਮੁੜ ਕਨੈਕਟ ਕਰਨ ਲਈ, ਕਿਰਪਾ ਕਰਕੇ ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।
APP_UPDATED_MESSAGE: |
app.updated.message: |-
🔄 **ਅਪਡੇਟ ਕੀਤਾ: ਵਟਸਐਪ ਸੈਸ਼ਨ ਸੈਟਿੰਗਾਂ**
✅ ਵਟਸਐਪ ਸੈਸ਼ਨ **{{{name}}}** ਲਈ ਸੈਟਿੰਗਾਂ ਅਪਡੇਟ ਕੀਤੀਆਂ ਗਈਆਂ ਹਨ।
APP_COMMANDS_LIST: |
app.commands.list: |-
ਤੁਸੀਂ ਹੇਠਾਂ ਦਿੱਤੇ ਕਮਾਂਡਾਂ ਵਿੱਚੋਂ ਇੱਕ ਭੇਜ ਕੇ **ਵਟਸਐਪ ਇੰਟੀਗ੍ਰੇਸ਼ਨ** ਦਾ ਪ੍ਰਬੰਧਨ ਕਰ ਸਕਦੇ ਹੋ:
🖥️ ਸੈਸ਼ਨ:
🖥️ **ਸੈਸ਼ਨ**:
1. **status** - ਮੌਜੂਦਾ ਸੈਸ਼ਨ ਸਥਿਤੀ ਪ੍ਰਾਪਤ ਕਰੋ।
2. **restart** - ਸੈਸ਼ਨ ਮੁੜ ਚਾਲੂ ਕਰੋ - ਇਹ ਤੁਹਾਡੇ ਵਟਸਐਪ ਖਾਤੇ ਨੂੰ ਮੁੜ ਕਨੈਕਟ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੇਗਾ।
3. **start** - ਸੈਸ਼ਨ ਸ਼ੁਰੂ ਕਰੋ।
@@ -107,42 +130,47 @@ APP_COMMANDS_LIST: |
7. **screenshot** - ਸੈਸ਼ਨ ਦਾ ਸਕ੍ਰੀਨਸ਼ਾਟ ਪ੍ਰਾਪਤ ਕਰੋ (ਸਿਰਫ **WEBJS** ਇੰਜਣ ਵਿੱਚ ਉਪਲਬਧ)।
8. **help** - ਉਪਲਬਧ ਕਮਾਂਡਾਂ।
{{#commands.server}}
⚙️ ਸਰਵਰ:
- **server status** - ਸਰਵਰ ਵਰਜਨ ਅਤੇ ਸਥਿਤੀ ਜਾਣਕਾਰੀ ਪ੍ਰਾਪਤ ਕਰੋ।
- **server reboot** - ਸਰਵਰ ਨੂੰ ਸੁਚਾਰੂ ਢੰਗ ਨਾਲ ਮੁੜ ਚਾਲੂ ਕਰੋ।
- **server reboot force** - ਸਰਵਰ ਨੂੰ ਜ਼ਬਰਦਸਤੀ ਮੁੜ ਚਾਲੂ ਕਰੋ।
{{/commands.server}}
ਇਸ ਗੱਲਬਾਤ ਵਿੱਚ **ਕਮਾਂਡ** (ਕੇਸ ਇਨਸੈਂਸਿਟਿਵ) ਜਾਂ **ਕਮਾਂਡ ਨੰਬਰ** ਭੇਜੋ।
APP_HELP_REMINDER: |
app.commands.server.disabled: ⛔ **ਸਰਵਰ ਕਮਾਂਡ ਅਯੋਗ ਹਨ**।
ਕਿਰਪਾ ਕਰਕੇ ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।
ਉਪਲਬਧ ਕਮਾਂਡਾਂ ਦੀ ਸੂਚੀ ਲਈ **help** ਭੇਜੋ।
app.help.reminder: |-
ਉਪਲਬਧ ਕਮਾਂਡਾਂ ਦੀ ਸੂਚੀ ਪ੍ਰਾਪਤ ਕਰਨ ਲਈ **help** ਭੇਜੋ।
APP_SESSION_STATUS_CHANGE: |
app.session.status.change: |-
{{{emoji}}} "{{{session}}}" ਸੈਸ਼ਨ {{{status}}} ਸਥਿਤੀ 'ਤੇ ਬਦਲ ਗਿਆ
APP_SESSION_CURRENT_STATUS: |
app.session.current.status: |-
{{{emoji}}} **{{{session}}}** ਸੈਸ਼ਨ ਸਥਿਤੀ **{{{status}}}** ਵਿੱਚ ਹੈ
**ਵਟਸਐਪ ਖਾਤਾ:**
📱 **{{{name}}} ({{{id}}})**
APP_DASHBOARD_LINK: |
ਵਧੇਰੇ ਵੇਰਵਿਆਂ ਲਈ [WAHA ਡੈਸ਼ਬੋਰਡ]({{{url}}}) 'ਤੇ ਜਾਓ।
APP_SESSION_STATUS_WORKING: |
app.session.status.working: |-
✅ ਇਹ ChatWoot ਇਨਬਾਕਸ **ਵਟਸਐਪ ਖਾਤੇ** ਨਾਲ ਜੁੜਿਆ ਹੋਇਆ ਹੈ ਅਤੇ ਸੁਨੇਹੇ ਭੇਜਣ ਅਤੇ ਪ੍ਰਾਪਤ ਕਰਨ ਲਈ ਤਿਆਰ ਹੈ!
📱 **{{{name}}} ({{{id}}})**
APP_SESSION_STATUS_ERROR: |
app.session.status.error: |-
⚠️ **ਇਹ ChatWoot ਇਨਬਾਕਸ ਵਟਸਐਪ ਖਾਤੇ ਨਾਲ ਜੁੜਿਆ ਹੋਇਆ ਹੈ ਪਰ ਸੁਨੇਹੇ ਭੇਜਣ ਅਤੇ ਪ੍ਰਾਪਤ ਕਰਨ ਲਈ ਤਿਆਰ ਨਹੀਂ ਹੈ!**
ਕਿਰਪਾ ਕਰਕੇ ਸੈਸ਼ਨ ਸਥਿਤੀ ਦੀ ਜਾਂਚ ਕਰੋ ਅਤੇ ਇਸਨੂੰ ਮੁੜ ਚਾਲੂ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੋ ਜਾਂ ਲੌਗਆਉਟ ਕਰੋ ਅਤੇ QR ਕੋਡ ਦੁਬਾਰਾ ਸਕੈਨ ਕਰੋ।
APP_SESSION_SCAN_QR_CODE: |
app.session.scan.qr.code: |-
⚠️ **ਵਟਸਐਪ ਖਾਤੇ ਨੂੰ ਇਸ ChatWoot ਇਨਬਾਕਸ ਨਾਲ ਜੋੜਨ ਲਈ ਆਪਣੇ ਫੋਨ 'ਤੇ QR ਕੋਡ ਸਕੈਨ ਕਰੋ!**
APP_SERVER_VERSION_AND_STATUS: |
app.server.version.and.status: |-
**ਵਰਜਨ:**
```
{{{version}}}
@@ -153,16 +181,16 @@ APP_SERVER_VERSION_AND_STATUS: |
{{{status}}}
```
APP_SERVER_REBOOT: |
app.server.reboot: |-
ਸਰਵਰ ਸੁਚਾਰੂ ਢੰਗ ਨਾਲ ਮੁੜ ਚਾਲੂ ਹੋ ਰਿਹਾ ਹੈ...
APP_SERVER_REBOOT_FORCE: |
app.server.reboot.force: |-
ਸਰਵਰ ਜ਼ਬਰਦਸਤੀ ਮੁੜ ਚਾਲੂ ਹੋ ਰਿਹਾ ਹੈ...
APP_LOGOUT_SUCCESS: |
app.logout.success: |-
✅ ਖਾਤਾ ਸਫਲਤਾਪੂਰਵਕ ਅਣਅਧਿਕਾਰਤ ਕੀਤਾ ਗਿਆ!
APP_NEW_VERSION_AVAILABLE: |
waha.new.version.available: |-
🔄 **ਨਵਾਂ ਵਰਜਨ ਉਪਲਬਧ!**
ਮੌਜੂਦਾ ਵਰਜਨ: **{{{currentVersion}}}**
@@ -170,7 +198,7 @@ APP_NEW_VERSION_AVAILABLE: |
👉 [**🆕 ਬਦਲਾਅ ਲੌਗ**]({{{changelogUrl}}}) ਵਿੱਚ ਨਵਾਂ ਕੀ ਹੈ ਦੇਖੋ
APP_CORE_VERSION_USED: |
waha.core.version.used: |-
❤️ **WAHA ਦਾ ਸਮਰਥਨ ਕਰੋ!**
ਤੁਸੀਂ ਮੁਫਤ **WAHA Core** ਵਰਜਨ ਦੀ ਵਰਤੋਂ ਕਰ ਰਹੇ ਹੋ। ਜੇ ਤੁਹਾਨੂੰ ਇਹ ਪ੍ਰੋਜੈਕਟ ਲਾਭਦਾਇਕ ਲੱਗਦਾ ਹੈ, ਤਾਂ ਕਿਰਪਾ ਕਰਕੇ ਇਸਦੇ ਵਿਕਾਸ ਦਾ ਸਮਰਥਨ ਕਰਨ 'ਤੇ ਵਿਚਾਰ ਕਰੋ।
@@ -178,3 +206,149 @@ APP_CORE_VERSION_USED: |
ਤੁਹਾਡਾ ਸਮਰਥਨ ਹੀ ਇੱਕੋ ਇੱਕ ਤਰੀਕਾ ਹੈ ਜਿਸ ਨਾਲ ਅਸੀਂ ਅਪਡੇਟਾਂ, ਫਿਕਸਾਂ, ਅਤੇ ਨਵੀਆਂ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ 'ਤੇ ਕੰਮ ਕਰਨਾ ਜਾਰੀ ਰੱਖ ਸਕਦੇ ਹਾਂ।
[**🎁 ਸਾਡਾ ਸਮਰਥਨ ਕਰੋ**]({{{supportUrl}}})
chatwoot.to.whatsapp.message.text: |-
{{{ content }}}
chatwoot.to.whatsapp.message.media.caption: |-
{{#singleAttachment}}
{{#content}}
{{{ content }}}
{{/content}}
{{/singleAttachment}}
whatsapp.to.chatwoot.message: |-
{{{payload.body}}}
whatsapp.to.chatwoot.message.contacts: |-
👤 **ਸਾਂਝੇ ਕੀਤੇ ਸੰਪਰਕ**
{{#contacts}}
🪪 ਨਾਮ: **{{fullName}}**
{{#phoneNumbers}}
- 📞 ਫ਼ੋਨ: **{{.}}**
{{/phoneNumbers}}
{{/contacts}}
whatsapp.to.chatwoot.message.location: |-
{{#message}}
{{#locationMessage}}
📍 **ਸਾਂਝੀ ਸਥਿਤੀ**
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **ਪਤਾ:** {{address}}
{{/address}}
{{#url}}
🌐 **ਵੈਬਸਾਈਟ:** {{url}}
{{/url}}
🔗 **ਨਕਸ਼ੇ 'ਤੇ ਵੇਖੋ:** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/locationMessage}}
{{#liveLocationMessage}}
📍📡 **ਲਾਈਵ ਸਥਿਤੀ ਸਾਂਝੀ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ**
ਰੀਅਲ-ਟਾਈਮ ਅੱਪਡੇਟ ਦੇਖਣ ਲਈ **WhatsApp** ਖੋਲ੍ਹੋ।
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **ਪਤਾ:** {{address}}
{{/address}}
{{#url}}
🌐 **ਵੈਬਸਾਈਟ:** {{url}}
{{/url}}
🔗 **ਨਕਸ਼ੇ 'ਤੇ ਵੇਖੋ:** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/liveLocationMessage}}
{{/message}}
whatsapp.to.chatwoot.message.poll: |-
{{#poll}}
📊 **ਸਰਵੇਖਣ**
**{{name}}**
{{#options}}
- {{optionName}}
{{/options}}
{{/poll}}
whatsapp.to.chatwoot.message.event: |-
{{#message}}
{{#eventMessage}}
📅 **ਇਵੈਂਟ**
**{{name}}**
{{#description}}
{{description}}
{{/description}}
{{#location.name}}
📍 **ਸਥਾਨ:** {{location.name}}
{{/location.name}}
{{#startTime}}
🕐 **ਸ਼ੁਰੂਆਤ:** {{startTime}}
{{/startTime}}
{{#endTime}}
🕐 **ਖਾਤਮਾ:** {{endTime}}
{{/endTime}}
{{#joinLink}}
🔗 **ਜੁੜਨ ਲਈ ਲਿੰਕ:** [{{joinLink}}]({{joinLink}})
{{/joinLink}}
{{/eventMessage}}
{{/message}}
whatsapp.to.chatwoot.message.pix: |-
💳 **PIX - ਕਾਪੀ ਅਤੇ ਪੇਸਟ**
{{#pixData}}
{{#merchantName}}
**{{merchantName}}**
{{/merchantName}}
{{#key}}
**PIX ਕੁੰਜੀ:** {{key}}
{{/key}}
{{#keyType}}
**ਕਿਸਮ:** {{keyType}}
{{/keyType}}
{{#totalAmount}}
**ਰਕਮ:** {{totalAmountFormatted}}
{{/totalAmount}}
{{#referenceId}}
**ਹਵਾਲਾ:** {{referenceId}}
{{/referenceId}}
💳 **PIX ਕਾਪੀ ਅਤੇ ਪੇਸਟ ਭੇਜਿਆ ਗਿਆ**
{{/pixData}}
whatsapp.to.chatwoot.message.unsupported: |-
⚠️ **ਇਹ ਸੁਨੇਹੇ ਦੀ ਕਿਸਮ ChatWoot ਵਿੱਚ ਸਮਰਥਿਤ ਨਹੀਂ ਹੈ।**
📱 ਇਸਨੂੰ ਦੇਖਣ ਲਈ ਕਿਰਪਾ ਕਰਕੇ **WhatsApp** ਖੋਲ੍ਹੋ।
ਵੇਰਵੇ: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **ਫੇਸਬੁੱਕ ਵਿਗਿਆਪਨ**
**ਸਿਰਲੇਖ:** {{{adData.title}}}
**ਵੇਰਵਾ:**
{{{adData.body}}}
**ਵਿਗਿਆਪਨ ਲਿੰਕ:** [ਫੇਸਬੁੱਕ 'ਤੇ ਵੇਖੋ]({{{adData.sourceUrl}}})
**ਵਿਗਿਆਪਨ ਆਈਡੀ:** {{{adData.sourceId}}}
---
💬 **ਗਾਹਕ ਦਾ ਸੁਨੇਹਾ:**
{{{payload.body}}}
+361
View File
@@ -0,0 +1,361 @@
# Portuguese translations for ChatWoot integration
locale.name: '🇧🇷🇵🇹 Português (Portuguese)'
# Código de locale base - deve ser um locale BCP 47 válido
# https://en.wikipedia.org/wiki/IETF_language_tag
# A WAHA usa isso para formatar números, moeda e data/hora
locale.base: 'pt-BR'
app.inbox.contact.name: 'Integração WhatsApp (WAHA)'
app.inbox.contact.avatar.url: 'https://raw.githubusercontent.com/devlikeapro/waha/core/logo.png'
# "opções" de date.toLocaleString
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#options
datetime:
locales: pt-BR
day: 2-digit
month: 2-digit
year: numeric
hour: 2-digit
minute: 2-digit
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#timezonename
timeZoneName: shortGeneric
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
timeZone: 'America/Sao_Paulo'
job.report.error: |-
⚠️ **{{{header}}}**
{{#attempts.nextDelay}}
🔄 Tentando novamente em {{attempts.nextDelay}} segundos...
{{/attempts.nextDelay}}
{{^attempts.nextDelay}}
❌ Não há mais tentativas restantes. Por favor, tente novamente mais tarde.
{{/attempts.nextDelay}}
Tentativa: {{{attempts.current}}} / {{{attempts.max}}}
Detalhes: [{{{details.text}}}]({{{details.url}}})
{{#error}}
```
{{{error}}}
```
{{/error}}
job.report.succeeded: |-
✅ **Sucesso**
Tentativa: {{{attempts.current}}} / {{{attempts.max}}}
Detalhes: [{{{details.text}}}]({{{details.url}}})
whatsapp.message.sending.error:
Não foi possível enviar uma mensagem no WhatsApp.
whatsapp.message.receiving.error:
Não foi possível receber uma mensagem do WhatsApp
whatsapp.message.removing.error:
Não foi possível remover uma mensagem do WhatsApp
job.scheduled.error.header: Falha ao executar tarefa agendada
message.from.whatsapp: |-
{{{text}}}
📱 *Enviado do WhatsApp*
message.from.api: |-
{{{text}}}
📱 *Enviado via API*
message.removed.in.whatsapp: |-
❌ *Esta mensagem foi excluída no WhatsApp*
message.edited.in.whatsapp: |-
{{{text}}}
✏️ *Editado no WhatsApp*
whatsapp.group.message: |-
👥 *{{{participant}}}*
{{{text}}}
whatsapp.reaction.added: |-
*Reagiu com* {{{emoji}}}
whatsapp.reaction.removed: |-
*Reação removida*
whatsapp.contact.group.suffix: 'Grupo'
whatsapp.contact.channel.suffix: 'Canal'
whatsapp.contact.broadcast.suffix: 'Lista de transmissão'
# Aka Stories
whatsapp.contact.status.name: 'Status'
app.connected.message: |-
🔗 **CONECTADO: Sessão do WhatsApp para Caixa de Entrada do ChatWoot**
✅ A sessão do WhatsApp **{{{name}}}** foi conectada com sucesso a esta Caixa de Entrada do ChatWoot.
Esta caixa de entrada agora está vinculada à sua **Conta do WhatsApp**. Você pode enviar e receber mensagens diretamente daqui — assim como usar o WhatsApp, mas dentro do ChatWoot.
Você também pode gerenciar a sessão do WhatsApp vinculada a esta caixa de entrada. Para ver as ações disponíveis, envie **help** para este chat.
📋 Ações comuns que você pode fazer:
- Verificar se a sessão do WhatsApp está ativa
- Reiniciar ou Parar a sessão do WhatsApp
- Sair e reconectar escaneando um novo código QR
Se tudo estiver funcionando, você poderá conversar livremente. Se você vir avisos, pode precisar reconectar sua conta do WhatsApp.
Vamos começar! 🚀
app.disconnected.message: |-
🔌 **DESCONECTADO: Sessão do WhatsApp da Caixa de Entrada do ChatWoot**
❌ A sessão do WhatsApp **{{{name}}}** foi desconectada desta Caixa de Entrada do ChatWoot.
Você não poderá mais enviar ou receber mensagens do WhatsApp.
Para reconectar, entre em contato com seu administrador.
app.updated.message: |-
🔄 **ATUALIZADO: Configurações da Sessão do WhatsApp**
✅ As configurações para a sessão do WhatsApp **{{{name}}}** foram atualizadas.
app.commands.list: |-
Você pode gerenciar a **Integração WhatsApp** enviando um dos seguintes comandos:
🖥️ **Sessão**:
1. **status** - obter o status atual da sessão.
2. **restart** - reiniciar a sessão - isso tentará reconectar sua conta do WhatsApp.
3. **start** - iniciar a sessão.
4. **stop** - parar a sessão.
5. **logout** - sair da sessão, para que você possa escanear o código QR e reparar a sessão.
6. **qr** - obter o código QR para a sessão.
7. **screenshot** - obter uma captura de tela da sessão (disponível apenas no motor **WEBJS**).
8. **help** - comandos disponíveis.
{{#commands.server}}
⚙️ Servidor:
- **server status** - obter informações sobre a versão e status do servidor.
- **server reboot** - reiniciar o servidor suavemente.
- **server reboot force** - forçar a reinicialização do servidor.
{{/commands.server}}
Envie um **comando** (não sensível a maiúsculas/minúsculas) ou um **número de comando** para esta conversa.
app.commands.server.disabled: ⛔ **Os comandos do servidor estão desativados**.
Por favor, contate o seu administrador.
Envie **help** para obter a lista de comandos disponíveis.
app.help.reminder: |-
Envie **help** para obter a lista de comandos disponíveis.
app.session.status.change: |-
{{{emoji}}} A sessão "{{{session}}}" mudou para o status {{{status}}}
app.session.current.status: |-
{{{emoji}}} O status da sessão **{{{session}}}** é **{{{status}}}**
**Conta do WhatsApp:**
📱 **{{{name}}} ({{{id}}})**
app.session.status.working: |-
✅ Esta Caixa de Entrada do ChatWoot está vinculada à **Conta do WhatsApp** e pronta para enviar e receber mensagens!
📱 **{{{name}}} ({{{id}}})**
app.session.status.error: |-
⚠️ **Esta Caixa de Entrada do ChatWoot está vinculada à Conta do WhatsApp, mas NÃO está pronta para enviar e receber mensagens!**
Por favor, verifique o status da sessão e tente reiniciá-la ou saia e escaneie o código QR novamente.
app.session.scan.qr.code: |-
⚠️ **Escaneie o código QR no seu telefone para vincular a Conta do WhatsApp a esta Caixa de Entrada do ChatWoot!**
app.server.version.and.status: |-
**Versão:**
```
{{{version}}}
```
**Status:**
```
{{{status}}}
```
app.server.reboot: |-
O servidor está reiniciando suavemente...
app.server.reboot.force: |-
O servidor está reiniciando forçadamente...
app.logout.success: |-
✅ Conta desautorizada com sucesso!
waha.new.version.available: |-
🔄 **Nova Versão Disponível!**
Versão atual: **{{{currentVersion}}}**
Nova versão: **{{{newVersion}}}**
👉 Confira o que há de novo no [**🆕 Registro de Alterações**]({{{changelogUrl}}})
waha.core.version.used: |-
❤️ **Apoie o WAHA!**
Você está usando a versão gratuita **WAHA Core**. Se você acha este projeto útil, considere apoiar seu desenvolvimento.
Seu apoio é a única maneira de continuarmos trabalhando em atualizações, correções e novos recursos.
[**🎁 Apoie-nos**]({{{supportUrl}}})
chatwoot.to.whatsapp.message.text: |-
{{{ content }}}
chatwoot.to.whatsapp.message.media.caption: |-
{{#singleAttachment}}
{{#content}}
{{{ content }}}
{{/content}}
{{/singleAttachment}}
whatsapp.to.chatwoot.message: |-
{{{payload.body}}}
whatsapp.to.chatwoot.message.contacts: |-
👤 **Contato(s) compartilhado(s)**
{{#contacts}}
🪪 Nome: **{{fullName}}**
{{#phoneNumbers}}
- 📞 Telefone: **{{.}}**
{{/phoneNumbers}}
{{/contacts}}
whatsapp.to.chatwoot.message.location: |-
{{#message}}
{{#locationMessage}}
📍 **Localização compartilhada**
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **Endereço:** {{address}}
{{/address}}
{{#url}}
🌐 **Site:** {{url}}
{{/url}}
🔗 **Ver no mapa:** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/locationMessage}}
{{#liveLocationMessage}}
📍📡 **Compartilhando localização ao vivo**
Abra o **WhatsApp** para ver as atualizações em tempo real.
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **Endereço:** {{address}}
{{/address}}
{{#url}}
🌐 **Site:** {{url}}
{{/url}}
🔗 **Ver no mapa:** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/liveLocationMessage}}
{{/message}}
whatsapp.to.chatwoot.message.poll: |-
{{#poll}}
📊 **Enquete**
**{{name}}**
{{#options}}
- {{optionName}}
{{/options}}
{{/poll}}
whatsapp.to.chatwoot.message.event: |-
{{#message}}
{{#eventMessage}}
📅 **Evento**
**{{name}}**
{{#description}}
{{description}}
{{/description}}
{{#location.name}}
📍 **Local:** {{location.name}}
{{/location.name}}
{{#startTime}}
🕐 **Início:** {{startTime}}
{{/startTime}}
{{#endTime}}
🕐 **Fim:** {{endTime}}
{{/endTime}}
{{#joinLink}}
🔗 **Link de participação:** [{{joinLink}}]({{joinLink}})
{{/joinLink}}
{{/eventMessage}}
{{/message}}
whatsapp.to.chatwoot.message.pix: |-
💳 **PIX - Copia e Cola**
{{#pixData}}
{{#merchantName}}
**{{merchantName}}**
{{/merchantName}}
{{#key}}
**Chave PIX:** {{key}}
{{/key}}
{{#keyType}}
**Tipo:** {{keyType}}
{{/keyType}}
{{#totalAmount}}
**Valor:** {{totalAmountFormatted}}
{{/totalAmount}}
{{#referenceId}}
**Referência:** {{referenceId}}
{{/referenceId}}
💳 **PIX Copia e Cola enviado**
{{/pixData}}
whatsapp.to.chatwoot.message.unsupported: |-
⚠️ **Esse tipo de mensagem não é suportado no ChatWoot.**
📱 Por favor, abra o **WhatsApp** para visualizá-la.
Detalhes: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **ANÚNCIO DO FACEBOOK**
**Título:** {{{adData.title}}}
**Descrição:**
{{{adData.body}}}
**Link do Anúncio:** [Ver no Facebook]({{{adData.sourceUrl}}})
**ID do Anúncio:** {{{adData.sourceId}}}
---
💬 **MENSAGEM DO CLIENTE:**
{{{payload.body}}}
@@ -1,7 +1,29 @@
# Russian translations for ChatWoot integration
APP_INBOX_CONTACT_NAME: 'WhatsApp Интеграция (WAHA)'
locale.name: '🇷🇺 Русский (Russian)'
JOB_ERROR_REPORT: |
# Базовый код локали - должен быть корректной локалью BCP 47
# https://en.wikipedia.org/wiki/IETF_language_tag
# WAHA использует его для форматирования чисел, валют и даты/времени
locale.base: 'ru-RU'
app.inbox.contact.name: 'WhatsApp Интеграция (WAHA)'
app.inbox.contact.avatar.url: 'https://raw.githubusercontent.com/devlikeapro/waha/core/logo.png'
# "параметры" из date.toLocaleString
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#options
datetime:
locales: ru-RU
day: 2-digit
month: 2-digit
year: numeric
hour: 2-digit
minute: 2-digit
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#timezonename
timeZoneName: shortGeneric
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
# timeZone: 'Europe/Moscow'
job.report.error: |-
⚠️ **{{{header}}}**
{{#attempts.nextDelay}}
🔄 Повторная попытка через {{attempts.nextDelay}} секунд...
@@ -18,51 +40,52 @@ JOB_ERROR_REPORT: |
```
{{/error}}
JOB_SUCCEEDED_REPORT: |
job.report.succeeded: |-
✅ **Успешно**
Попытка: {{{attempts.current}}} / {{{attempts.max}}}
Подробности: [{{{details.text}}}]({{{details.url}}})
WHATSAPP_ERROR_SENDING_MESSAGE: Не удалось отправить сообщение в WhatsApp.
WHATSAPP_ERROR_RECEIVING_MESSAGE: Не удалось получить сообщение из WhatsApp
WHATSAPP_ERROR_REMOVING_MESSAGE: Не удалось удалить сообщение из WhatsApp
APP_SCHEDULED_JOB_ERROR: Запланированная задача не выполнена
whatsapp.message.sending.error: Не удалось отправить сообщение в WhatsApp.
whatsapp.message.receiving.error: Не удалось получить сообщение из WhatsApp
whatsapp.message.removing.error: Не удалось удалить сообщение из WhatsApp
job.scheduled.error.header: Запланированная задача не выполнена
MESSAGE_FROM_WHATSAPP: |
message.from.whatsapp: |-
{{{text}}}
📱 *Отправлено из WhatsApp*
MESSAGE_FROM_API: |
message.from.api: |-
{{{text}}}
📱 *Отправлено через API*
MESSAGE_REMOVED_IN_WHATSAPP: |
message.removed.in.whatsapp: |-
❌ *Это сообщение было удалено в WhatsApp*
MESSAGE_EDITED_IN_WHATSAPP: |
message.edited.in.whatsapp: |-
{{{text}}}
✏️ *Отредактировано в WhatsApp*
WHATSAPP_GROUP_MESSAGE: |
{{{text}}}
whatsapp.group.message: |-
👥 *{{{participant}}}*
WHATSAPP_REACTION_ADDED: |
{{{text}}}
whatsapp.reaction.added: |-
*Реакция* {{{emoji}}}
WHATSAPP_REACTION_REMOVED: |
whatsapp.reaction.removed: |-
*Реакция удалена*
WHATSAPP_CONTACT_GROUP_SUFFIX: 'Группа'
WHATSAPP_CONTACT_CHANNEL_SUFFIX: 'Канал'
whatsapp.contact.group.suffix: 'Группа'
whatsapp.contact.channel.suffix: 'Канал'
whatsapp.contact.broadcast.suffix: 'Список рассылки'
# Aka Stories
WHATSAPP_CONTACT_STATUS_NAME: 'Статус'
whatsapp.contact.status.name: 'Статус'
APP_CONNECTED_MESSAGE: |
app.connected.message: |-
🔗 **ПОДКЛЮЧЕНО: Сессия WhatsApp к ChatWoot Inbox**
✅ Сессия WhatsApp **{{{name}}}** была успешно подключена к этому ChatWoot Inbox.
@@ -80,7 +103,7 @@ APP_CONNECTED_MESSAGE: |
Давайте начнем! 🚀
APP_DISCONNECTED_MESSAGE: |
app.disconnected.message: |-
🔌 **ОТКЛЮЧЕНО: Сессия WhatsApp от ChatWoot Inbox**
❌ Сессия WhatsApp **{{{name}}}** была отключена от этого ChatWoot Inbox.
@@ -89,15 +112,15 @@ APP_DISCONNECTED_MESSAGE: |
Для переподключения, пожалуйста, обратитесь к вашему администратору.
APP_UPDATED_MESSAGE: |
app.updated.message: |-
🔄 **ОБНОВЛЕНО: Настройки сессии WhatsApp**
✅ Настройки для сессии WhatsApp **{{{name}}}** были обновлены.
APP_COMMANDS_LIST: |
app.commands.list: |-
Вы можете управлять **WhatsApp Интеграцией**, отправив одну из следующих команд:
🖥️ Сессии:
🖥️ **Сессия**:
1. **status** - получить текущий статус сессии.
2. **restart** - перезапустить сессию - это попытается переподключить ваш аккаунт WhatsApp.
3. **start** - запустить сессию.
@@ -107,42 +130,47 @@ APP_COMMANDS_LIST: |
7. **screenshot** - получить скриншот сессии (доступно только в движке **WEBJS**).
8. **help** - доступные команды.
{{#commands.server}}
⚙️ Сервер:
- **server status** - получить информацию о версии и статусе сервера.
- **server reboot** - корректно перезагрузить сервер.
- **server reboot force** - принудительно перезагрузить сервер.
{{/commands.server}}
Отправьте **команду** (без учета регистра) или **номер команды** в этот разговор.
APP_HELP_REMINDER: |
app.commands.server.disabled: ⛔ **Команды сервера отключены**.
Пожалуйста, свяжитесь с вашим администратором.
Отправьте **help**, чтобы получить список доступных команд.
APP_SESSION_STATUS_CHANGE: |
app.help.reminder: |-
Отправьте **help**, чтобы получить список доступных команд.
app.session.status.change: |-
{{{emoji}}} Сессия "{{{session}}}" переключилась в статус {{{status}}}
APP_SESSION_CURRENT_STATUS: |
app.session.current.status: |-
{{{emoji}}} Статус сессии **{{{session}}}** - **{{{status}}}**
**Аккаунт WhatsApp:**
📱 **{{{name}}} ({{{id}}})**
APP_DASHBOARD_LINK: |
Посетите [WAHA Dashboard]({{{url}}}) для получения дополнительной информации.
APP_SESSION_STATUS_WORKING: |
app.session.status.working: |-
✅ Этот ChatWoot Inbox связан с **аккаунтом WhatsApp** и готов отправлять и получать сообщения!
📱 **{{{name}}} ({{{id}}})**
APP_SESSION_STATUS_ERROR: |
app.session.status.error: |-
⚠️ **Этот ChatWoot Inbox связан с аккаунтом WhatsApp, но НЕ готов отправлять и получать сообщения!**
Пожалуйста, проверьте статус сессии и попробуйте перезапустить её или выйдите и отсканируйте QR-код снова.
APP_SESSION_SCAN_QR_CODE: |
app.session.scan.qr.code: |-
⚠️ **Отсканируйте QR-код на вашем телефоне, чтобы связать аккаунт WhatsApp с этим ChatWoot Inbox!**
APP_SERVER_VERSION_AND_STATUS: |
app.server.version.and.status: |-
**Версия:**
```
{{{version}}}
@@ -153,16 +181,16 @@ APP_SERVER_VERSION_AND_STATUS: |
{{{status}}}
```
APP_SERVER_REBOOT: |
app.server.reboot: |-
Сервер корректно перезагружается...
APP_SERVER_REBOOT_FORCE: |
app.server.reboot.force: |-
Сервер принудительно перезагружается...
APP_LOGOUT_SUCCESS: |
app.logout.success: |-
✅ Аккаунт успешно деавторизован!
APP_NEW_VERSION_AVAILABLE: |
waha.new.version.available: |-
🔄 **Доступна новая версия!**
Текущая версия: **{{{currentVersion}}}**
@@ -170,7 +198,7 @@ APP_NEW_VERSION_AVAILABLE: |
👉 Узнайте, что нового в [**🆕 Списке изменений**]({{{changelogUrl}}})
APP_CORE_VERSION_USED: |
waha.core.version.used: |-
❤️ **Поддержите WAHA!**
Вы используете бесплатную версию **WAHA Core**. Если вы находите этот проект полезным, пожалуйста, рассмотрите возможность поддержать его разработку.
@@ -178,3 +206,149 @@ APP_CORE_VERSION_USED: |
Ваша поддержка - единственный способ, которым мы можем продолжать работать над обновлениями, исправлениями и новыми функциями.
[**🎁 Поддержать нас**]({{{supportUrl}}})
chatwoot.to.whatsapp.message.text: |-
{{{ content }}}
chatwoot.to.whatsapp.message.media.caption: |-
{{#singleAttachment}}
{{#content}}
{{{ content }}}
{{/content}}
{{/singleAttachment}}
whatsapp.to.chatwoot.message: |-
{{{payload.body}}}
whatsapp.to.chatwoot.message.contacts: |-
👤 **Переданные контакты**
{{#contacts}}
🪪 Имя: **{{fullName}}**
{{#phoneNumbers}}
- 📞 Телефон: **{{.}}**
{{/phoneNumbers}}
{{/contacts}}
whatsapp.to.chatwoot.message.location: |-
{{#message}}
{{#locationMessage}}
📍 **Переданное местоположение**
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **Адрес:** {{address}}
{{/address}}
{{#url}}
🌐 **Сайт:** {{url}}
{{/url}}
🔗 **Открыть на карте:** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/locationMessage}}
{{#liveLocationMessage}}
📍📡 **Делится геопозицией в реальном времени**
Откройте **WhatsApp**, чтобы увидеть обновления в реальном времени.
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **Адрес:** {{address}}
{{/address}}
{{#url}}
🌐 **Сайт:** {{url}}
{{/url}}
🔗 **Открыть на карте:** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/liveLocationMessage}}
{{/message}}
whatsapp.to.chatwoot.message.poll: |-
{{#poll}}
📊 **Опрос**
**{{name}}**
{{#options}}
- {{optionName}}
{{/options}}
{{/poll}}
whatsapp.to.chatwoot.message.event: |-
{{#message}}
{{#eventMessage}}
📅 **Событие**
**{{name}}**
{{#description}}
{{description}}
{{/description}}
{{#location.name}}
📍 **Место:** {{location.name}}
{{/location.name}}
{{#startTime}}
🕐 **Начало:** {{startTime}}
{{/startTime}}
{{#endTime}}
🕐 **Окончание:** {{endTime}}
{{/endTime}}
{{#joinLink}}
🔗 **Ссылка для участия:** [{{joinLink}}]({{joinLink}})
{{/joinLink}}
{{/eventMessage}}
{{/message}}
whatsapp.to.chatwoot.message.pix: |-
💳 **PIX - Копировать и вставить**
{{#pixData}}
{{#merchantName}}
**{{merchantName}}**
{{/merchantName}}
{{#key}}
**Ключ PIX:** {{key}}
{{/key}}
{{#keyType}}
**Тип:** {{keyType}}
{{/keyType}}
{{#totalAmount}}
**Сумма:** {{totalAmountFormatted}}
{{/totalAmount}}
{{#referenceId}}
**Референс:** {{referenceId}}
{{/referenceId}}
💳 **PIX Копировать и вставить отправлен**
{{/pixData}}
whatsapp.to.chatwoot.message.unsupported: |-
⚠️ **Этот тип сообщения не поддерживается в ChatWoot.**
📱 Пожалуйста, откройте **WhatsApp**, чтобы просмотреть.
Подробности: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **РЕКЛАМА FACEBOOK**
**Заголовок:** {{{adData.title}}}
**Описание:**
{{{adData.body}}}
**Ссылка на объявление:** [Посмотреть в Facebook]({{{adData.sourceUrl}}})
**Идентификатор объявления:** {{{adData.sourceId}}}
---
💬 **Сообщение клиента:**
{{{payload.body}}}
+354
View File
@@ -0,0 +1,354 @@
# Turkish translations for ChatWoot integration
locale.name: '🇹🇷 Türkçe (Turkish)'
# Temel yerel kodu - geçerli bir BCP 47 yerel kodu olmalı
# https://en.wikipedia.org/wiki/IETF_language_tag
# WAHA bunu sayı, para birimi ve tarih/saat gösterimi için kullanır
locale.base: 'tr-TR'
app.inbox.contact.name: 'WhatsApp Entegrasyonu (WAHA)'
app.inbox.contact.avatar.url: 'https://raw.githubusercontent.com/devlikeapro/waha/core/logo.png'
# date.toLocaleString için "options"
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#options
datetime:
locales: tr-TR
day: 2-digit
month: 2-digit
year: numeric
hour: 2-digit
minute: 2-digit
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#timezonename
timeZoneName: shortGeneric
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
# timeZone: 'Europe/Istanbul'
job.report.error: |-
⚠️ **{{{header}}}**
{{#attempts.nextDelay}}
🔄 {{attempts.nextDelay}} saniye içinde tekrar deneniyor...
{{/attempts.nextDelay}}
{{^attempts.nextDelay}}
❌ Başka deneme hakkı kalmadı. Lütfen daha sonra tekrar deneyin.
{{/attempts.nextDelay}}
Deneme: {{{attempts.current}}} / {{{attempts.max}}}
Detaylar: [{{{details.text}}}]({{{details.url}}})
{{#error}}
```
{{{error}}}
```
{{/error}}
job.report.succeeded: |-
✅ **Başarılı**
Deneme: {{{attempts.current}}} / {{{attempts.max}}}
Detaylar: [{{{details.text}}}]({{{details.url}}})
whatsapp.message.sending.error: WhatsApp'ta mesaj gönderilemedi.
whatsapp.message.receiving.error: WhatsApp'tan mesaj alınamadı
whatsapp.message.removing.error: WhatsApp'tan mesaj kaldırılamadı
job.scheduled.error.header: Zamanlanmış görev yürütülemedi
message.from.whatsapp: |-
{{{text}}}
📱 *WhatsApp'tan gönderildi*
message.from.api: |-
{{{text}}}
📱 *API aracılığıyla gönderildi*
message.removed.in.whatsapp: |-
❌ *Bu mesaj WhatsApp'ta silindi*
message.edited.in.whatsapp: |-
{{{text}}}
✏️ *WhatsApp'ta düzenlendi*
whatsapp.group.message: |-
👥 *{{{participant}}}*
{{{text}}}
whatsapp.reaction.added: |-
*Tepki verdi* {{{emoji}}}
whatsapp.reaction.removed: |-
*Tepki kaldırıldı*
whatsapp.contact.group.suffix: 'Grup'
whatsapp.contact.channel.suffix: 'Kanal'
whatsapp.contact.broadcast.suffix: 'Yayın Listesi'
# Aka Stories
whatsapp.contact.status.name: 'Durum'
app.connected.message: |-
🔗 **BAĞLANDI: WhatsApp Oturumu ChatWoot Gelen Kutusuna**
✅ WhatsApp oturumu **{{{name}}}** bu ChatWoot Gelen Kutusuna başarıyla bağlandı.
Bu gelen kutusu artık **WhatsApp Hesabınıza** bağlı. Mesajları doğrudan buradan gönderip alabilirsiniz — tıpkı WhatsApp kullanır gibi, ancak ChatWoot içinde.
Ayrıca bu gelen kutusuna bağlı WhatsApp oturumunu da yönetebilirsiniz. Kullanılabilir eylemleri görmek için, bu sohbete **help** gönderin.
📋 Yapabileceğiniz yaygın eylemler:
- WhatsApp oturumunun aktif olup olmadığını kontrol etme
- WhatsApp oturumunu yeniden başlatma veya durdurma
- Çıkış yapma ve yeni bir QR kod tarayarak yeniden bağlanma
Her şey çalışıyorsa, özgürce sohbet edebileceksiniz. Uyarılar görürseniz, WhatsApp hesabınızı yeniden bağlamanız gerekebilir.
Hadi başlayalım! 🚀
app.disconnected.message: |-
🔌 **BAĞLANTI KESİLDİ: WhatsApp Oturumu ChatWoot Gelen Kutusundan**
❌ WhatsApp oturumu **{{{name}}}** bu ChatWoot Gelen Kutusundan bağlantısı kesildi.
Artık WhatsApp'tan mesaj gönderemez veya alamazsınız.
Yeniden bağlanmak için, lütfen yöneticinizle iletişime geçin.
app.updated.message: |-
🔄 **GÜNCELLENDİ: WhatsApp Oturum Ayarları**
✅ WhatsApp oturumu **{{{name}}}** için ayarlar güncellendi.
app.commands.list: |-
Aşağıdaki komutlardan birini göndererek **WhatsApp Entegrasyonu**nu yönetebilirsiniz:
🖥️ **Oturum**:
1. **status** - mevcut oturum durumunu alın.
2. **restart** - oturumu yeniden başlatın - bu, WhatsApp hesabınızı yeniden bağlamaya çalışacaktır.
3. **start** - oturumu başlatın.
4. **stop** - oturumu durdurun.
5. **logout** - oturumdan çıkış yapın, böylece QR kodu tarayabilir ve oturumu onarabilirsiniz.
6. **qr** - oturum için QR kodu alın.
7. **screenshot** - oturumun ekran görüntüsünü alın (yalnızca **WEBJS** motorunda kullanılabilir).
8. **help** - kullanılabilir komutlar.
{{#commands.server}}
⚙️ Sunucu:
- **server status** - sunucu sürümü ve durum bilgilerini alın.
- **server reboot** - sunucuyu nazikçe yeniden başlatın.
- **server reboot force** - sunucuyu zorla yeniden başlatın.
{{/commands.server}}
Bu konuşmaya bir **komut** (büyük/küçük harf duyarsız) veya **komut numarası** gönderin.
app.commands.server.disabled: ⛔ **Sunucu komutları devre dışı**.
Lütfen yöneticinizle iletişime geçin.
Kullanılabilir komutların listesini almak için **help** gönderin.
app.help.reminder: |-
Kullanılabilir komutların listesini almak için **help** gönderin.
app.session.status.change: |-
{{{emoji}}} "{{{session}}}" oturumu {{{status}}} durumuna geçti
app.session.current.status: |-
{{{emoji}}} **{{{session}}}** oturum durumu **{{{status}}}** içinde
**WhatsApp Hesabı:**
📱 **{{{name}}} ({{{id}}})**
app.session.status.working: |-
✅ Bu ChatWoot Gelen Kutusu **WhatsApp Hesabına** bağlı ve mesaj gönderip almaya hazır!
📱 **{{{name}}} ({{{id}}})**
app.session.status.error: |-
⚠️ **Bu ChatWoot Gelen Kutusu WhatsApp Hesabına bağlı ancak mesaj gönderip almaya hazır DEĞİL!**
Lütfen oturum durumunu kontrol edin ve yeniden başlatmayı deneyin veya çıkış yapın ve QR kodu tekrar tarayın.
app.session.scan.qr.code: |-
⚠️ **WhatsApp Hesabını bu ChatWoot Gelen Kutusuna bağlamak için telefonunuzda QR kodu tarayın!**
app.server.version.and.status: |-
**Sürüm:**
```
{{{version}}}
```
**Durum:**
```
{{{status}}}
```
app.server.reboot: |-
Sunucu nazikçe yeniden başlatılıyor...
app.server.reboot.force: |-
Sunucu zorla yeniden başlatılıyor...
app.logout.success: |-
✅ Hesap başarıyla yetkilendirilmedi!
waha.new.version.available: |-
🔄 **Yeni Sürüm Mevcut!**
Mevcut sürüm: **{{{currentVersion}}}**
Yeni sürüm: **{{{newVersion}}}**
👉 [**🆕 Değişiklik Günlüğü**]({{{changelogUrl}}}) içinde yenilikleri kontrol edin
waha.core.version.used: |-
❤️ **WAHA'yı Destekleyin!**
Ücretsiz **WAHA Core** sürümünü kullanıyorsunuz. Bu projeyi faydalı buluyorsanız, lütfen geliştirilmesini desteklemeyi düşünün.
Desteğiniz, güncellemeler, düzeltmeler ve yeni özellikler üzerinde çalışmaya devam edebilmemizin tek yoludur.
[**🎁 Bizi Destekleyin**]({{{supportUrl}}})
chatwoot.to.whatsapp.message.text: |-
{{{ content }}}
chatwoot.to.whatsapp.message.media.caption: |-
{{#singleAttachment}}
{{#content}}
{{{ content }}}
{{/content}}
{{/singleAttachment}}
whatsapp.to.chatwoot.message: |-
{{{payload.body}}}
whatsapp.to.chatwoot.message.contacts: |-
👤 **Paylaşılan Kişi(ler)**
{{#contacts}}
🪪 İsim: **{{fullName}}**
{{#phoneNumbers}}
- 📞 Telefon: **{{.}}**
{{/phoneNumbers}}
{{/contacts}}
whatsapp.to.chatwoot.message.location: |-
{{#message}}
{{#locationMessage}}
📍 **Paylaşılan Konum**
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **Adres:** {{address}}
{{/address}}
{{#url}}
🌐 **Web sitesi:** {{url}}
{{/url}}
🔗 **Haritada görüntüle:** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/locationMessage}}
{{#liveLocationMessage}}
📍📡 **Canlı Konum Paylaşılıyor**
Gerçek zamanlı güncellemeleri görmek için **WhatsApp’ı** açın.
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **Adres:** {{address}}
{{/address}}
{{#url}}
🌐 **Web sitesi:** {{url}}
{{/url}}
🔗 **Haritada görüntüle:** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/liveLocationMessage}}
{{/message}}
whatsapp.to.chatwoot.message.poll: |-
{{#poll}}
📊 **Anket**
**{{name}}**
{{#options}}
- {{optionName}}
{{/options}}
{{/poll}}
whatsapp.to.chatwoot.message.event: |-
{{#message}}
{{#eventMessage}}
📅 **Etkinlik**
**{{name}}**
{{#description}}
{{description}}
{{/description}}
{{#location.name}}
📍 **Konum:** {{location.name}}
{{/location.name}}
{{#startTime}}
🕐 **Başlangıç:** {{startTime}}
{{/startTime}}
{{#endTime}}
🕐 **Bitiş:** {{endTime}}
{{/endTime}}
{{#joinLink}}
🔗 **Katılma bağlantısı:** [{{joinLink}}]({{joinLink}})
{{/joinLink}}
{{/eventMessage}}
{{/message}}
whatsapp.to.chatwoot.message.pix: |-
💳 **PIX - Kopyala ve Yapıştır**
{{#pixData}}
{{#merchantName}}
**{{merchantName}}**
{{/merchantName}}
{{#key}}
**PIX Anahtarı:** {{key}}
{{/key}}
{{#keyType}}
**Tür:** {{keyType}}
{{/keyType}}
{{#totalAmount}}
**Tutar:** {{totalAmountFormatted}}
{{/totalAmount}}
{{#referenceId}}
**Referans:** {{referenceId}}
{{/referenceId}}
💳 **PIX Kopyala ve Yapıştır gönderildi**
{{/pixData}}
whatsapp.to.chatwoot.message.unsupported: |-
⚠️ **Bu mesaj türü ChatWoot’ta desteklenmiyor.**
📱 Görüntülemek için lütfen **WhatsApp’ı** açın.
Ayrıntılar: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **FACEBOOK İLANI**
**Başlık:** {{{adData.title}}}
**Açıklama:**
{{{adData.body}}}
**İlan Bağlantısı:** [Facebook’ta Görüntüle]({{{adData.sourceUrl}}})
**İlan Kimliği:** {{{adData.sourceId}}}
---
💬 **Müşteri Mesajı:**
{{{payload.body}}}
@@ -1,7 +1,29 @@
# Ukrainian translations for ChatWoot integration
APP_INBOX_CONTACT_NAME: 'Інтеграція WhatsApp (WAHA)'
locale.name: '🇺🇦 Українська (Ukrainian)'
JOB_ERROR_REPORT: |
# Базовий код локалі - має бути чинною локаллю BCP 47
# https://en.wikipedia.org/wiki/IETF_language_tag
# WAHA використовує його для форматування чисел, валют і дати/часу
locale.base: 'uk-UA'
app.inbox.contact.name: 'Інтеграція WhatsApp (WAHA)'
app.inbox.contact.avatar.url: 'https://raw.githubusercontent.com/devlikeapro/waha/core/logo.png'
# "параметри" з date.toLocaleString
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#options
datetime:
locales: uk-UA
day: 2-digit
month: 2-digit
year: numeric
hour: 2-digit
minute: 2-digit
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#timezonename
timeZoneName: shortGeneric
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
# timeZone: 'Europe/Kyiv'
job.report.error: |-
⚠️ **{{{header}}}**
{{#attempts.nextDelay}}
🔄 Повторна спроба через {{attempts.nextDelay}} секунд...
@@ -18,51 +40,52 @@ JOB_ERROR_REPORT: |
```
{{/error}}
JOB_SUCCEEDED_REPORT: |
job.report.succeeded: |-
✅ **Успішно**
Спроба: {{{attempts.current}}} / {{{attempts.max}}}
Деталі: [{{{details.text}}}]({{{details.url}}})
WHATSAPP_ERROR_SENDING_MESSAGE: Не вдалося надіслати повідомлення у WhatsApp.
WHATSAPP_ERROR_RECEIVING_MESSAGE: Не вдалося отримати повідомлення з WhatsApp
WHATSAPP_ERROR_REMOVING_MESSAGE: Не вдалося видалити повідомлення з WhatsApp
APP_SCHEDULED_JOB_ERROR: Заплановане завдання не вдалося виконати
whatsapp.message.sending.error: Не вдалося надіслати повідомлення у WhatsApp.
whatsapp.message.receiving.error: Не вдалося отримати повідомлення з WhatsApp
whatsapp.message.removing.error: Не вдалося видалити повідомлення з WhatsApp
job.scheduled.error.header: Заплановане завдання не вдалося виконати
MESSAGE_FROM_WHATSAPP: |
message.from.whatsapp: |-
{{{text}}}
📱 *Надіслано з WhatsApp*
MESSAGE_FROM_API: |
message.from.api: |-
{{{text}}}
📱 *Надіслано через API*
MESSAGE_REMOVED_IN_WHATSAPP: |
message.removed.in.whatsapp: |-
❌ *Це повідомлення було видалено у WhatsApp*
MESSAGE_EDITED_IN_WHATSAPP: |
message.edited.in.whatsapp: |-
{{{text}}}
✏️ *Відредаговано у WhatsApp*
WHATSAPP_GROUP_MESSAGE: |
{{{text}}}
whatsapp.group.message: |-
👥 *{{{participant}}}*
WHATSAPP_REACTION_ADDED: |
{{{text}}}
whatsapp.reaction.added: |-
*Реакція* {{{emoji}}}
WHATSAPP_REACTION_REMOVED: |
whatsapp.reaction.removed: |-
*Реакцію видалено*
WHATSAPP_CONTACT_GROUP_SUFFIX: 'Група'
WHATSAPP_CONTACT_CHANNEL_SUFFIX: 'Канал'
whatsapp.contact.group.suffix: 'Група'
whatsapp.contact.channel.suffix: 'Канал'
whatsapp.contact.broadcast.suffix: 'Список розсилки'
# Aka Stories
WHATSAPP_CONTACT_STATUS_NAME: 'Статус'
whatsapp.contact.status.name: 'Статус'
APP_CONNECTED_MESSAGE: |
app.connected.message: |-
🔗 **ПІДКЛЮЧЕНО: Сесія WhatsApp до Вхідних ChatWoot**
✅ Сесія WhatsApp **{{{name}}}** була успішно підключена до цих Вхідних ChatWoot.
@@ -80,7 +103,7 @@ APP_CONNECTED_MESSAGE: |
Давайте почнемо! 🚀
APP_DISCONNECTED_MESSAGE: |
app.disconnected.message: |-
🔌 **ВІДКЛЮЧЕНО: Сесія WhatsApp від Вхідних ChatWoot**
❌ Сесія WhatsApp **{{{name}}}** була відключена від цих Вхідних ChatWoot.
@@ -89,15 +112,15 @@ APP_DISCONNECTED_MESSAGE: |
Щоб повторно підключитися, зверніться до свого адміністратора.
APP_UPDATED_MESSAGE: |
app.updated.message: |-
🔄 **ОНОВЛЕНО: Налаштування сесії WhatsApp**
✅ Налаштування для сесії WhatsApp **{{{name}}}** були оновлені.
APP_COMMANDS_LIST: |
app.commands.list: |-
Ви можете керувати **Інтеграцією WhatsApp**, надіславши одну з наступних команд:
🖥️ Сесії:
🖥️ **Сесія**:
1. **status** - отримати поточний статус сесії.
2. **restart** - перезапустити сесію - це спробує повторно підключити ваш обліковий запис WhatsApp.
3. **start** - запустити сесію.
@@ -107,42 +130,47 @@ APP_COMMANDS_LIST: |
7. **screenshot** - отримати знімок екрану сесії (доступно лише в двигуні **WEBJS**).
8. **help** - доступні команди.
{{#commands.server}}
⚙️ Сервер:
- **server status** - отримати інформацію про версію та статус сервера.
- **server reboot** - перезавантажити сервер плавно.
- **server reboot force** - примусово перезавантажити сервер.
{{/commands.server}}
Надішліть **команду** (без урахування регістру) або **номер команди** у цю розмову.
APP_HELP_REMINDER: |
app.commands.server.disabled: ⛔ **Команди сервера вимкнені**.
Будь ласка, зв’яжіться з вашим адміністратором.
Надішліть **help**, щоб отримати список доступних команд.
APP_SESSION_STATUS_CHANGE: |
app.help.reminder: |-
Надішліть **help**, щоб отримати список доступних команд.
app.session.status.change: |-
{{{emoji}}} Сесія "{{{session}}}" перейшла у статус {{{status}}}
APP_SESSION_CURRENT_STATUS: |
app.session.current.status: |-
{{{emoji}}} Статус сесії **{{{session}}}** - **{{{status}}}**
**Обліковий запис WhatsApp:**
📱 **{{{name}}} ({{{id}}})**
APP_DASHBOARD_LINK: |
Відвідайте [Панель керування WAHA]({{{url}}}) для отримання додаткової інформації.
APP_SESSION_STATUS_WORKING: |
app.session.status.working: |-
✅ Ці Вхідні ChatWoot пов'язані з **Обліковим записом WhatsApp** і готові надсилати та отримувати повідомлення!
📱 **{{{name}}} ({{{id}}})**
APP_SESSION_STATUS_ERROR: |
app.session.status.error: |-
⚠️ **Ці Вхідні ChatWoot пов'язані з Обліковим записом WhatsApp, але НЕ готові надсилати та отримувати повідомлення!**
Будь ласка, перевірте статус сесії та спробуйте перезапустити її або вийдіть і відскануйте QR-код знову.
APP_SESSION_SCAN_QR_CODE: |
app.session.scan.qr.code: |-
⚠️ **Відскануйте QR-код на вашому телефоні, щоб пов'язати Обліковий запис WhatsApp з цими Вхідними ChatWoot!**
APP_SERVER_VERSION_AND_STATUS: |
app.server.version.and.status: |-
**Версія:**
```
{{{version}}}
@@ -153,16 +181,16 @@ APP_SERVER_VERSION_AND_STATUS: |
{{{status}}}
```
APP_SERVER_REBOOT: |
app.server.reboot: |-
Сервер плавно перезавантажується...
APP_SERVER_REBOOT_FORCE: |
app.server.reboot.force: |-
Сервер примусово перезавантажується...
APP_LOGOUT_SUCCESS: |
app.logout.success: |-
✅ Обліковий запис успішно деавторизовано!
APP_NEW_VERSION_AVAILABLE: |
waha.new.version.available: |-
🔄 **Доступна нова версія!**
Поточна версія: **{{{currentVersion}}}**
@@ -170,7 +198,7 @@ APP_NEW_VERSION_AVAILABLE: |
👉 Перевірте, що нового у [**🆕 Журналі змін**]({{{changelogUrl}}})
APP_CORE_VERSION_USED: |
waha.core.version.used: |-
❤️ **Підтримайте WAHA!**
Ви використовуєте безкоштовну версію **WAHA Core**. Якщо ви вважаєте цей проект корисним, будь ласка, розгляньте можливість підтримати його розробку.
@@ -178,3 +206,149 @@ APP_CORE_VERSION_USED: |
Ваша підтримка - єдиний спосіб, яким ми можемо продовжувати працювати над оновленнями, виправленнями та новими функціями.
[**🎁 Підтримайте нас**]({{{supportUrl}}})
chatwoot.to.whatsapp.message.text: |-
{{{ content }}}
chatwoot.to.whatsapp.message.media.caption: |-
{{#singleAttachment}}
{{#content}}
{{{ content }}}
{{/content}}
{{/singleAttachment}}
whatsapp.to.chatwoot.message: |-
{{{payload.body}}}
whatsapp.to.chatwoot.message.contacts: |-
👤 **Надісланий контакт(и)**
{{#contacts}}
🪪 Ім’я: **{{fullName}}**
{{#phoneNumbers}}
- 📞 Телефон: **{{.}}**
{{/phoneNumbers}}
{{/contacts}}
whatsapp.to.chatwoot.message.location: |-
{{#message}}
{{#locationMessage}}
📍 **Надіслана локація**
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **Адреса:** {{address}}
{{/address}}
{{#url}}
🌐 **Вебсайт:** {{url}}
{{/url}}
🔗 **Переглянути на карті:** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/locationMessage}}
{{#liveLocationMessage}}
📍📡 **Надсилання геолокації в реальному часі**
Відкрийте **WhatsApp**, щоб побачити оновлення в реальному часі.
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **Адреса:** {{address}}
{{/address}}
{{#url}}
🌐 **Вебсайт:** {{url}}
{{/url}}
🔗 **Переглянути на карті:** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/liveLocationMessage}}
{{/message}}
whatsapp.to.chatwoot.message.poll: |-
{{#poll}}
📊 **Опитування**
**{{name}}**
{{#options}}
- {{optionName}}
{{/options}}
{{/poll}}
whatsapp.to.chatwoot.message.event: |-
{{#message}}
{{#eventMessage}}
📅 **Подія**
**{{name}}**
{{#description}}
{{description}}
{{/description}}
{{#location.name}}
📍 **Місце:** {{location.name}}
{{/location.name}}
{{#startTime}}
🕐 **Початок:** {{startTime}}
{{/startTime}}
{{#endTime}}
🕐 **Завершення:** {{endTime}}
{{/endTime}}
{{#joinLink}}
🔗 **Посилання для приєднання:** [{{joinLink}}]({{joinLink}})
{{/joinLink}}
{{/eventMessage}}
{{/message}}
whatsapp.to.chatwoot.message.pix: |-
💳 **PIX - Копіювати та Вставити**
{{#pixData}}
{{#merchantName}}
**{{merchantName}}**
{{/merchantName}}
{{#key}}
**Ключ PIX:** {{key}}
{{/key}}
{{#keyType}}
**Тип:** {{keyType}}
{{/keyType}}
{{#totalAmount}}
**Сума:** {{totalAmountFormatted}}
{{/totalAmount}}
{{#referenceId}}
**Референс:** {{referenceId}}
{{/referenceId}}
💳 **PIX Копіювати та Вставити надіслано**
{{/pixData}}
whatsapp.to.chatwoot.message.unsupported: |-
⚠️ **Цей тип повідомлення не підтримується в ChatWoot.**
📱 Будь ласка, відкрийте **WhatsApp**, щоб переглянути.
Подробиці: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **РЕКЛАМА FACEBOOK**
**Заголовок:** {{{adData.title}}}
**Опис:**
{{{adData.body}}}
**Посилання на рекламу:** [Переглянути у Facebook]({{{adData.sourceUrl}}})
**Ідентифікатор реклами:** {{{adData.sourceId}}}
---
💬 **Повідомлення клієнта:**
{{{payload.body}}}
+354
View File
@@ -0,0 +1,354 @@
# Urdu translations for ChatWoot integration
locale.name: '🇵🇰 اردو (Urdu)'
# بنیادی لوکل کوڈ - یہ ایک معتبر BCP 47 لوکل ہونا چاہیے
# https://en.wikipedia.org/wiki/IETF_language_tag
# WAHA اسے نمبرز، کرنسی اور تاریخ/وقت کی نمائندگی کے لیے استعمال کرتا ہے۔
locale.base: 'ur-PK'
app.inbox.contact.name: 'واٹس ایپ انٹیگریشن (WAHA)'
app.inbox.contact.avatar.url: 'https://raw.githubusercontent.com/devlikeapro/waha/core/logo.png'
# date.toLocaleString کی "options"
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#options
datetime:
locales: ur-PK
day: 2-digit
month: 2-digit
year: numeric
hour: 2-digit
minute: 2-digit
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#timezonename
timeZoneName: shortGeneric
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
# timeZone: 'Asia/Karachi'
job.report.error: |-
⚠️ **{{{header}}}**
{{#attempts.nextDelay}}
🔄 {{attempts.nextDelay}} سیکنڈ میں دوبارہ کوشش کر رہا ہے...
{{/attempts.nextDelay}}
{{^attempts.nextDelay}}
❌ مزید کوششیں نہیں بچی ہیں۔ براہ کرم بعد میں دوبارہ کوشش کریں۔
{{/attempts.nextDelay}}
کوشش: {{{attempts.current}}} / {{{attempts.max}}}
تفصیلات: [{{{details.text}}}]({{{details.url}}})
{{#error}}
```
{{{error}}}
```
{{/error}}
job.report.succeeded: |-
✅ **کامیاب ہوا**
کوشش: {{{attempts.current}}} / {{{attempts.max}}}
تفصیلات: [{{{details.text}}}]({{{details.url}}})
whatsapp.message.sending.error: واٹس ایپ پر پیغام نہیں بھیج سکا۔
whatsapp.message.receiving.error: واٹس ایپ سے پیغام موصول نہیں کر سکا
whatsapp.message.removing.error: واٹس ایپ سے پیغام ہٹا نہیں سکا
job.scheduled.error.header: شیڈول کردہ کام انجام دینے میں ناکام رہا
message.from.whatsapp: |-
{{{text}}}
📱 *واٹس ایپ سے بھیجا گیا*
message.from.api: |-
{{{text}}}
📱 *API کے ذریعے بھیجا گیا*
message.removed.in.whatsapp: |-
❌ *یہ پیغام واٹس ایپ میں حذف کر دیا گیا تھا*
message.edited.in.whatsapp: |-
{{{text}}}
✏️ *واٹس ایپ میں ترمیم کی گئی*
whatsapp.group.message: |-
👥 *{{{participant}}}*
{{{text}}}
whatsapp.reaction.added: |-
*ردعمل دیا* {{{emoji}}}
whatsapp.reaction.removed: |-
*ردعمل ہٹا دیا گیا*
whatsapp.contact.group.suffix: 'گروپ'
whatsapp.contact.channel.suffix: 'چینل'
whatsapp.contact.broadcast.suffix: 'براڈکاسٹ فہرست'
# Aka Stories
whatsapp.contact.status.name: 'سٹیٹس'
app.connected.message: |-
🔗 **منسلک: واٹس ایپ سیشن ChatWoot انبکس سے**
✅ واٹس ایپ سیشن **{{{name}}}** کامیابی سے اس ChatWoot انبکس سے منسلک ہو گیا ہے۔
یہ انبکس اب آپ کے **واٹس ایپ اکاؤنٹ** سے منسلک ہے۔ آپ یہاں سے براہ راست پیغامات بھیج اور موصول کر سکتے ہیں — بالکل واٹس ایپ استعمال کرنے کی طرح، لیکن ChatWoot کے اندر۔
آپ اس انبکس سے منسلک واٹس ایپ سیشن کا انتظام بھی کر سکتے ہیں۔ دستیاب اقدامات دیکھنے کے لیے، اس چیٹ میں **help** بھیجیں۔
📋 عام اقدامات جو آپ کر سکتے ہیں:
- چیک کریں کہ آیا واٹس ایپ سیشن فعال ہے
- واٹس ایپ سیشن کو دوبارہ شروع کریں یا روکیں
- لاگ آؤٹ کریں اور نیا QR کوڈ اسکین کر کے دوبارہ منسلک ہوں
اگر سب کچھ کام کر رہا ہے، تو آپ آزادانہ طور پر چیٹ کر سکیں گے۔ اگر آپ کو انتباہات نظر آتے ہیں، تو آپ کو اپنے واٹس ایپ اکاؤنٹ کو دوبارہ منسلک کرنے کی ضرورت ہو سکتی ہے۔
آئیے شروع کریں! 🚀
app.disconnected.message: |-
🔌 **منقطع: واٹس ایپ سیشن ChatWoot انبکس سے**
❌ واٹس ایپ سیشن **{{{name}}}** اس ChatWoot انبکس سے منقطع ہو گیا ہے۔
آپ اب واٹس ایپ سے پیغامات بھیجنے یا موصول کرنے کے قابل نہیں ہوں گے۔
دوبارہ منسلک ہونے کے لیے، براہ کرم اپنے منتظم سے رابطہ کریں۔
app.updated.message: |-
🔄 **اپڈیٹ شدہ: واٹس ایپ سیشن کی ترتیبات**
✅ واٹس ایپ سیشن **{{{name}}}** کی ترتیبات اپڈیٹ کر دی گئی ہیں۔
app.commands.list: |-
آپ درج ذیل کمانڈز میں سے ایک بھیج کر **واٹس ایپ انٹیگریشن** کا انتظام کر سکتے ہیں:
🖥️ **سیشن**:
1. **status** - موجودہ سیشن کی حالت حاصل کریں۔
2. **restart** - سیشن کو دوبارہ شروع کریں - یہ آپ کے واٹس ایپ اکاؤنٹ کو دوبارہ منسلک کرنے کی کوشش کرے گا۔
3. **start** - سیشن شروع کریں۔
4. **stop** - سیشن روکیں۔
5. **logout** - سیشن سے لاگ آؤٹ کریں، تاکہ آپ QR کوڈ اسکین کر سکیں اور سیشن کی مرمت کر سکیں۔
6. **qr** - سیشن کے لیے QR کوڈ حاصل کریں۔
7. **screenshot** - سیشن کا اسکرین شاٹ حاصل کریں (صرف **WEBJS** انجن میں دستیاب)۔
8. **help** - دستیاب کمانڈز۔
{{#commands.server}}
⚙️ سرور:
- **server status** - سرور ورژن اور حالت کی معلومات حاصل کریں۔
- **server reboot** - سرور کو آرام سے دوبارہ شروع کریں۔
- **server reboot force** - سرور کو زبردستی دوبارہ شروع کریں۔
{{/commands.server}}
اس گفتگو میں **کمانڈ** (کیس سے غیر حساس) یا **کمانڈ نمبر** بھیجیں۔
app.commands.server.disabled: ⛔ **سرور کمانڈز غیر فعال ہیں**۔
براہ کرم اپنے منتظم سے رابطہ کریں۔
دستیاب کمانڈز کی فہرست حاصل کرنے کے لیے **help** بھیجیں۔
app.help.reminder: |-
دستیاب کمانڈز کی فہرست حاصل کرنے کے لیے **help** بھیجیں۔
app.session.status.change: |-
{{{emoji}}} "{{{session}}}" سیشن {{{status}}} حالت میں تبدیل ہو گیا
app.session.current.status: |-
{{{emoji}}} **{{{session}}}** سیشن کی حالت **{{{status}}}** میں ہے
**واٹس ایپ اکاؤنٹ:**
📱 **{{{name}}} ({{{id}}})**
app.session.status.working: |-
✅ یہ ChatWoot انبکس **واٹس ایپ اکاؤنٹ** سے منسلک ہے اور پیغامات بھیجنے اور موصول کرنے کے لیے تیار ہے!
📱 **{{{name}}} ({{{id}}})**
app.session.status.error: |-
⚠️ **یہ ChatWoot انبکس واٹس ایپ اکاؤنٹ سے منسلک ہے لیکن پیغامات بھیجنے اور موصول کرنے کے لیے تیار نہیں ہے!**
براہ کرم سیشن کی حالت چیک کریں اور اسے دوبارہ شروع کرنے کی کوشش کریں یا لاگ آؤٹ کریں اور QR کوڈ دوبارہ اسکین کریں۔
app.session.scan.qr.code: |-
⚠️ **اس ChatWoot انبکس کے ساتھ واٹس ایپ اکاؤنٹ کو منسلک کرنے کے لیے اپنے فون پر QR کوڈ اسکین کریں!**
app.server.version.and.status: |-
**ورژن:**
```
{{{version}}}
```
**حالت:**
```
{{{status}}}
```
app.server.reboot: |-
سرور آرام سے دوبارہ شروع ہو رہا ہے...
app.server.reboot.force: |-
سرور زبردستی دوبارہ شروع ہو رہا ہے...
app.logout.success: |-
✅ اکاؤنٹ کامیابی سے غیر مجاز ہو گیا!
waha.new.version.available: |-
🔄 **نیا ورژن دستیاب ہے!**
موجودہ ورژن: **{{{currentVersion}}}**
نیا ورژن: **{{{newVersion}}}**
👉 [**🆕 تبدیلیوں کی فہرست**]({{{changelogUrl}}}) میں نیا کیا ہے دیکھیں
waha.core.version.used: |-
❤️ **WAHA کی حمایت کریں!**
آپ مفت **WAHA Core** ورژن استعمال کر رہے ہیں۔ اگر آپ کو یہ پروجیکٹ مفید لگتا ہے، تو براہ کرم اس کی ترقی کی حمایت کرنے پر غور کریں۔
آپ کی حمایت ہی وہ واحد طریقہ ہے جس سے ہم اپڈیٹس، فکسز، اور نئی خصوصیات پر کام جاری رکھ سکتے ہیں۔
[**🎁 ہماری حمایت کریں**]({{{supportUrl}}})
chatwoot.to.whatsapp.message.text: |-
{{{ content }}}
chatwoot.to.whatsapp.message.media.caption: |-
{{#singleAttachment}}
{{#content}}
{{{ content }}}
{{/content}}
{{/singleAttachment}}
whatsapp.to.chatwoot.message: |-
{{{payload.body}}}
whatsapp.to.chatwoot.message.contacts: |-
👤 **شیئر کیے گئے رابطہ(رابطے)**
{{#contacts}}
🪪 نام: **{{fullName}}**
{{#phoneNumbers}}
- 📞 فون: **{{.}}**
{{/phoneNumbers}}
{{/contacts}}
whatsapp.to.chatwoot.message.location: |-
{{#message}}
{{#locationMessage}}
📍 **شیئر کی گئی لوکیشن**
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **پتہ:** {{address}}
{{/address}}
{{#url}}
🌐 **ویب سائٹ:** {{url}}
{{/url}}
🔗 **نقشے پر دیکھیں:** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/locationMessage}}
{{#liveLocationMessage}}
📍📡 **لائیو لوکیشن شیئر کی جا رہی ہے**
حقیقی وقت کی تازہ کاریوں کے لیے **WhatsApp** کھولیں۔
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **پتہ:** {{address}}
{{/address}}
{{#url}}
🌐 **ویب سائٹ:** {{url}}
{{/url}}
🔗 **نقشے پر دیکھیں:** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/liveLocationMessage}}
{{/message}}
whatsapp.to.chatwoot.message.poll: |-
{{#poll}}
📊 **رائے شماری**
**{{name}}**
{{#options}}
- {{optionName}}
{{/options}}
{{/poll}}
whatsapp.to.chatwoot.message.event: |-
{{#message}}
{{#eventMessage}}
📅 **ایونٹ**
**{{name}}**
{{#description}}
{{description}}
{{/description}}
{{#location.name}}
📍 **مقام:** {{location.name}}
{{/location.name}}
{{#startTime}}
🕐 **آغاز:** {{startTime}}
{{/startTime}}
{{#endTime}}
🕐 **اختتام:** {{endTime}}
{{/endTime}}
{{#joinLink}}
🔗 **شمولیت کا لنک:** [{{joinLink}}]({{joinLink}})
{{/joinLink}}
{{/eventMessage}}
{{/message}}
whatsapp.to.chatwoot.message.pix: |-
💳 **PIX - کاپی اور پیسٹ**
{{#pixData}}
{{#merchantName}}
**{{merchantName}}**
{{/merchantName}}
{{#key}}
**PIX کلید:** {{key}}
{{/key}}
{{#keyType}}
**قسم:** {{keyType}}
{{/keyType}}
{{#totalAmount}}
**رقم:** {{totalAmountFormatted}}
{{/totalAmount}}
{{#referenceId}}
**حوالہ:** {{referenceId}}
{{/referenceId}}
💳 **PIX کاپی اور پیسٹ بھیج دیا گیا**
{{/pixData}}
whatsapp.to.chatwoot.message.unsupported: |-
⚠️ **ChatWoot میں اس قسم کا پیغام معاونت یافتہ نہیں ہے۔**
📱 اسے دیکھنے کے لیے براہ کرم **WhatsApp** کھولیں۔
تفصیلات: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **فیس بک اشتہار**
**عنوان:** {{{adData.title}}}
**تفصیل:**
{{{adData.body}}}
**اشتہار کا لنک:** [فیس بک پر دیکھیں]({{{adData.sourceUrl}}})
**اشتہار کا شناختی نمبر:** {{{adData.sourceId}}}
---
💬 **گاہک کا پیغام:**
{{{payload.body}}}
+356
View File
@@ -0,0 +1,356 @@
# Simplified Chinese translations for ChatWoot integration
locale.name: '🇨🇳 中文(Simplified Chinese)'
# 基础语言代码 - 必须是有效的 BCP 47 语言区域
# https://en.wikipedia.org/wiki/IETF_language_tag
# WAHA 使用它来格式化数字、货币和日期时间。
locale.base: 'zh-CN'
app.inbox.contact.name: 'WhatsApp 集成(WAHA)'
app.inbox.contact.avatar.url: 'https://raw.githubusercontent.com/devlikeapro/waha/core/logo.png'
# date.toLocaleString 的 "options"
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#options
datetime:
locales: zh-CN
day: 2-digit
month: 2-digit
year: numeric
hour: 2-digit
minute: 2-digit
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#timezonename
timeZoneName: shortGeneric
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
# timeZone: 'Asia/Shanghai'
job.report.error: |-
⚠️ **{{{header}}}**
{{#attempts.nextDelay}}
🔄 将在 {{attempts.nextDelay}} 秒后重试...
{{/attempts.nextDelay}}
{{^attempts.nextDelay}}
❌ 没有更多重试机会。请稍后再试。
{{/attempts.nextDelay}}
尝试:{{{attempts.current}}} / {{{attempts.max}}}
详情:[{{{details.text}}}]({{{details.url}}})
{{#error}}
```
{{{error}}}
```
{{/error}}
job.report.succeeded: |-
✅ **成功**
尝试:{{{attempts.current}}} / {{{attempts.max}}}
详情:[{{{details.text}}}]({{{details.url}}})
whatsapp.message.sending.error: 无法在 WhatsApp 中发送消息。
whatsapp.message.receiving.error: 无法接收来自 WhatsApp 的消息
whatsapp.message.removing.error: 无法从 WhatsApp 中删除消息
job.scheduled.error.header: 计划任务执行失败
message.from.whatsapp: |-
{{{text}}}
📱 *通过 WhatsApp 发送*
message.from.api: |-
{{{text}}}
📱 *通过 API 发送*
message.removed.in.whatsapp: |-
❌ *此消息已在 WhatsApp 中被删除*
message.edited.in.whatsapp: |-
{{{text}}}
✏️ *已在 WhatsApp 中编辑*
whatsapp.group.message: |-
👥 *{{{participant}}}*
{{{text}}}
whatsapp.reaction.added: |-
*已反应* {{{emoji}}}
whatsapp.reaction.removed: |-
*已移除反应*
whatsapp.contact.group.suffix: '群组'
whatsapp.contact.channel.suffix: '频道'
whatsapp.contact.broadcast.suffix: '广播列表'
# Aka Stories
whatsapp.contact.status.name: '状态'
app.connected.message: |-
🔗 **已连接:WhatsApp 会话到 ChatWoot 收件箱**
✅ WhatsApp 会话 **{{{name}}}** 已成功连接到此 ChatWoot 收件箱。
此收件箱现已链接到你的**WhatsApp 账号**。你可以在这里直接收发消息——就像使用 WhatsApp 一样,但在 ChatWoot 内完成。
你也可以管理与此收件箱关联的 WhatsApp 会话。要查看可用操作,请向此对话发送 **help**。
📋 你可以执行的常见操作:
- 检查 WhatsApp 会话是否活动
- 重启或停止 WhatsApp 会话
- 登出并通过扫描新的二维码重新连接
如果一切正常,你就可以自由聊天。如果你看到警告,可能需要重新连接你的 WhatsApp 账号。
开始吧!🚀
app.disconnected.message: |-
🔌 **已断开:从 ChatWoot 收件箱断开 WhatsApp 会话**
❌ WhatsApp 会话 **{{{name}}}** 已与此 ChatWoot 收件箱断开。
你将无法再从 WhatsApp 发送或接收消息。
如需重新连接,请联系你的管理员。
app.updated.message: |-
🔄 **已更新:WhatsApp 会话设置**
✅ WhatsApp 会话 **{{{name}}}** 的设置已更新。
app.commands.list: |-
你可以通过发送以下命令来管理**WhatsApp 集成**:
🖥️ **会话**:
1. **status** - 获取当前会话状态。
2. **restart** - 重启会话——将尝试重新连接你的 WhatsApp 账号。
3. **start** - 启动会话。
4. **stop** - 停止会话。
5. **logout** - 登出会话,以便你可以扫描二维码并修复会话。
6. **qr** - 获取该会话的二维码。
7. **screenshot** - 获取会话截图(仅在 **WEBJS** 引擎中可用)。
8. **help** - 查看可用命令。
{{#commands.server}}
{{#commands.server}}
⚙️ 服务器:
- **server status** - 获取服务器版本和状态信息。
- **server reboot** - 优雅地重启服务器。
- **server reboot force** - 强制重启服务器。
{{/commands.server}}
{{/commands.server}}
向此对话发送**命令**(不区分大小写)或**命令编号**。
app.commands.server.disabled: ⛔ **服务器命令已禁用**。
请联系你的管理员。
发送 **help** 获取可用命令列表。
app.help.reminder: |-
发送 **help** 获取可用命令列表。
app.session.status.change: |-
{{{emoji}}} "{{{session}}}" 会话已切换为 {{{status}}} 状态
app.session.current.status: |-
{{{emoji}}} **{{{session}}}** 会话状态为 **{{{status}}}**
**WhatsApp 账号:**
📱 **{{{name}}} ({{{id}}})**
app.session.status.working: |-
✅ 此 ChatWoot 收件箱已链接到**WhatsApp 账号**,可以正常收发消息!
📱 **{{{name}}} ({{{id}}})**
app.session.status.error: |-
⚠️ **此 ChatWoot 收件箱已链接到 WhatsApp 账号,但尚未准备好收发消息!**
请检查会话状态,尝试重启,或登出后重新扫描二维码。
app.session.scan.qr.code: |-
⚠️ **请在手机上扫描二维码,将 WhatsApp 账号与此 ChatWoot 收件箱关联!**
app.server.version.and.status: |-
**版本:**
```
{{{version}}}
```
**状态:**
```
{{{status}}}
```
app.server.reboot: |-
服务器正在优雅重启...
app.server.reboot.force: |-
服务器正在强制重启...
app.logout.success: |-
✅ 账号已成功取消授权!
waha.new.version.available: |-
🔄 **有新版本可用!**
当前版本:**{{{currentVersion}}}**
新版本:**{{{newVersion}}}**
👉 查看[**🆕 更新日志**]({{{changelogUrl}}})
waha.core.version.used: |-
❤️ **支持 WAHA!**
你正在使用免费的 **WAHA Core** 版本。如果你觉得该项目有帮助,请考虑支持其开发。
你的支持是我们持续进行更新、修复和新增功能的唯一动力。
[**🎁 支持我们**]({{{supportUrl}}})
chatwoot.to.whatsapp.message.text: |-
{{{ content }}}
chatwoot.to.whatsapp.message.media.caption: |-
{{#singleAttachment}}
{{#content}}
{{{ content }}}
{{/content}}
{{/singleAttachment}}
whatsapp.to.chatwoot.message: |-
{{{payload.body}}}
whatsapp.to.chatwoot.message.contacts: |-
👤 **共享联系人**
{{#contacts}}
🪪 姓名: **{{fullName}}**
{{#phoneNumbers}}
- 📞 电话: **{{.}}**
{{/phoneNumbers}}
{{/contacts}}
whatsapp.to.chatwoot.message.location: |-
{{#message}}
{{#locationMessage}}
📍 **共享位置**
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **地址:** {{address}}
{{/address}}
{{#url}}
🌐 **网站:** {{url}}
{{/url}}
🔗 **在地图上查看:** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/locationMessage}}
{{#liveLocationMessage}}
📍📡 **正在共享实时位置**
打开 **WhatsApp** 查看实时更新。
{{#name}}
**{{name}}**
{{/name}}
{{#address}}
📍 **地址:** {{address}}
{{/address}}
{{#url}}
🌐 **网站:** {{url}}
{{/url}}
🔗 **在地图上查看:** https://www.google.com/maps?q={{degreesLatitude}},{{degreesLongitude}}
{{#caption}}{{caption}}{{/caption}}
{{/liveLocationMessage}}
{{/message}}
whatsapp.to.chatwoot.message.poll: |-
{{#poll}}
📊 **投票**
**{{name}}**
{{#options}}
- {{optionName}}
{{/options}}
{{/poll}}
whatsapp.to.chatwoot.message.event: |-
{{#message}}
{{#eventMessage}}
📅 **活动**
**{{name}}**
{{#description}}
{{description}}
{{/description}}
{{#location.name}}
📍 **地点:** {{location.name}}
{{/location.name}}
{{#startTime}}
🕐 **开始时间:** {{startTime}}
{{/startTime}}
{{#endTime}}
🕐 **结束时间:** {{endTime}}
{{/endTime}}
{{#joinLink}}
🔗 **加入链接:** [{{joinLink}}]({{joinLink}})
{{/joinLink}}
{{/eventMessage}}
{{/message}}
whatsapp.to.chatwoot.message.pix: |-
💳 **PIX - 复制粘贴**
{{#pixData}}
{{#merchantName}}
**{{merchantName}}**
{{/merchantName}}
{{#key}}
**PIX 密钥:** {{key}}
{{/key}}
{{#keyType}}
**类型:** {{keyType}}
{{/keyType}}
{{#totalAmount}}
**金额:** {{totalAmountFormatted}}
{{/totalAmount}}
{{#referenceId}}
**参考:** {{referenceId}}
{{/referenceId}}
💳 **PIX 复制粘贴已发送**
{{/pixData}}
whatsapp.to.chatwoot.message.unsupported: |-
⚠️ **ChatWoot 不支持此消息类型。**
📱 请打开 **WhatsApp** 查看。
详情: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **Facebook 广告**
**标题:** {{{adData.title}}}
**描述:**
{{{adData.body}}}
**广告链接:** [在 Facebook 查看]({{{adData.sourceUrl}}})
**广告 ID:** {{{adData.sourceId}}}
---
💬 **客户消息:**
{{{payload.body}}}
Loaded 100 of 196 files, more files were not shown because too many files have changed in this diff. Show more