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