@theotherwillembotha/node-red-whatsapp 0.0.55 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -21
- package/build/GenerateNodes.d.ts +2 -0
- package/build/GenerateNodes.d.ts.map +1 -0
- package/build/GenerateNodes.js +5 -7
- package/build/Nodes.html +1522 -538
- package/build/Nodes.js +52261 -14
- package/build/Plugins.html +37 -0
- package/build/Plugins.js +45828 -55
- package/build/index.d.ts +7 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +1 -0
- package/build/runtime/NodeManagerRuntime.js +140 -0
- package/build/whatsapp/node/WhatsappAccountConfigNode.d.ts +14 -0
- package/build/whatsapp/node/WhatsappAccountConfigNode.d.ts.map +1 -0
- package/build/whatsapp/node/WhatsappAccountConfigNode.js +7 -2
- package/build/whatsapp/node/WhatsappDynamicSendMessageNode.d.ts +19 -0
- package/build/whatsapp/node/WhatsappDynamicSendMessageNode.d.ts.map +1 -0
- package/build/whatsapp/node/WhatsappDynamicSendMessageNode.js +112 -0
- package/build/whatsapp/node/WhatsappGroupConfigNode.d.ts +16 -0
- package/build/whatsapp/node/WhatsappGroupConfigNode.d.ts.map +1 -0
- package/build/whatsapp/node/WhatsappGroupConfigNode.js +19 -8
- package/build/whatsapp/node/WhatsappReceiveMessageNode.d.ts +20 -0
- package/build/whatsapp/node/WhatsappReceiveMessageNode.d.ts.map +1 -0
- package/build/whatsapp/node/WhatsappReceiveMessageNode.js +2 -2
- package/build/whatsapp/node/WhatsappSendMessageNode.d.ts +17 -0
- package/build/whatsapp/node/WhatsappSendMessageNode.d.ts.map +1 -0
- package/build/whatsapp/node/WhatsappSendMessageNode.js +55 -33
- package/build/whatsapp/service/WhatsappClient.d.ts +189 -0
- package/build/whatsapp/service/WhatsappClient.d.ts.map +1 -0
- package/build/whatsapp/service/WhatsappClient.js +140 -14
- package/build/whatsapp/service/WhatsappService.d.ts +26 -0
- package/build/whatsapp/service/WhatsappService.d.ts.map +1 -0
- package/build/whatsapp/service/WhatsappService.js +85 -23
- package/build/whatsapp/service/WhatsappStore.d.ts +127 -0
- package/build/whatsapp/service/WhatsappStore.d.ts.map +1 -0
- package/build/whatsapp/service/WhatsappStore.js +10 -7
- package/package.json +11 -8
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { AuthenticationState, WASocket } from 'baileys';
|
|
2
|
+
import { MessageType, Role, WhatsappStore } from './WhatsappStore';
|
|
3
|
+
export interface WAClientConfig {
|
|
4
|
+
localConnectionId: string;
|
|
5
|
+
fileStorageRoot: string;
|
|
6
|
+
}
|
|
7
|
+
export interface WAClientDetails {
|
|
8
|
+
userID: string;
|
|
9
|
+
msisdn: string;
|
|
10
|
+
name?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface GroupMessage {
|
|
13
|
+
groupId: string;
|
|
14
|
+
replyTo?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface PendingAlbum {
|
|
17
|
+
chatId: string;
|
|
18
|
+
albumMessageId: string;
|
|
19
|
+
expectedImages: number;
|
|
20
|
+
expectedVideos: number;
|
|
21
|
+
receivedImages: number;
|
|
22
|
+
receivedVideos: number;
|
|
23
|
+
createdAt: number;
|
|
24
|
+
mediaIds: string[];
|
|
25
|
+
}
|
|
26
|
+
export declare const ALBUM_TIMEOUT_MS: number;
|
|
27
|
+
export interface GroupTextMessage extends GroupMessage {
|
|
28
|
+
text: string;
|
|
29
|
+
}
|
|
30
|
+
export interface GroupImageMessage extends GroupMessage {
|
|
31
|
+
image: Buffer;
|
|
32
|
+
}
|
|
33
|
+
export interface GoupMessageResult {
|
|
34
|
+
messageId: string;
|
|
35
|
+
}
|
|
36
|
+
export interface WhatsappTextMessage extends WhatsappMessage {
|
|
37
|
+
text: string;
|
|
38
|
+
}
|
|
39
|
+
export interface WhatsappImageMessage extends WhatsappMessage {
|
|
40
|
+
image: Buffer;
|
|
41
|
+
}
|
|
42
|
+
export interface WhatsappMessage {
|
|
43
|
+
timestamp: number;
|
|
44
|
+
messageId: string;
|
|
45
|
+
chat: {
|
|
46
|
+
id: string;
|
|
47
|
+
name: string;
|
|
48
|
+
};
|
|
49
|
+
sender: {
|
|
50
|
+
id: string;
|
|
51
|
+
name: string;
|
|
52
|
+
me: boolean;
|
|
53
|
+
};
|
|
54
|
+
type: MessageType;
|
|
55
|
+
payload: object;
|
|
56
|
+
}
|
|
57
|
+
export interface WhatsappSendMessageRequest {
|
|
58
|
+
text?: any;
|
|
59
|
+
image?: any;
|
|
60
|
+
video?: any;
|
|
61
|
+
document?: any;
|
|
62
|
+
documentName?: string;
|
|
63
|
+
documentMimetype?: string;
|
|
64
|
+
replyTo?: any;
|
|
65
|
+
}
|
|
66
|
+
export interface WhatsappSendMessageResponse {
|
|
67
|
+
messageId: string;
|
|
68
|
+
}
|
|
69
|
+
export interface WhatsappSubscribeFilter {
|
|
70
|
+
types?: MessageType[];
|
|
71
|
+
groupId?: string;
|
|
72
|
+
}
|
|
73
|
+
export declare class WhatsappClient {
|
|
74
|
+
private currentQRCode;
|
|
75
|
+
private onQRCodeListeners;
|
|
76
|
+
private onConnectionSuccessListeners;
|
|
77
|
+
private config;
|
|
78
|
+
private socket;
|
|
79
|
+
private store;
|
|
80
|
+
private state;
|
|
81
|
+
private messageSubscribers;
|
|
82
|
+
private subscriberKeys;
|
|
83
|
+
private logger;
|
|
84
|
+
private saveCreds;
|
|
85
|
+
private groupClients;
|
|
86
|
+
private pendingAlbums;
|
|
87
|
+
private albumCleanupTimer?;
|
|
88
|
+
private reconnectTimer?;
|
|
89
|
+
private _groupService;
|
|
90
|
+
constructor(config: WAClientConfig);
|
|
91
|
+
clientConfig(): WAClientConfig;
|
|
92
|
+
details(): WAClientDetails | null;
|
|
93
|
+
onQRCode(listener: (qrcode: string) => void): void;
|
|
94
|
+
groups(): GroupService;
|
|
95
|
+
getGroupClient(groupId: string): GroupClient;
|
|
96
|
+
subscribe(listener: (message: WhatsappMessage) => void, filter?: WhatsappSubscribeFilter): string;
|
|
97
|
+
unsubscribe(subscriber: Subscription): void;
|
|
98
|
+
private subscribers;
|
|
99
|
+
sendMessage(chatId: string, message: WhatsappSendMessageRequest): Promise<WhatsappSendMessageResponse>;
|
|
100
|
+
onConnectionSuccess(listener: () => void): void;
|
|
101
|
+
start(): Promise<void>;
|
|
102
|
+
private messages_upsert;
|
|
103
|
+
private messages_update;
|
|
104
|
+
private groups_upsert;
|
|
105
|
+
private group_participants_update;
|
|
106
|
+
private group_member_tag_update;
|
|
107
|
+
private connection_update;
|
|
108
|
+
private scheduleReconnect;
|
|
109
|
+
/**
|
|
110
|
+
* Normalises a JID for outbound sending:
|
|
111
|
+
* - @lid → resolves to phone-number JID via the contact store
|
|
112
|
+
* - contains "@" → assumed to be a fully-qualified JID; passed through unchanged
|
|
113
|
+
* - otherwise → treated as a bare phone number; non-digits are stripped and
|
|
114
|
+
* "@s.whatsapp.net" is appended (works for arbitrary contacts too)
|
|
115
|
+
*/
|
|
116
|
+
resolveJid(jid: string): Promise<string>;
|
|
117
|
+
stop(): Promise<void>;
|
|
118
|
+
private cleanupTimedOutAlbums;
|
|
119
|
+
private contacts_received;
|
|
120
|
+
private contacts_updated;
|
|
121
|
+
private messaging_history;
|
|
122
|
+
private chats_receieved;
|
|
123
|
+
private message_received;
|
|
124
|
+
/**
|
|
125
|
+
* Lookup or create the sender contact from a message.
|
|
126
|
+
* For received messages, uses lid-based lookup first (if addressingMode is "lid"),
|
|
127
|
+
* then falls back to id-based lookup.
|
|
128
|
+
* Creates a new contact if not found, and back-populates the name from pushName if missing.
|
|
129
|
+
*/
|
|
130
|
+
private lookupOrCreateSender;
|
|
131
|
+
private doNothing;
|
|
132
|
+
}
|
|
133
|
+
declare class GroupService {
|
|
134
|
+
private store;
|
|
135
|
+
private socket;
|
|
136
|
+
private state;
|
|
137
|
+
constructor(socket: WASocket, store: WhatsappStore, state: AuthenticationState);
|
|
138
|
+
getAll(): Promise<Group[]>;
|
|
139
|
+
createGroup(subject: string): Promise<Group>;
|
|
140
|
+
/**
|
|
141
|
+
* Add a user as a participant to a group.
|
|
142
|
+
* @param userId the Id of the user. should be in the phonenumber format: <phone>@s.whatsapp.net
|
|
143
|
+
* @param groupId the groupId. it is expectedd that the group is known and can be added to at this point.
|
|
144
|
+
* @param role the role that the user should be assigned.
|
|
145
|
+
* @returns nothing.
|
|
146
|
+
*/
|
|
147
|
+
addUserToGroup(userId: string, groupId: string, role: Role): Promise<void>;
|
|
148
|
+
/**
|
|
149
|
+
* Update a user's role in a group.
|
|
150
|
+
* @param userId the Id of the user. should be in the phonenumber format: <phone>@s.whatsapp.net
|
|
151
|
+
* @param groupId the groupId.
|
|
152
|
+
* @param role the new role for the user.
|
|
153
|
+
*/
|
|
154
|
+
updateUserRole(userId: string, groupId: string, role: Role): Promise<void>;
|
|
155
|
+
/**
|
|
156
|
+
* Remove a user from a group.
|
|
157
|
+
* @param userId the Id of the user. should be in the phonenumber format: <phone>@s.whatsapp.net
|
|
158
|
+
* @param groupId the groupId. it is expectedd that the group is known and can be added to at this point.
|
|
159
|
+
* @returns nothing
|
|
160
|
+
*/
|
|
161
|
+
removeUserFromGroup(userId: string, groupId: string): Promise<void>;
|
|
162
|
+
}
|
|
163
|
+
export declare class GroupClient {
|
|
164
|
+
private _client;
|
|
165
|
+
private _id;
|
|
166
|
+
constructor(client: WhatsappClient, id: string);
|
|
167
|
+
id(): string;
|
|
168
|
+
subscribe(subscription: Subscription): void;
|
|
169
|
+
unsubscribe(subscription: Subscription): void;
|
|
170
|
+
sendMessage(message: WhatsappSendMessageRequest): void;
|
|
171
|
+
}
|
|
172
|
+
export type Group = {
|
|
173
|
+
id: string;
|
|
174
|
+
subject: string;
|
|
175
|
+
participants: {
|
|
176
|
+
id: string;
|
|
177
|
+
name?: string;
|
|
178
|
+
role: Role;
|
|
179
|
+
label?: string;
|
|
180
|
+
isMe?: boolean;
|
|
181
|
+
}[];
|
|
182
|
+
};
|
|
183
|
+
export declare enum ChatType {
|
|
184
|
+
Group = "Group",
|
|
185
|
+
Conversation = "Conversation"
|
|
186
|
+
}
|
|
187
|
+
export type Subscription = (message: WhatsappMessage) => void;
|
|
188
|
+
export {};
|
|
189
|
+
//# sourceMappingURL=WhatsappClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WhatsappClient.d.ts","sourceRoot":"","sources":["../../../src/whatsapp/service/WhatsappClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -50,6 +50,7 @@ class WhatsappClient {
|
|
|
50
50
|
this.onQRCodeListeners = [];
|
|
51
51
|
this.onConnectionSuccessListeners = [];
|
|
52
52
|
this.messageSubscribers = {};
|
|
53
|
+
this.subscriberKeys = new Map();
|
|
53
54
|
this.groupClients = {};
|
|
54
55
|
this.pendingAlbums = new Map();
|
|
55
56
|
this.config = config;
|
|
@@ -58,11 +59,13 @@ class WhatsappClient {
|
|
|
58
59
|
return this.config;
|
|
59
60
|
}
|
|
60
61
|
details() {
|
|
61
|
-
|
|
62
|
-
|
|
62
|
+
if (!this.state?.creds?.me)
|
|
63
|
+
return null;
|
|
64
|
+
const userID = this.state.creds.me.id.replace(/:\d+(?=@)/, "");
|
|
63
65
|
return {
|
|
64
|
-
userID
|
|
65
|
-
msisdn: userID.substring(0, userID.indexOf("@"))
|
|
66
|
+
userID,
|
|
67
|
+
msisdn: userID.substring(0, userID.indexOf("@")),
|
|
68
|
+
name: this.state.creds.me.name ?? undefined,
|
|
66
69
|
};
|
|
67
70
|
}
|
|
68
71
|
onQRCode(listener) {
|
|
@@ -85,20 +88,21 @@ class WhatsappClient {
|
|
|
85
88
|
subscribe(listener, filter) {
|
|
86
89
|
let subscriberID = (0, uuid_1.v4)();
|
|
87
90
|
filter = filter ? filter : {};
|
|
88
|
-
console.log("subscribe to whatsapp messages", filter);
|
|
89
91
|
this.messageSubscribers[subscriberID] = (message) => {
|
|
90
|
-
console.log("Received message: ", message);
|
|
91
92
|
if ((!filter.groupId || filter.groupId === message.chat.id) &&
|
|
92
93
|
(!filter.types || filter.types.length === 0 || filter.types.indexOf(message.type) > -1)) {
|
|
93
94
|
listener(message);
|
|
94
95
|
}
|
|
95
96
|
};
|
|
97
|
+
this.subscriberKeys.set(listener, subscriberID);
|
|
96
98
|
return subscriberID;
|
|
97
99
|
}
|
|
98
100
|
unsubscribe(subscriber) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
101
|
+
const id = this.subscriberKeys.get(subscriber);
|
|
102
|
+
if (id) {
|
|
103
|
+
delete this.messageSubscribers[id];
|
|
104
|
+
this.subscriberKeys.delete(subscriber);
|
|
105
|
+
}
|
|
102
106
|
}
|
|
103
107
|
subscribers() {
|
|
104
108
|
return Object.values(this.messageSubscribers);
|
|
@@ -106,18 +110,30 @@ class WhatsappClient {
|
|
|
106
110
|
async sendMessage(chatId, message) {
|
|
107
111
|
let result;
|
|
108
112
|
if (message.image) {
|
|
109
|
-
// send image, with optional caption if text is provided
|
|
110
113
|
result = await this.socket.sendMessage(chatId, {
|
|
111
114
|
image: message.image,
|
|
112
115
|
caption: message.text
|
|
113
116
|
});
|
|
114
117
|
}
|
|
118
|
+
else if (message.video) {
|
|
119
|
+
result = await this.socket.sendMessage(chatId, {
|
|
120
|
+
video: message.video,
|
|
121
|
+
caption: message.text
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
else if (message.document) {
|
|
125
|
+
result = await this.socket.sendMessage(chatId, {
|
|
126
|
+
document: message.document,
|
|
127
|
+
fileName: message.documentName ?? 'document',
|
|
128
|
+
mimetype: message.documentMimetype ?? 'application/octet-stream',
|
|
129
|
+
caption: message.text
|
|
130
|
+
});
|
|
131
|
+
}
|
|
115
132
|
else if (message.text) {
|
|
116
|
-
// send text-only message
|
|
117
133
|
result = await this.socket.sendMessage(chatId, { text: message.text });
|
|
118
134
|
}
|
|
119
135
|
else {
|
|
120
|
-
throw new Error("Message must contain
|
|
136
|
+
throw new Error("Message must contain text, image, or video");
|
|
121
137
|
}
|
|
122
138
|
return { messageId: result.key.id };
|
|
123
139
|
}
|
|
@@ -336,6 +352,27 @@ class WhatsappClient {
|
|
|
336
352
|
this.start();
|
|
337
353
|
}, delayMs);
|
|
338
354
|
}
|
|
355
|
+
/**
|
|
356
|
+
* Normalises a JID for outbound sending:
|
|
357
|
+
* - @lid → resolves to phone-number JID via the contact store
|
|
358
|
+
* - contains "@" → assumed to be a fully-qualified JID; passed through unchanged
|
|
359
|
+
* - otherwise → treated as a bare phone number; non-digits are stripped and
|
|
360
|
+
* "@s.whatsapp.net" is appended (works for arbitrary contacts too)
|
|
361
|
+
*/
|
|
362
|
+
async resolveJid(jid) {
|
|
363
|
+
if (jid.endsWith("@lid")) {
|
|
364
|
+
const contact = await this.store.contacts().getByLid(jid);
|
|
365
|
+
if (contact)
|
|
366
|
+
return contact.id;
|
|
367
|
+
console.log(`resolveJid: cannot resolve LID ${jid} — sending as-is`);
|
|
368
|
+
return jid;
|
|
369
|
+
}
|
|
370
|
+
if (jid.includes("@"))
|
|
371
|
+
return jid;
|
|
372
|
+
// Bare phone number — strip formatting characters and construct JID
|
|
373
|
+
const digits = jid.replace(/\D/g, "");
|
|
374
|
+
return `${digits}@s.whatsapp.net`;
|
|
375
|
+
}
|
|
339
376
|
async stop() {
|
|
340
377
|
if (this.reconnectTimer) {
|
|
341
378
|
clearTimeout(this.reconnectTimer);
|
|
@@ -482,8 +519,11 @@ class WhatsappClient {
|
|
|
482
519
|
message.message?.contactMessage ? WhatsappStore_1.MessageType.Contact :
|
|
483
520
|
message.message?.locationMessage ? WhatsappStore_1.MessageType.Location :
|
|
484
521
|
message.message?.liveLocationMessage ? WhatsappStore_1.MessageType.LiveLocation :
|
|
485
|
-
message.
|
|
486
|
-
WhatsappStore_1.MessageType.
|
|
522
|
+
message.message?.eventMessage ? WhatsappStore_1.MessageType.Event :
|
|
523
|
+
message.message?.encEventResponseMessage ? WhatsappStore_1.MessageType.EventResponse :
|
|
524
|
+
message.message?.stickerMessage ? WhatsappStore_1.MessageType.Sticker :
|
|
525
|
+
message.messageStubType ? WhatsappStore_1.MessageType.Stub :
|
|
526
|
+
WhatsappStore_1.MessageType.Unknown;
|
|
487
527
|
if (messageType === WhatsappStore_1.MessageType.Unknown) {
|
|
488
528
|
if (baileys_1.proto.WebMessageInfo.StubType.BIZ_PRIVACY_MODE_TO_FB === message.messageStubType) {
|
|
489
529
|
return;
|
|
@@ -583,6 +623,16 @@ class WhatsappClient {
|
|
|
583
623
|
pageCount: docMsg.pageCount,
|
|
584
624
|
caption: docMsg.caption,
|
|
585
625
|
};
|
|
626
|
+
if (live) {
|
|
627
|
+
try {
|
|
628
|
+
const documentData = await (0, baileys_1.downloadMediaMessage)(message, 'buffer', {}, { logger: this.logger, reuploadRequest: this.socket.updateMediaMessage });
|
|
629
|
+
subscriberPayload = { ...messageContents, data: documentData };
|
|
630
|
+
}
|
|
631
|
+
catch (error) {
|
|
632
|
+
console.log("Failed to download document:", error);
|
|
633
|
+
subscriberPayload = { ...messageContents, data: null };
|
|
634
|
+
}
|
|
635
|
+
}
|
|
586
636
|
}
|
|
587
637
|
if (messageType === WhatsappStore_1.MessageType.Template) {
|
|
588
638
|
// the sensible way to handle this for now is to change it to a Text Mesasge.
|
|
@@ -676,6 +726,82 @@ class WhatsappClient {
|
|
|
676
726
|
sequenceNumber: loc.sequenceNumber != null ? String(loc.sequenceNumber) : undefined,
|
|
677
727
|
};
|
|
678
728
|
}
|
|
729
|
+
if (messageType === WhatsappStore_1.MessageType.Event) {
|
|
730
|
+
const evt = message.message?.eventMessage;
|
|
731
|
+
const secret = message.message?.messageContextInfo?.messageSecret;
|
|
732
|
+
messageContents = {
|
|
733
|
+
name: evt.name,
|
|
734
|
+
description: evt.description,
|
|
735
|
+
startTime: evt.startTime ? Number(evt.startTime) : undefined,
|
|
736
|
+
isCanceled: evt.isCanceled,
|
|
737
|
+
hasReminder: evt.hasReminder,
|
|
738
|
+
reminderOffsetSec: evt.reminderOffsetSec ? Number(evt.reminderOffsetSec) : undefined,
|
|
739
|
+
extraGuestsAllowed: evt.extraGuestsAllowed,
|
|
740
|
+
isScheduleCall: evt.isScheduleCall,
|
|
741
|
+
messageSecret: secret ? Buffer.from(secret).toString('base64') : undefined,
|
|
742
|
+
};
|
|
743
|
+
}
|
|
744
|
+
if (messageType === WhatsappStore_1.MessageType.EventResponse) {
|
|
745
|
+
const encResp = message.message?.encEventResponseMessage;
|
|
746
|
+
const creationKey = encResp.eventCreationMessageKey;
|
|
747
|
+
const originalMessage = await this.store.messages().get(creationKey.id);
|
|
748
|
+
const originalPayload = originalMessage ? JSON.parse(originalMessage.payload) : null;
|
|
749
|
+
const messageSecretB64 = originalPayload?.messageSecret;
|
|
750
|
+
if (!messageSecretB64) {
|
|
751
|
+
console.log("encEventResponseMessage: missing messageSecret for event", creationKey.id);
|
|
752
|
+
messageContents = { eventMessageId: creationKey.id, response: "unknown" };
|
|
753
|
+
}
|
|
754
|
+
else {
|
|
755
|
+
try {
|
|
756
|
+
// WhatsApp LID-addressed clients use raw LIDs (not resolved phone numbers) in key derivation.
|
|
757
|
+
const eventCreatorJid = creationKey.participant || creationKey.remoteJid || "";
|
|
758
|
+
const responderJid = message.key?.participant || message.key?.remoteJid || "";
|
|
759
|
+
const responseMsg = (0, baileys_1.decryptEventResponse)({ encPayload: encResp.encPayload, encIv: encResp.encIv }, {
|
|
760
|
+
eventEncKey: Buffer.from(messageSecretB64, 'base64'),
|
|
761
|
+
eventCreatorJid,
|
|
762
|
+
eventMsgId: creationKey.id,
|
|
763
|
+
responderJid,
|
|
764
|
+
});
|
|
765
|
+
const responseType = responseMsg.response;
|
|
766
|
+
const responseStr = responseType === baileys_1.proto.Message.EventResponseMessage.EventResponseType.GOING ? "going" :
|
|
767
|
+
responseType === baileys_1.proto.Message.EventResponseMessage.EventResponseType.NOT_GOING ? "not_going" :
|
|
768
|
+
responseType === baileys_1.proto.Message.EventResponseMessage.EventResponseType.MAYBE ? "maybe" :
|
|
769
|
+
"unknown";
|
|
770
|
+
messageContents = {
|
|
771
|
+
eventMessageId: creationKey.id,
|
|
772
|
+
response: responseStr,
|
|
773
|
+
timestampMs: responseMsg.timestampMs ? Number(responseMsg.timestampMs) : undefined,
|
|
774
|
+
extraGuestCount: responseMsg.extraGuestCount ?? undefined,
|
|
775
|
+
};
|
|
776
|
+
}
|
|
777
|
+
catch (error) {
|
|
778
|
+
console.log("encEventResponseMessage: decryption failed", error);
|
|
779
|
+
messageContents = { eventMessageId: creationKey.id, response: "unknown" };
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
if (messageType === WhatsappStore_1.MessageType.Sticker) {
|
|
784
|
+
const stickerMsg = message.message?.stickerMessage;
|
|
785
|
+
messageContents = {
|
|
786
|
+
mimetype: stickerMsg.mimetype,
|
|
787
|
+
width: stickerMsg.width,
|
|
788
|
+
height: stickerMsg.height,
|
|
789
|
+
fileLength: stickerMsg.fileLength ? Number(stickerMsg.fileLength) : undefined,
|
|
790
|
+
isAnimated: stickerMsg.isAnimated,
|
|
791
|
+
isLottie: stickerMsg.isLottie,
|
|
792
|
+
isAiSticker: stickerMsg.isAiSticker,
|
|
793
|
+
};
|
|
794
|
+
if (live) {
|
|
795
|
+
try {
|
|
796
|
+
const stickerData = await (0, baileys_1.downloadMediaMessage)(message, 'buffer', {}, { logger: this.logger, reuploadRequest: this.socket.updateMediaMessage });
|
|
797
|
+
subscriberPayload = { ...messageContents, data: stickerData };
|
|
798
|
+
}
|
|
799
|
+
catch (error) {
|
|
800
|
+
console.log("Failed to download sticker:", error);
|
|
801
|
+
subscriberPayload = { ...messageContents, data: null };
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
}
|
|
679
805
|
if (messageType === WhatsappStore_1.MessageType.Stub) {
|
|
680
806
|
// stub message. doesnt do much by the looks of it.
|
|
681
807
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { BaseService } from "@theotherwillembotha/node-red-plugincore";
|
|
2
|
+
import { NodeAPI, NodeAPISettingsWithData } from "node-red";
|
|
3
|
+
import { WhatsappClient } from "./WhatsappClient";
|
|
4
|
+
export declare class WhatsappService extends BaseService {
|
|
5
|
+
private red;
|
|
6
|
+
private configDir;
|
|
7
|
+
private configFile;
|
|
8
|
+
private connections;
|
|
9
|
+
private tempClients;
|
|
10
|
+
private static readonly _CLIENTS_KEY;
|
|
11
|
+
private static clients;
|
|
12
|
+
constructor();
|
|
13
|
+
init(red: NodeAPI<NodeAPISettingsWithData>): Promise<void>;
|
|
14
|
+
private saveConnectionDetails;
|
|
15
|
+
private getAccounts;
|
|
16
|
+
deinit(red: NodeAPI<NodeAPISettingsWithData>): Promise<void> | void;
|
|
17
|
+
static getClient(localConnectionId: string): WhatsappClient;
|
|
18
|
+
private linkAccount;
|
|
19
|
+
private unlinkaccount;
|
|
20
|
+
private getGroups;
|
|
21
|
+
private createGroup;
|
|
22
|
+
private groupAddUser;
|
|
23
|
+
private groupUpdateUser;
|
|
24
|
+
private groupRemoveUser;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=WhatsappService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WhatsappService.d.ts","sourceRoot":"","sources":["../../../src/whatsapp/service/WhatsappService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAsB,MAAM,0CAA0C,CAAA;AAC1F,OAAO,EAAE,OAAO,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAE5D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAMlD,qBAMa,eAAgB,SAAQ,WAAW;IAE5C,OAAO,CAAC,GAAG,CAAoC;IAC/C,OAAO,CAAC,SAAS,CAAU;IAC3B,OAAO,CAAC,UAAU,CAAU;IAC5B,OAAO,CAAC,WAAW,CAAmB;IACtC,OAAO,CAAC,WAAW,CAAoC;IAIvD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAA4B;IAChE,OAAO,CAAC,MAAM,CAAC,OAAO;IAQtB,cAEC;IAEY,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAqDtE;IAED,OAAO,CAAC,qBAAqB;IAiB7B,OAAO,CAAC,WAAW;IAoBZ,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAEzE;IAED,OAAc,SAAS,CAAC,iBAAiB,EAAE,MAAM,GAAG,cAAc,CAEjE;IAED,OAAO,CAAC,WAAW;IA6EnB,OAAO,CAAC,aAAa;YAwBP,SAAS;YAUT,WAAW;YAUX,YAAY;YAWZ,eAAe;YAWf,eAAe;CAWhC"}
|