Compare commits

..
27 Commits
Author SHA1 Message Date
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
devlikepro 5bd1a43df6 [core] 2025.7.8
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-23 15:02:05 +07:00
devlikepro c9279a4b59 [core] ChatWoot - send png as images 2025-07-23 15:02:04 +07:00
devlikepro 9ff8eed6ba [core] Add, edit, and remove contact API
fix #1124
2025-07-23 15:02:03 +07:00
devlikepro 96ffdd251f [core] Up GOWS 2025-07-23 15:01:53 +07:00
44 changed files with 1256 additions and 129 deletions

No files matched your search

+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
+3 -1
View File
@@ -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",
@@ -96,6 +97,7 @@
"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",
+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() {
@@ -17,9 +17,9 @@ export class ChatwootLocalesController {
description: 'Get available languages for Chatwoot app',
})
getLanguages(): LanguageResponse[] {
return Object.entries(LOCALE_NAMES).map(([locale, name]) => ({
name: name,
locale: locale,
return Array.from(LOCALE_NAMES.entries()).map(([locale, name]) => ({
name,
locale,
}));
}
}
@@ -1,6 +1,6 @@
import { Body, Controller, 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';
@@ -43,7 +43,7 @@ export class ChatwootWebhookController {
// 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
+13
View File
@@ -15,6 +15,19 @@ export function GetChatID(contact: any): string | null {
return contact?.custom_attributes?.[AttributeKey.WA_CHAT_ID];
}
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,
+2 -2
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';
@@ -124,7 +124,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) {
@@ -180,7 +180,7 @@ export class MessageHandler {
switch (file.file_type) {
case 'image':
if (mimetype != 'image/jpeg') {
if (mimetype != 'image/jpeg' && mimetype != 'image/png') {
// Send it as a file
break;
}
+1
View File
@@ -1,4 +1,5 @@
# Arabic translations for ChatWoot integration
LOCALE_NAME: '🇦🇪 العربية (Arabic)'
APP_INBOX_CONTACT_NAME: 'تكامل واتساب (WAHA)'
JOB_ERROR_REPORT: |
+1
View File
@@ -1,4 +1,5 @@
# Bengali translations for ChatWoot integration
LOCALE_NAME: '🇧🇩 বাংলা (Bengali)'
APP_INBOX_CONTACT_NAME: 'হোয়াটসঅ্যাপ ইন্টিগ্রেশন (WAHA)'
JOB_ERROR_REPORT: |
+1
View File
@@ -1,4 +1,5 @@
# German translations for ChatWoot integration
LOCALE_NAME: '🇩🇪 Deutsch (German)'
APP_INBOX_CONTACT_NAME: 'WhatsApp Integration (WAHA)'
JOB_ERROR_REPORT: |
+1
View File
@@ -1,4 +1,5 @@
# English translations for ChatWoot integration
LOCALE_NAME: '🇺🇸 English (English)'
APP_INBOX_CONTACT_NAME: 'WhatsApp Integration (WAHA)'
APP_INBOX_CONTACT_AVATAR_URL: 'https://raw.githubusercontent.com/devlikeapro/waha/core/logo.png'
+1
View File
@@ -1,4 +1,5 @@
# Spanish translations for ChatWoot integration
LOCALE_NAME: '🇪🇸 Español (Spanish)'
APP_INBOX_CONTACT_NAME: 'Integración de WhatsApp (WAHA)'
JOB_ERROR_REPORT: |
+1
View File
@@ -1,4 +1,5 @@
# Persian translations for ChatWoot integration
LOCALE_NAME: '🇮🇷 فارسی (Persian)'
APP_INBOX_CONTACT_NAME: 'ادغام واتساپ (WAHA)'
JOB_ERROR_REPORT: |
+1
View File
@@ -1,4 +1,5 @@
# French translations for ChatWoot integration
LOCALE_NAME: '🇫🇷 Français (French)'
APP_INBOX_CONTACT_NAME: 'Intégration WhatsApp (WAHA)'
JOB_ERROR_REPORT: |
+1
View File
@@ -1,4 +1,5 @@
# Hebrew translations for ChatWoot integration
LOCALE_NAME: '🇮🇱 עברית (Hebrew)'
APP_INBOX_CONTACT_NAME: 'אינטגרציית וואטסאפ (WAHA)'
JOB_ERROR_REPORT: |
+1
View File
@@ -1,4 +1,5 @@
# Hindi translations for ChatWoot integration
LOCALE_NAME: '🇮🇳 हिंदी (Hindi)'
APP_INBOX_CONTACT_NAME: 'व्हाट्सएप इंटीग्रेशन (WAHA)'
JOB_ERROR_REPORT: |
+1
View File
@@ -1,4 +1,5 @@
# Indonesian translations for ChatWoot integration
LOCALE_NAME: '🇮🇩 Bahasa Indonesia (Indonesian)'
APP_INBOX_CONTACT_NAME: 'Integrasi WhatsApp (WAHA)'
JOB_ERROR_REPORT: |
+1
View File
@@ -1,4 +1,5 @@
# Punjabi translations for ChatWoot integration
LOCALE_NAME: '🇵🇰 ਪੰਜਾਬੀ (Punjabi)'
APP_INBOX_CONTACT_NAME: 'ਵਟਸਐਪ ਇੰਟੀਗ੍ਰੇਸ਼ਨ (WAHA)'
JOB_ERROR_REPORT: |
+1
View File
@@ -1,4 +1,5 @@
# Portuguese translations for ChatWoot integration
LOCALE_NAME: '🇧🇷🇵🇹 Português (Portuguese)'
APP_INBOX_CONTACT_NAME: 'Integração WhatsApp (WAHA)'
JOB_ERROR_REPORT: |
+1
View File
@@ -1,4 +1,5 @@
# Russian translations for ChatWoot integration
LOCALE_NAME: '🇷🇺 Русский (Russian)'
APP_INBOX_CONTACT_NAME: 'WhatsApp Интеграция (WAHA)'
JOB_ERROR_REPORT: |
+1
View File
@@ -1,4 +1,5 @@
# Turkish translations for ChatWoot integration
LOCALE_NAME: '🇹🇷 Türkçe (Turkish)'
APP_INBOX_CONTACT_NAME: 'WhatsApp Entegrasyonu (WAHA)'
JOB_ERROR_REPORT: |
+1
View File
@@ -1,4 +1,5 @@
# Ukrainian translations for ChatWoot integration
LOCALE_NAME: '🇺🇦 Українська (Ukrainian)'
APP_INBOX_CONTACT_NAME: 'Інтеграція WhatsApp (WAHA)'
JOB_ERROR_REPORT: |
+182
View File
@@ -0,0 +1,182 @@
# Urdu translations for ChatWoot integration
LOCALE_NAME: '🇵🇰 اردو (Urdu)'
APP_INBOX_CONTACT_NAME: 'واٹس ایپ انٹیگریشن (WAHA)'
APP_INBOX_CONTACT_AVATAR_URL: 'https://raw.githubusercontent.com/devlikeapro/waha/core/logo.png'
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: |
⚠️ **اس ChatWoot انبکس کے ساتھ واٹس ایپ اکاؤنٹ کو منسلک کرنے کے لیے اپنے فون پر QR کوڈ اسکین کریں!**
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}}})
+7 -17
View File
@@ -20,6 +20,7 @@ export enum LocaleCode {
RU_RU = 'ru-RU',
TR_TR = 'tr-TR',
UK_UA = 'uk-UA',
UR_PK = 'ur-PK',
}
export const LOCALES = [
@@ -38,25 +39,9 @@ export const LOCALES = [
LocaleCode.RU_RU,
LocaleCode.TR_TR,
LocaleCode.UK_UA,
LocaleCode.UR_PK,
];
export const LOCALE_NAMES: Record<LocaleCode, string> = {
[LocaleCode.EN_US]: '🇺🇸 English (English)',
[LocaleCode.AR_AE]: '🇦🇪 العربية (Arabic)',
[LocaleCode.BN_BD]: '🇧🇩 বাংলা (Bengali)',
[LocaleCode.PT_BR]: '🇧🇷🇵🇹 Português (Portuguese)',
[LocaleCode.DE_DE]: '🇩🇪 Deutsch (German)',
[LocaleCode.ES_ES]: '🇪🇸 Español (Spanish)',
[LocaleCode.FR_FR]: '🇫🇷 Français (French)',
[LocaleCode.ID_ID]: '🇮🇩 Bahasa Indonesia (Indonesian)',
[LocaleCode.HE_IL]: '🇮🇱 עברית (Hebrew)',
[LocaleCode.HI_IN]: '🇮🇳 हिंदी (Hindi)',
[LocaleCode.FA_IR]: '🇮🇷 فارسی (Persian)',
[LocaleCode.PA_PK]: '🇵🇰 ਪੰਜਾਬੀ (Punjabi)',
[LocaleCode.RU_RU]: '🇷🇺 Русский (Russian)',
[LocaleCode.TR_TR]: '🇹🇷 Türkçe (Turkish)',
[LocaleCode.UK_UA]: '🇺🇦 Українська (Ukrainian)',
};
export const DEFAULT_LOCALE = 'en-US';
function loadTemplateStrings(locale: string) {
@@ -82,8 +67,13 @@ function loadLocales(locales: string[]) {
}
let locales: Record<string, Record<string, string>> = {};
export const LOCALE_NAMES: Map<LocaleCode, string> = new Map();
try {
locales = loadLocales(LOCALES);
for (const [locale, strings] of Object.entries(locales)) {
LOCALE_NAMES.set(locale as LocaleCode, strings['LOCALE_NAME']);
}
} catch (error) {
console.error('Error loading locales:', error);
process.exit(1);
+38
View File
@@ -0,0 +1,38 @@
import { Body, Controller, Delete, Param, Put, UsePipes } from '@nestjs/common';
import { ApiOperation, ApiSecurity, ApiTags } from '@nestjs/swagger';
import { WhatsappSession } from '@waha/core/abc/session.abc';
import { ChatIdApiParam } from '@waha/nestjs/params/ChatIdApiParam';
import {
SessionApiParam,
WorkingSessionParam,
} from '@waha/nestjs/params/SessionApiParam';
import { WAHAValidationPipe } from '@waha/nestjs/pipes/WAHAValidationPipe';
import { SessionManager } from './core/abc/manager.abc';
import { Result } from './structures/base.dto';
import { ContactUpdateBody } from './structures/contacts.dto';
@ApiSecurity('api_key')
@Controller('api/:session/contacts')
@ApiTags('👤 Contacts')
export class ContactsSessionController {
constructor(private manager: SessionManager) {}
@Put('/:chatId')
@SessionApiParam
@ChatIdApiParam
@ApiOperation({
summary: 'Create or update contact',
description:
'Create or update contact on the phone address book. May not work if you have installed many WhatsApp apps on the same phone',
})
@UsePipes(new WAHAValidationPipe())
async put(
@WorkingSessionParam session: WhatsappSession,
@Param('chatId') chatId: string,
@Body() body: ContactUpdateBody,
): Promise<Result> {
await session.upsertContact(chatId, body);
return { success: true };
}
}
+9 -1
View File
@@ -77,7 +77,11 @@ import {
MessageVoiceRequest,
SendSeenRequest,
} from '../../structures/chatting.dto';
import { ContactQuery, ContactRequest } from '../../structures/contacts.dto';
import {
ContactQuery,
ContactRequest,
ContactUpdateBody,
} from '../../structures/contacts.dto';
import {
WAHAEngine,
WAHAEvents,
@@ -639,6 +643,10 @@ export abstract class WhatsappSession {
/**
* Contacts methods
*/
public upsertContact(chatId: string, body: ContactUpdateBody): Promise<void> {
throw new NotImplementedByEngineError();
}
public getContact(query: ContactQuery) {
throw new NotImplementedByEngineError();
}
+2
View File
@@ -14,6 +14,7 @@ import { ServerController } from '@waha/api/server.controller';
import { ServerDebugController } from '@waha/api/server.debug.controller';
import { WebsocketGatewayCore } from '@waha/api/websocket.gateway.core';
import { AppsModuleExports } from '@waha/apps/apps.module';
import { ContactsSessionController } from '@waha/contacts.session.controller';
import { ApiKeyStrategy } from '@waha/core/auth/apiKey.strategy';
import { IApiKeyAuth } from '@waha/core/auth/auth';
import { AuthMiddleware } from '@waha/core/auth/auth.middleware';
@@ -146,6 +147,7 @@ export const CONTROLLERS = [
StatusController,
LabelsController,
ContactsController,
ContactsSessionController,
LidsController,
GroupsController,
PresenceController,
+178 -26
View File
@@ -7941,6 +7941,145 @@ export namespace messages {
return GetMessagesRequest.deserialize(bytes);
}
}
export class UpdateContactRequest extends pb_1.Message {
#one_of_decls: number[][] = [];
constructor(data?: any[] | {
session?: Session;
jid?: string;
firstName?: string;
lastName?: string;
}) {
super();
pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [], this.#one_of_decls);
if (!Array.isArray(data) && typeof data == "object") {
if ("session" in data && data.session != undefined) {
this.session = data.session;
}
if ("jid" in data && data.jid != undefined) {
this.jid = data.jid;
}
if ("firstName" in data && data.firstName != undefined) {
this.firstName = data.firstName;
}
if ("lastName" in data && data.lastName != undefined) {
this.lastName = data.lastName;
}
}
}
get session() {
return pb_1.Message.getWrapperField(this, Session, 1) as Session;
}
set session(value: Session) {
pb_1.Message.setWrapperField(this, 1, value);
}
get has_session() {
return pb_1.Message.getField(this, 1) != null;
}
get jid() {
return pb_1.Message.getFieldWithDefault(this, 2, "") as string;
}
set jid(value: string) {
pb_1.Message.setField(this, 2, value);
}
get firstName() {
return pb_1.Message.getFieldWithDefault(this, 3, "") as string;
}
set firstName(value: string) {
pb_1.Message.setField(this, 3, value);
}
get lastName() {
return pb_1.Message.getFieldWithDefault(this, 4, "") as string;
}
set lastName(value: string) {
pb_1.Message.setField(this, 4, value);
}
static fromObject(data: {
session?: ReturnType<typeof Session.prototype.toObject>;
jid?: string;
firstName?: string;
lastName?: string;
}): UpdateContactRequest {
const message = new UpdateContactRequest({});
if (data.session != null) {
message.session = Session.fromObject(data.session);
}
if (data.jid != null) {
message.jid = data.jid;
}
if (data.firstName != null) {
message.firstName = data.firstName;
}
if (data.lastName != null) {
message.lastName = data.lastName;
}
return message;
}
toObject() {
const data: {
session?: ReturnType<typeof Session.prototype.toObject>;
jid?: string;
firstName?: string;
lastName?: string;
} = {};
if (this.session != null) {
data.session = this.session.toObject();
}
if (this.jid != null) {
data.jid = this.jid;
}
if (this.firstName != null) {
data.firstName = this.firstName;
}
if (this.lastName != null) {
data.lastName = this.lastName;
}
return data;
}
serialize(): Uint8Array;
serialize(w: pb_1.BinaryWriter): void;
serialize(w?: pb_1.BinaryWriter): Uint8Array | void {
const writer = w || new pb_1.BinaryWriter();
if (this.has_session)
writer.writeMessage(1, this.session, () => this.session.serialize(writer));
if (this.jid.length)
writer.writeString(2, this.jid);
if (this.firstName.length)
writer.writeString(3, this.firstName);
if (this.lastName.length)
writer.writeString(4, this.lastName);
if (!w)
return writer.getResultBuffer();
}
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): UpdateContactRequest {
const reader = bytes instanceof pb_1.BinaryReader ? bytes : new pb_1.BinaryReader(bytes), message = new UpdateContactRequest();
while (reader.nextField()) {
if (reader.isEndGroup())
break;
switch (reader.getFieldNumber()) {
case 1:
reader.readMessage(message.session, () => message.session = Session.deserialize(reader));
break;
case 2:
message.jid = reader.readString();
break;
case 3:
message.firstName = reader.readString();
break;
case 4:
message.lastName = reader.readString();
break;
default: reader.skipField();
}
}
return message;
}
serializeBinary(): Uint8Array {
return this.serialize();
}
static deserializeBinary(bytes: Uint8Array): UpdateContactRequest {
return UpdateContactRequest.deserialize(bytes);
}
}
export class GetContactsRequest extends pb_1.Message {
#one_of_decls: number[][] = [];
constructor(data?: any[] | {
@@ -9603,6 +9742,33 @@ export namespace messages {
responseSerialize: (message: JsonList) => Buffer.from(message.serialize()),
responseDeserialize: (bytes: Buffer) => JsonList.deserialize(new Uint8Array(bytes))
},
UpdateContact: {
path: "/messages.MessageService/UpdateContact",
requestStream: false,
responseStream: false,
requestSerialize: (message: UpdateContactRequest) => Buffer.from(message.serialize()),
requestDeserialize: (bytes: Buffer) => UpdateContactRequest.deserialize(new Uint8Array(bytes)),
responseSerialize: (message: Empty) => Buffer.from(message.serialize()),
responseDeserialize: (bytes: Buffer) => Empty.deserialize(new Uint8Array(bytes))
},
GetContacts: {
path: "/messages.MessageService/GetContacts",
requestStream: false,
responseStream: false,
requestSerialize: (message: GetContactsRequest) => Buffer.from(message.serialize()),
requestDeserialize: (bytes: Buffer) => GetContactsRequest.deserialize(new Uint8Array(bytes)),
responseSerialize: (message: JsonList) => Buffer.from(message.serialize()),
responseDeserialize: (bytes: Buffer) => JsonList.deserialize(new Uint8Array(bytes))
},
GetContactById: {
path: "/messages.MessageService/GetContactById",
requestStream: false,
responseStream: false,
requestSerialize: (message: EntityByIdRequest) => Buffer.from(message.serialize()),
requestDeserialize: (bytes: Buffer) => EntityByIdRequest.deserialize(new Uint8Array(bytes)),
responseSerialize: (message: Json) => Buffer.from(message.serialize()),
responseDeserialize: (bytes: Buffer) => Json.deserialize(new Uint8Array(bytes))
},
CancelEventMessage: {
path: "/messages.MessageService/CancelEventMessage",
requestStream: false,
@@ -9639,24 +9805,6 @@ export namespace messages {
responseSerialize: (message: JsonList) => Buffer.from(message.serialize()),
responseDeserialize: (bytes: Buffer) => JsonList.deserialize(new Uint8Array(bytes))
},
GetContacts: {
path: "/messages.MessageService/GetContacts",
requestStream: false,
responseStream: false,
requestSerialize: (message: GetContactsRequest) => Buffer.from(message.serialize()),
requestDeserialize: (bytes: Buffer) => GetContactsRequest.deserialize(new Uint8Array(bytes)),
responseSerialize: (message: JsonList) => Buffer.from(message.serialize()),
responseDeserialize: (bytes: Buffer) => JsonList.deserialize(new Uint8Array(bytes))
},
GetContactById: {
path: "/messages.MessageService/GetContactById",
requestStream: false,
responseStream: false,
requestSerialize: (message: EntityByIdRequest) => Buffer.from(message.serialize()),
requestDeserialize: (bytes: Buffer) => EntityByIdRequest.deserialize(new Uint8Array(bytes)),
responseSerialize: (message: Json) => Buffer.from(message.serialize()),
responseDeserialize: (bytes: Buffer) => Json.deserialize(new Uint8Array(bytes))
},
GetChats: {
path: "/messages.MessageService/GetChats",
requestStream: false,
@@ -9722,12 +9870,13 @@ export namespace messages {
abstract RemoveChatLabel(call: grpc_1.ServerUnaryCall<ChatLabelRequest, Empty>, callback: grpc_1.sendUnaryData<Empty>): void;
abstract GetLabelsByJid(call: grpc_1.ServerUnaryCall<EntityByIdRequest, JsonList>, callback: grpc_1.sendUnaryData<JsonList>): void;
abstract GetChatsByLabelId(call: grpc_1.ServerUnaryCall<EntityByIdRequest, JsonList>, callback: grpc_1.sendUnaryData<JsonList>): void;
abstract UpdateContact(call: grpc_1.ServerUnaryCall<UpdateContactRequest, Empty>, callback: grpc_1.sendUnaryData<Empty>): void;
abstract GetContacts(call: grpc_1.ServerUnaryCall<GetContactsRequest, JsonList>, callback: grpc_1.sendUnaryData<JsonList>): void;
abstract GetContactById(call: grpc_1.ServerUnaryCall<EntityByIdRequest, Json>, callback: grpc_1.sendUnaryData<Json>): void;
abstract CancelEventMessage(call: grpc_1.ServerUnaryCall<CancelEventMessageRequest, MessageResponse>, callback: grpc_1.sendUnaryData<MessageResponse>): void;
abstract DownloadMedia(call: grpc_1.ServerUnaryCall<DownloadMediaRequest, DownloadMediaResponse>, callback: grpc_1.sendUnaryData<DownloadMediaResponse>): void;
abstract GetMessageById(call: grpc_1.ServerUnaryCall<EntityByIdRequest, Json>, callback: grpc_1.sendUnaryData<Json>): void;
abstract GetMessages(call: grpc_1.ServerUnaryCall<GetMessagesRequest, JsonList>, callback: grpc_1.sendUnaryData<JsonList>): void;
abstract GetContacts(call: grpc_1.ServerUnaryCall<GetContactsRequest, JsonList>, callback: grpc_1.sendUnaryData<JsonList>): void;
abstract GetContactById(call: grpc_1.ServerUnaryCall<EntityByIdRequest, Json>, callback: grpc_1.sendUnaryData<Json>): void;
abstract GetChats(call: grpc_1.ServerUnaryCall<GetChatsRequest, JsonList>, callback: grpc_1.sendUnaryData<JsonList>): void;
}
export class MessageServiceClient extends grpc_1.makeGenericClientConstructor(UnimplementedMessageServiceService.definition, "MessageService", {}) {
@@ -9896,6 +10045,15 @@ export namespace messages {
GetChatsByLabelId: GrpcUnaryServiceInterface<EntityByIdRequest, JsonList> = (message: EntityByIdRequest, metadata: grpc_1.Metadata | grpc_1.CallOptions | grpc_1.requestCallback<JsonList>, options?: grpc_1.CallOptions | grpc_1.requestCallback<JsonList>, callback?: grpc_1.requestCallback<JsonList>): grpc_1.ClientUnaryCall => {
return super.GetChatsByLabelId(message, metadata, options, callback);
};
UpdateContact: GrpcUnaryServiceInterface<UpdateContactRequest, Empty> = (message: UpdateContactRequest, metadata: grpc_1.Metadata | grpc_1.CallOptions | grpc_1.requestCallback<Empty>, options?: grpc_1.CallOptions | grpc_1.requestCallback<Empty>, callback?: grpc_1.requestCallback<Empty>): grpc_1.ClientUnaryCall => {
return super.UpdateContact(message, metadata, options, callback);
};
GetContacts: GrpcUnaryServiceInterface<GetContactsRequest, JsonList> = (message: GetContactsRequest, metadata: grpc_1.Metadata | grpc_1.CallOptions | grpc_1.requestCallback<JsonList>, options?: grpc_1.CallOptions | grpc_1.requestCallback<JsonList>, callback?: grpc_1.requestCallback<JsonList>): grpc_1.ClientUnaryCall => {
return super.GetContacts(message, metadata, options, callback);
};
GetContactById: GrpcUnaryServiceInterface<EntityByIdRequest, Json> = (message: EntityByIdRequest, metadata: grpc_1.Metadata | grpc_1.CallOptions | grpc_1.requestCallback<Json>, options?: grpc_1.CallOptions | grpc_1.requestCallback<Json>, callback?: grpc_1.requestCallback<Json>): grpc_1.ClientUnaryCall => {
return super.GetContactById(message, metadata, options, callback);
};
CancelEventMessage: GrpcUnaryServiceInterface<CancelEventMessageRequest, MessageResponse> = (message: CancelEventMessageRequest, metadata: grpc_1.Metadata | grpc_1.CallOptions | grpc_1.requestCallback<MessageResponse>, options?: grpc_1.CallOptions | grpc_1.requestCallback<MessageResponse>, callback?: grpc_1.requestCallback<MessageResponse>): grpc_1.ClientUnaryCall => {
return super.CancelEventMessage(message, metadata, options, callback);
};
@@ -9908,12 +10066,6 @@ export namespace messages {
GetMessages: GrpcUnaryServiceInterface<GetMessagesRequest, JsonList> = (message: GetMessagesRequest, metadata: grpc_1.Metadata | grpc_1.CallOptions | grpc_1.requestCallback<JsonList>, options?: grpc_1.CallOptions | grpc_1.requestCallback<JsonList>, callback?: grpc_1.requestCallback<JsonList>): grpc_1.ClientUnaryCall => {
return super.GetMessages(message, metadata, options, callback);
};
GetContacts: GrpcUnaryServiceInterface<GetContactsRequest, JsonList> = (message: GetContactsRequest, metadata: grpc_1.Metadata | grpc_1.CallOptions | grpc_1.requestCallback<JsonList>, options?: grpc_1.CallOptions | grpc_1.requestCallback<JsonList>, callback?: grpc_1.requestCallback<JsonList>): grpc_1.ClientUnaryCall => {
return super.GetContacts(message, metadata, options, callback);
};
GetContactById: GrpcUnaryServiceInterface<EntityByIdRequest, Json> = (message: EntityByIdRequest, metadata: grpc_1.Metadata | grpc_1.CallOptions | grpc_1.requestCallback<Json>, options?: grpc_1.CallOptions | grpc_1.requestCallback<Json>, callback?: grpc_1.requestCallback<Json>): grpc_1.ClientUnaryCall => {
return super.GetContactById(message, metadata, options, callback);
};
GetChats: GrpcUnaryServiceInterface<GetChatsRequest, JsonList> = (message: GetChatsRequest, metadata: grpc_1.Metadata | grpc_1.CallOptions | grpc_1.requestCallback<JsonList>, options?: grpc_1.CallOptions | grpc_1.requestCallback<JsonList>, callback?: grpc_1.requestCallback<JsonList>): grpc_1.ClientUnaryCall => {
return super.GetChats(message, metadata, options, callback);
};
+47 -22
View File
@@ -631,6 +631,17 @@ function deserialize_messages_SubscribePresenceRequest(buffer_arg) {
return gows_pb.SubscribePresenceRequest.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_UpdateContactRequest(arg) {
if (!(arg instanceof gows_pb.UpdateContactRequest)) {
throw new Error('Expected argument of type messages.UpdateContactRequest');
}
return Buffer.from(arg.serializeBinary());
}
function deserialize_messages_UpdateContactRequest(buffer_arg) {
return gows_pb.UpdateContactRequest.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_messages_UpdateParticipantsRequest(arg) {
if (!(arg instanceof gows_pb.UpdateParticipantsRequest)) {
throw new Error('Expected argument of type messages.UpdateParticipantsRequest');
@@ -1294,6 +1305,42 @@ getLabels: {
responseDeserialize: deserialize_messages_JsonList,
},
//
// Contacts
//
updateContact: {
path: '/messages.MessageService/UpdateContact',
requestStream: false,
responseStream: false,
requestType: gows_pb.UpdateContactRequest,
responseType: gows_pb.Empty,
requestSerialize: serialize_messages_UpdateContactRequest,
requestDeserialize: deserialize_messages_UpdateContactRequest,
responseSerialize: serialize_messages_Empty,
responseDeserialize: deserialize_messages_Empty,
},
getContacts: {
path: '/messages.MessageService/GetContacts',
requestStream: false,
responseStream: false,
requestType: gows_pb.GetContactsRequest,
responseType: gows_pb.JsonList,
requestSerialize: serialize_messages_GetContactsRequest,
requestDeserialize: deserialize_messages_GetContactsRequest,
responseSerialize: serialize_messages_JsonList,
responseDeserialize: deserialize_messages_JsonList,
},
getContactById: {
path: '/messages.MessageService/GetContactById',
requestStream: false,
responseStream: false,
requestType: gows_pb.EntityByIdRequest,
responseType: gows_pb.Json,
requestSerialize: serialize_messages_EntityByIdRequest,
requestDeserialize: deserialize_messages_EntityByIdRequest,
responseSerialize: serialize_messages_Json,
responseDeserialize: deserialize_messages_Json,
},
//
// Events
//
cancelEventMessage: {
@@ -1346,28 +1393,6 @@ getMessageById: {
responseSerialize: serialize_messages_JsonList,
responseDeserialize: deserialize_messages_JsonList,
},
getContacts: {
path: '/messages.MessageService/GetContacts',
requestStream: false,
responseStream: false,
requestType: gows_pb.GetContactsRequest,
responseType: gows_pb.JsonList,
requestSerialize: serialize_messages_GetContactsRequest,
requestDeserialize: deserialize_messages_GetContactsRequest,
responseSerialize: serialize_messages_JsonList,
responseDeserialize: deserialize_messages_JsonList,
},
getContactById: {
path: '/messages.MessageService/GetContactById',
requestStream: false,
responseStream: false,
requestType: gows_pb.EntityByIdRequest,
responseType: gows_pb.Json,
requestSerialize: serialize_messages_EntityByIdRequest,
requestDeserialize: deserialize_messages_EntityByIdRequest,
responseSerialize: serialize_messages_Json,
responseDeserialize: deserialize_messages_Json,
},
getChats: {
path: '/messages.MessageService/GetChats',
requestStream: false,
+263
View File
@@ -107,6 +107,7 @@ goog.exportSymbol('proto.messages.SortBy', null, global);
goog.exportSymbol('proto.messages.SortBy.Order', null, global);
goog.exportSymbol('proto.messages.StartSessionRequest', null, global);
goog.exportSymbol('proto.messages.SubscribePresenceRequest', null, global);
goog.exportSymbol('proto.messages.UpdateContactRequest', null, global);
goog.exportSymbol('proto.messages.UpdateParticipantsRequest', null, global);
goog.exportSymbol('proto.messages.UpsertLabelRequest', null, global);
goog.exportSymbol('proto.messages.vCardContact', null, global);
@@ -1601,6 +1602,27 @@ if (goog.DEBUG && !COMPILED) {
*/
proto.messages.GetMessagesRequest.displayName = 'proto.messages.GetMessagesRequest';
}
/**
* Generated by JsPbCodeGenerator.
* @param {Array=} opt_data Optional initial data array, typically from a
* server response, or constructed directly in Javascript. The array is used
* in place and becomes part of the constructed object. It is not cloned.
* If no data is provided, the constructed object will be empty, but still
* valid.
* @extends {jspb.Message}
* @constructor
*/
proto.messages.UpdateContactRequest = function(opt_data) {
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.messages.UpdateContactRequest, jspb.Message);
if (goog.DEBUG && !COMPILED) {
/**
* @public
* @override
*/
proto.messages.UpdateContactRequest.displayName = 'proto.messages.UpdateContactRequest';
}
/**
* Generated by JsPbCodeGenerator.
* @param {Array=} opt_data Optional initial data array, typically from a
@@ -16661,6 +16683,247 @@ proto.messages.GetMessagesRequest.prototype.hasPagination = function() {
if (jspb.Message.GENERATE_TO_OBJECT) {
/**
* Creates an object representation of this proto.
* Field names that are reserved in JavaScript and will be renamed to pb_name.
* Optional fields that are not set will be set to undefined.
* To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
* For the list of reserved names please see:
* net/proto2/compiler/js/internal/generator.cc#kKeyword.
* @param {boolean=} opt_includeInstance Deprecated. whether to include the
* JSPB instance for transitional soy proto support:
* http://goto/soy-param-migration
* @return {!Object}
*/
proto.messages.UpdateContactRequest.prototype.toObject = function(opt_includeInstance) {
return proto.messages.UpdateContactRequest.toObject(opt_includeInstance, this);
};
/**
* Static version of the {@see toObject} method.
* @param {boolean|undefined} includeInstance Deprecated. Whether to include
* the JSPB instance for transitional soy proto support:
* http://goto/soy-param-migration
* @param {!proto.messages.UpdateContactRequest} msg The msg instance to transform.
* @return {!Object}
* @suppress {unusedLocalVariables} f is only used for nested messages
*/
proto.messages.UpdateContactRequest.toObject = function(includeInstance, msg) {
var f, obj = {
session: (f = msg.getSession()) && proto.messages.Session.toObject(includeInstance, f),
jid: jspb.Message.getFieldWithDefault(msg, 2, ""),
firstname: jspb.Message.getFieldWithDefault(msg, 3, ""),
lastname: jspb.Message.getFieldWithDefault(msg, 4, "")
};
if (includeInstance) {
obj.$jspbMessageInstance = msg;
}
return obj;
};
}
/**
* Deserializes binary data (in protobuf wire format).
* @param {jspb.ByteSource} bytes The bytes to deserialize.
* @return {!proto.messages.UpdateContactRequest}
*/
proto.messages.UpdateContactRequest.deserializeBinary = function(bytes) {
var reader = new jspb.BinaryReader(bytes);
var msg = new proto.messages.UpdateContactRequest;
return proto.messages.UpdateContactRequest.deserializeBinaryFromReader(msg, reader);
};
/**
* Deserializes binary data (in protobuf wire format) from the
* given reader into the given message object.
* @param {!proto.messages.UpdateContactRequest} msg The message object to deserialize into.
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
* @return {!proto.messages.UpdateContactRequest}
*/
proto.messages.UpdateContactRequest.deserializeBinaryFromReader = function(msg, reader) {
while (reader.nextField()) {
if (reader.isEndGroup()) {
break;
}
var field = reader.getFieldNumber();
switch (field) {
case 1:
var value = new proto.messages.Session;
reader.readMessage(value,proto.messages.Session.deserializeBinaryFromReader);
msg.setSession(value);
break;
case 2:
var value = /** @type {string} */ (reader.readString());
msg.setJid(value);
break;
case 3:
var value = /** @type {string} */ (reader.readString());
msg.setFirstname(value);
break;
case 4:
var value = /** @type {string} */ (reader.readString());
msg.setLastname(value);
break;
default:
reader.skipField();
break;
}
}
return msg;
};
/**
* Serializes the message to binary data (in protobuf wire format).
* @return {!Uint8Array}
*/
proto.messages.UpdateContactRequest.prototype.serializeBinary = function() {
var writer = new jspb.BinaryWriter();
proto.messages.UpdateContactRequest.serializeBinaryToWriter(this, writer);
return writer.getResultBuffer();
};
/**
* Serializes the given message to binary data (in protobuf wire
* format), writing to the given BinaryWriter.
* @param {!proto.messages.UpdateContactRequest} message
* @param {!jspb.BinaryWriter} writer
* @suppress {unusedLocalVariables} f is only used for nested messages
*/
proto.messages.UpdateContactRequest.serializeBinaryToWriter = function(message, writer) {
var f = undefined;
f = message.getSession();
if (f != null) {
writer.writeMessage(
1,
f,
proto.messages.Session.serializeBinaryToWriter
);
}
f = message.getJid();
if (f.length > 0) {
writer.writeString(
2,
f
);
}
f = message.getFirstname();
if (f.length > 0) {
writer.writeString(
3,
f
);
}
f = message.getLastname();
if (f.length > 0) {
writer.writeString(
4,
f
);
}
};
/**
* optional Session session = 1;
* @return {?proto.messages.Session}
*/
proto.messages.UpdateContactRequest.prototype.getSession = function() {
return /** @type{?proto.messages.Session} */ (
jspb.Message.getWrapperField(this, proto.messages.Session, 1));
};
/**
* @param {?proto.messages.Session|undefined} value
* @return {!proto.messages.UpdateContactRequest} returns this
*/
proto.messages.UpdateContactRequest.prototype.setSession = function(value) {
return jspb.Message.setWrapperField(this, 1, value);
};
/**
* Clears the message field making it undefined.
* @return {!proto.messages.UpdateContactRequest} returns this
*/
proto.messages.UpdateContactRequest.prototype.clearSession = function() {
return this.setSession(undefined);
};
/**
* Returns whether this field is set.
* @return {boolean}
*/
proto.messages.UpdateContactRequest.prototype.hasSession = function() {
return jspb.Message.getField(this, 1) != null;
};
/**
* optional string jid = 2;
* @return {string}
*/
proto.messages.UpdateContactRequest.prototype.getJid = function() {
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
};
/**
* @param {string} value
* @return {!proto.messages.UpdateContactRequest} returns this
*/
proto.messages.UpdateContactRequest.prototype.setJid = function(value) {
return jspb.Message.setProto3StringField(this, 2, value);
};
/**
* optional string firstName = 3;
* @return {string}
*/
proto.messages.UpdateContactRequest.prototype.getFirstname = function() {
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
};
/**
* @param {string} value
* @return {!proto.messages.UpdateContactRequest} returns this
*/
proto.messages.UpdateContactRequest.prototype.setFirstname = function(value) {
return jspb.Message.setProto3StringField(this, 3, value);
};
/**
* optional string lastName = 4;
* @return {string}
*/
proto.messages.UpdateContactRequest.prototype.getLastname = function() {
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
};
/**
* @param {string} value
* @return {!proto.messages.UpdateContactRequest} returns this
*/
proto.messages.UpdateContactRequest.prototype.setLastname = function(value) {
return jspb.Message.setProto3StringField(this, 4, value);
};
if (jspb.Message.GENERATE_TO_OBJECT) {
/**
* Creates an object representation of this proto.
+14 -1
View File
@@ -1,5 +1,6 @@
import {
aggregateMessageKeysNotFromMe,
Contact,
getContentType,
getUrlFromDirectPath,
isJidGroup,
@@ -86,7 +87,7 @@ import {
SendSeenRequest,
WANumberExistResult,
} from '@waha/structures/chatting.dto';
import { ContactQuery } from '@waha/structures/contacts.dto';
import { ContactQuery, ContactUpdateBody } from '@waha/structures/contacts.dto';
import {
ACK_UNKNOWN,
WAHAEvents,
@@ -1464,6 +1465,18 @@ export class WhatsappSessionGoWSCore extends WhatsappSession {
* Contacts methods
*/
public async upsertContact(chatId: string, body: ContactUpdateBody) {
const jid = toJID(chatId);
const request = new messages.UpdateContactRequest({
session: this.session,
jid: jid,
firstName: body.firstName || '',
lastName: body.lastName || '',
});
const response = await promisify(this.client.UpdateContact)(request);
response.toObject();
}
protected toWAContact(contact) {
return {
id: toCusFormat(contact.Jid),
+31 -2
View File
@@ -121,7 +121,11 @@ import {
SendSeenRequest,
WANumberExistResult,
} from '@waha/structures/chatting.dto';
import { ContactQuery, ContactRequest } from '@waha/structures/contacts.dto';
import {
ContactQuery,
ContactRequest,
ContactUpdateBody,
} from '@waha/structures/contacts.dto';
import {
ACK_UNKNOWN,
SECOND,
@@ -1322,6 +1326,28 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
/**
* Contacts methods
*/
public async upsertContact(chatId: string, body: ContactUpdateBody) {
const jid = toJID(chatId);
let fullName = body.firstName;
if (body.lastName) {
fullName = `${body.firstName} ${body.lastName}`;
}
const action = {
fullName: fullName,
firstName: body.firstName,
saveOnPrimaryAddressbook: true,
};
await this.sock.addOrEditContact(jid, action);
const updates: Partial<Contact>[] = [
{
id: jid,
name: fullName,
},
];
this.sock.ev.emit('contacts.update', updates);
}
async getContact(query: ContactQuery) {
const jid = toJID(query.contactId);
const contact = await this.store.getContactById(jid);
@@ -1742,7 +1768,10 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
public async channelsList(query: ListChannelsQuery): Promise<Channel[]> {
const newsletters = await this.sock.newsletterSubscribed();
let channels = newsletters.map(toNewsletterMetadata).map(this.toChannel);
let channels = newsletters
.map(toNewsletterMetadata)
.filter(Boolean)
.map(this.toChannel);
if (query.role) {
// @ts-ignore
channels = channels.filter((channel) => channel.role === query.role);
@@ -22,7 +22,7 @@ export class Sqlite3Storage extends INowebStorage {
constructor(filePath: string) {
super();
this.knex = Knex({
client: 'better-sqlite3',
client: 'sqlite3',
connection: { filename: filePath },
useNullAsDefault: true,
});
+3 -3
View File
@@ -49,7 +49,7 @@ export function TagReceiptNodeToReceiptEvent(
const { attrs, content } = node;
const status = getStatusFromReceiptType(attrs.type);
if (status == null) {
return null;
return [];
}
const from = jidNormalizedUser(jid(attrs.from));
@@ -118,14 +118,14 @@ function handleGroupedReceipts(
fromMe: boolean,
isLid: boolean,
me: Me,
): ReceiptEvent[] | null {
): ReceiptEvent[] {
const { content } = node;
if (!Array.isArray(content)) {
return [];
}
const participantsTags = content.filter((c) => c.tag === 'participants');
if (participantsTags.length === 0) {
return null;
return [];
}
const receiptEvents: ReceiptEvent[] = [];
+15 -1
View File
@@ -80,7 +80,11 @@ import {
SendSeenRequest,
WANumberExistResult,
} from '@waha/structures/chatting.dto';
import { ContactQuery, ContactRequest } from '@waha/structures/contacts.dto';
import {
ContactQuery,
ContactRequest,
ContactUpdateBody,
} from '@waha/structures/contacts.dto';
import {
ACK_UNKNOWN,
SECOND,
@@ -953,6 +957,16 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
/**
* Contacts methods
*/
public async upsertContact(chatId: string, body: ContactUpdateBody) {
const phoneNumber = chatId.split('@')[0];
await this.whatsapp.saveOrEditAddressbookContact(
phoneNumber,
body.firstName,
body.lastName,
true,
);
}
getContact(query: ContactQuery) {
return this.whatsapp
.getContactById(this.ensureSuffix(query.contactId))
+1 -1
View File
@@ -3,7 +3,7 @@ import { SessionConfig } from '../../structures/sessions.dto';
export abstract class ISessionConfigRepository {
abstract saveConfig(
sessionName: string,
config: SessionConfig | null,
config: SessionConfig,
): Promise<void>;
abstract getConfig(sessionName: string): Promise<SessionConfig | null>;
@@ -48,13 +48,13 @@ export class LocalSessionConfigRepository extends ISessionConfigRepository {
return JSON.parse(content);
}
async saveConfig(sessionName: string, config: SessionConfig | null) {
// Create folder if not exist
async saveConfig(sessionName: string, config: SessionConfig) {
// Create a folder if not exist
const folder = this.store.getSessionDirectory(sessionName);
await fs.mkdir(folder, { recursive: true });
// Save config
const filepath = this.getFilePath(sessionName);
const content = JSON.stringify(config || null);
const content = JSON.stringify(config || {});
await writeFileAtomic(filepath, content);
}
+1 -1
View File
@@ -68,7 +68,7 @@ export class LocalStoreCore extends LocalStore {
const engineDir = this.getEngineDirectory();
const database = path.join(engineDir, 'waha.sqlite3');
return Knex({
client: 'better-sqlite3',
client: 'sqlite3',
connection: { filename: database },
useNullAsDefault: true,
});
+18
View File
@@ -54,3 +54,21 @@ export class ContactRequest extends SessionBaseRequest {
@IsString()
contactId: string;
}
export class ContactUpdateBody {
@ApiProperty({
description: 'Contact First Name',
example: 'John',
required: true,
})
@IsString()
firstName: string = 'John';
@ApiProperty({
description: 'Contact Last Name',
example: 'Doe',
required: true,
})
@IsString()
lastName: string = 'Doe';
}
+6 -1
View File
@@ -7,6 +7,7 @@ import {
IsBoolean,
IsOptional,
IsString,
Matches,
MaxLength,
ValidateNested,
} from 'class-validator';
@@ -122,7 +123,7 @@ export class SessionConfig {
})
@IsBoolean()
@IsOptional()
debug: boolean;
debug?: boolean;
@ApiProperty({
example: {
@@ -179,6 +180,10 @@ export class SessionCreateRequest {
@IsString()
@IsOptional()
@MaxLength(DB_NAME_LIMIT - DB_NAME_MAX_PREFIX_LEN)
@Matches(/^[a-zA-Z0-9_-]*$/, {
message:
'Session name can only contain alphanumeric characters, hyphens, and underscores (a-z, A-Z, 0-9, -, _) or be empty',
})
name: string | undefined;
@ValidateNested()
+1 -1
View File
@@ -33,7 +33,7 @@ export function getEngineName(): string {
}
export const VERSION: WAHAEnvironment = {
version: '2025.7.7',
version: '2025.8.1',
engine: getEngineName(),
tier: getWAHAVersion(),
browser:
+2 -2
View File
@@ -2,11 +2,11 @@
"waha": {
"gows": {
"repo": "devlikeapro/gows",
"ref": "v1.0.9"
"ref": "v1.0.11"
},
"dashboard": {
"repo": "devlikeapro/dashboard",
"ref": "a74c4ede4e963dd7f4a0eebb9923e3e174ef51fd"
"ref": "59ebfe14fc89b42f77dd9da173d3e7e2983beb21"
}
}
}
+363 -27
View File
@@ -7,7 +7,7 @@ __metadata:
"@adiwajshing/baileys@github:devlikeapro/Baileys#fork-master-2025-07-04":
version: 6.7.18
resolution: "@adiwajshing/baileys@https://github.com/devlikeapro/Baileys.git#commit=599231e9f18be6ebe6e8eb48a5c57ec9f587ee5e"
resolution: "@adiwajshing/baileys@https://github.com/devlikeapro/Baileys.git#commit=bca2147eee9de863f5fd58673027a7286e559bed"
dependencies:
"@cacheable/node-cache": ^1.4.0
"@hapi/boom": ^9.1.3
@@ -33,7 +33,7 @@ __metadata:
optional: true
sharp:
optional: true
checksum: 4a0d0221ea30efbbe50dd3c639c45bed677da6688d550787b7c4fa2b3a1bb3992e3d3ebb920be2429113996c02e87a0801f94e6d6609f4ceaf8637b7490691ee
checksum: b20db4943ed6b228e5ec10a6916f4be0f68aee150337c94267e623ab0c6c396191b0d7c82c83bf8efd55f17d8a57c2e339d12fc47c0a8152b45e4c9aaf8f996f
languageName: node
linkType: hard
@@ -1271,6 +1271,13 @@ __metadata:
languageName: node
linkType: hard
"@gar/promisify@npm:^1.0.1":
version: 1.1.3
resolution: "@gar/promisify@npm:1.1.3"
checksum: 4059f790e2d07bf3c3ff3e0fec0daa8144fe35c1f6e0111c9921bd32106adaa97a4ab096ad7dab1e28ee6a9060083c4d1a4ada42a7f5f3f7a96b8812e2b757c1
languageName: node
linkType: hard
"@grpc/grpc-js@npm:^1.13.4":
version: 1.13.4
resolution: "@grpc/grpc-js@npm:1.13.4"
@@ -2392,19 +2399,19 @@ __metadata:
languageName: node
linkType: hard
"@nestjs/platform-express@npm:^11.0.0":
version: 11.1.3
resolution: "@nestjs/platform-express@npm:11.1.3"
"@nestjs/platform-express@npm:^11.1.5":
version: 11.1.5
resolution: "@nestjs/platform-express@npm:11.1.5"
dependencies:
cors: 2.8.5
express: 5.1.0
multer: 2.0.1
multer: 2.0.2
path-to-regexp: 8.2.0
tslib: 2.8.1
peerDependencies:
"@nestjs/common": ^11.0.0
"@nestjs/core": ^11.0.0
checksum: df28ad07b992b368e83e9b8d0215dd9115ec7e32106a72181843fa0db7ca6b724208bddf4f06505ceae97dc86e27367a109f676b3910d44feb6d771633845005
checksum: de4720511a4a7ac84002b9c778a8698ef80a95c4e925a9edd1f0d46a04dae0c8b0ad3b3c274881ac27aa29da9bde3df789fdb85a5e1d290a1a4c81b6c09ea273
languageName: node
linkType: hard
@@ -2621,6 +2628,16 @@ __metadata:
languageName: node
linkType: hard
"@npmcli/fs@npm:^1.0.0":
version: 1.1.1
resolution: "@npmcli/fs@npm:1.1.1"
dependencies:
"@gar/promisify": ^1.0.1
semver: ^7.3.5
checksum: f5ad92f157ed222e4e31c352333d0901df02c7c04311e42a81d8eb555d4ec4276ea9c635011757de20cc476755af33e91622838de573b17e52e2e7703f0a9965
languageName: node
linkType: hard
"@npmcli/fs@npm:^4.0.0":
version: 4.0.0
resolution: "@npmcli/fs@npm:4.0.0"
@@ -2630,6 +2647,16 @@ __metadata:
languageName: node
linkType: hard
"@npmcli/move-file@npm:^1.0.1":
version: 1.1.2
resolution: "@npmcli/move-file@npm:1.1.2"
dependencies:
mkdirp: ^1.0.4
rimraf: ^3.0.2
checksum: c96381d4a37448ea280951e46233f7e541058cf57a57d4094dd4bdcaae43fa5872b5f2eb6bfb004591a68e29c5877abe3cdc210cb3588cbf20ab2877f31a7de7
languageName: node
linkType: hard
"@nuxt/opencollective@npm:0.4.1":
version: 0.4.1
resolution: "@nuxt/opencollective@npm:0.4.1"
@@ -3446,6 +3473,13 @@ __metadata:
languageName: node
linkType: hard
"@tootallnate/once@npm:1":
version: 1.1.2
resolution: "@tootallnate/once@npm:1.1.2"
checksum: e1fb1bbbc12089a0cb9433dc290f97bddd062deadb6178ce9bcb93bb7c1aecde5e60184bc7065aec42fe1663622a213493c48bbd4972d931aae48315f18e1be9
languageName: node
linkType: hard
"@tootallnate/quickjs-emscripten@npm:^0.23.0":
version: 0.23.0
resolution: "@tootallnate/quickjs-emscripten@npm:0.23.0"
@@ -3817,6 +3851,15 @@ __metadata:
languageName: node
linkType: hard
"@types/sqlite3@npm:^5.1.0":
version: 5.1.0
resolution: "@types/sqlite3@npm:5.1.0"
dependencies:
sqlite3: "*"
checksum: 3301245c9b20569da719dab0df0ee5c6ee88709133254f9ba65d8822514483971f87a1580f750ec4af5528811e7beafc99c5ada84ced9534a02e3a921838ece6
languageName: node
linkType: hard
"@types/stack-utils@npm:^2.0.0":
version: 2.0.3
resolution: "@types/stack-utils@npm:2.0.3"
@@ -4279,7 +4322,7 @@ __metadata:
languageName: node
linkType: hard
"agent-base@npm:6":
"agent-base@npm:6, agent-base@npm:^6.0.2":
version: 6.0.2
resolution: "agent-base@npm:6.0.2"
dependencies:
@@ -4295,7 +4338,7 @@ __metadata:
languageName: node
linkType: hard
"agentkeepalive@npm:^4.5.0":
"agentkeepalive@npm:^4.1.3, agentkeepalive@npm:^4.5.0":
version: 4.6.0
resolution: "agentkeepalive@npm:4.6.0"
dependencies:
@@ -4304,6 +4347,16 @@ __metadata:
languageName: node
linkType: hard
"aggregate-error@npm:^3.0.0":
version: 3.1.0
resolution: "aggregate-error@npm:3.1.0"
dependencies:
clean-stack: ^2.0.0
indent-string: ^4.0.0
checksum: 1101a33f21baa27a2fa8e04b698271e64616b886795fd43c31068c07533c7b3facfcaf4e9e0cab3624bd88f729a592f1c901a1a229c9e490eafce411a8644b79
languageName: node
linkType: hard
"ajv-formats@npm:3.0.1":
version: 3.0.1
resolution: "ajv-formats@npm:3.0.1"
@@ -4546,6 +4599,16 @@ __metadata:
languageName: node
linkType: hard
"are-we-there-yet@npm:^3.0.0":
version: 3.0.1
resolution: "are-we-there-yet@npm:3.0.1"
dependencies:
delegates: ^1.0.0
readable-stream: ^3.6.0
checksum: 52590c24860fa7173bedeb69a4c05fb573473e860197f618b9a28432ee4379049336727ae3a1f9c4cb083114601c1140cee578376164d0e651217a9843f9fe83
languageName: node
linkType: hard
"arg@npm:^4.1.0":
version: 4.1.3
resolution: "arg@npm:4.1.3"
@@ -5221,6 +5284,32 @@ __metadata:
languageName: node
linkType: hard
"cacache@npm:^15.2.0":
version: 15.3.0
resolution: "cacache@npm:15.3.0"
dependencies:
"@npmcli/fs": ^1.0.0
"@npmcli/move-file": ^1.0.1
chownr: ^2.0.0
fs-minipass: ^2.0.0
glob: ^7.1.4
infer-owner: ^1.0.4
lru-cache: ^6.0.0
minipass: ^3.1.1
minipass-collect: ^1.0.2
minipass-flush: ^1.0.5
minipass-pipeline: ^1.2.2
mkdirp: ^1.0.3
p-map: ^4.0.0
promise-inflight: ^1.0.1
rimraf: ^3.0.2
ssri: ^8.0.1
tar: ^6.0.2
unique-filename: ^1.1.1
checksum: a07327c27a4152c04eb0a831c63c00390d90f94d51bb80624a66f4e14a6b6360bbf02a84421267bd4d00ca73ac9773287d8d7169e8d2eafe378d2ce140579db8
languageName: node
linkType: hard
"cacache@npm:^19.0.1":
version: 19.0.1
resolution: "cacache@npm:19.0.1"
@@ -5502,6 +5591,13 @@ __metadata:
languageName: node
linkType: hard
"clean-stack@npm:^2.0.0":
version: 2.2.0
resolution: "clean-stack@npm:2.2.0"
checksum: 2ac8cd2b2f5ec986a3c743935ec85b07bc174d5421a5efc8017e1f146a1cf5f781ae962618f416352103b32c9cd7e203276e8c28241bbe946160cab16149fb68
languageName: node
linkType: hard
"cli-boxes@npm:^2.2.1":
version: 2.2.1
resolution: "cli-boxes@npm:2.2.1"
@@ -5651,7 +5747,7 @@ __metadata:
languageName: node
linkType: hard
"color-support@npm:^1.1.2":
"color-support@npm:^1.1.2, color-support@npm:^1.1.3":
version: 1.1.3
resolution: "color-support@npm:1.1.3"
bin:
@@ -6011,7 +6107,7 @@ __metadata:
languageName: node
linkType: hard
"debug@npm:4, debug@npm:^4.0.1, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.4, debug@npm:^4.3.5, debug@npm:^4.4.0, debug@npm:^4.4.1":
"debug@npm:4, debug@npm:^4.0.1, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.3, debug@npm:^4.3.4, debug@npm:^4.3.5, debug@npm:^4.4.0, debug@npm:^4.4.1":
version: 4.4.1
resolution: "debug@npm:4.4.1"
dependencies:
@@ -6390,7 +6486,7 @@ __metadata:
languageName: node
linkType: hard
"encoding@npm:^0.1.13":
"encoding@npm:^0.1.12, encoding@npm:^0.1.13":
version: 0.1.13
resolution: "encoding@npm:0.1.13"
dependencies:
@@ -7499,6 +7595,22 @@ __metadata:
languageName: node
linkType: hard
"gauge@npm:^4.0.3":
version: 4.0.4
resolution: "gauge@npm:4.0.4"
dependencies:
aproba: ^1.0.3 || ^2.0.0
color-support: ^1.1.3
console-control-strings: ^1.1.0
has-unicode: ^2.0.1
signal-exit: ^3.0.7
string-width: ^4.2.3
strip-ansi: ^6.0.1
wide-align: ^1.1.5
checksum: 788b6bfe52f1dd8e263cda800c26ac0ca2ff6de0b6eee2fe0d9e3abf15e149b651bd27bf5226be10e6e3edb5c4e5d5985a5a1a98137e7a892f75eff76467ad2d
languageName: node
linkType: hard
"gensync@npm:^1.0.0-beta.2":
version: 1.0.0-beta.2
resolution: "gensync@npm:1.0.0-beta.2"
@@ -7865,7 +7977,7 @@ __metadata:
languageName: node
linkType: hard
"http-cache-semantics@npm:^4.1.1":
"http-cache-semantics@npm:^4.1.0, http-cache-semantics@npm:^4.1.1":
version: 4.2.0
resolution: "http-cache-semantics@npm:4.2.0"
checksum: 7a7246ddfce629f96832791176fd643589d954e6f3b49548dadb4290451961237fab8fcea41cd2008fe819d95b41c1e8b97f47d088afc0a1c81705287b4ddbcc
@@ -7885,6 +7997,17 @@ __metadata:
languageName: node
linkType: hard
"http-proxy-agent@npm:^4.0.1":
version: 4.0.1
resolution: "http-proxy-agent@npm:4.0.1"
dependencies:
"@tootallnate/once": 1
agent-base: 6
debug: 4
checksum: c6a5da5a1929416b6bbdf77b1aca13888013fe7eb9d59fc292e25d18e041bb154a8dfada58e223fc7b76b9b2d155a87e92e608235201f77d34aa258707963a82
languageName: node
linkType: hard
"http-proxy-agent@npm:^7.0.0, http-proxy-agent@npm:^7.0.1":
version: 7.0.2
resolution: "http-proxy-agent@npm:7.0.2"
@@ -7999,6 +8122,20 @@ __metadata:
languageName: node
linkType: hard
"indent-string@npm:^4.0.0":
version: 4.0.0
resolution: "indent-string@npm:4.0.0"
checksum: 824cfb9929d031dabf059bebfe08cf3137365e112019086ed3dcff6a0a7b698cb80cf67ccccde0e25b9e2d7527aa6cc1fed1ac490c752162496caba3e6699612
languageName: node
linkType: hard
"infer-owner@npm:^1.0.4":
version: 1.0.4
resolution: "infer-owner@npm:1.0.4"
checksum: 181e732764e4a0611576466b4b87dac338972b839920b2a8cde43642e4ed6bd54dc1fb0b40874728f2a2df9a1b097b8ff83b56d5f8f8e3927f837fdcb47d8a89
languageName: node
linkType: hard
"inflight@npm:^1.0.4":
version: 1.0.6
resolution: "inflight@npm:1.0.6"
@@ -8243,6 +8380,13 @@ __metadata:
languageName: node
linkType: hard
"is-lambda@npm:^1.0.1":
version: 1.0.1
resolution: "is-lambda@npm:1.0.1"
checksum: 93a32f01940220532e5948538699ad610d5924ac86093fcee83022252b363eb0cc99ba53ab084a04e4fb62bf7b5731f55496257a4c38adf87af9c4d352c71c35
languageName: node
linkType: hard
"is-map@npm:^2.0.3":
version: 2.0.3
resolution: "is-map@npm:2.0.3"
@@ -9405,6 +9549,15 @@ __metadata:
languageName: node
linkType: hard
"lru-cache@npm:^6.0.0":
version: 6.0.0
resolution: "lru-cache@npm:6.0.0"
dependencies:
yallist: ^4.0.0
checksum: f97f499f898f23e4585742138a22f22526254fdba6d75d41a1c2526b3b6cc5747ef59c5612ba7375f42aca4f8461950e925ba08c991ead0651b4918b7c978297
languageName: node
linkType: hard
"lru-cache@npm:^7.14.1":
version: 7.18.3
resolution: "lru-cache@npm:7.18.3"
@@ -9472,6 +9625,30 @@ __metadata:
languageName: node
linkType: hard
"make-fetch-happen@npm:^9.1.0":
version: 9.1.0
resolution: "make-fetch-happen@npm:9.1.0"
dependencies:
agentkeepalive: ^4.1.3
cacache: ^15.2.0
http-cache-semantics: ^4.1.0
http-proxy-agent: ^4.0.1
https-proxy-agent: ^5.0.0
is-lambda: ^1.0.1
lru-cache: ^6.0.0
minipass: ^3.1.3
minipass-collect: ^1.0.2
minipass-fetch: ^1.3.2
minipass-flush: ^1.0.5
minipass-pipeline: ^1.2.4
negotiator: ^0.6.2
promise-retry: ^2.0.1
socks-proxy-agent: ^6.0.0
ssri: ^8.0.0
checksum: 0eb371c85fdd0b1584fcfdf3dc3c62395761b3c14658be02620c310305a9a7ecf1617a5e6fb30c1d081c5c8aaf177fa133ee225024313afabb7aa6a10f1e3d04
languageName: node
linkType: hard
"makeerror@npm:1.0.12":
version: 1.0.12
resolution: "makeerror@npm:1.0.12"
@@ -9682,6 +9859,15 @@ __metadata:
languageName: node
linkType: hard
"minipass-collect@npm:^1.0.2":
version: 1.0.2
resolution: "minipass-collect@npm:1.0.2"
dependencies:
minipass: ^3.0.0
checksum: 14df761028f3e47293aee72888f2657695ec66bd7d09cae7ad558da30415fdc4752bbfee66287dcc6fd5e6a2fa3466d6c484dc1cbd986525d9393b9523d97f10
languageName: node
linkType: hard
"minipass-collect@npm:^2.0.1":
version: 2.0.1
resolution: "minipass-collect@npm:2.0.1"
@@ -9691,6 +9877,21 @@ __metadata:
languageName: node
linkType: hard
"minipass-fetch@npm:^1.3.2":
version: 1.4.1
resolution: "minipass-fetch@npm:1.4.1"
dependencies:
encoding: ^0.1.12
minipass: ^3.1.0
minipass-sized: ^1.0.3
minizlib: ^2.0.0
dependenciesMeta:
encoding:
optional: true
checksum: ec93697bdb62129c4e6c0104138e681e30efef8c15d9429dd172f776f83898471bc76521b539ff913248cc2aa6d2b37b652c993504a51cc53282563640f29216
languageName: node
linkType: hard
"minipass-fetch@npm:^4.0.0":
version: 4.0.1
resolution: "minipass-fetch@npm:4.0.1"
@@ -9715,7 +9916,7 @@ __metadata:
languageName: node
linkType: hard
"minipass-pipeline@npm:^1.2.4":
"minipass-pipeline@npm:^1.2.2, minipass-pipeline@npm:^1.2.4":
version: 1.2.4
resolution: "minipass-pipeline@npm:1.2.4"
dependencies:
@@ -9733,7 +9934,7 @@ __metadata:
languageName: node
linkType: hard
"minipass@npm:^3.0.0":
"minipass@npm:^3.0.0, minipass@npm:^3.1.0, minipass@npm:^3.1.1, minipass@npm:^3.1.3":
version: 3.3.6
resolution: "minipass@npm:3.3.6"
dependencies:
@@ -9763,7 +9964,7 @@ __metadata:
languageName: node
linkType: hard
"minizlib@npm:^2.1.1":
"minizlib@npm:^2.0.0, minizlib@npm:^2.1.1":
version: 2.1.2
resolution: "minizlib@npm:2.1.2"
dependencies:
@@ -9807,7 +10008,7 @@ __metadata:
languageName: node
linkType: hard
"mkdirp@npm:^1.0.3":
"mkdirp@npm:^1.0.3, mkdirp@npm:^1.0.4":
version: 1.0.4
resolution: "mkdirp@npm:1.0.4"
bin:
@@ -9935,9 +10136,9 @@ __metadata:
languageName: node
linkType: hard
"multer@npm:2.0.1":
version: 2.0.1
resolution: "multer@npm:2.0.1"
"multer@npm:2.0.2":
version: 2.0.2
resolution: "multer@npm:2.0.2"
dependencies:
append-field: ^1.0.0
busboy: ^1.6.0
@@ -9946,7 +10147,7 @@ __metadata:
object-assign: ^4.1.1
type-is: ^1.6.18
xtend: ^4.0.2
checksum: bcbc523108c337cdb0a3f2610fd743a8ad0b7ce773f1970c69e9a338ba3d4389ce3a6339a6bf66b80b96a7aa82442ae505121a2eaa07f3e843b342b84ce8bc2f
checksum: 187f3539b3d5b7f80a289288fc21d3e4116ab9ed21ac9b9ceb25272c7344d215e9572f7e7ed01edb876afddf24661b06578f2c0fc67f36655ebb51a13ccf83dc
languageName: node
linkType: hard
@@ -9995,6 +10196,13 @@ __metadata:
languageName: node
linkType: hard
"negotiator@npm:^0.6.2":
version: 0.6.4
resolution: "negotiator@npm:0.6.4"
checksum: 7ded10aa02a0707d1d12a9973fdb5954f98547ca7beb60e31cb3a403cc6e8f11138db7a3b0128425cf836fc85d145ec4ce983b2bdf83dca436af879c2d683510
languageName: node
linkType: hard
"negotiator@npm:^1.0.0":
version: 1.0.0
resolution: "negotiator@npm:1.0.0"
@@ -10044,6 +10252,15 @@ __metadata:
languageName: node
linkType: hard
"node-addon-api@npm:^7.0.0":
version: 7.1.1
resolution: "node-addon-api@npm:7.1.1"
dependencies:
node-gyp: latest
checksum: 46051999e3289f205799dfaf6bcb017055d7569090f0004811110312e2db94cb4f8654602c7eb77a60a1a05142cc2b96e1b5c56ca4622c41a5c6370787faaf30
languageName: node
linkType: hard
"node-cache@npm:5.1.2":
version: 5.1.2
resolution: "node-cache@npm:5.1.2"
@@ -10100,6 +10317,26 @@ __metadata:
languageName: node
linkType: hard
"node-gyp@npm:8.x":
version: 8.4.1
resolution: "node-gyp@npm:8.4.1"
dependencies:
env-paths: ^2.2.0
glob: ^7.1.4
graceful-fs: ^4.2.6
make-fetch-happen: ^9.1.0
nopt: ^5.0.0
npmlog: ^6.0.0
rimraf: ^3.0.2
semver: ^7.3.5
tar: ^6.1.2
which: ^2.0.2
bin:
node-gyp: bin/node-gyp.js
checksum: 341710b5da39d3660e6a886b37e210d33f8282047405c2e62c277bcc744c7552c5b8b972ebc3a7d5c2813794e60cc48c3ebd142c46d6e0321db4db6c92dd0355
languageName: node
linkType: hard
"node-gyp@npm:latest":
version: 11.2.0
resolution: "node-gyp@npm:11.2.0"
@@ -10198,6 +10435,18 @@ __metadata:
languageName: node
linkType: hard
"npmlog@npm:^6.0.0":
version: 6.0.2
resolution: "npmlog@npm:6.0.2"
dependencies:
are-we-there-yet: ^3.0.0
console-control-strings: ^1.1.0
gauge: ^4.0.3
set-blocking: ^2.0.0
checksum: ae238cd264a1c3f22091cdd9e2b106f684297d3c184f1146984ecbe18aaa86343953f26b9520dedd1b1372bc0316905b736c1932d778dbeb1fcf5a1001390e2a
languageName: node
linkType: hard
"nth-check@npm:^2.0.1":
version: 2.1.1
resolution: "nth-check@npm:2.1.1"
@@ -10415,6 +10664,15 @@ __metadata:
languageName: node
linkType: hard
"p-map@npm:^4.0.0":
version: 4.0.0
resolution: "p-map@npm:4.0.0"
dependencies:
aggregate-error: ^3.0.0
checksum: cb0ab21ec0f32ddffd31dfc250e3afa61e103ef43d957cc45497afe37513634589316de4eb88abdfd969fe6410c22c0b93ab24328833b8eb1ccc087fc0442a1c
languageName: node
linkType: hard
"p-map@npm:^7.0.2":
version: 7.0.3
resolution: "p-map@npm:7.0.3"
@@ -10986,6 +11244,13 @@ __metadata:
languageName: node
linkType: hard
"promise-inflight@npm:^1.0.1":
version: 1.0.1
resolution: "promise-inflight@npm:1.0.1"
checksum: 22749483091d2c594261517f4f80e05226d4d5ecc1fc917e1886929da56e22b5718b7f2a75f3807e7a7d471bc3be2907fe92e6e8f373ddf5c64bae35b5af3981
languageName: node
linkType: hard
"promise-retry@npm:^2.0.1":
version: 2.0.1
resolution: "promise-retry@npm:2.0.1"
@@ -12055,6 +12320,17 @@ __metadata:
languageName: node
linkType: hard
"socks-proxy-agent@npm:^6.0.0":
version: 6.2.1
resolution: "socks-proxy-agent@npm:6.2.1"
dependencies:
agent-base: ^6.0.2
debug: ^4.3.3
socks: ^2.6.2
checksum: 9ca089d489e5ee84af06741135c4b0d2022977dad27ac8d649478a114cdce87849e8d82b7c22b51501a4116e231241592946fc7fae0afc93b65030ee57084f58
languageName: node
linkType: hard
"socks-proxy-agent@npm:^8.0.3, socks-proxy-agent@npm:^8.0.5":
version: 8.0.5
resolution: "socks-proxy-agent@npm:8.0.5"
@@ -12066,6 +12342,16 @@ __metadata:
languageName: node
linkType: hard
"socks@npm:^2.6.2":
version: 2.8.6
resolution: "socks@npm:2.8.6"
dependencies:
ip-address: ^9.0.5
smart-buffer: ^4.2.0
checksum: 3d2a696d42d94b05b2a7e797b9291483d6768b23300b015353f34f8046cce35f23fe59300a38a77a9f0dee4274dd6c333afbdef628cf48f3df171bfb86c2d21c
languageName: node
linkType: hard
"socks@npm:^2.8.3":
version: 2.8.5
resolution: "socks@npm:2.8.5"
@@ -12149,6 +12435,27 @@ __metadata:
languageName: node
linkType: hard
"sqlite3@npm:*, sqlite3@npm:^5.1.7":
version: 5.1.7
resolution: "sqlite3@npm:5.1.7"
dependencies:
bindings: ^1.5.0
node-addon-api: ^7.0.0
node-gyp: 8.x
prebuild-install: ^7.1.1
tar: ^6.1.11
peerDependencies:
node-gyp: 8.x
dependenciesMeta:
node-gyp:
optional: true
peerDependenciesMeta:
node-gyp:
optional: true
checksum: 37e387b74e34aea3d0fc5cea76e14de3139e4bdbf6574ff6ca876c3b5e36e859b278e99922c179c14337cb0d487d8da8dbbaaf7d63fbab5928dc134a9d5db262
languageName: node
linkType: hard
"ssri@npm:^12.0.0":
version: 12.0.0
resolution: "ssri@npm:12.0.0"
@@ -12158,6 +12465,15 @@ __metadata:
languageName: node
linkType: hard
"ssri@npm:^8.0.0, ssri@npm:^8.0.1":
version: 8.0.1
resolution: "ssri@npm:8.0.1"
dependencies:
minipass: ^3.1.1
checksum: bc447f5af814fa9713aa201ec2522208ae0f4d8f3bda7a1f445a797c7b929a02720436ff7c478fb5edc4045adb02b1b88d2341b436a80798734e2494f1067b36
languageName: node
linkType: hard
"stack-utils@npm:^2.0.3":
version: 2.0.6
resolution: "stack-utils@npm:2.0.6"
@@ -12581,7 +12897,7 @@ __metadata:
languageName: node
linkType: hard
"tar@npm:^6.1.11":
"tar@npm:^6.0.2, tar@npm:^6.1.11, tar@npm:^6.1.2":
version: 6.2.1
resolution: "tar@npm:6.2.1"
dependencies:
@@ -13181,6 +13497,15 @@ __metadata:
languageName: node
linkType: hard
"unique-filename@npm:^1.1.1":
version: 1.1.1
resolution: "unique-filename@npm:1.1.1"
dependencies:
unique-slug: ^2.0.0
checksum: cf4998c9228cc7647ba7814e255dec51be43673903897b1786eff2ac2d670f54d4d733357eb08dea969aa5e6875d0e1bd391d668fbdb5a179744e7c7551a6f80
languageName: node
linkType: hard
"unique-filename@npm:^4.0.0":
version: 4.0.0
resolution: "unique-filename@npm:4.0.0"
@@ -13190,6 +13515,15 @@ __metadata:
languageName: node
linkType: hard
"unique-slug@npm:^2.0.0":
version: 2.0.2
resolution: "unique-slug@npm:2.0.2"
dependencies:
imurmurhash: ^0.1.4
checksum: 5b6876a645da08d505dedb970d1571f6cebdf87044cb6b740c8dbb24f0d6e1dc8bdbf46825fd09f994d7cf50760e6f6e063cfa197d51c5902c00a861702eb75a
languageName: node
linkType: hard
"unique-slug@npm:^5.0.0":
version: 5.0.0
resolution: "unique-slug@npm:5.0.0"
@@ -13348,7 +13682,7 @@ __metadata:
"@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/schematics": ^11.0.0
"@nestjs/serve-static": ^5.0.0
@@ -13363,6 +13697,7 @@ __metadata:
"@types/mustache": ^4.2.5
"@types/node": ^18.14.2
"@types/passport": ^1.0.17
"@types/sqlite3": ^5.1.0
"@types/supertest": ^2.0.8
"@types/ws": ^8.5.4
"@typescript-eslint/eslint-plugin": 3.9.1
@@ -13420,6 +13755,7 @@ __metadata:
rimraf: ^4.3.0
rxjs: ^7.8.1
sharp: ^0.33.4
sqlite3: ^5.1.7
supertest: ^4.0.2
swagger-ui-express: ^4.1.4
ts-jest: ^29.1.3
@@ -13525,7 +13861,7 @@ __metadata:
"whatsapp-web.js@github:devlikeapro/whatsapp-web.js#fork-main-2025-06-09":
version: 1.30.1-alpha.2
resolution: "whatsapp-web.js@https://github.com/devlikeapro/whatsapp-web.js.git#commit=3db9c9d867a0cb5be8525552ad2dc7de9ba42580"
resolution: "whatsapp-web.js@https://github.com/devlikeapro/whatsapp-web.js.git#commit=55581239a70ddb76e6fe32381d9f991557cf9df3"
dependencies:
"@pedroslopez/moduleraid": ^5.0.2
archiver: ^5.3.1
@@ -13543,7 +13879,7 @@ __metadata:
optional: true
unzipper:
optional: true
checksum: 6aeee54f021f48fcd73df7b3b26f785fe9ae376715b76de53d7a491dec60ff281b149754fab20be01192ff9bf7aa246a18475b14a69fb6e006ae23985b95ebcb
checksum: 2af8df50bf3f6225222417d3d21e63750cc520cf19636c5ffdd3e828b26c132b9f5acd36fc43a4d041a245ce1f75b3b080550f844cbf6142a322ce4ca73734c4
languageName: node
linkType: hard
@@ -13636,7 +13972,7 @@ __metadata:
languageName: node
linkType: hard
"which@npm:^2.0.1":
"which@npm:^2.0.1, which@npm:^2.0.2":
version: 2.0.2
resolution: "which@npm:2.0.2"
dependencies:
@@ -13658,7 +13994,7 @@ __metadata:
languageName: node
linkType: hard
"wide-align@npm:^1.1.2":
"wide-align@npm:^1.1.2, wide-align@npm:^1.1.5":
version: 1.1.5
resolution: "wide-align@npm:1.1.5"
dependencies: