wexa-chat 0.3.2 → 0.3.4

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/dist/index.d.cts CHANGED
@@ -176,11 +176,13 @@ interface IMessage extends Document {
176
176
  linkedin?: {
177
177
  subject?: string;
178
178
  isInMail?: boolean;
179
+ linkedinApi?: string;
179
180
  senderName?: string;
180
181
  senderProfileUrl?: string;
181
182
  };
182
183
  whatsapp?: {
183
184
  senderName?: string;
185
+ senderPhone?: string;
184
186
  };
185
187
  };
186
188
  parentMessageId?: string;
@@ -276,6 +278,7 @@ type SendMessageArgs = {
276
278
  linkedin?: {
277
279
  subject?: string;
278
280
  isInMail?: boolean;
281
+ linkedinApi?: 'classic' | 'recruiter' | 'sales_navigator';
279
282
  };
280
283
  };
281
284
  };
@@ -302,6 +305,7 @@ type ReceiveWhatsappMessageArgs = {
302
305
  message: string;
303
306
  messageId?: string;
304
307
  senderName?: string;
308
+ senderPhone?: string;
305
309
  };
306
310
  type ReceiveLinkedinMessageArgs = {
307
311
  linkedinChatId: string;
package/dist/index.d.ts CHANGED
@@ -176,11 +176,13 @@ interface IMessage extends Document {
176
176
  linkedin?: {
177
177
  subject?: string;
178
178
  isInMail?: boolean;
179
+ linkedinApi?: string;
179
180
  senderName?: string;
180
181
  senderProfileUrl?: string;
181
182
  };
182
183
  whatsapp?: {
183
184
  senderName?: string;
185
+ senderPhone?: string;
184
186
  };
185
187
  };
186
188
  parentMessageId?: string;
@@ -276,6 +278,7 @@ type SendMessageArgs = {
276
278
  linkedin?: {
277
279
  subject?: string;
278
280
  isInMail?: boolean;
281
+ linkedinApi?: 'classic' | 'recruiter' | 'sales_navigator';
279
282
  };
280
283
  };
281
284
  };
@@ -302,6 +305,7 @@ type ReceiveWhatsappMessageArgs = {
302
305
  message: string;
303
306
  messageId?: string;
304
307
  senderName?: string;
308
+ senderPhone?: string;
305
309
  };
306
310
  type ReceiveLinkedinMessageArgs = {
307
311
  linkedinChatId: string;
package/dist/index.js CHANGED
@@ -594,32 +594,67 @@ function createMessagesService(models, hooks = {}) {
594
594
  const linkedinMeta = metadata == null ? void 0 : metadata.linkedin;
595
595
  lastLinkedInId = LinkedinConnector == null ? void 0 : LinkedinConnector.connectorId;
596
596
  if (LinkedinConnector) {
597
- tasks.push({
598
- name: "linkedin",
599
- run: async () => {
600
- const path = paths.linkedin.startChat(String(LinkedinConnector.connectorId));
601
- const payload = {
602
- linkedin_url: LinkedinConnector.contactId,
603
- text
604
- };
605
- if (linkedinMeta == null ? void 0 : linkedinMeta.subject) {
606
- payload.subject = linkedinMeta.subject;
607
- }
608
- if (linkedinMeta == null ? void 0 : linkedinMeta.isInMail) {
609
- payload.linkedin_inmail = linkedinMeta.isInMail;
610
- }
611
- console.log("LinkedIn payload:", payload);
612
- try {
613
- const res = await getAxios().post(path, payload);
614
- const data = res.data;
615
- console.log("linkedinChatId", data);
616
- linkedinChatId = data.chat_data.chat_id;
617
- return { status: "fulfilled", value: data };
618
- } catch (error) {
619
- return { status: "rejected", reason: error };
620
- }
597
+ if (linkedinMeta == null ? void 0 : linkedinMeta.isInMail) {
598
+ const missingFields = [];
599
+ if (!linkedinMeta.subject) missingFields.push("subject");
600
+ if (!linkedinMeta.linkedinApi) missingFields.push("linkedinApi");
601
+ if (missingFields.length > 0) {
602
+ failed_source.push({
603
+ source: "linkedin",
604
+ message: `InMail requires the following fields: ${missingFields.join(", ")}`
605
+ });
606
+ } else {
607
+ tasks.push({
608
+ name: "linkedin",
609
+ run: async () => {
610
+ const path = paths.linkedin.startChat(String(LinkedinConnector.connectorId));
611
+ const payload = {
612
+ linkedin_url: LinkedinConnector.contactId,
613
+ text
614
+ };
615
+ if (linkedinMeta.subject) {
616
+ payload.subject = linkedinMeta.subject;
617
+ }
618
+ if (linkedinMeta.linkedinApi) {
619
+ payload.linkedin_api = linkedinMeta.linkedinApi;
620
+ }
621
+ if (linkedinMeta.isInMail) {
622
+ payload.linkedin_inmail = linkedinMeta.isInMail;
623
+ }
624
+ try {
625
+ const res = await getAxios().post(path, payload);
626
+ const data = res.data;
627
+ linkedinChatId = data.chat_data.chat_id;
628
+ return { status: "fulfilled", value: data };
629
+ } catch (error) {
630
+ return { status: "rejected", reason: error };
631
+ }
632
+ }
633
+ });
621
634
  }
622
- });
635
+ } else {
636
+ tasks.push({
637
+ name: "linkedin",
638
+ run: async () => {
639
+ const path = paths.linkedin.startChat(String(LinkedinConnector.connectorId));
640
+ const payload = {
641
+ linkedin_url: LinkedinConnector.contactId,
642
+ text
643
+ };
644
+ if (linkedinMeta == null ? void 0 : linkedinMeta.linkedinApi) {
645
+ payload.linkedin_api = linkedinMeta.linkedinApi;
646
+ }
647
+ try {
648
+ const res = await getAxios().post(path, payload);
649
+ const data = res.data;
650
+ linkedinChatId = data.chat_data.chat_id;
651
+ return { status: "fulfilled", value: data };
652
+ } catch (error) {
653
+ return { status: "rejected", reason: error };
654
+ }
655
+ }
656
+ });
657
+ }
623
658
  } else {
624
659
  failed_source.push({ source: "linkedin", message: "Missing connector configuration" });
625
660
  }
@@ -793,121 +828,152 @@ function createMessagesService(models, hooks = {}) {
793
828
  return message;
794
829
  },
795
830
  /**
796
- * Receive a new message by whatsappChatId
831
+ * Receive a new message by whatsappChatId — delivers to ALL conversations
832
+ * that share this chatId (across organizations).
797
833
  */
798
834
  async receiveWhatsappMessage(args) {
799
- const { whatsappChatId, message, messageId, senderName } = args;
800
- const conversation = await Conversation.findOne({ whatsappChatId }).lean();
801
- if (!conversation) {
835
+ const { whatsappChatId, message, messageId, senderName, senderPhone } = args;
836
+ const conversations = await Conversation.find({ whatsappChatId }).lean();
837
+ if (!conversations.length) {
802
838
  throw new Error("Conversation not found for given whatsappChatId");
803
839
  }
804
- if (messageId) {
805
- const existingMessage = await Message.findOne({
806
- organizationId: conversation.organizationId,
807
- conversationId: String(conversation._id),
808
- externalMessageId: messageId
809
- }).lean();
810
- if (existingMessage) {
811
- console.log(`Duplicate WhatsApp message detected: ${messageId}`);
812
- return existingMessage;
840
+ let lastSavedMessage = null;
841
+ for (const conversation of conversations) {
842
+ if (messageId) {
843
+ const existingMessage = await Message.findOne({
844
+ organizationId: conversation.organizationId,
845
+ conversationId: String(conversation._id),
846
+ externalMessageId: messageId
847
+ }).lean();
848
+ if (existingMessage) {
849
+ console.log(`Duplicate WhatsApp message detected for conversation ${conversation._id}: ${messageId}`);
850
+ lastSavedMessage = existingMessage;
851
+ continue;
852
+ }
813
853
  }
814
- }
815
- const applicationParticipant = conversation.participants.find(
816
- (p) => p.entityModel === "Application"
817
- );
818
- if (!applicationParticipant) {
819
- throw new Error("Application participant not found in conversation");
820
- }
821
- const orgId = conversation.organizationId;
822
- const senderModel = "Application";
823
- const senderId = applicationParticipant.entityId;
824
- const msgDoc = new Message({
825
- organizationId: orgId,
826
- conversationId: String(conversation._id),
827
- senderModel,
828
- senderId,
829
- text: message,
830
- kind: "text",
831
- source: ["whatsapp"],
832
- externalMessageId: messageId,
833
- parentMessageId: void 0,
834
- rootThreadId: void 0,
835
- metadata: senderName ? {
836
- whatsapp: {
837
- senderName
854
+ const applicationParticipant = conversation.participants.find(
855
+ (p) => p.entityModel === "Application"
856
+ );
857
+ if (!applicationParticipant) {
858
+ console.log(`Application participant not found in conversation ${conversation._id}, skipping`);
859
+ continue;
860
+ }
861
+ const orgId = conversation.organizationId;
862
+ const senderModel = "Application";
863
+ const senderId = applicationParticipant.entityId;
864
+ const msgDoc = new Message({
865
+ organizationId: orgId,
866
+ conversationId: String(conversation._id),
867
+ senderModel,
868
+ senderId,
869
+ text: message,
870
+ kind: "text",
871
+ source: ["whatsapp"],
872
+ externalMessageId: messageId,
873
+ parentMessageId: void 0,
874
+ rootThreadId: void 0,
875
+ metadata: senderName || senderPhone ? {
876
+ whatsapp: {
877
+ senderName,
878
+ senderPhone
879
+ }
880
+ } : void 0
881
+ });
882
+ try {
883
+ await msgDoc.save();
884
+ } catch (saveError) {
885
+ if ((saveError == null ? void 0 : saveError.code) === 11e3) {
886
+ console.log(`Duplicate key for conversation ${conversation._id}, already saved by concurrent request`);
887
+ continue;
838
888
  }
839
- } : void 0
840
- });
841
- await msgDoc.save();
842
- await Conversation.findByIdAndUpdate(conversation._id, {
843
- $set: {
844
- lastMessageAt: msgDoc.createdAt,
845
- lastMessagePreview: message.substring(0, 100),
846
- lastMessageSenderId: senderId,
847
- lastMessageSenderModel: senderModel
889
+ throw saveError;
848
890
  }
849
- });
850
- if (onMessageCreated) onMessageCreated(msgDoc);
851
- return msgDoc;
891
+ await Conversation.findByIdAndUpdate(conversation._id, {
892
+ $set: {
893
+ lastMessageAt: msgDoc.createdAt,
894
+ lastMessagePreview: message.substring(0, 100),
895
+ lastMessageSenderId: senderId,
896
+ lastMessageSenderModel: senderModel
897
+ }
898
+ });
899
+ if (onMessageCreated) onMessageCreated(msgDoc);
900
+ lastSavedMessage = msgDoc;
901
+ }
902
+ return lastSavedMessage;
852
903
  },
853
904
  /**
854
- * Receive a new message by linkedinChatId
905
+ * Receive a new message by linkedinChatId — delivers to ALL conversations
906
+ * that share this chatId (across organizations).
855
907
  */
856
908
  async receiveLinkedinMessage(args) {
857
909
  const { linkedinChatId, message, messageId, senderName, senderProfileUrl } = args;
858
- const conversation = await Conversation.findOne({ linkedinChatId }).sort({ lastMessageAt: -1 }).lean();
859
- if (!conversation) {
910
+ const conversations = await Conversation.find({ linkedinChatId }).lean();
911
+ if (!conversations.length) {
860
912
  throw new Error("Conversation not found for given linkedinChatId");
861
913
  }
862
- if (messageId) {
863
- const existingMessage = await Message.findOne({
864
- organizationId: conversation.organizationId,
865
- conversationId: String(conversation._id),
866
- externalMessageId: messageId
867
- }).lean();
868
- if (existingMessage) {
869
- console.log(`Duplicate LinkedIn message detected: ${messageId}`);
870
- return existingMessage;
914
+ let lastSavedMessage = null;
915
+ for (const conversation of conversations) {
916
+ if (messageId) {
917
+ const existingMessage = await Message.findOne({
918
+ organizationId: conversation.organizationId,
919
+ conversationId: String(conversation._id),
920
+ externalMessageId: messageId
921
+ }).lean();
922
+ if (existingMessage) {
923
+ console.log(`Duplicate LinkedIn message detected for conversation ${conversation._id}: ${messageId}`);
924
+ lastSavedMessage = existingMessage;
925
+ continue;
926
+ }
871
927
  }
872
- }
873
- const applicationParticipant = conversation.participants.find(
874
- (p) => p.entityModel === "Application"
875
- );
876
- if (!applicationParticipant) {
877
- throw new Error("Application participant not found in conversation");
878
- }
879
- const orgId = conversation.organizationId;
880
- const senderModel = "Application";
881
- const senderId = applicationParticipant.entityId;
882
- const msgDoc = new Message({
883
- organizationId: orgId,
884
- conversationId: String(conversation._id),
885
- senderModel,
886
- senderId,
887
- text: message,
888
- kind: "text",
889
- source: ["linkedin"],
890
- externalMessageId: messageId,
891
- parentMessageId: void 0,
892
- rootThreadId: void 0,
893
- metadata: senderName || senderProfileUrl ? {
894
- linkedin: {
895
- senderName,
896
- senderProfileUrl
928
+ const applicationParticipant = conversation.participants.find(
929
+ (p) => p.entityModel === "Application"
930
+ );
931
+ if (!applicationParticipant) {
932
+ console.log(`Application participant not found in conversation ${conversation._id}, skipping`);
933
+ continue;
934
+ }
935
+ const orgId = conversation.organizationId;
936
+ const senderModel = "Application";
937
+ const senderId = applicationParticipant.entityId;
938
+ const msgDoc = new Message({
939
+ organizationId: orgId,
940
+ conversationId: String(conversation._id),
941
+ senderModel,
942
+ senderId,
943
+ text: message,
944
+ kind: "text",
945
+ source: ["linkedin"],
946
+ externalMessageId: messageId,
947
+ parentMessageId: void 0,
948
+ rootThreadId: void 0,
949
+ metadata: senderName || senderProfileUrl ? {
950
+ linkedin: {
951
+ senderName,
952
+ senderProfileUrl
953
+ }
954
+ } : void 0
955
+ });
956
+ try {
957
+ await msgDoc.save();
958
+ } catch (saveError) {
959
+ if ((saveError == null ? void 0 : saveError.code) === 11e3) {
960
+ console.log(`Duplicate key for conversation ${conversation._id}, already saved by concurrent request`);
961
+ continue;
897
962
  }
898
- } : void 0
899
- });
900
- await msgDoc.save();
901
- await Conversation.findByIdAndUpdate(conversation._id, {
902
- $set: {
903
- lastMessageAt: msgDoc.createdAt,
904
- lastMessagePreview: message.substring(0, 100),
905
- lastMessageSenderId: senderId,
906
- lastMessageSenderModel: senderModel
963
+ throw saveError;
907
964
  }
908
- });
909
- if (onMessageCreated) onMessageCreated(msgDoc);
910
- return msgDoc;
965
+ await Conversation.findByIdAndUpdate(conversation._id, {
966
+ $set: {
967
+ lastMessageAt: msgDoc.createdAt,
968
+ lastMessagePreview: message.substring(0, 100),
969
+ lastMessageSenderId: senderId,
970
+ lastMessageSenderModel: senderModel
971
+ }
972
+ });
973
+ if (onMessageCreated) onMessageCreated(msgDoc);
974
+ lastSavedMessage = msgDoc;
975
+ }
976
+ return lastSavedMessage;
911
977
  },
912
978
  /**
913
979
  * Receive a new message by emailChatId with full email metadata