[core] NOWEB, GOWS - add location and vcards

closes #1609
This commit is contained in:
Emir Muhammadzadeh authored and devlikepro committed 2025-11-14 10:23:28 +07:00
1 parent 31533b5d19
commit 87f79c1dc5
7 files changed
+130 -7

No files matched your search

+16 -1
View File
@@ -120,6 +120,7 @@ import {
} from '@waha/structures/presence.dto';
import {
MessageSource,
WALocation,
WAMessage,
WAMessageReaction,
} from '@waha/structures/responses.dto';
@@ -174,6 +175,9 @@ import {
import esm from '@waha/vendor/esm';
import { IsEditedMessage } from '@waha/core/utils/pwa';
import MessageServiceClient = messages.MessageServiceClient;
import { GoToJSWAProto } from '@waha/core/engines/gows/waproto';
import { extractWALocation } from '@waha/core/engines/waproto/locaiton';
import { extractVCards } from '@waha/core/engines/waproto/vcards';
enum WhatsMeowEvent {
CONNECTED = 'gows.ConnectedEventData',
@@ -2041,6 +2045,16 @@ export class WhatsappSessionGoWSCore extends WhatsappSession {
const mediaContent = extractMediaContent(message.Message);
const source = this.getSourceDeviceByMsg(message);
let waproto: proto.Message | null = null;
try {
waproto = GoToJSWAProto(message.Message);
} catch (e) {
this.logger.error(
'Failed to resolve proto message from GOWS to JS format',
);
this.logger.error(e, e.stack);
}
return {
id: id,
timestamp: parseTimestampToSeconds(message.Info.Timestamp),
@@ -2056,7 +2070,8 @@ export class WhatsappSessionGoWSCore extends WhatsappSession {
mediaUrl: message.media?.url,
// @ts-ignore
ack: ack,
// @ts-ignore
location: extractWALocation(waproto),
vCards: extractVCards(waproto),
ackName: WAMessageAck[ack] || ACK_UNKNOWN,
replyTo: replyTo,
_data: message,
+10 -3
View File
@@ -159,7 +159,11 @@ import {
WAHAChatPresences,
WAHAPresenceData,
} from '@waha/structures/presence.dto';
import { WAMessage, WAMessageReaction } from '@waha/structures/responses.dto';
import {
WALocation,
WAMessage,
WAMessageReaction,
} from '@waha/structures/responses.dto';
import { MeInfo } from '@waha/structures/sessions.dto';
import {
BROADCAST_ID,
@@ -205,6 +209,8 @@ import {
IsEditedMessage,
IsHistorySyncNotification,
} from '@waha/core/utils/pwa';
import { extractWALocation } from '@waha/core/engines/waproto/locaiton';
import { extractVCards } from '@waha/core/engines/waproto/vcards';
// eslint-disable-next-line @typescript-eslint/no-var-requires
const promiseRetry = require('promise-retry');
@@ -2280,6 +2286,7 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
const ack = message.ack || StatusToAck(message.status);
const mediaContent = extractMediaContent(message.message);
const source = this.getMessageSource(message.key.id);
const waproto = message.message;
return {
id: id,
timestamp: ensureNumber(message.messageTimestamp),
@@ -2297,8 +2304,8 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
ack: ack,
// @ts-ignore
ackName: WAMessageAck[ack] || ACK_UNKNOWN,
location: message.location,
vCards: message.vCards,
location: extractWALocation(waproto),
vCards: extractVCards(waproto),
replyTo: replyTo,
_data: message,
};
+34
View File
@@ -0,0 +1,34 @@
import type { proto } from '@adiwajshing/baileys';
import { WALocation } from '@waha/structures/responses.dto';
import * as lodash from 'lodash';
import { ensureBase64 } from '@waha/utils/bytes';
export function extractWALocation(waproto: proto.Message): WALocation | null {
if (!waproto) {
return null;
}
if (!lodash.isEmpty(waproto.locationMessage)) {
const location = waproto.locationMessage;
return {
live: false,
latitude: location.degreesLatitude?.toString(),
longitude: location.degreesLongitude?.toString(),
name: location.name,
address: location.address,
url: location.url,
description: location.comment,
thumbnail: ensureBase64(location.jpegThumbnail),
};
}
if (!lodash.isEmpty(waproto.liveLocationMessage)) {
const location = waproto.liveLocationMessage;
return {
live: true,
latitude: location.degreesLatitude?.toString(),
longitude: location.degreesLongitude?.toString(),
description: location.caption,
thumbnail: ensureBase64(location.jpegThumbnail),
};
}
return null;
}
+18
View File
@@ -0,0 +1,18 @@
import type { proto } from '@adiwajshing/baileys';
import * as lodash from 'lodash';
export function extractVCards(waproto: proto.Message): string[] | null {
if (!waproto) {
return null;
}
if (!lodash.isEmpty(waproto.contactMessage)) {
return [waproto.contactMessage.vcard];
}
if (!lodash.isEmpty(waproto.contactsArrayMessage)) {
return waproto.contactsArrayMessage.contacts.map(
(contact) => contact.vcard,
);
}
return null;
}
+24 -2
View File
@@ -110,7 +110,11 @@ import {
WAHAChatPresences,
WAHAPresenceData,
} from '@waha/structures/presence.dto';
import { WAMessage, WAMessageReaction } from '@waha/structures/responses.dto';
import {
WALocation,
WAMessage,
WAMessageReaction,
} from '@waha/structures/responses.dto';
import { BrowserTraceQuery } from '@waha/structures/server.debug.dto';
import { MeInfo } from '@waha/structures/sessions.dto';
import { StatusRequest, TextStatus } from '@waha/structures/status.dto';
@@ -1802,7 +1806,7 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
// @ts-ignore
ack: message.ack,
ackName: WAMessageAck[message.ack] || ACK_UNKNOWN,
location: message.location,
location: this.extractLocation(message),
vCards: message.vCards,
replyTo: replyTo,
_data: message.rawData,
@@ -1823,6 +1827,24 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
};
}
protected extractLocation(message: Message): WALocation | null {
const location = message.location;
if (lodash.isEmpty(location)) {
return null;
}
const rawData: any = message.rawData;
return {
live: Boolean(rawData.isLive),
latitude: location.latitude,
longitude: location.longitude,
name: location.name,
address: location.address,
description: rawData.comment || location.description,
url: location.url,
thumbnail: message.body,
};
}
public async getEngineInfo() {
if (!this.whatsapp || !this.whatsapp.pupPage) {
return null;
+6 -1
View File
@@ -6,9 +6,14 @@ import { WAMessageAck } from './enums.dto';
import { ChatIdProperty, MessageIdProperty } from './properties.dto';
export class WALocation {
description?: string;
latitude: string;
longitude: string;
live: boolean;
name?: string;
address?: string;
url?: string;
description?: string; // "comment" in proto
thumbnail?: string;
}
export enum MessageSource {
+22
View File
@@ -0,0 +1,22 @@
export function ensureBase64(
data: string | Uint8Array | ArrayBuffer | null | undefined,
): string | null | undefined {
// Preserves null or undefined
if (!data) {
return data as any;
}
// Already base64
if (typeof data === 'string') {
return data.trim();
}
if (data instanceof Uint8Array) {
return Buffer.from(data).toString('base64');
}
if (data instanceof ArrayBuffer) {
return Buffer.from(new Uint8Array(data)).toString('base64');
}
return null;
}