@meltwater/conversations-api-services 1.1.16 → 1.1.18

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.
@@ -150,11 +150,6 @@ async function privateMessage(token, messageText, inReplyToId, sourceId, mediaId
150
150
  };
151
151
  }
152
152
  async function publish(token, discussionType, mediaId, inReplyToId, socialAccountId, messageText, logger) {
153
- // for now this is needed to make the urns from the images api work until the docs are updated to reflect how to use these new ids.
154
- if (mediaId) {
155
- mediaId = mediaId.replace('urn:li:image:', 'urn:li:digitalmediaAsset:');
156
- }
157
-
158
153
  // Extract mentions from the messageText
159
154
  // https://learn.microsoft.com/en-us/linkedin/compliance/integrations/shares/ugc-post-api?tabs=http#memberattributedentity
160
155
  const mentionRegex = /<span class="highlight-mention" data-mention-id="([^"]+)"[^>]*>([^<]+)<\/span>/g;
@@ -193,11 +188,11 @@ async function publish(token, discussionType, mediaId, inReplyToId, socialAccoun
193
188
  body.parentComment = inReplyToId;
194
189
  }
195
190
  if (mediaId) {
191
+ const imageUrn = mediaId.replace('urn:li:digitalmediaAsset:', 'urn:li:image:');
196
192
  body.content = [{
197
193
  entity: {
198
- digitalmediaAsset: mediaId
199
- },
200
- type: 'IMAGE'
194
+ image: imageUrn
195
+ }
201
196
  }];
202
197
  }
203
198
  let query = `${LINKEDIN_API_REST}/socialActions/${fixedEncodeURIComponent(inReplyToId)}/comments`;
@@ -4,55 +4,71 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.isMention = isMention;
7
- function isMention(_ref, credential) {
8
- let {
9
- appData: {
10
- isMention = false
11
- } = {},
12
- body: {
13
- mentions = []
14
- } = {},
15
- metaData: {
16
- authors: [{
17
- authorInfo: {
18
- externalId: authorExternalId,
19
- handle: authorHandle
20
- } = {}
21
- } = {}] = [{}],
22
- inReplyTo: {
23
- author: {
24
- externalId: inReplyToExternalId,
25
- handle: inReplyToHandle
26
- } = {}
27
- } = {},
28
- discussionType = '',
29
- source: {
30
- socialOriginType
31
- } = {}
32
- } = {},
33
- providerSpecific
34
- } = _ref;
35
- if (socialOriginType == 'twitter' && discussionType != 'og') {
36
- return false;
7
+ var _externalId = require("./externalId.helpers");
8
+ function isMention(document, credentialTemp) {
9
+ const hasMentionCredential = trimApplicationTagsAndCheckForMentionCredential(document);
10
+
11
+ // normalize credential
12
+ const credential = {
13
+ pageName: credentialTemp.pageName || credentialTemp.target_page_name || credentialTemp.TargetPageName,
14
+ userName: credentialTemp.userName || credentialTemp.username || credentialTemp.Username,
15
+ socialAccountId: credentialTemp.socialAccountId || credentialTemp.social_account_id || credentialTemp.SocialAccountId,
16
+ credentialId: credentialTemp.credentialId || credentialTemp.credential_id || credentialTemp.CredentialId
17
+ };
18
+ let providerSpecificMention = false;
19
+ if (!hasMentionCredential && document.providerSpecific?.some(_ref => {
20
+ let {
21
+ facebookPostType
22
+ } = _ref;
23
+ return facebookPostType === 'mention';
24
+ })) {
25
+ providerSpecificMention = true;
37
26
  }
38
- // if inReplyToExternalId is the same as the credential's social_account_id, then it's not a mention
39
- if (inReplyToExternalId && credential.social_account_id && inReplyToExternalId === credential.social_account_id || inReplyToHandle === credential.username) {
40
- return false;
27
+ const mentionCredentials = document.metaData.applicationTags.filter(tag => tag.startsWith('mentionCredential='));
28
+ // Check if this is a mention based on multiple criteria
29
+ let isMention = false;
30
+
31
+ // Check if document type supports mentions
32
+ const supportsMentions = ['og', 're', 'qt'].includes(document.metaData.discussionType) || document.metaData.discussionType === 'dm' && document.metaData.source.socialOriginType === 'instagram';
33
+ if (supportsMentions) {
34
+ // New format: Check mentionCredentials (preferred method)
35
+ if (mentionCredentials.length > 0) {
36
+ isMention = mentionCredentials.includes(`mentionCredential=${credential.credentialId}`);
37
+ }
38
+ // Legacy format: Check body.mentions array
39
+ else if (document.body.mentions) {
40
+ const mentionMatches = document.body.mentions.some(mention => mention.toLowerCase() === credential.pageName.toLowerCase() || mention.toLowerCase() === (credential.userName || '').toLowerCase() || mention === credential.socialAccountId);
41
+ isMention = mentionMatches;
42
+ }
43
+ // Facebook-specific legacy logic
44
+ else if (providerSpecificMention && document.metaData.source.socialOriginType === 'facebook') {
45
+ isMention = true;
46
+ }
41
47
  }
42
- if (authorExternalId && credential.social_account_id && authorExternalId === credential.social_account_id || authorHandle?.length && (authorHandle.toLowerCase() === credential.username?.toLowerCase || authorHandle.toLowerCase() === credential.handle?.toLowerCase())) {
43
- return false;
48
+ // override isMention if the document is a direct reply to the credential
49
+ if ((0, _externalId.removePrefix)(document.metaData?.inReplyTo?.author?.externalId) === credential.socialAccountId) {
50
+ isMention = false;
44
51
  }
45
- let retIsMention = (['og', 're', 'qt'].includes(discussionType) || discussionType === 'dm' && socialOriginType === 'instagram') && (mentions?.length && mentions.some(mention => mention.toLowerCase() === credential.pageName?.toLowerCase() || mention.toLowerCase() === credential.target_page_name?.toLowerCase() || mention.toLowerCase() === credential.userName?.toLowerCase() || mention.toLowerCase() === credential.username?.toLowerCase() || mention.toLowerCase() === credential.social_account_id?.toLowerCase() || mention.toLowerCase() === credential.SocialAccountId?.toLowerCase()) || isMention && socialOriginType === 'facebook');
46
- if (providerSpecific) {
47
- let hasMention = providerSpecific.some(_ref2 => {
48
- let {
49
- facebookPostType
50
- } = _ref2;
51
- return facebookPostType === 'mention';
52
- });
53
- if (hasMention) {
54
- retIsMention = true;
52
+ return isMention;
53
+ }
54
+ function trimApplicationTagsAndCheckForMentionCredential(document) {
55
+ const connectionsCredentials = new Set(document.metaData.applicationTags.reduce((ids, tag) => {
56
+ if (tag.startsWith('connectionsCredential=')) {
57
+ ids.push(tag.split('=')[1]);
55
58
  }
56
- }
57
- return retIsMention;
59
+ return ids;
60
+ }, []));
61
+ let hasMentionCredential = false;
62
+ document.metaData.applicationTags = document.metaData.applicationTags.filter(tag => {
63
+ if (tag.startsWith('mentionCredential=')) {
64
+ hasMentionCredential = true;
65
+ const credentialId = tag.split('=')[1];
66
+ if (connectionsCredentials.has(credentialId)) {
67
+ document.metaData.selfMentionCredentialId = credentialId;
68
+ return false; // remove mentionCredential if it matches connectionsCredential
69
+ }
70
+ }
71
+ return true; // keep all other tags
72
+ });
73
+ return hasMentionCredential;
58
74
  }
@@ -128,11 +128,6 @@ export async function privateMessage(token, messageText, inReplyToId, sourceId,
128
128
  };
129
129
  }
130
130
  async function publish(token, discussionType, mediaId, inReplyToId, socialAccountId, messageText, logger) {
131
- // for now this is needed to make the urns from the images api work until the docs are updated to reflect how to use these new ids.
132
- if (mediaId) {
133
- mediaId = mediaId.replace('urn:li:image:', 'urn:li:digitalmediaAsset:');
134
- }
135
-
136
131
  // Extract mentions from the messageText
137
132
  // https://learn.microsoft.com/en-us/linkedin/compliance/integrations/shares/ugc-post-api?tabs=http#memberattributedentity
138
133
  const mentionRegex = /<span class="highlight-mention" data-mention-id="([^"]+)"[^>]*>([^<]+)<\/span>/g;
@@ -171,11 +166,11 @@ async function publish(token, discussionType, mediaId, inReplyToId, socialAccoun
171
166
  body.parentComment = inReplyToId;
172
167
  }
173
168
  if (mediaId) {
169
+ const imageUrn = mediaId.replace('urn:li:digitalmediaAsset:', 'urn:li:image:');
174
170
  body.content = [{
175
171
  entity: {
176
- digitalmediaAsset: mediaId
177
- },
178
- type: 'IMAGE'
172
+ image: imageUrn
173
+ }
179
174
  }];
180
175
  }
181
176
  let query = `${LINKEDIN_API_REST}/socialActions/${fixedEncodeURIComponent(inReplyToId)}/comments`;
@@ -1,52 +1,68 @@
1
- export function isMention(_ref, credential) {
2
- let {
3
- appData: {
4
- isMention = false
5
- } = {},
6
- body: {
7
- mentions = []
8
- } = {},
9
- metaData: {
10
- authors: [{
11
- authorInfo: {
12
- externalId: authorExternalId,
13
- handle: authorHandle
14
- } = {}
15
- } = {}] = [{}],
16
- inReplyTo: {
17
- author: {
18
- externalId: inReplyToExternalId,
19
- handle: inReplyToHandle
20
- } = {}
21
- } = {},
22
- discussionType = '',
23
- source: {
24
- socialOriginType
25
- } = {}
26
- } = {},
27
- providerSpecific
28
- } = _ref;
29
- if (socialOriginType == 'twitter' && discussionType != 'og') {
30
- return false;
1
+ import { removePrefix } from "./externalId.helpers";
2
+ export function isMention(document, credentialTemp) {
3
+ const hasMentionCredential = trimApplicationTagsAndCheckForMentionCredential(document);
4
+
5
+ // normalize credential
6
+ const credential = {
7
+ pageName: credentialTemp.pageName || credentialTemp.target_page_name || credentialTemp.TargetPageName,
8
+ userName: credentialTemp.userName || credentialTemp.username || credentialTemp.Username,
9
+ socialAccountId: credentialTemp.socialAccountId || credentialTemp.social_account_id || credentialTemp.SocialAccountId,
10
+ credentialId: credentialTemp.credentialId || credentialTemp.credential_id || credentialTemp.CredentialId
11
+ };
12
+ let providerSpecificMention = false;
13
+ if (!hasMentionCredential && document.providerSpecific?.some(_ref => {
14
+ let {
15
+ facebookPostType
16
+ } = _ref;
17
+ return facebookPostType === 'mention';
18
+ })) {
19
+ providerSpecificMention = true;
31
20
  }
32
- // if inReplyToExternalId is the same as the credential's social_account_id, then it's not a mention
33
- if (inReplyToExternalId && credential.social_account_id && inReplyToExternalId === credential.social_account_id || inReplyToHandle === credential.username) {
34
- return false;
21
+ const mentionCredentials = document.metaData.applicationTags.filter(tag => tag.startsWith('mentionCredential='));
22
+ // Check if this is a mention based on multiple criteria
23
+ let isMention = false;
24
+
25
+ // Check if document type supports mentions
26
+ const supportsMentions = ['og', 're', 'qt'].includes(document.metaData.discussionType) || document.metaData.discussionType === 'dm' && document.metaData.source.socialOriginType === 'instagram';
27
+ if (supportsMentions) {
28
+ // New format: Check mentionCredentials (preferred method)
29
+ if (mentionCredentials.length > 0) {
30
+ isMention = mentionCredentials.includes(`mentionCredential=${credential.credentialId}`);
31
+ }
32
+ // Legacy format: Check body.mentions array
33
+ else if (document.body.mentions) {
34
+ const mentionMatches = document.body.mentions.some(mention => mention.toLowerCase() === credential.pageName.toLowerCase() || mention.toLowerCase() === (credential.userName || '').toLowerCase() || mention === credential.socialAccountId);
35
+ isMention = mentionMatches;
36
+ }
37
+ // Facebook-specific legacy logic
38
+ else if (providerSpecificMention && document.metaData.source.socialOriginType === 'facebook') {
39
+ isMention = true;
40
+ }
35
41
  }
36
- if (authorExternalId && credential.social_account_id && authorExternalId === credential.social_account_id || authorHandle?.length && (authorHandle.toLowerCase() === credential.username?.toLowerCase || authorHandle.toLowerCase() === credential.handle?.toLowerCase())) {
37
- return false;
42
+ // override isMention if the document is a direct reply to the credential
43
+ if (removePrefix(document.metaData?.inReplyTo?.author?.externalId) === credential.socialAccountId) {
44
+ isMention = false;
38
45
  }
39
- let retIsMention = (['og', 're', 'qt'].includes(discussionType) || discussionType === 'dm' && socialOriginType === 'instagram') && (mentions?.length && mentions.some(mention => mention.toLowerCase() === credential.pageName?.toLowerCase() || mention.toLowerCase() === credential.target_page_name?.toLowerCase() || mention.toLowerCase() === credential.userName?.toLowerCase() || mention.toLowerCase() === credential.username?.toLowerCase() || mention.toLowerCase() === credential.social_account_id?.toLowerCase() || mention.toLowerCase() === credential.SocialAccountId?.toLowerCase()) || isMention && socialOriginType === 'facebook');
40
- if (providerSpecific) {
41
- let hasMention = providerSpecific.some(_ref2 => {
42
- let {
43
- facebookPostType
44
- } = _ref2;
45
- return facebookPostType === 'mention';
46
- });
47
- if (hasMention) {
48
- retIsMention = true;
46
+ return isMention;
47
+ }
48
+ function trimApplicationTagsAndCheckForMentionCredential(document) {
49
+ const connectionsCredentials = new Set(document.metaData.applicationTags.reduce((ids, tag) => {
50
+ if (tag.startsWith('connectionsCredential=')) {
51
+ ids.push(tag.split('=')[1]);
49
52
  }
50
- }
51
- return retIsMention;
53
+ return ids;
54
+ }, []));
55
+ let hasMentionCredential = false;
56
+ document.metaData.applicationTags = document.metaData.applicationTags.filter(tag => {
57
+ if (tag.startsWith('mentionCredential=')) {
58
+ hasMentionCredential = true;
59
+ const credentialId = tag.split('=')[1];
60
+ if (connectionsCredentials.has(credentialId)) {
61
+ document.metaData.selfMentionCredentialId = credentialId;
62
+ return false; // remove mentionCredential if it matches connectionsCredential
63
+ }
64
+ }
65
+ return true; // keep all other tags
66
+ });
67
+ return hasMentionCredential;
52
68
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meltwater/conversations-api-services",
3
- "version": "1.1.16",
3
+ "version": "1.1.18",
4
4
  "description": "Repository to contain all conversations api services shared across our services",
5
5
  "main": "dist/cjs/data-access/index.js",
6
6
  "module": "dist/esm/data-access/index.js",
@@ -172,14 +172,6 @@ export async function privateMessage(token, messageText, inReplyToId, sourceId,
172
172
  }
173
173
 
174
174
  async function publish(token,discussionType, mediaId,inReplyToId,socialAccountId, messageText, logger) {
175
- // for now this is needed to make the urns from the images api work until the docs are updated to reflect how to use these new ids.
176
- if (mediaId) {
177
- mediaId = mediaId.replace(
178
- 'urn:li:image:',
179
- 'urn:li:digitalmediaAsset:'
180
- );
181
- }
182
-
183
175
  // Extract mentions from the messageText
184
176
  // https://learn.microsoft.com/en-us/linkedin/compliance/integrations/shares/ugc-post-api?tabs=http#memberattributedentity
185
177
  const mentionRegex = /<span class="highlight-mention" data-mention-id="([^"]+)"[^>]*>([^<]+)<\/span>/g;
@@ -216,14 +208,15 @@ async function publish(token,discussionType, mediaId,inReplyToId,socialAccountId
216
208
  if (discussionType === 're') {
217
209
  body.parentComment = inReplyToId;
218
210
  }
211
+
219
212
  if (mediaId) {
213
+ const imageUrn = mediaId.replace('urn:li:digitalmediaAsset:', 'urn:li:image:');
220
214
  body.content = [
221
215
  {
222
216
  entity: {
223
- digitalmediaAsset: mediaId,
224
- },
225
- type: 'IMAGE',
226
- },
217
+ image: imageUrn
218
+ }
219
+ }
227
220
  ];
228
221
  }
229
222
 
@@ -1,92 +1,95 @@
1
+ import { removePrefix } from "./externalId.helpers";
1
2
 
2
3
 
3
4
 
4
- export function isMention({
5
- appData:{
6
- isMention = false,
7
- } = {},
8
- body:{
9
- mentions = []
10
- } = {},
11
- metaData:{
12
- authors:[
13
- {
14
- authorInfo:{
15
- externalId: authorExternalId,
16
- handle: authorHandle,
17
- } = {}
18
- } = {}
19
- ] = [{}],
20
- inReplyTo:{
21
- author:{
22
- externalId: inReplyToExternalId,
23
- handle: inReplyToHandle,
24
- } = {},
25
- } = {},
26
- discussionType = '',
27
- source:{
28
- socialOriginType
29
- } = {}
30
- } = {},
31
- providerSpecific,
32
- }, credential){
33
- if(socialOriginType == 'twitter' && discussionType != 'og'){
34
- return false;
35
- }
36
- // if inReplyToExternalId is the same as the credential's social_account_id, then it's not a mention
37
- if(inReplyToExternalId && credential.social_account_id &&
38
- (
39
- inReplyToExternalId === credential.social_account_id) ||
40
- inReplyToHandle === credential.username
41
- ){
42
- return false;
43
- }
5
+ export function isMention(document, credentialTemp) {
6
+ const hasMentionCredential = trimApplicationTagsAndCheckForMentionCredential(
7
+ document
8
+ );
9
+
10
+ // normalize credential
11
+ const credential = {
12
+ pageName: credentialTemp.pageName || credentialTemp.target_page_name || credentialTemp.TargetPageName,
13
+ userName: credentialTemp.userName || credentialTemp.username || credentialTemp.Username,
14
+ socialAccountId: credentialTemp.socialAccountId || credentialTemp.social_account_id || credentialTemp.SocialAccountId,
15
+ credentialId: credentialTemp.credentialId || credentialTemp.credential_id || credentialTemp.CredentialId,
44
16
 
45
- if(authorExternalId && credential.social_account_id &&
46
- (
47
- authorExternalId === credential.social_account_id) ||
48
- (
49
- authorHandle?.length &&
50
- (
51
- authorHandle.toLowerCase() === credential.username?.toLowerCase ||
52
- authorHandle.toLowerCase() === credential.handle?.toLowerCase()
53
- )
54
- )
55
- ){
56
- return false;
57
17
  }
58
-
59
- let retIsMention =
60
- (['og', 're', 'qt'].includes(discussionType) ||
61
- (discussionType === 'dm' &&
62
- socialOriginType ===
63
- 'instagram')) &&
64
- ((mentions?.length &&
65
- mentions.some(
66
- (mention) =>
67
- mention.toLowerCase() ===
68
- credential.pageName?.toLowerCase() ||
69
- mention.toLowerCase() ===
70
- credential.target_page_name?.toLowerCase() ||
71
- mention.toLowerCase() ===
72
- credential.userName?.toLowerCase() ||
73
- mention.toLowerCase() ===
74
- credential.username?.toLowerCase() ||
75
- mention.toLowerCase() ===
76
- credential.social_account_id?.toLowerCase() ||
77
- mention.toLowerCase() ===
78
- credential.SocialAccountId?.toLowerCase()
79
- ))
80
- ||
81
- (isMention && socialOriginType === 'facebook'));
82
- if (providerSpecific) {
83
- let hasMention = providerSpecific.some(
18
+ let providerSpecificMention = false;
19
+ if (
20
+ !hasMentionCredential &&
21
+ document.providerSpecific?.some(
84
22
  ({ facebookPostType }) => facebookPostType === 'mention'
85
- );
23
+ )
24
+ ) {
25
+ providerSpecificMention = true;
26
+ }
27
+ const mentionCredentials = document.metaData.applicationTags.filter((tag) =>
28
+ tag.startsWith('mentionCredential=')
29
+ );
30
+ // Check if this is a mention based on multiple criteria
31
+ let isMention = false;
86
32
 
87
- if (hasMention) {
88
- retIsMention = true;
33
+ // Check if document type supports mentions
34
+ const supportsMentions =
35
+ ['og', 're', 'qt'].includes(document.metaData.discussionType) ||
36
+ (document.metaData.discussionType === 'dm' &&
37
+ document.metaData.source.socialOriginType === 'instagram');
38
+
39
+ if (supportsMentions) {
40
+ // New format: Check mentionCredentials (preferred method)
41
+ if (mentionCredentials.length > 0) {
42
+ isMention = mentionCredentials.includes(
43
+ `mentionCredential=${credential.credentialId}`
44
+ );
45
+ }
46
+ // Legacy format: Check body.mentions array
47
+ else if (document.body.mentions) {
48
+ const mentionMatches = document.body.mentions.some(mention =>
49
+ mention.toLowerCase() === credential.pageName.toLowerCase() ||
50
+ mention.toLowerCase() === (credential.userName || '').toLowerCase() ||
51
+ mention === credential.socialAccountId
52
+ );
53
+ isMention = mentionMatches;
54
+ }
55
+ // Facebook-specific legacy logic
56
+ else if (providerSpecificMention &&
57
+ document.metaData.source.socialOriginType === 'facebook') {
58
+ isMention = true;
89
59
  }
90
60
  }
91
- return retIsMention;
92
- }
61
+ // override isMention if the document is a direct reply to the credential
62
+ if (
63
+ removePrefix(document.metaData?.inReplyTo?.author?.externalId) ===
64
+ credential.socialAccountId
65
+ ) {
66
+ isMention = false;
67
+ }
68
+ return isMention;
69
+ }
70
+
71
+ function trimApplicationTagsAndCheckForMentionCredential(document) {
72
+ const connectionsCredentials = new Set(
73
+ document.metaData.applicationTags.reduce((ids, tag) => {
74
+ if (tag.startsWith('connectionsCredential=')) {
75
+ ids.push(tag.split('=')[1]);
76
+ }
77
+ return ids;
78
+ }, [])
79
+ );
80
+ let hasMentionCredential = false;
81
+ document.metaData.applicationTags = document.metaData.applicationTags.filter(
82
+ (tag) => {
83
+ if (tag.startsWith('mentionCredential=')) {
84
+ hasMentionCredential = true;
85
+ const credentialId = tag.split('=')[1];
86
+ if (connectionsCredentials.has(credentialId)) {
87
+ document.metaData.selfMentionCredentialId = credentialId;
88
+ return false; // remove mentionCredential if it matches connectionsCredential
89
+ }
90
+ }
91
+ return true; // keep all other tags
92
+ }
93
+ );
94
+ return hasMentionCredential;
95
+ }