@classytic/social 0.1.0
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/CHANGELOG.md +65 -0
- package/LICENSE +21 -0
- package/README.md +368 -0
- package/dist/base-Bw7e52V8.mjs +246 -0
- package/dist/base-Bw7e52V8.mjs.map +1 -0
- package/dist/base-DBtKFiSX.d.mts +226 -0
- package/dist/base-DBtKFiSX.d.mts.map +1 -0
- package/dist/chunk-DQk6qfdC.mjs +18 -0
- package/dist/client/index.d.mts +44 -0
- package/dist/client/index.d.mts.map +1 -0
- package/dist/client/index.mjs +154 -0
- package/dist/client/index.mjs.map +1 -0
- package/dist/common/index.d.mts +3 -0
- package/dist/common/index.mjs +7 -0
- package/dist/contracts-Cdwa4zlg.d.mts +121 -0
- package/dist/contracts-Cdwa4zlg.d.mts.map +1 -0
- package/dist/contracts-lCa069IK.mjs +221 -0
- package/dist/contracts-lCa069IK.mjs.map +1 -0
- package/dist/env-Bl0cwwjC.mjs +955 -0
- package/dist/env-Bl0cwwjC.mjs.map +1 -0
- package/dist/env-DxOZHf0p.d.mts +394 -0
- package/dist/env-DxOZHf0p.d.mts.map +1 -0
- package/dist/errors-Cm6LeKf7.mjs +32 -0
- package/dist/errors-Cm6LeKf7.mjs.map +1 -0
- package/dist/facebook-l_4CghaA.mjs +95 -0
- package/dist/facebook-l_4CghaA.mjs.map +1 -0
- package/dist/http-DpcLSR1M.mjs +197 -0
- package/dist/http-DpcLSR1M.mjs.map +1 -0
- package/dist/index.d.mts +42 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +71 -0
- package/dist/index.mjs.map +1 -0
- package/dist/instagram-BGaeUFU2.mjs +90 -0
- package/dist/instagram-BGaeUFU2.mjs.map +1 -0
- package/dist/linkedin-70whtVKa.mjs +101 -0
- package/dist/linkedin-70whtVKa.mjs.map +1 -0
- package/dist/meta-D3vcJU1c.mjs +126 -0
- package/dist/meta-D3vcJU1c.mjs.map +1 -0
- package/dist/pkce-jq5II68b.mjs +72 -0
- package/dist/pkce-jq5II68b.mjs.map +1 -0
- package/dist/polling-DZ1apXtA.mjs +25 -0
- package/dist/polling-DZ1apXtA.mjs.map +1 -0
- package/dist/providers/facebook.d.mts +135 -0
- package/dist/providers/facebook.d.mts.map +1 -0
- package/dist/providers/facebook.mjs +450 -0
- package/dist/providers/facebook.mjs.map +1 -0
- package/dist/providers/instagram.d.mts +122 -0
- package/dist/providers/instagram.d.mts.map +1 -0
- package/dist/providers/instagram.mjs +496 -0
- package/dist/providers/instagram.mjs.map +1 -0
- package/dist/providers/linkedin.d.mts +145 -0
- package/dist/providers/linkedin.d.mts.map +1 -0
- package/dist/providers/linkedin.mjs +574 -0
- package/dist/providers/linkedin.mjs.map +1 -0
- package/dist/providers/reddit.d.mts +102 -0
- package/dist/providers/reddit.d.mts.map +1 -0
- package/dist/providers/reddit.mjs +657 -0
- package/dist/providers/reddit.mjs.map +1 -0
- package/dist/providers/telegram.d.mts +139 -0
- package/dist/providers/telegram.d.mts.map +1 -0
- package/dist/providers/telegram.mjs +517 -0
- package/dist/providers/telegram.mjs.map +1 -0
- package/dist/providers/tiktok.d.mts +116 -0
- package/dist/providers/tiktok.d.mts.map +1 -0
- package/dist/providers/tiktok.mjs +676 -0
- package/dist/providers/tiktok.mjs.map +1 -0
- package/dist/providers/twitter.d.mts +150 -0
- package/dist/providers/twitter.d.mts.map +1 -0
- package/dist/providers/twitter.mjs +628 -0
- package/dist/providers/twitter.mjs.map +1 -0
- package/dist/providers/whatsapp.d.mts +79 -0
- package/dist/providers/whatsapp.d.mts.map +1 -0
- package/dist/providers/whatsapp.mjs +376 -0
- package/dist/providers/whatsapp.mjs.map +1 -0
- package/dist/providers/youtube.d.mts +153 -0
- package/dist/providers/youtube.d.mts.map +1 -0
- package/dist/providers/youtube.mjs +902 -0
- package/dist/providers/youtube.mjs.map +1 -0
- package/dist/reddit-B10kS4Se.mjs +126 -0
- package/dist/reddit-B10kS4Se.mjs.map +1 -0
- package/dist/schemas/index.d.mts +819 -0
- package/dist/schemas/index.d.mts.map +1 -0
- package/dist/schemas/index.mjs +31 -0
- package/dist/schemas/index.mjs.map +1 -0
- package/dist/security-BXhfebWm.d.mts +338 -0
- package/dist/security-BXhfebWm.d.mts.map +1 -0
- package/dist/shared-Fvc6xQku.mjs +100 -0
- package/dist/shared-Fvc6xQku.mjs.map +1 -0
- package/dist/telegram-FaUHpZgB.mjs +107 -0
- package/dist/telegram-FaUHpZgB.mjs.map +1 -0
- package/dist/tiktok-B_bMk4G-.mjs +94 -0
- package/dist/tiktok-B_bMk4G-.mjs.map +1 -0
- package/dist/twitter-BC22zfuc.mjs +98 -0
- package/dist/twitter-BC22zfuc.mjs.map +1 -0
- package/dist/types-BFE4psYI.d.mts +102 -0
- package/dist/types-BFE4psYI.d.mts.map +1 -0
- package/dist/types-Bv27tcT0.d.mts +230 -0
- package/dist/types-Bv27tcT0.d.mts.map +1 -0
- package/dist/types-BwkKyqpi.d.mts +253 -0
- package/dist/types-BwkKyqpi.d.mts.map +1 -0
- package/dist/types-CJrHMDV9.mjs +27 -0
- package/dist/types-CJrHMDV9.mjs.map +1 -0
- package/dist/types-ClbVc2rc.d.mts +117 -0
- package/dist/types-ClbVc2rc.d.mts.map +1 -0
- package/dist/types-D91N16Ym.d.mts +242 -0
- package/dist/types-D91N16Ym.d.mts.map +1 -0
- package/dist/types-DfLp_ibQ.d.mts +178 -0
- package/dist/types-DfLp_ibQ.d.mts.map +1 -0
- package/dist/types-DfjDgEoJ.d.mts +88 -0
- package/dist/types-DfjDgEoJ.d.mts.map +1 -0
- package/dist/types-Dp5Z9VBr.mjs +23 -0
- package/dist/types-Dp5Z9VBr.mjs.map +1 -0
- package/dist/types-hriBJTsU.d.mts +129 -0
- package/dist/types-hriBJTsU.d.mts.map +1 -0
- package/dist/types-rn6UuLL8.d.mts +184 -0
- package/dist/types-rn6UuLL8.d.mts.map +1 -0
- package/dist/whatsapp-CFp7ryR4.mjs +101 -0
- package/dist/whatsapp-CFp7ryR4.mjs.map +1 -0
- package/dist/youtube-Bs0fdY7H.mjs +98 -0
- package/dist/youtube-Bs0fdY7H.mjs.map +1 -0
- package/package.json +148 -0
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
import { t as PlatformProvider } from "../base-Bw7e52V8.mjs";
|
|
2
|
+
import { t as SocialError } from "../errors-Cm6LeKf7.mjs";
|
|
3
|
+
import { a as parseGraphError, c as META_GRAPH_VERSION, l as META_GRAPH_VIDEO_BASE, n as metaExchangeLongLived, o as META_AUTH_URL, r as metaRefreshLongLivedFacebook, s as META_GRAPH_BASE } from "../meta-D3vcJU1c.mjs";
|
|
4
|
+
import { t as httpRequest } from "../http-DpcLSR1M.mjs";
|
|
5
|
+
import { t as FacebookCredentialsSchema } from "../facebook-l_4CghaA.mjs";
|
|
6
|
+
|
|
7
|
+
//#region src/providers/facebook/index.ts
|
|
8
|
+
/**
|
|
9
|
+
* Facebook Pages Platform Provider
|
|
10
|
+
* =================================
|
|
11
|
+
* Facebook Page integration via Meta Graph API v25.0.
|
|
12
|
+
*
|
|
13
|
+
* Features:
|
|
14
|
+
* - OAuth2 via Facebook Login dialog
|
|
15
|
+
* - Two-step token exchange (short-lived -> long-lived, 60 days)
|
|
16
|
+
* - Facebook Page discovery and page-level access tokens
|
|
17
|
+
* - Text post publishing
|
|
18
|
+
* - Link/article sharing
|
|
19
|
+
* - Photo post publishing (via URL)
|
|
20
|
+
* - Video post publishing (via URL, uses graph-video.facebook.com)
|
|
21
|
+
* - Scheduled post publishing
|
|
22
|
+
* - Post management (get, update, delete)
|
|
23
|
+
* - Page insights/analytics
|
|
24
|
+
* - Credential validation
|
|
25
|
+
*
|
|
26
|
+
* Facebook Page API Quirks:
|
|
27
|
+
* - User tokens vs Page tokens: user token grants access to /me/accounts;
|
|
28
|
+
* each page in the response includes its own page-specific access_token
|
|
29
|
+
* - Page tokens never expire if derived from a long-lived user token
|
|
30
|
+
* - Video uploads use graph-video.facebook.com (not graph.facebook.com)
|
|
31
|
+
* - Scheduled posts: set published=false + scheduled_publish_time (Unix epoch, 10 min-6 months)
|
|
32
|
+
* - Photos accept URLs or binary upload (we use URL-based for simplicity, matching Instagram pattern)
|
|
33
|
+
* - Webhook signature validation uses SHA256 HMAC of app secret
|
|
34
|
+
*
|
|
35
|
+
* @see https://developers.facebook.com/docs/pages-api
|
|
36
|
+
* @see https://developers.facebook.com/docs/graph-api/reference/page/feed
|
|
37
|
+
* @see https://developers.facebook.com/docs/video-api/guides/publishing
|
|
38
|
+
*/
|
|
39
|
+
const GRAPH_API_VERSION = META_GRAPH_VERSION;
|
|
40
|
+
const FB_AUTH_URL = META_AUTH_URL;
|
|
41
|
+
const GRAPH_API_BASE = META_GRAPH_BASE;
|
|
42
|
+
const GRAPH_VIDEO_BASE = META_GRAPH_VIDEO_BASE;
|
|
43
|
+
var FacebookProvider = class extends PlatformProvider {
|
|
44
|
+
defaultRedirectUri;
|
|
45
|
+
scopes;
|
|
46
|
+
constructor(cfg = {}) {
|
|
47
|
+
super(cfg);
|
|
48
|
+
this.name = "facebook";
|
|
49
|
+
this.displayName = "Facebook Pages";
|
|
50
|
+
this.authType = "oauth2";
|
|
51
|
+
this.defaultRedirectUri = cfg.redirectUri || `http://localhost:${cfg.port || 8060}/api/oauth/facebook/callback`;
|
|
52
|
+
this.scopes = [
|
|
53
|
+
"business_management",
|
|
54
|
+
"pages_show_list",
|
|
55
|
+
"pages_read_engagement",
|
|
56
|
+
"pages_manage_posts",
|
|
57
|
+
"pages_read_user_content"
|
|
58
|
+
];
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Unified Graph API request — used by all GET / POST / DELETE call sites.
|
|
62
|
+
* Delegates to the shared `httpRequest` helper for retry, timeout, and 429 handling.
|
|
63
|
+
*
|
|
64
|
+
* @param method HTTP method
|
|
65
|
+
* @param path Graph API path (e.g. `/me/accounts`)
|
|
66
|
+
* @param accessToken Access token (sent as `access_token` query for GET/DELETE; body field for POST)
|
|
67
|
+
* @param body POST body (merged with `access_token`); ignored for GET/DELETE
|
|
68
|
+
* @param query Extra query params for GET
|
|
69
|
+
* @param baseUrl Optional base URL override (video uploads use graph-video.facebook.com)
|
|
70
|
+
*/
|
|
71
|
+
async _graph(method, path, accessToken, body, query, baseUrl = GRAPH_API_BASE) {
|
|
72
|
+
const isWriteWithBody = method === "POST" && body !== void 0;
|
|
73
|
+
return (await httpRequest("facebook", {
|
|
74
|
+
method,
|
|
75
|
+
url: `${baseUrl}${path}`,
|
|
76
|
+
query: !isWriteWithBody ? {
|
|
77
|
+
access_token: accessToken,
|
|
78
|
+
...query ?? {}
|
|
79
|
+
} : query,
|
|
80
|
+
json: isWriteWithBody ? {
|
|
81
|
+
...body,
|
|
82
|
+
access_token: accessToken
|
|
83
|
+
} : void 0,
|
|
84
|
+
timeout: 6e4,
|
|
85
|
+
retry: { attempts: 2 },
|
|
86
|
+
parseError: parseGraphError
|
|
87
|
+
})).data;
|
|
88
|
+
}
|
|
89
|
+
async _graphGet(path, accessToken, params = {}) {
|
|
90
|
+
return this._graph("GET", path, accessToken, void 0, params);
|
|
91
|
+
}
|
|
92
|
+
async _graphPost(path, body, accessToken, baseUrl = GRAPH_API_BASE) {
|
|
93
|
+
return this._graph("POST", path, accessToken, body, void 0, baseUrl);
|
|
94
|
+
}
|
|
95
|
+
async _graphDelete(path, accessToken) {
|
|
96
|
+
return this._graph("DELETE", path, accessToken);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Get Facebook OAuth authorization URL
|
|
100
|
+
*/
|
|
101
|
+
getAuthUrl(state, credentials = {}, _options) {
|
|
102
|
+
return `${FB_AUTH_URL}?${new URLSearchParams({
|
|
103
|
+
client_id: credentials.appId,
|
|
104
|
+
redirect_uri: credentials.redirectUri || this.defaultRedirectUri,
|
|
105
|
+
scope: this.scopes.join(","),
|
|
106
|
+
response_type: "code",
|
|
107
|
+
state
|
|
108
|
+
}).toString()}`;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Exchange authorization code for tokens (two-step).
|
|
112
|
+
*
|
|
113
|
+
* Step 1: code → short-lived token (1 hour)
|
|
114
|
+
* Step 2: short-lived → long-lived token (60 days)
|
|
115
|
+
*/
|
|
116
|
+
async exchangeCode(code, credentials = {}) {
|
|
117
|
+
return metaExchangeLongLived("facebook", {
|
|
118
|
+
graphVersion: GRAPH_API_VERSION,
|
|
119
|
+
clientId: credentials.appId,
|
|
120
|
+
clientSecret: credentials.appSecret,
|
|
121
|
+
redirectUri: credentials.redirectUri || this.defaultRedirectUri,
|
|
122
|
+
code
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Refresh long-lived user token. Facebook long-lived tokens can be refreshed
|
|
127
|
+
* before expiry by re-exchanging them via `fb_exchange_token`.
|
|
128
|
+
*/
|
|
129
|
+
async refreshToken(refreshToken, credentials = {}) {
|
|
130
|
+
return metaRefreshLongLivedFacebook({
|
|
131
|
+
graphVersion: GRAPH_API_VERSION,
|
|
132
|
+
clientId: credentials.appId,
|
|
133
|
+
clientSecret: credentials.appSecret,
|
|
134
|
+
refreshToken
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Get user's Facebook Pages with page-level access tokens
|
|
139
|
+
* Each page has its own never-expiring token (when derived from long-lived user token)
|
|
140
|
+
*
|
|
141
|
+
* @param userAccessToken - Long-lived user access token
|
|
142
|
+
* @returns List of pages with { id, name, access_token, category, ... }
|
|
143
|
+
*/
|
|
144
|
+
async getPages(userAccessToken) {
|
|
145
|
+
return (await this._graphGet("/me/accounts", userAccessToken, { fields: "id,name,access_token,category,picture{url},fan_count,followers_count" })).data || [];
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Get account information -- returns the first managed page
|
|
149
|
+
*/
|
|
150
|
+
async getAccountInfo(accessToken) {
|
|
151
|
+
const pages = await this.getPages(accessToken);
|
|
152
|
+
if (!pages.length) throw new SocialError("facebook", "No Facebook Pages found. Your account must manage at least one Facebook Page.");
|
|
153
|
+
const page = pages[0];
|
|
154
|
+
return {
|
|
155
|
+
id: page.id,
|
|
156
|
+
name: page.name,
|
|
157
|
+
profileImage: page.picture?.data?.url || null,
|
|
158
|
+
category: page.category,
|
|
159
|
+
fanCount: page.fan_count,
|
|
160
|
+
pageAccessToken: page.access_token,
|
|
161
|
+
pageId: page.id,
|
|
162
|
+
pages: pages.map((p) => ({
|
|
163
|
+
id: p.id,
|
|
164
|
+
name: p.name,
|
|
165
|
+
category: p.category,
|
|
166
|
+
profileImage: p.picture?.data?.url || null
|
|
167
|
+
}))
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Test credential validity
|
|
172
|
+
*/
|
|
173
|
+
async testCredential(credentialData) {
|
|
174
|
+
try {
|
|
175
|
+
if (credentialData.oauthTokenData) {
|
|
176
|
+
const tokenData = typeof credentialData.oauthTokenData === "string" ? JSON.parse(credentialData.oauthTokenData) : credentialData.oauthTokenData;
|
|
177
|
+
const accountInfo = await this.getAccountInfo(tokenData.access_token);
|
|
178
|
+
return {
|
|
179
|
+
status: "OK",
|
|
180
|
+
message: `Connected — managing ${accountInfo.pages.length} page(s)`,
|
|
181
|
+
data: {
|
|
182
|
+
channelId: accountInfo.id,
|
|
183
|
+
channelTitle: accountInfo.name,
|
|
184
|
+
profileImage: accountInfo.profileImage,
|
|
185
|
+
pages: accountInfo.pages
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
if (!credentialData.appId || !credentialData.appSecret) return {
|
|
190
|
+
status: "Error",
|
|
191
|
+
message: "Meta App ID and App Secret are required"
|
|
192
|
+
};
|
|
193
|
+
return {
|
|
194
|
+
status: "Pending",
|
|
195
|
+
message: "Credential needs OAuth authorization. Click \"Connect Account\" to link your Facebook."
|
|
196
|
+
};
|
|
197
|
+
} catch (error) {
|
|
198
|
+
return {
|
|
199
|
+
status: "Error",
|
|
200
|
+
message: error.message || "Failed to validate Facebook credential"
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Get the page-level access token for a specific page
|
|
206
|
+
* Page tokens derived from long-lived user tokens never expire.
|
|
207
|
+
*
|
|
208
|
+
* @param userAccessToken - Long-lived user access token
|
|
209
|
+
* @param pageId - Facebook Page ID
|
|
210
|
+
* @returns Page access token
|
|
211
|
+
*/
|
|
212
|
+
async getPageAccessToken(userAccessToken, pageId) {
|
|
213
|
+
const page = (await this.getPages(userAccessToken)).find((p) => p.id === pageId);
|
|
214
|
+
if (!page) throw new SocialError("facebook", `Page ${pageId} not found or you don't have admin access. Check your page permissions.`);
|
|
215
|
+
return page.access_token;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Publish a text post to a Facebook Page
|
|
219
|
+
* @param pageAccessToken - Page-level access token
|
|
220
|
+
* @param pageId - Facebook Page ID
|
|
221
|
+
* @param message - Post text
|
|
222
|
+
* @param options
|
|
223
|
+
*/
|
|
224
|
+
async createPost(pageAccessToken, pageId, message, options = {}) {
|
|
225
|
+
const body = { message };
|
|
226
|
+
if (options.scheduledAt) {
|
|
227
|
+
const publishTime = Math.floor(new Date(options.scheduledAt).getTime() / 1e3);
|
|
228
|
+
body.published = false;
|
|
229
|
+
body.scheduled_publish_time = publishTime;
|
|
230
|
+
}
|
|
231
|
+
return {
|
|
232
|
+
postId: (await this._graphPost(`/${pageId}/feed`, body, pageAccessToken)).id,
|
|
233
|
+
status: options.scheduledAt ? "scheduled" : "published",
|
|
234
|
+
scheduledAt: options.scheduledAt ? new Date(options.scheduledAt) : null
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Publish a link/article share to a Facebook Page
|
|
239
|
+
* @param pageAccessToken
|
|
240
|
+
* @param pageId
|
|
241
|
+
* @param link - URL to share
|
|
242
|
+
* @param options
|
|
243
|
+
*/
|
|
244
|
+
async createLinkPost(pageAccessToken, pageId, link, options = {}) {
|
|
245
|
+
const body = { link };
|
|
246
|
+
if (options.message) body.message = options.message;
|
|
247
|
+
if (options.scheduledAt) {
|
|
248
|
+
const publishTime = Math.floor(new Date(options.scheduledAt).getTime() / 1e3);
|
|
249
|
+
body.published = false;
|
|
250
|
+
body.scheduled_publish_time = publishTime;
|
|
251
|
+
}
|
|
252
|
+
return {
|
|
253
|
+
postId: (await this._graphPost(`/${pageId}/feed`, body, pageAccessToken)).id,
|
|
254
|
+
status: options.scheduledAt ? "scheduled" : "published"
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Publish a photo to a Facebook Page (via public URL)
|
|
259
|
+
* @param pageAccessToken
|
|
260
|
+
* @param pageId
|
|
261
|
+
* @param photoUrl - Publicly accessible photo URL
|
|
262
|
+
* @param options
|
|
263
|
+
*/
|
|
264
|
+
async createPhotoPost(pageAccessToken, pageId, photoUrl, options = {}) {
|
|
265
|
+
const body = { url: photoUrl };
|
|
266
|
+
if (options.caption) body.message = options.caption;
|
|
267
|
+
if (options.scheduledAt) {
|
|
268
|
+
const publishTime = Math.floor(new Date(options.scheduledAt).getTime() / 1e3);
|
|
269
|
+
body.published = false;
|
|
270
|
+
body.scheduled_publish_time = publishTime;
|
|
271
|
+
}
|
|
272
|
+
const data = await this._graphPost(`/${pageId}/photos`, body, pageAccessToken);
|
|
273
|
+
return {
|
|
274
|
+
postId: data.post_id || data.id,
|
|
275
|
+
photoId: data.id,
|
|
276
|
+
status: options.scheduledAt ? "scheduled" : "published"
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Upload a video to a Facebook Page (via public URL)
|
|
281
|
+
* Uses graph-video.facebook.com for video uploads.
|
|
282
|
+
*/
|
|
283
|
+
async uploadVideo(params) {
|
|
284
|
+
const { videoUrl, title = "", description = "", tokens, scheduledAt, onProgress } = params;
|
|
285
|
+
const pageAccessToken = tokens.pageAccessToken || tokens.access_token;
|
|
286
|
+
const pageId = tokens.pageId;
|
|
287
|
+
if (!pageId) throw new SocialError("facebook", "Page ID is required. Select a page from your connected pages.");
|
|
288
|
+
if (!videoUrl) throw new SocialError("facebook", "Video URL is required. Facebook accepts public URLs for video uploads.");
|
|
289
|
+
const body = {
|
|
290
|
+
file_url: videoUrl,
|
|
291
|
+
title: title.substring(0, 255),
|
|
292
|
+
description: description.substring(0, 5e3)
|
|
293
|
+
};
|
|
294
|
+
if (scheduledAt) {
|
|
295
|
+
const publishTime = Math.floor(new Date(scheduledAt).getTime() / 1e3);
|
|
296
|
+
body.published = false;
|
|
297
|
+
body.scheduled_publish_time = publishTime;
|
|
298
|
+
}
|
|
299
|
+
if (onProgress) onProgress(10);
|
|
300
|
+
const data = await this._graphPost(`/${pageId}/videos`, body, pageAccessToken, GRAPH_VIDEO_BASE);
|
|
301
|
+
if (onProgress) onProgress(100);
|
|
302
|
+
return {
|
|
303
|
+
platformVideoId: data.id,
|
|
304
|
+
platformUrl: `https://www.facebook.com/${pageId}/videos/${data.id}/`,
|
|
305
|
+
status: scheduledAt ? "scheduled" : "published",
|
|
306
|
+
uploadedAt: /* @__PURE__ */ new Date(),
|
|
307
|
+
scheduledAt: scheduledAt ? new Date(scheduledAt) : null,
|
|
308
|
+
metadata: {
|
|
309
|
+
pageId,
|
|
310
|
+
videoId: data.id,
|
|
311
|
+
title
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Get a post by ID
|
|
317
|
+
* @param pageAccessToken
|
|
318
|
+
* @param postId
|
|
319
|
+
* @param fields - Comma-separated fields
|
|
320
|
+
*/
|
|
321
|
+
async getPost(pageAccessToken, postId, fields = "id,message,created_time,permalink_url,shares,likes.summary(true),comments.summary(true)") {
|
|
322
|
+
return this._graphGet(`/${postId}`, pageAccessToken, { fields });
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Update a post's message
|
|
326
|
+
* @param pageAccessToken
|
|
327
|
+
* @param postId
|
|
328
|
+
* @param message - New message text
|
|
329
|
+
*/
|
|
330
|
+
async updatePost(pageAccessToken, postId, message) {
|
|
331
|
+
return this._graphPost(`/${postId}`, { message }, pageAccessToken);
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Delete a post
|
|
335
|
+
* @param pageAccessToken
|
|
336
|
+
* @param postId
|
|
337
|
+
*/
|
|
338
|
+
async deletePost(pageAccessToken, postId) {
|
|
339
|
+
return this._graphDelete(`/${postId}`, pageAccessToken);
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Get page feed (recent posts)
|
|
343
|
+
* @param pageAccessToken
|
|
344
|
+
* @param pageId
|
|
345
|
+
* @param limit
|
|
346
|
+
*/
|
|
347
|
+
async getPageFeed(pageAccessToken, pageId, limit = 25) {
|
|
348
|
+
return this._graphGet(`/${pageId}/feed`, pageAccessToken, {
|
|
349
|
+
fields: "id,message,created_time,permalink_url,type,shares",
|
|
350
|
+
limit: String(limit)
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Get page insights (basic analytics)
|
|
355
|
+
* @param pageAccessToken
|
|
356
|
+
* @param pageId
|
|
357
|
+
* @param period - 'day' | 'week' | 'days_28'
|
|
358
|
+
*/
|
|
359
|
+
async getPageInsights(pageAccessToken, pageId, period = "day") {
|
|
360
|
+
return this._graphGet(`/${pageId}/insights`, pageAccessToken, {
|
|
361
|
+
metric: "page_impressions,page_engaged_users,page_post_engagements,page_fan_adds",
|
|
362
|
+
period
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
getCredentialZodSchema() {
|
|
366
|
+
return FacebookCredentialsSchema;
|
|
367
|
+
}
|
|
368
|
+
getCredentialSchema() {
|
|
369
|
+
return [{
|
|
370
|
+
name: "appId",
|
|
371
|
+
displayName: "Meta App ID",
|
|
372
|
+
type: "text",
|
|
373
|
+
required: true,
|
|
374
|
+
description: "App ID from Meta Developer Portal (developers.facebook.com)"
|
|
375
|
+
}, {
|
|
376
|
+
name: "appSecret",
|
|
377
|
+
displayName: "Meta App Secret",
|
|
378
|
+
type: "password",
|
|
379
|
+
required: true,
|
|
380
|
+
description: "App Secret from Meta Developer Portal"
|
|
381
|
+
}];
|
|
382
|
+
}
|
|
383
|
+
getMetadata() {
|
|
384
|
+
return {
|
|
385
|
+
name: this.name,
|
|
386
|
+
displayName: this.displayName,
|
|
387
|
+
authType: this.authType,
|
|
388
|
+
icon: "facebook",
|
|
389
|
+
brandColor: "#1877F2",
|
|
390
|
+
description: "Publish posts, photos, and videos to Facebook Pages",
|
|
391
|
+
scopes: this.scopes,
|
|
392
|
+
scopeDescriptions: {
|
|
393
|
+
pages_show_list: "View the list of Facebook Pages you manage",
|
|
394
|
+
pages_read_engagement: "Read engagement metrics from your pages",
|
|
395
|
+
pages_manage_posts: "Create, edit, and delete posts on your pages",
|
|
396
|
+
pages_read_user_content: "Read user-generated content on your pages"
|
|
397
|
+
},
|
|
398
|
+
supportsScheduling: true,
|
|
399
|
+
supportsEnvironment: false,
|
|
400
|
+
setupGuide: [
|
|
401
|
+
{
|
|
402
|
+
step: 1,
|
|
403
|
+
title: "Create Meta Developer Account",
|
|
404
|
+
description: "Go to developers.facebook.com and create an account or log in"
|
|
405
|
+
},
|
|
406
|
+
{
|
|
407
|
+
step: 2,
|
|
408
|
+
title: "Create a New App",
|
|
409
|
+
description: "Click \"My Apps\" → \"Create App\". Enter your app name and email. On the use case step, filter by \"Content management\" and select \"Manage everything on your Page\""
|
|
410
|
+
},
|
|
411
|
+
{
|
|
412
|
+
step: 3,
|
|
413
|
+
title: "Connect Business Portfolio",
|
|
414
|
+
description: "Select or create a Business Portfolio when prompted. Click \"Create App\" to proceed to the dashboard"
|
|
415
|
+
},
|
|
416
|
+
{
|
|
417
|
+
step: 4,
|
|
418
|
+
title: "Set Redirect URI",
|
|
419
|
+
description: `Go to "Facebook Login" → "Settings" in the left sidebar. Add this as a Valid OAuth Redirect URI: ${this.defaultRedirectUri}`
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
step: 5,
|
|
423
|
+
title: "Configure App Settings",
|
|
424
|
+
description: "Go to Settings → Basic. Add your App Domain and a Privacy Policy URL. Copy your App ID and App Secret and paste them above"
|
|
425
|
+
},
|
|
426
|
+
{
|
|
427
|
+
step: 6,
|
|
428
|
+
title: "Add Permissions",
|
|
429
|
+
description: "Click \"Customize\" on your use case → \"Permissions and features\". pages_show_list, business_management, and public_profile are pre-added. Click \"+ Add\" for: pages_manage_posts, pages_read_engagement, pages_read_user_content, pages_manage_engagement, read_insights"
|
|
430
|
+
},
|
|
431
|
+
{
|
|
432
|
+
step: 7,
|
|
433
|
+
title: "Go Live",
|
|
434
|
+
description: "Switch app to \"Live\" mode. For development, Standard Access works with app role users. For production, request Advanced Access via App Review"
|
|
435
|
+
},
|
|
436
|
+
{
|
|
437
|
+
step: 8,
|
|
438
|
+
title: "Page Admin Required",
|
|
439
|
+
description: "You must be an admin of the Facebook Page(s) you want to post to. The page will be auto-discovered during authorization"
|
|
440
|
+
}
|
|
441
|
+
],
|
|
442
|
+
redirectUriPattern: this.defaultRedirectUri,
|
|
443
|
+
credentialSchema: this.getCredentialSchema()
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
};
|
|
447
|
+
|
|
448
|
+
//#endregion
|
|
449
|
+
export { FacebookProvider };
|
|
450
|
+
//# sourceMappingURL=facebook.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"facebook.mjs","names":[],"sources":["../../src/providers/facebook/index.ts"],"sourcesContent":["/**\n * Facebook Pages Platform Provider\n * =================================\n * Facebook Page integration via Meta Graph API v25.0.\n *\n * Features:\n * - OAuth2 via Facebook Login dialog\n * - Two-step token exchange (short-lived -> long-lived, 60 days)\n * - Facebook Page discovery and page-level access tokens\n * - Text post publishing\n * - Link/article sharing\n * - Photo post publishing (via URL)\n * - Video post publishing (via URL, uses graph-video.facebook.com)\n * - Scheduled post publishing\n * - Post management (get, update, delete)\n * - Page insights/analytics\n * - Credential validation\n *\n * Facebook Page API Quirks:\n * - User tokens vs Page tokens: user token grants access to /me/accounts;\n * each page in the response includes its own page-specific access_token\n * - Page tokens never expire if derived from a long-lived user token\n * - Video uploads use graph-video.facebook.com (not graph.facebook.com)\n * - Scheduled posts: set published=false + scheduled_publish_time (Unix epoch, 10 min-6 months)\n * - Photos accept URLs or binary upload (we use URL-based for simplicity, matching Instagram pattern)\n * - Webhook signature validation uses SHA256 HMAC of app secret\n *\n * @see https://developers.facebook.com/docs/pages-api\n * @see https://developers.facebook.com/docs/graph-api/reference/page/feed\n * @see https://developers.facebook.com/docs/video-api/guides/publishing\n */\n\nimport {\n PlatformProvider,\n type AuthUrlOptions,\n type CredentialField,\n type ProviderMetadata,\n type UploadResult,\n type OAuthTokens,\n type ProviderConfig,\n} from '../../base.js';\nimport { SocialError } from '../../errors.js';\nimport { FacebookCredentialsSchema } from '../../schemas/facebook.js';\nimport { httpRequest } from '../../common/http.js';\nimport { META_GRAPH_VERSION, META_GRAPH_BASE, META_GRAPH_VIDEO_BASE, META_AUTH_URL, META_TOKEN_URL } from '../../common/meta.js';\nimport {\n metaExchangeLongLived,\n metaRefreshLongLivedFacebook,\n parseGraphError,\n} from '../../common/oauth/index.js';\nimport type { z } from 'zod';\nimport type {\n FacebookCredentials,\n FacebookPage,\n FacebookAccountInfo,\n FacebookTestResult,\n FacebookUploadParams,\n CreatePostOptions,\n CreatePostResult,\n CreateLinkPostOptions,\n CreateLinkPostResult,\n CreatePhotoPostOptions,\n CreatePhotoPostResult,\n GraphApiErrorResponse,\n FacebookCredentialData,\n FacebookPost,\n FacebookInsightsPeriod,\n} from './types.js';\n\nexport type {\n FacebookCredentials,\n FacebookCredentialData,\n FacebookPage,\n FacebookAccountInfo,\n FacebookTestResult,\n FacebookUploadParams,\n CreatePostOptions,\n CreatePostResult,\n CreateLinkPostOptions,\n CreateLinkPostResult,\n CreatePhotoPostOptions,\n CreatePhotoPostResult,\n FacebookPost,\n FacebookInsightsPeriod,\n GraphApiErrorResponse,\n} from './types.js';\n\n// --- Graph API Endpoints (version in src/common/meta.ts) ---\n\nconst GRAPH_API_VERSION = META_GRAPH_VERSION;\nconst FB_AUTH_URL = META_AUTH_URL;\nconst FB_TOKEN_URL = META_TOKEN_URL;\nconst GRAPH_API_BASE = META_GRAPH_BASE;\nconst GRAPH_VIDEO_BASE = META_GRAPH_VIDEO_BASE;\n\n// --- Provider ---\n\nexport class FacebookProvider extends PlatformProvider {\n public defaultRedirectUri: string;\n public scopes: string[];\n\n constructor(cfg: ProviderConfig = {}) {\n super(cfg);\n this.name = 'facebook';\n this.displayName = 'Facebook Pages';\n this.authType = 'oauth2';\n\n this.defaultRedirectUri =\n cfg.redirectUri ||\n `http://localhost:${cfg.port || 8060}/api/oauth/facebook/callback`;\n\n this.scopes = [\n 'business_management',\n 'pages_show_list',\n 'pages_read_engagement',\n 'pages_manage_posts',\n 'pages_read_user_content',\n ];\n }\n\n // --- API Helper ---\n\n /**\n * Unified Graph API request — used by all GET / POST / DELETE call sites.\n * Delegates to the shared `httpRequest` helper for retry, timeout, and 429 handling.\n *\n * @param method HTTP method\n * @param path Graph API path (e.g. `/me/accounts`)\n * @param accessToken Access token (sent as `access_token` query for GET/DELETE; body field for POST)\n * @param body POST body (merged with `access_token`); ignored for GET/DELETE\n * @param query Extra query params for GET\n * @param baseUrl Optional base URL override (video uploads use graph-video.facebook.com)\n */\n private async _graph<T = any>(\n method: 'GET' | 'POST' | 'DELETE',\n path: string,\n accessToken: string,\n body?: Record<string, any>,\n query?: Record<string, string>,\n baseUrl: string = GRAPH_API_BASE,\n ): Promise<T> {\n const isWriteWithBody = method === 'POST' && body !== undefined;\n const result = await httpRequest<T>('facebook', {\n method,\n url: `${baseUrl}${path}`,\n query: !isWriteWithBody ? { access_token: accessToken, ...(query ?? {}) } : query,\n json: isWriteWithBody ? { ...body, access_token: accessToken } : undefined,\n timeout: 60_000,\n retry: { attempts: 2 },\n parseError: parseGraphError,\n });\n return result.data;\n }\n\n // Backward-compatible shims so existing call sites work unchanged.\n private async _graphGet(path: string, accessToken: string, params: Record<string, string> = {}): Promise<any> {\n return this._graph('GET', path, accessToken, undefined, params);\n }\n private async _graphPost(path: string, body: Record<string, any>, accessToken: string, baseUrl: string = GRAPH_API_BASE): Promise<any> {\n return this._graph('POST', path, accessToken, body, undefined, baseUrl);\n }\n private async _graphDelete(path: string, accessToken: string): Promise<any> {\n return this._graph('DELETE', path, accessToken);\n }\n\n // --- OAuth ---\n\n /**\n * Get Facebook OAuth authorization URL\n */\n getAuthUrl(state: string, credentials: Partial<FacebookCredentials> = {}, _options?: AuthUrlOptions): string {\n const params = new URLSearchParams({\n client_id: credentials.appId!,\n redirect_uri: credentials.redirectUri || this.defaultRedirectUri,\n scope: this.scopes.join(','),\n response_type: 'code',\n state,\n });\n\n return `${FB_AUTH_URL}?${params.toString()}`;\n }\n\n /**\n * Exchange authorization code for tokens (two-step).\n *\n * Step 1: code → short-lived token (1 hour)\n * Step 2: short-lived → long-lived token (60 days)\n */\n async exchangeCode(code: string, credentials: Partial<FacebookCredentials> = {}): Promise<OAuthTokens> {\n return metaExchangeLongLived('facebook', {\n graphVersion: GRAPH_API_VERSION,\n clientId: credentials.appId!,\n clientSecret: credentials.appSecret!,\n redirectUri: credentials.redirectUri || this.defaultRedirectUri,\n code,\n });\n }\n\n /**\n * Refresh long-lived user token. Facebook long-lived tokens can be refreshed\n * before expiry by re-exchanging them via `fb_exchange_token`.\n */\n async refreshToken(refreshToken: string, credentials: Partial<FacebookCredentials> = {}): Promise<OAuthTokens> {\n return metaRefreshLongLivedFacebook({\n graphVersion: GRAPH_API_VERSION,\n clientId: credentials.appId!,\n clientSecret: credentials.appSecret!,\n refreshToken,\n });\n }\n\n // --- Account & Page Info ---\n\n /**\n * Get user's Facebook Pages with page-level access tokens\n * Each page has its own never-expiring token (when derived from long-lived user token)\n *\n * @param userAccessToken - Long-lived user access token\n * @returns List of pages with { id, name, access_token, category, ... }\n */\n async getPages(userAccessToken: string): Promise<FacebookPage[]> {\n const data = await this._graphGet(\n '/me/accounts',\n userAccessToken,\n { fields: 'id,name,access_token,category,picture{url},fan_count,followers_count' },\n );\n return data.data || [];\n }\n\n /**\n * Get account information -- returns the first managed page\n */\n async getAccountInfo(accessToken: string): Promise<FacebookAccountInfo> {\n const pages = await this.getPages(accessToken);\n\n if (!pages.length) {\n throw new SocialError(\n 'facebook',\n 'No Facebook Pages found. Your account must manage at least one Facebook Page.',\n );\n }\n\n const page = pages[0];\n return {\n id: page.id,\n name: page.name,\n profileImage: page.picture?.data?.url || null,\n category: page.category,\n fanCount: page.fan_count,\n pageAccessToken: page.access_token,\n pageId: page.id,\n pages: pages.map(p => ({\n id: p.id,\n name: p.name,\n category: p.category,\n profileImage: p.picture?.data?.url || null,\n })),\n };\n }\n\n /**\n * Test credential validity\n */\n async testCredential(credentialData: Record<string, any>): Promise<FacebookTestResult> {\n try {\n if (credentialData.oauthTokenData) {\n const tokenData = typeof credentialData.oauthTokenData === 'string'\n ? JSON.parse(credentialData.oauthTokenData)\n : credentialData.oauthTokenData;\n const accountInfo = await this.getAccountInfo(tokenData.access_token);\n\n return {\n status: 'OK',\n message: `Connected — managing ${accountInfo.pages.length} page(s)`,\n data: {\n channelId: accountInfo.id,\n channelTitle: accountInfo.name,\n profileImage: accountInfo.profileImage,\n pages: accountInfo.pages,\n },\n };\n }\n\n if (!credentialData.appId || !credentialData.appSecret) {\n return {\n status: 'Error',\n message: 'Meta App ID and App Secret are required',\n };\n }\n\n return {\n status: 'Pending',\n message: 'Credential needs OAuth authorization. Click \"Connect Account\" to link your Facebook.',\n };\n } catch (error: any) {\n return {\n status: 'Error',\n message: error.message || 'Failed to validate Facebook credential',\n };\n }\n }\n\n // --- Page Token Resolution ---\n\n /**\n * Get the page-level access token for a specific page\n * Page tokens derived from long-lived user tokens never expire.\n *\n * @param userAccessToken - Long-lived user access token\n * @param pageId - Facebook Page ID\n * @returns Page access token\n */\n async getPageAccessToken(userAccessToken: string, pageId: string): Promise<string> {\n const pages = await this.getPages(userAccessToken);\n const page = pages.find(p => p.id === pageId);\n\n if (!page) {\n throw new SocialError(\n 'facebook',\n `Page ${pageId} not found or you don't have admin access. Check your page permissions.`,\n );\n }\n\n return page.access_token;\n }\n\n // --- Content Publishing ---\n\n /**\n * Publish a text post to a Facebook Page\n * @param pageAccessToken - Page-level access token\n * @param pageId - Facebook Page ID\n * @param message - Post text\n * @param options\n */\n async createPost(\n pageAccessToken: string,\n pageId: string,\n message: string,\n options: CreatePostOptions = {},\n ): Promise<CreatePostResult> {\n const body: Record<string, any> = { message };\n\n if (options.scheduledAt) {\n const publishTime = Math.floor(new Date(options.scheduledAt).getTime() / 1000);\n body.published = false;\n body.scheduled_publish_time = publishTime;\n }\n\n const data = await this._graphPost(`/${pageId}/feed`, body, pageAccessToken);\n\n return {\n postId: data.id,\n status: options.scheduledAt ? 'scheduled' : 'published',\n scheduledAt: options.scheduledAt ? new Date(options.scheduledAt) : null,\n };\n }\n\n /**\n * Publish a link/article share to a Facebook Page\n * @param pageAccessToken\n * @param pageId\n * @param link - URL to share\n * @param options\n */\n async createLinkPost(\n pageAccessToken: string,\n pageId: string,\n link: string,\n options: CreateLinkPostOptions = {},\n ): Promise<CreateLinkPostResult> {\n const body: Record<string, any> = { link };\n if (options.message) body.message = options.message;\n\n if (options.scheduledAt) {\n const publishTime = Math.floor(new Date(options.scheduledAt).getTime() / 1000);\n body.published = false;\n body.scheduled_publish_time = publishTime;\n }\n\n const data = await this._graphPost(`/${pageId}/feed`, body, pageAccessToken);\n\n return {\n postId: data.id,\n status: options.scheduledAt ? 'scheduled' : 'published',\n };\n }\n\n /**\n * Publish a photo to a Facebook Page (via public URL)\n * @param pageAccessToken\n * @param pageId\n * @param photoUrl - Publicly accessible photo URL\n * @param options\n */\n async createPhotoPost(\n pageAccessToken: string,\n pageId: string,\n photoUrl: string,\n options: CreatePhotoPostOptions = {},\n ): Promise<CreatePhotoPostResult> {\n const body: Record<string, any> = { url: photoUrl };\n if (options.caption) body.message = options.caption;\n\n if (options.scheduledAt) {\n const publishTime = Math.floor(new Date(options.scheduledAt).getTime() / 1000);\n body.published = false;\n body.scheduled_publish_time = publishTime;\n }\n\n const data = await this._graphPost(`/${pageId}/photos`, body, pageAccessToken);\n\n return {\n postId: data.post_id || data.id,\n photoId: data.id,\n status: options.scheduledAt ? 'scheduled' : 'published',\n };\n }\n\n /**\n * Upload a video to a Facebook Page (via public URL)\n * Uses graph-video.facebook.com for video uploads.\n */\n async uploadVideo(params: FacebookUploadParams): Promise<UploadResult> {\n const {\n videoUrl,\n title = '',\n description = '',\n tokens,\n scheduledAt,\n onProgress,\n } = params;\n\n const pageAccessToken = tokens.pageAccessToken || tokens.access_token;\n const pageId = tokens.pageId;\n\n if (!pageId) {\n throw new SocialError('facebook', 'Page ID is required. Select a page from your connected pages.');\n }\n\n if (!videoUrl) {\n throw new SocialError('facebook', 'Video URL is required. Facebook accepts public URLs for video uploads.');\n }\n\n const body: Record<string, any> = {\n file_url: videoUrl,\n title: title.substring(0, 255),\n description: description.substring(0, 5000),\n };\n\n if (scheduledAt) {\n const publishTime = Math.floor(new Date(scheduledAt).getTime() / 1000);\n body.published = false;\n body.scheduled_publish_time = publishTime;\n }\n\n if (onProgress) onProgress(10);\n\n // Video uploads use graph-video.facebook.com\n const data = await this._graphPost(\n `/${pageId}/videos`,\n body,\n pageAccessToken,\n GRAPH_VIDEO_BASE,\n );\n\n if (onProgress) onProgress(100);\n\n return {\n platformVideoId: data.id,\n platformUrl: `https://www.facebook.com/${pageId}/videos/${data.id}/`,\n status: scheduledAt ? 'scheduled' : 'published',\n uploadedAt: new Date(),\n scheduledAt: scheduledAt ? new Date(scheduledAt) : null,\n metadata: {\n pageId,\n videoId: data.id,\n title,\n },\n };\n }\n\n // --- Post Management ---\n\n /**\n * Get a post by ID\n * @param pageAccessToken\n * @param postId\n * @param fields - Comma-separated fields\n */\n async getPost(\n pageAccessToken: string,\n postId: string,\n fields: string = 'id,message,created_time,permalink_url,shares,likes.summary(true),comments.summary(true)',\n ): Promise<any> {\n return this._graphGet(`/${postId}`, pageAccessToken, { fields });\n }\n\n /**\n * Update a post's message\n * @param pageAccessToken\n * @param postId\n * @param message - New message text\n */\n async updatePost(pageAccessToken: string, postId: string, message: string): Promise<any> {\n return this._graphPost(`/${postId}`, { message }, pageAccessToken);\n }\n\n /**\n * Delete a post\n * @param pageAccessToken\n * @param postId\n */\n async deletePost(pageAccessToken: string, postId: string): Promise<any> {\n return this._graphDelete(`/${postId}`, pageAccessToken);\n }\n\n /**\n * Get page feed (recent posts)\n * @param pageAccessToken\n * @param pageId\n * @param limit\n */\n async getPageFeed(pageAccessToken: string, pageId: string, limit: number = 25): Promise<any> {\n return this._graphGet(\n `/${pageId}/feed`,\n pageAccessToken,\n { fields: 'id,message,created_time,permalink_url,type,shares', limit: String(limit) },\n );\n }\n\n /**\n * Get page insights (basic analytics)\n * @param pageAccessToken\n * @param pageId\n * @param period - 'day' | 'week' | 'days_28'\n */\n async getPageInsights(\n pageAccessToken: string,\n pageId: string,\n period: 'day' | 'week' | 'days_28' = 'day',\n ): Promise<any> {\n return this._graphGet(\n `/${pageId}/insights`,\n pageAccessToken,\n {\n metric: 'page_impressions,page_engaged_users,page_post_engagements,page_fan_adds',\n period,\n },\n );\n }\n\n // --- Schema & Metadata ---\n\n getCredentialZodSchema(): z.ZodType {\n return FacebookCredentialsSchema;\n }\n\n getCredentialSchema(): CredentialField[] {\n return [\n {\n name: 'appId',\n displayName: 'Meta App ID',\n type: 'text',\n required: true,\n description: 'App ID from Meta Developer Portal (developers.facebook.com)',\n },\n {\n name: 'appSecret',\n displayName: 'Meta App Secret',\n type: 'password',\n required: true,\n description: 'App Secret from Meta Developer Portal',\n },\n ];\n }\n\n getMetadata(): ProviderMetadata {\n return {\n name: this.name,\n displayName: this.displayName,\n authType: this.authType,\n icon: 'facebook',\n brandColor: '#1877F2',\n description: 'Publish posts, photos, and videos to Facebook Pages',\n scopes: this.scopes,\n scopeDescriptions: {\n pages_show_list: 'View the list of Facebook Pages you manage',\n pages_read_engagement: 'Read engagement metrics from your pages',\n pages_manage_posts: 'Create, edit, and delete posts on your pages',\n pages_read_user_content: 'Read user-generated content on your pages',\n },\n supportsScheduling: true,\n supportsEnvironment: false,\n setupGuide: [\n { step: 1, title: 'Create Meta Developer Account', description: 'Go to developers.facebook.com and create an account or log in' },\n { step: 2, title: 'Create a New App', description: 'Click \"My Apps\" → \"Create App\". Enter your app name and email. On the use case step, filter by \"Content management\" and select \"Manage everything on your Page\"' },\n { step: 3, title: 'Connect Business Portfolio', description: 'Select or create a Business Portfolio when prompted. Click \"Create App\" to proceed to the dashboard' },\n { step: 4, title: 'Set Redirect URI', description: `Go to \"Facebook Login\" → \"Settings\" in the left sidebar. Add this as a Valid OAuth Redirect URI: ${this.defaultRedirectUri}` },\n { step: 5, title: 'Configure App Settings', description: 'Go to Settings → Basic. Add your App Domain and a Privacy Policy URL. Copy your App ID and App Secret and paste them above' },\n { step: 6, title: 'Add Permissions', description: 'Click \"Customize\" on your use case → \"Permissions and features\". pages_show_list, business_management, and public_profile are pre-added. Click \"+ Add\" for: pages_manage_posts, pages_read_engagement, pages_read_user_content, pages_manage_engagement, read_insights' },\n { step: 7, title: 'Go Live', description: 'Switch app to \"Live\" mode. For development, Standard Access works with app role users. For production, request Advanced Access via App Review' },\n { step: 8, title: 'Page Admin Required', description: 'You must be an admin of the Facebook Page(s) you want to post to. The page will be auto-discovered during authorization' },\n ],\n redirectUriPattern: this.defaultRedirectUri,\n credentialSchema: this.getCredentialSchema(),\n };\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { d as ProviderMetadata, g as UploadResult, i as CredentialField, l as ProviderConfig, o as OAuthTokens, r as AuthUrlOptions, s as PlatformProvider } from "../base-DBtKFiSX.mjs";
|
|
2
|
+
import { _ as MediaInsights, a as InstagramCredentialData, c as InstagramSetupStep, d as InstagramUploadCarouselParams, f as InstagramUploadPhotoParams, g as ListMediaResult, h as ListMediaOptions, i as InstagramAccountInfo, l as InstagramTestResult, m as InstagramUserTag, n as ContainerStatus, o as InstagramMedia, p as InstagramUploadVideoParams, r as ContainerStatusCode, s as InstagramMediaType, t as CarouselItem, u as InstagramTokens } from "../types-hriBJTsU.mjs";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
//#region src/providers/instagram/index.d.ts
|
|
6
|
+
declare class InstagramProvider extends PlatformProvider {
|
|
7
|
+
private defaultRedirectUri;
|
|
8
|
+
private scopes;
|
|
9
|
+
constructor(cfg?: ProviderConfig);
|
|
10
|
+
/**
|
|
11
|
+
* Get Facebook OAuth authorization URL
|
|
12
|
+
* Instagram uses Facebook's OAuth dialog for authorization
|
|
13
|
+
*/
|
|
14
|
+
getAuthUrl(state: string, credentials?: Record<string, any>, _options?: AuthUrlOptions): string;
|
|
15
|
+
/**
|
|
16
|
+
* Exchange authorization code for tokens (two-step).
|
|
17
|
+
*
|
|
18
|
+
* Step 1: code → short-lived token (1 hour)
|
|
19
|
+
* Step 2: short-lived → long-lived token (60 days)
|
|
20
|
+
*/
|
|
21
|
+
exchangeCode(code: string, credentials?: Record<string, any>): Promise<OAuthTokens>;
|
|
22
|
+
/**
|
|
23
|
+
* Refresh long-lived token. Instagram uses the access token itself as the
|
|
24
|
+
* refresh credential (must be ≥24h old, not yet expired) and hits the
|
|
25
|
+
* `graph.instagram.com` refresh endpoint.
|
|
26
|
+
*/
|
|
27
|
+
refreshToken(refreshToken: string): Promise<OAuthTokens>;
|
|
28
|
+
/**
|
|
29
|
+
* Get Instagram Business Account info
|
|
30
|
+
*
|
|
31
|
+
* Flow:
|
|
32
|
+
* 1. Get user's Facebook Pages via /me/accounts
|
|
33
|
+
* 2. For first page, get linked instagram_business_account
|
|
34
|
+
* 3. Get IG profile details
|
|
35
|
+
*/
|
|
36
|
+
getAccountInfo(accessToken: string): Promise<InstagramAccountInfo>;
|
|
37
|
+
/**
|
|
38
|
+
* Test credential validity
|
|
39
|
+
*/
|
|
40
|
+
testCredential(credentialData: InstagramCredentialData): Promise<InstagramTestResult>;
|
|
41
|
+
/**
|
|
42
|
+
* Upload a video as a Reel to Instagram
|
|
43
|
+
*
|
|
44
|
+
* Instagram requires publicly accessible video URLs (no binary upload).
|
|
45
|
+
* Flow: create container → poll status → publish
|
|
46
|
+
*
|
|
47
|
+
* @param params
|
|
48
|
+
* @param params.videoUrl - Publicly accessible video URL (required)
|
|
49
|
+
* @param params.title - Used as caption
|
|
50
|
+
* @param params.description - Appended to caption if title is empty
|
|
51
|
+
* @param params.tokens - { access_token, ig_user_id }
|
|
52
|
+
* @param params.onProgress - Progress callback
|
|
53
|
+
*/
|
|
54
|
+
uploadVideo(params: InstagramUploadVideoParams): Promise<UploadResult>;
|
|
55
|
+
/**
|
|
56
|
+
* Create a single photo post on Instagram
|
|
57
|
+
*
|
|
58
|
+
* @param params
|
|
59
|
+
* @param params.imageUrl - Publicly accessible image URL
|
|
60
|
+
* @param params.caption - Post caption (max 2200 chars)
|
|
61
|
+
* @param params.tokens - { access_token, ig_user_id }
|
|
62
|
+
*/
|
|
63
|
+
uploadPhoto(params: InstagramUploadPhotoParams): Promise<{
|
|
64
|
+
mediaId: string;
|
|
65
|
+
status: string;
|
|
66
|
+
}>;
|
|
67
|
+
/**
|
|
68
|
+
* Create a carousel post on Instagram
|
|
69
|
+
*
|
|
70
|
+
* @param params
|
|
71
|
+
* @param params.items - 2-10 media items with type ('IMAGE'|'VIDEO') and url
|
|
72
|
+
* @param params.caption - Post caption (max 2200 chars)
|
|
73
|
+
* @param params.tokens - { access_token, ig_user_id }
|
|
74
|
+
*/
|
|
75
|
+
uploadCarousel(params: InstagramUploadCarouselParams): Promise<{
|
|
76
|
+
mediaId: string;
|
|
77
|
+
status: string;
|
|
78
|
+
}>;
|
|
79
|
+
/**
|
|
80
|
+
* Get a single media object by ID
|
|
81
|
+
*
|
|
82
|
+
* @param accessToken - Valid access token
|
|
83
|
+
* @param mediaId - Instagram media ID
|
|
84
|
+
*/
|
|
85
|
+
getMedia(accessToken: string, mediaId: string): Promise<InstagramMedia>;
|
|
86
|
+
/**
|
|
87
|
+
* List media for an Instagram user
|
|
88
|
+
*
|
|
89
|
+
* @param accessToken - Valid access token
|
|
90
|
+
* @param userId - IG user ID (if omitted, fetched via getAccountInfo)
|
|
91
|
+
* @param options - Pagination options (limit, after, before)
|
|
92
|
+
*/
|
|
93
|
+
listMedia(accessToken: string, userId?: string, options?: ListMediaOptions): Promise<ListMediaResult>;
|
|
94
|
+
/**
|
|
95
|
+
* Get insights for a specific media object
|
|
96
|
+
*
|
|
97
|
+
* @param accessToken - Valid access token
|
|
98
|
+
* @param mediaId - Instagram media ID
|
|
99
|
+
*/
|
|
100
|
+
getMediaInsights(accessToken: string, mediaId: string): Promise<MediaInsights>;
|
|
101
|
+
getCredentialZodSchema(): z.ZodType;
|
|
102
|
+
getCredentialSchema(): CredentialField[];
|
|
103
|
+
getMetadata(): ProviderMetadata;
|
|
104
|
+
/**
|
|
105
|
+
* Make a GET request to the Graph API
|
|
106
|
+
* @private
|
|
107
|
+
*/
|
|
108
|
+
private _graphGet;
|
|
109
|
+
/**
|
|
110
|
+
* Make a POST request to the Graph API
|
|
111
|
+
* @private
|
|
112
|
+
*/
|
|
113
|
+
private _graphPost;
|
|
114
|
+
/**
|
|
115
|
+
* Poll container status until FINISHED, ERROR, or timeout
|
|
116
|
+
* @private
|
|
117
|
+
*/
|
|
118
|
+
private _pollContainerStatus;
|
|
119
|
+
}
|
|
120
|
+
//#endregion
|
|
121
|
+
export { type CarouselItem, type ContainerStatus, type ContainerStatusCode, type InstagramAccountInfo, type InstagramCredentialData, type InstagramMedia, type InstagramMediaType, InstagramProvider, type InstagramSetupStep, type InstagramTestResult, type InstagramTokens, type InstagramUploadCarouselParams, type InstagramUploadPhotoParams, type InstagramUploadVideoParams, type InstagramUserTag, type ListMediaOptions, type ListMediaResult, type MediaInsights };
|
|
122
|
+
//# sourceMappingURL=instagram.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instagram.d.mts","names":[],"sources":["../../src/providers/instagram/index.ts"],"mappings":";;;;;cA0Fa,iBAAA,SAA0B,gBAAA;EAAA,QAC7B,kBAAA;EAAA,QACA,MAAA;cAEI,GAAA,GAAK,cAAA;EAkc6C;;;;EAxa9D,UAAA,CAAW,KAAA,UAAe,WAAA,GAAa,MAAA,eAA0B,QAAA,GAAW,cAAA;EA9BvB;;;;;;EAgD/C,YAAA,CAAa,IAAA,UAAc,WAAA,GAAa,MAAA,gBAA2B,OAAA,CAAQ,WAAA;EA5CrE;;;;;EA2DN,YAAA,CAAa,YAAA,WAAuB,OAAA,CAAQ,WAAA;EAjCe;;;;;;;;EA+C3D,cAAA,CAAe,WAAA,WAAsB,OAAA,CAAQ,oBAAA;EAdT;;;EAmEpC,cAAA,CAAe,cAAA,EAAgB,uBAAA,GAA0B,OAAA,CAAQ,mBAAA;EArD5B;;;;;;;;;;;;;EA0GrC,WAAA,CAAY,MAAA,EAAQ,0BAAA,GAA6B,OAAA,CAAQ,YAAA;EAmF7C;;;;;;;;EAAZ,WAAA,CAAY,MAAA,EAAQ,0BAAA,GAA6B,OAAA;IAAU,OAAA;IAAiB,MAAA;EAAA;EAmH9C;;;;;;;;EAnE9B,cAAA,CAAe,MAAA,EAAQ,6BAAA,GAAgC,OAAA;IAAU,OAAA;IAAiB,MAAA;EAAA;EA4I5C;;;;;;EAzEtC,QAAA,CAAS,WAAA,UAAqB,OAAA,WAAkB,OAAA,CAAQ,cAAA;EAgHvC;;;;;;;EAjFjB,SAAA,CAAU,WAAA,UAAqB,MAAA,WAAiB,OAAA,GAAS,gBAAA,GAAwB,OAAA,CAAQ,eAAA;;;;;;;EA0CzF,gBAAA,CAAiB,WAAA,UAAqB,OAAA,WAAkB,OAAA,CAAQ,aAAA;EAmCtE,sBAAA,CAAA,GAA0B,CAAA,CAAE,OAAA;EAI5B,mBAAA,CAAA,GAAuB,eAAA;EAmBvB,WAAA,CAAA,GAAe,gBAAA;;;;;UAuED,SAAA;;;;;UAkBA,UAAA;;;;;UAgBA,oBAAA;AAAA"}
|