@auxiora/connector-social 1.0.0 → 1.3.1
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/package.json +8 -2
- package/src/index.ts +0 -4
- package/src/instagram.ts +0 -212
- package/src/linkedin.ts +0 -243
- package/src/reddit.ts +0 -268
- package/src/twitter.ts +0 -253
- package/tests/instagram.test.ts +0 -108
- package/tests/linkedin.test.ts +0 -104
- package/tests/reddit.test.ts +0 -127
- package/tests/twitter.test.ts +0 -120
- package/tsconfig.json +0 -11
- package/tsconfig.tsbuildinfo +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@auxiora/connector-social",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "Social media connectors: Twitter/X, LinkedIn, Reddit, Instagram",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -12,11 +12,17 @@
|
|
|
12
12
|
}
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@auxiora/connectors": "1.
|
|
15
|
+
"@auxiora/connectors": "1.3.1"
|
|
16
16
|
},
|
|
17
17
|
"engines": {
|
|
18
18
|
"node": ">=22.0.0"
|
|
19
19
|
},
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"access": "public"
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"dist/"
|
|
25
|
+
],
|
|
20
26
|
"scripts": {
|
|
21
27
|
"build": "tsc",
|
|
22
28
|
"clean": "rm -rf dist",
|
package/src/index.ts
DELETED
package/src/instagram.ts
DELETED
|
@@ -1,212 +0,0 @@
|
|
|
1
|
-
import { defineConnector } from '@auxiora/connectors';
|
|
2
|
-
import type { TriggerEvent } from '@auxiora/connectors';
|
|
3
|
-
|
|
4
|
-
async function instagramFetch(token: string, path: string, options?: { method?: string; body?: unknown }) {
|
|
5
|
-
const url = new URL(`https://graph.instagram.com${path}`);
|
|
6
|
-
if (!options?.method || options.method === 'GET') {
|
|
7
|
-
url.searchParams.set('access_token', token);
|
|
8
|
-
}
|
|
9
|
-
const res = await fetch(url.toString(), {
|
|
10
|
-
method: options?.method ?? 'GET',
|
|
11
|
-
headers: options?.body ? { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` } : { 'Authorization': `Bearer ${token}` },
|
|
12
|
-
body: options?.body ? JSON.stringify(options.body) : undefined,
|
|
13
|
-
});
|
|
14
|
-
if (!res.ok) throw new Error(`Instagram API error: ${res.status} ${await res.text().catch(() => res.statusText)}`);
|
|
15
|
-
return res.json() as Promise<Record<string, unknown>>;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export const instagramConnector = defineConnector({
|
|
19
|
-
id: 'instagram',
|
|
20
|
-
name: 'Instagram',
|
|
21
|
-
description: 'Integration with Instagram for posts, stories, and direct messages',
|
|
22
|
-
version: '1.0.0',
|
|
23
|
-
category: 'social',
|
|
24
|
-
icon: 'instagram',
|
|
25
|
-
|
|
26
|
-
auth: {
|
|
27
|
-
type: 'oauth2',
|
|
28
|
-
oauth2: {
|
|
29
|
-
authUrl: 'https://api.instagram.com/oauth/authorize',
|
|
30
|
-
tokenUrl: 'https://api.instagram.com/oauth/access_token',
|
|
31
|
-
scopes: ['user_profile', 'user_media', 'instagram_basic', 'instagram_manage_messages'],
|
|
32
|
-
},
|
|
33
|
-
},
|
|
34
|
-
|
|
35
|
-
actions: [
|
|
36
|
-
{
|
|
37
|
-
id: 'feed-read',
|
|
38
|
-
name: 'Read Feed',
|
|
39
|
-
description: 'Read the Instagram feed',
|
|
40
|
-
trustMinimum: 1,
|
|
41
|
-
trustDomain: 'messaging',
|
|
42
|
-
reversible: false,
|
|
43
|
-
sideEffects: false,
|
|
44
|
-
params: {},
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
id: 'stories-read',
|
|
48
|
-
name: 'Read Stories',
|
|
49
|
-
description: 'Read Instagram stories',
|
|
50
|
-
trustMinimum: 1,
|
|
51
|
-
trustDomain: 'messaging',
|
|
52
|
-
reversible: false,
|
|
53
|
-
sideEffects: false,
|
|
54
|
-
params: {},
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
id: 'dm-list',
|
|
58
|
-
name: 'List Direct Messages',
|
|
59
|
-
description: 'List Instagram direct messages',
|
|
60
|
-
trustMinimum: 1,
|
|
61
|
-
trustDomain: 'messaging',
|
|
62
|
-
reversible: false,
|
|
63
|
-
sideEffects: false,
|
|
64
|
-
params: {},
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
id: 'dm-send',
|
|
68
|
-
name: 'Send Direct Message',
|
|
69
|
-
description: 'Send an Instagram direct message',
|
|
70
|
-
trustMinimum: 3,
|
|
71
|
-
trustDomain: 'messaging',
|
|
72
|
-
reversible: false,
|
|
73
|
-
sideEffects: true,
|
|
74
|
-
params: {
|
|
75
|
-
recipientId: { type: 'string', description: 'Recipient user ID', required: true },
|
|
76
|
-
text: { type: 'string', description: 'Message text', required: true },
|
|
77
|
-
},
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
id: 'post-schedule',
|
|
81
|
-
name: 'Schedule Post',
|
|
82
|
-
description: 'Schedule a post on Instagram',
|
|
83
|
-
trustMinimum: 3,
|
|
84
|
-
trustDomain: 'messaging',
|
|
85
|
-
reversible: false,
|
|
86
|
-
sideEffects: true,
|
|
87
|
-
params: {
|
|
88
|
-
caption: { type: 'string', description: 'Post caption', required: true },
|
|
89
|
-
mediaUrl: { type: 'string', description: 'Media URL', required: true },
|
|
90
|
-
scheduledAt: { type: 'string', description: 'Scheduled time (ISO 8601)' },
|
|
91
|
-
},
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
id: 'profile-get',
|
|
95
|
-
name: 'Get Profile',
|
|
96
|
-
description: 'Get an Instagram profile',
|
|
97
|
-
trustMinimum: 1,
|
|
98
|
-
trustDomain: 'messaging',
|
|
99
|
-
reversible: false,
|
|
100
|
-
sideEffects: false,
|
|
101
|
-
params: {
|
|
102
|
-
userId: { type: 'string', description: 'User ID (default: authenticated user)' },
|
|
103
|
-
},
|
|
104
|
-
},
|
|
105
|
-
],
|
|
106
|
-
|
|
107
|
-
triggers: [
|
|
108
|
-
{
|
|
109
|
-
id: 'new-dm',
|
|
110
|
-
name: 'New Direct Message',
|
|
111
|
-
description: 'Triggered when a new direct message is received',
|
|
112
|
-
type: 'poll',
|
|
113
|
-
pollIntervalMs: 120_000,
|
|
114
|
-
},
|
|
115
|
-
{
|
|
116
|
-
id: 'new-comment',
|
|
117
|
-
name: 'New Comment',
|
|
118
|
-
description: 'Triggered when a new comment is posted on your content',
|
|
119
|
-
type: 'poll',
|
|
120
|
-
pollIntervalMs: 300_000,
|
|
121
|
-
},
|
|
122
|
-
],
|
|
123
|
-
|
|
124
|
-
entities: [
|
|
125
|
-
{
|
|
126
|
-
id: 'post',
|
|
127
|
-
name: 'Post',
|
|
128
|
-
description: 'An Instagram post',
|
|
129
|
-
fields: { id: 'string', caption: 'string', mediaUrl: 'string', likeCount: 'number', commentCount: 'number' },
|
|
130
|
-
},
|
|
131
|
-
{
|
|
132
|
-
id: 'story',
|
|
133
|
-
name: 'Story',
|
|
134
|
-
description: 'An Instagram story',
|
|
135
|
-
fields: { id: 'string', mediaUrl: 'string', expiresAt: 'string' },
|
|
136
|
-
},
|
|
137
|
-
],
|
|
138
|
-
|
|
139
|
-
async executeAction(actionId: string, params: Record<string, unknown>, token: string): Promise<unknown> {
|
|
140
|
-
switch (actionId) {
|
|
141
|
-
case 'feed-read': {
|
|
142
|
-
const res = await instagramFetch(token, '/me/media?fields=id,caption,media_url,timestamp,like_count,comments_count');
|
|
143
|
-
return { posts: res.data };
|
|
144
|
-
}
|
|
145
|
-
case 'stories-read': {
|
|
146
|
-
const res = await instagramFetch(token, '/me/stories?fields=id,media_url,timestamp');
|
|
147
|
-
return { stories: res.data };
|
|
148
|
-
}
|
|
149
|
-
case 'dm-list': {
|
|
150
|
-
return { messages: [], note: 'Instagram Messaging API requires approved app access' };
|
|
151
|
-
}
|
|
152
|
-
case 'dm-send': {
|
|
153
|
-
return { error: 'Instagram Messaging API requires approved app access', status: 'unavailable' };
|
|
154
|
-
}
|
|
155
|
-
case 'post-schedule': {
|
|
156
|
-
// Step 1: Create media container
|
|
157
|
-
const container = await instagramFetch(token, '/me/media', {
|
|
158
|
-
method: 'POST',
|
|
159
|
-
body: {
|
|
160
|
-
caption: params.caption,
|
|
161
|
-
image_url: params.mediaUrl,
|
|
162
|
-
},
|
|
163
|
-
});
|
|
164
|
-
const creationId = container.id as string;
|
|
165
|
-
// Step 2: Publish the media
|
|
166
|
-
const published = await instagramFetch(token, '/me/media_publish', {
|
|
167
|
-
method: 'POST',
|
|
168
|
-
body: { creation_id: creationId },
|
|
169
|
-
});
|
|
170
|
-
return { postId: published.id, status: 'published' };
|
|
171
|
-
}
|
|
172
|
-
case 'profile-get': {
|
|
173
|
-
const userId = (params.userId as string | undefined) ?? 'me';
|
|
174
|
-
const fields = 'id,username,name,biography,media_count,followers_count,follows_count';
|
|
175
|
-
const res = await instagramFetch(token, `/${userId}?fields=${fields}`);
|
|
176
|
-
return res;
|
|
177
|
-
}
|
|
178
|
-
default:
|
|
179
|
-
throw new Error(`Unknown action: ${actionId}`);
|
|
180
|
-
}
|
|
181
|
-
},
|
|
182
|
-
|
|
183
|
-
async pollTrigger(triggerId: string, token: string, lastPollAt?: number): Promise<TriggerEvent[]> {
|
|
184
|
-
switch (triggerId) {
|
|
185
|
-
case 'new-dm':
|
|
186
|
-
// Instagram Messaging API requires approved access
|
|
187
|
-
return [];
|
|
188
|
-
case 'new-comment': {
|
|
189
|
-
const media = await instagramFetch(token, '/me/media?fields=id&limit=10');
|
|
190
|
-
const posts = (media.data ?? []) as Array<Record<string, unknown>>;
|
|
191
|
-
const events: TriggerEvent[] = [];
|
|
192
|
-
const since = lastPollAt ? new Date(lastPollAt).toISOString() : undefined;
|
|
193
|
-
for (const post of posts) {
|
|
194
|
-
const sinceParam = since ? `&since=${since}` : '';
|
|
195
|
-
const commentsRes = await instagramFetch(token, `/${post.id as string}/comments?fields=id,text,username,timestamp${sinceParam}`);
|
|
196
|
-
const comments = (commentsRes.data ?? []) as Array<Record<string, unknown>>;
|
|
197
|
-
for (const comment of comments) {
|
|
198
|
-
events.push({
|
|
199
|
-
triggerId: 'new-comment',
|
|
200
|
-
connectorId: 'instagram',
|
|
201
|
-
data: { ...comment, mediaId: post.id },
|
|
202
|
-
timestamp: comment.timestamp ? new Date(comment.timestamp as string).getTime() : Date.now(),
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
return events;
|
|
207
|
-
}
|
|
208
|
-
default:
|
|
209
|
-
return [];
|
|
210
|
-
}
|
|
211
|
-
},
|
|
212
|
-
});
|
package/src/linkedin.ts
DELETED
|
@@ -1,243 +0,0 @@
|
|
|
1
|
-
import { defineConnector } from '@auxiora/connectors';
|
|
2
|
-
import type { TriggerEvent } from '@auxiora/connectors';
|
|
3
|
-
|
|
4
|
-
async function linkedinFetch(token: string, path: string, options?: { method?: string; body?: unknown }) {
|
|
5
|
-
const res = await fetch(`https://api.linkedin.com/v2${path}`, {
|
|
6
|
-
method: options?.method ?? 'GET',
|
|
7
|
-
headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
|
|
8
|
-
body: options?.body ? JSON.stringify(options.body) : undefined,
|
|
9
|
-
});
|
|
10
|
-
if (!res.ok) throw new Error(`LinkedIn API error: ${res.status} ${await res.text().catch(() => res.statusText)}`);
|
|
11
|
-
return res.json() as Promise<Record<string, unknown>>;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export const linkedinConnector = defineConnector({
|
|
15
|
-
id: 'linkedin',
|
|
16
|
-
name: 'LinkedIn',
|
|
17
|
-
description: 'Integration with LinkedIn for posts, connections, and messaging',
|
|
18
|
-
version: '1.0.0',
|
|
19
|
-
category: 'social',
|
|
20
|
-
icon: 'linkedin',
|
|
21
|
-
|
|
22
|
-
auth: {
|
|
23
|
-
type: 'oauth2',
|
|
24
|
-
oauth2: {
|
|
25
|
-
authUrl: 'https://www.linkedin.com/oauth/v2/authorization',
|
|
26
|
-
tokenUrl: 'https://www.linkedin.com/oauth/v2/accessToken',
|
|
27
|
-
scopes: ['r_liteprofile', 'r_emailaddress', 'w_member_social', 'r_basicprofile'],
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
|
|
31
|
-
actions: [
|
|
32
|
-
{
|
|
33
|
-
id: 'feed-read',
|
|
34
|
-
name: 'Read Feed',
|
|
35
|
-
description: 'Read the LinkedIn news feed',
|
|
36
|
-
trustMinimum: 1,
|
|
37
|
-
trustDomain: 'integrations',
|
|
38
|
-
reversible: false,
|
|
39
|
-
sideEffects: false,
|
|
40
|
-
params: {},
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
id: 'post-update',
|
|
44
|
-
name: 'Post Update',
|
|
45
|
-
description: 'Post a status update on LinkedIn',
|
|
46
|
-
trustMinimum: 3,
|
|
47
|
-
trustDomain: 'integrations',
|
|
48
|
-
reversible: false,
|
|
49
|
-
sideEffects: true,
|
|
50
|
-
params: {
|
|
51
|
-
text: { type: 'string', description: 'Post text', required: true },
|
|
52
|
-
},
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
id: 'post-article',
|
|
56
|
-
name: 'Post Article',
|
|
57
|
-
description: 'Share an article on LinkedIn',
|
|
58
|
-
trustMinimum: 3,
|
|
59
|
-
trustDomain: 'integrations',
|
|
60
|
-
reversible: false,
|
|
61
|
-
sideEffects: true,
|
|
62
|
-
params: {
|
|
63
|
-
title: { type: 'string', description: 'Article title', required: true },
|
|
64
|
-
url: { type: 'string', description: 'Article URL', required: true },
|
|
65
|
-
commentary: { type: 'string', description: 'Commentary text' },
|
|
66
|
-
},
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
id: 'connections-list',
|
|
70
|
-
name: 'List Connections',
|
|
71
|
-
description: 'List LinkedIn connections',
|
|
72
|
-
trustMinimum: 1,
|
|
73
|
-
trustDomain: 'integrations',
|
|
74
|
-
reversible: false,
|
|
75
|
-
sideEffects: false,
|
|
76
|
-
params: {},
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
id: 'messages-list',
|
|
80
|
-
name: 'List Messages',
|
|
81
|
-
description: 'List LinkedIn messages',
|
|
82
|
-
trustMinimum: 1,
|
|
83
|
-
trustDomain: 'messaging',
|
|
84
|
-
reversible: false,
|
|
85
|
-
sideEffects: false,
|
|
86
|
-
params: {},
|
|
87
|
-
},
|
|
88
|
-
{
|
|
89
|
-
id: 'message-send',
|
|
90
|
-
name: 'Send Message',
|
|
91
|
-
description: 'Send a message on LinkedIn',
|
|
92
|
-
trustMinimum: 3,
|
|
93
|
-
trustDomain: 'messaging',
|
|
94
|
-
reversible: false,
|
|
95
|
-
sideEffects: true,
|
|
96
|
-
params: {
|
|
97
|
-
recipientId: { type: 'string', description: 'Recipient profile ID', required: true },
|
|
98
|
-
text: { type: 'string', description: 'Message text', required: true },
|
|
99
|
-
},
|
|
100
|
-
},
|
|
101
|
-
{
|
|
102
|
-
id: 'profile-get',
|
|
103
|
-
name: 'Get Profile',
|
|
104
|
-
description: 'Get a LinkedIn profile',
|
|
105
|
-
trustMinimum: 1,
|
|
106
|
-
trustDomain: 'integrations',
|
|
107
|
-
reversible: false,
|
|
108
|
-
sideEffects: false,
|
|
109
|
-
params: {
|
|
110
|
-
profileId: { type: 'string', description: 'Profile ID (default: authenticated user)' },
|
|
111
|
-
},
|
|
112
|
-
},
|
|
113
|
-
],
|
|
114
|
-
|
|
115
|
-
triggers: [
|
|
116
|
-
{
|
|
117
|
-
id: 'new-message',
|
|
118
|
-
name: 'New Message',
|
|
119
|
-
description: 'Triggered when a new LinkedIn message is received',
|
|
120
|
-
type: 'poll',
|
|
121
|
-
pollIntervalMs: 120_000,
|
|
122
|
-
},
|
|
123
|
-
{
|
|
124
|
-
id: 'post-engagement',
|
|
125
|
-
name: 'Post Engagement',
|
|
126
|
-
description: 'Triggered when a post receives engagement',
|
|
127
|
-
type: 'poll',
|
|
128
|
-
pollIntervalMs: 300_000,
|
|
129
|
-
},
|
|
130
|
-
],
|
|
131
|
-
|
|
132
|
-
entities: [
|
|
133
|
-
{
|
|
134
|
-
id: 'post',
|
|
135
|
-
name: 'Post',
|
|
136
|
-
description: 'A LinkedIn post',
|
|
137
|
-
fields: { id: 'string', text: 'string', authorName: 'string', likes: 'number', comments: 'number', shares: 'number' },
|
|
138
|
-
},
|
|
139
|
-
{
|
|
140
|
-
id: 'connection',
|
|
141
|
-
name: 'Connection',
|
|
142
|
-
description: 'A LinkedIn connection',
|
|
143
|
-
fields: { id: 'string', name: 'string', headline: 'string', company: 'string' },
|
|
144
|
-
},
|
|
145
|
-
],
|
|
146
|
-
|
|
147
|
-
async executeAction(actionId: string, params: Record<string, unknown>, token: string): Promise<unknown> {
|
|
148
|
-
switch (actionId) {
|
|
149
|
-
case 'feed-read': {
|
|
150
|
-
const me = await linkedinFetch(token, '/me');
|
|
151
|
-
const urn = `urn:li:person:${me.id as string}`;
|
|
152
|
-
try {
|
|
153
|
-
const posts = await linkedinFetch(token, `/ugcPosts?q=authors&authors=List(${encodeURIComponent(urn)})&count=10`);
|
|
154
|
-
return { posts: posts.elements };
|
|
155
|
-
} catch (err) {
|
|
156
|
-
return { posts: [], error: `Feed access restricted: ${(err as Error).message}` };
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
case 'post-update': {
|
|
160
|
-
const me = await linkedinFetch(token, '/me');
|
|
161
|
-
const authorUrn = `urn:li:person:${me.id as string}`;
|
|
162
|
-
const res = await linkedinFetch(token, '/ugcPosts', {
|
|
163
|
-
method: 'POST',
|
|
164
|
-
body: {
|
|
165
|
-
author: authorUrn,
|
|
166
|
-
lifecycleState: 'PUBLISHED',
|
|
167
|
-
specificContent: {
|
|
168
|
-
'com.linkedin.ugc.ShareContent': {
|
|
169
|
-
shareCommentary: { text: params.text },
|
|
170
|
-
shareMediaCategory: 'NONE',
|
|
171
|
-
},
|
|
172
|
-
},
|
|
173
|
-
visibility: { 'com.linkedin.ugc.MemberNetworkVisibility': 'PUBLIC' },
|
|
174
|
-
},
|
|
175
|
-
});
|
|
176
|
-
return { postId: res.id, status: 'posted' };
|
|
177
|
-
}
|
|
178
|
-
case 'post-article': {
|
|
179
|
-
const me = await linkedinFetch(token, '/me');
|
|
180
|
-
const authorUrn = `urn:li:person:${me.id as string}`;
|
|
181
|
-
const res = await linkedinFetch(token, '/ugcPosts', {
|
|
182
|
-
method: 'POST',
|
|
183
|
-
body: {
|
|
184
|
-
author: authorUrn,
|
|
185
|
-
lifecycleState: 'PUBLISHED',
|
|
186
|
-
specificContent: {
|
|
187
|
-
'com.linkedin.ugc.ShareContent': {
|
|
188
|
-
shareCommentary: { text: (params.commentary as string) ?? '' },
|
|
189
|
-
shareMediaCategory: 'ARTICLE',
|
|
190
|
-
media: [{
|
|
191
|
-
status: 'READY',
|
|
192
|
-
originalUrl: params.url,
|
|
193
|
-
title: { text: params.title },
|
|
194
|
-
}],
|
|
195
|
-
},
|
|
196
|
-
},
|
|
197
|
-
visibility: { 'com.linkedin.ugc.MemberNetworkVisibility': 'PUBLIC' },
|
|
198
|
-
},
|
|
199
|
-
});
|
|
200
|
-
return { postId: res.id, status: 'shared' };
|
|
201
|
-
}
|
|
202
|
-
case 'connections-list': {
|
|
203
|
-
try {
|
|
204
|
-
const res = await linkedinFetch(token, '/connections?q=viewer&count=50');
|
|
205
|
-
return { connections: res.elements };
|
|
206
|
-
} catch (err) {
|
|
207
|
-
return { connections: [], error: `Connections access restricted: ${(err as Error).message}` };
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
case 'messages-list': {
|
|
211
|
-
try {
|
|
212
|
-
const res = await linkedinFetch(token, '/messages');
|
|
213
|
-
return { messages: res.elements };
|
|
214
|
-
} catch (err) {
|
|
215
|
-
return { messages: [], error: `Messages access restricted: ${(err as Error).message}` };
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
case 'message-send': {
|
|
219
|
-
const res = await linkedinFetch(token, '/messages', {
|
|
220
|
-
method: 'POST',
|
|
221
|
-
body: {
|
|
222
|
-
recipients: [`urn:li:person:${params.recipientId as string}`],
|
|
223
|
-
body: params.text,
|
|
224
|
-
},
|
|
225
|
-
});
|
|
226
|
-
return { messageId: res.id, status: 'sent' };
|
|
227
|
-
}
|
|
228
|
-
case 'profile-get': {
|
|
229
|
-
const profileId = params.profileId as string | undefined;
|
|
230
|
-
const path = profileId ? `/people/(id:${profileId})` : '/me';
|
|
231
|
-
const profile = await linkedinFetch(token, path);
|
|
232
|
-
return profile;
|
|
233
|
-
}
|
|
234
|
-
default:
|
|
235
|
-
throw new Error(`Unknown action: ${actionId}`);
|
|
236
|
-
}
|
|
237
|
-
},
|
|
238
|
-
|
|
239
|
-
// LinkedIn doesn't support efficient polling for triggers
|
|
240
|
-
async pollTrigger(_triggerId: string, _token: string, _lastPollAt?: number): Promise<TriggerEvent[]> {
|
|
241
|
-
return [];
|
|
242
|
-
},
|
|
243
|
-
});
|