@sellable/mcp 0.1.219 → 0.1.221
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/server.js +7 -1
- package/dist/tools/csv-linkedin.js +149 -22
- package/dist/tools/leads.d.ts +1721 -220
- package/dist/tools/leads.js +509 -3
- package/dist/tools/linkedin.d.ts +37 -0
- package/dist/tools/linkedin.js +47 -17
- package/dist/tools/registry.d.ts +1655 -176
- package/package.json +1 -1
- package/skills/create-campaign/SKILL.md +14 -0
- package/skills/create-campaign/core/flow.v1.json +2 -0
- package/skills/create-campaign/core/providers/prospeo.json +6 -2
- package/skills/create-campaign/references/provider-selection-strategy.md +8 -0
- package/skills/create-campaign-v2/SKILL.md +9 -1
- package/skills/create-campaign-v2/core/flow.v2.json +1 -1
- package/skills/find-leads/SKILL.md +13 -0
- package/skills/providers/prospeo.md +109 -1
- package/skills/research/config.json +0 -9
package/dist/tools/linkedin.js
CHANGED
|
@@ -137,6 +137,51 @@ export const linkedinToolDefinitions = [
|
|
|
137
137
|
},
|
|
138
138
|
},
|
|
139
139
|
];
|
|
140
|
+
function normalizePostDate(post) {
|
|
141
|
+
if (post.activityDate)
|
|
142
|
+
return post.activityDate;
|
|
143
|
+
if (typeof post.postedAt === "string")
|
|
144
|
+
return post.postedAt;
|
|
145
|
+
if (post.postedAt?.date)
|
|
146
|
+
return post.postedAt.date;
|
|
147
|
+
if (typeof post.postedAt?.timestamp === "number") {
|
|
148
|
+
return new Date(post.postedAt.timestamp).toISOString();
|
|
149
|
+
}
|
|
150
|
+
return "";
|
|
151
|
+
}
|
|
152
|
+
function normalizePostUrl(post) {
|
|
153
|
+
return (post.activityUrl ||
|
|
154
|
+
post.linkedinUrl ||
|
|
155
|
+
post.shareLinkedinUrl ||
|
|
156
|
+
post.socialContent?.shareUrl ||
|
|
157
|
+
post.header?.linkedinUrl ||
|
|
158
|
+
"");
|
|
159
|
+
}
|
|
160
|
+
function serializeLinkedInPost(post) {
|
|
161
|
+
return {
|
|
162
|
+
text: post.text || post.content || "",
|
|
163
|
+
date: normalizePostDate(post),
|
|
164
|
+
reactions: post.reactionsCount ?? post.engagement?.likes ?? 0,
|
|
165
|
+
comments: post.commentsCount ?? post.engagement?.comments ?? 0,
|
|
166
|
+
url: normalizePostUrl(post),
|
|
167
|
+
isRepost: Boolean(post.isRepublishedPost || post.repostedBy || post.repostedAt),
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
function isUsableSerializedPost(post) {
|
|
171
|
+
return Boolean(post.text.trim() ||
|
|
172
|
+
post.date ||
|
|
173
|
+
post.url ||
|
|
174
|
+
post.reactions > 0 ||
|
|
175
|
+
post.comments > 0);
|
|
176
|
+
}
|
|
177
|
+
export function serializeLinkedInPosts(rawPosts, context) {
|
|
178
|
+
const raw = rawPosts || [];
|
|
179
|
+
const posts = raw.map(serializeLinkedInPost).filter(isUsableSerializedPost);
|
|
180
|
+
if (raw.length > 0 && posts.length === 0) {
|
|
181
|
+
throw new Error(`${context} returned ${raw.length} post placeholder row(s), but none contained usable text, date, URL, or engagement data.`);
|
|
182
|
+
}
|
|
183
|
+
return posts;
|
|
184
|
+
}
|
|
140
185
|
export async function fetchLinkedInPosts(linkedinUrl, limit = 25) {
|
|
141
186
|
const api = getApi();
|
|
142
187
|
const normalizedLinkedinUrl = normalizeLinkedInProfileInput(linkedinUrl);
|
|
@@ -145,15 +190,7 @@ export async function fetchLinkedInPosts(linkedinUrl, limit = 25) {
|
|
|
145
190
|
limit: String(limit),
|
|
146
191
|
});
|
|
147
192
|
const response = await api.get(`/api/v1/scrape/linkedin/user-posts?${params.toString()}`);
|
|
148
|
-
|
|
149
|
-
const posts = (response.posts || []).map((post) => ({
|
|
150
|
-
text: post.text || "",
|
|
151
|
-
date: post.activityDate || "",
|
|
152
|
-
reactions: post.reactionsCount || 0,
|
|
153
|
-
comments: post.commentsCount || 0,
|
|
154
|
-
url: post.activityUrl || "",
|
|
155
|
-
isRepost: post.isRepublishedPost || false,
|
|
156
|
-
}));
|
|
193
|
+
const posts = serializeLinkedInPosts(response.posts, "LinkedIn user posts fetch");
|
|
157
194
|
return {
|
|
158
195
|
posts,
|
|
159
196
|
count: posts.length,
|
|
@@ -198,14 +235,7 @@ export async function fetchCompanyPosts(companyUrl, limit = 25, sortBy = "recent
|
|
|
198
235
|
sortBy,
|
|
199
236
|
});
|
|
200
237
|
const response = await api.get(`/api/v1/scrape/linkedin/company-posts?${params.toString()}`);
|
|
201
|
-
const posts = (response.posts
|
|
202
|
-
text: post.text || "",
|
|
203
|
-
date: post.activityDate || "",
|
|
204
|
-
reactions: post.reactionsCount || 0,
|
|
205
|
-
comments: post.commentsCount || 0,
|
|
206
|
-
url: post.activityUrl || "",
|
|
207
|
-
isRepost: post.isRepublishedPost || false,
|
|
208
|
-
}));
|
|
238
|
+
const posts = serializeLinkedInPosts(response.posts, "LinkedIn company posts fetch");
|
|
209
239
|
return {
|
|
210
240
|
posts,
|
|
211
241
|
count: posts.length,
|