naystack 1.8.12 → 1.8.14
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/README.md +189 -31
- package/dist/auth/index.cjs.js +158 -18
- package/dist/auth/index.d.mts +3 -1
- package/dist/auth/index.d.ts +3 -1
- package/dist/auth/index.esm.js +158 -18
- package/dist/auth/instagram/index.cjs.js +158 -18
- package/dist/auth/instagram/index.d.mts +6 -1
- package/dist/auth/instagram/index.d.ts +6 -1
- package/dist/auth/instagram/index.esm.js +158 -18
- package/dist/auth/instagram/route.cjs.js +158 -18
- package/dist/auth/instagram/route.d.mts +3 -1
- package/dist/auth/instagram/route.d.ts +3 -1
- package/dist/auth/instagram/route.esm.js +158 -18
- package/dist/auth/instagram/utils.cjs.js +2 -2
- package/dist/auth/instagram/utils.d.mts +13 -2
- package/dist/auth/instagram/utils.d.ts +13 -2
- package/dist/auth/instagram/utils.esm.js +2 -2
- package/dist/file/setup.d.mts +13 -5
- package/dist/file/setup.d.ts +13 -5
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/socials/index.cjs.js +298 -72
- package/dist/socials/index.d.mts +6 -4
- package/dist/socials/index.d.ts +6 -4
- package/dist/socials/index.esm.js +296 -72
- package/dist/socials/instagram/getters.cjs.js +76 -25
- package/dist/socials/instagram/getters.d.mts +56 -6
- package/dist/socials/instagram/getters.d.ts +56 -6
- package/dist/socials/instagram/getters.esm.js +74 -25
- package/dist/socials/instagram/setters.cjs.js +192 -14
- package/dist/socials/instagram/setters.d.mts +43 -3
- package/dist/socials/instagram/setters.d.ts +43 -3
- package/dist/socials/instagram/setters.esm.js +191 -14
- package/dist/socials/instagram/types.d.mts +48 -11
- package/dist/socials/instagram/types.d.ts +48 -11
- package/dist/socials/instagram/utils.cjs.js +28 -15
- package/dist/socials/instagram/utils.d.mts +7 -18
- package/dist/socials/instagram/utils.d.ts +7 -18
- package/dist/socials/instagram/utils.esm.js +26 -14
- package/dist/socials/instagram/webhook.cjs.js +1 -1
- package/dist/socials/instagram/webhook.esm.js +1 -1
- package/dist/socials/meta/container.cjs.js +82 -0
- package/dist/socials/meta/container.d.mts +38 -0
- package/dist/socials/meta/container.d.ts +38 -0
- package/dist/socials/meta/container.esm.js +57 -0
- package/dist/socials/meta/request.cjs.js +60 -0
- package/dist/socials/meta/request.d.mts +50 -0
- package/dist/socials/meta/request.d.ts +50 -0
- package/dist/socials/meta/request.esm.js +34 -0
- package/dist/socials/meta/types.cjs.js +34 -0
- package/dist/socials/meta/types.d.mts +51 -0
- package/dist/socials/meta/types.d.ts +51 -0
- package/dist/socials/meta/types.esm.js +9 -0
- package/dist/socials/{meta-webhook.cjs.js → meta/webhook.cjs.js} +4 -4
- package/dist/socials/{meta-webhook.esm.js → meta/webhook.esm.js} +1 -1
- package/dist/socials/threads/getters.cjs.js +36 -11
- package/dist/socials/threads/getters.d.mts +23 -2
- package/dist/socials/threads/getters.d.ts +23 -2
- package/dist/socials/threads/getters.esm.js +35 -11
- package/dist/socials/threads/setters.cjs.js +150 -44
- package/dist/socials/threads/setters.d.mts +25 -34
- package/dist/socials/threads/setters.d.ts +25 -34
- package/dist/socials/threads/setters.esm.js +149 -41
- package/dist/socials/threads/types.d.mts +40 -1
- package/dist/socials/threads/types.d.ts +40 -1
- package/dist/socials/threads/utils.cjs.js +29 -11
- package/dist/socials/threads/utils.d.mts +8 -17
- package/dist/socials/threads/utils.d.ts +8 -17
- package/dist/socials/threads/utils.esm.js +27 -10
- package/dist/socials/threads/webhook.cjs.js +1 -1
- package/dist/socials/threads/webhook.esm.js +1 -1
- package/package.json +1 -1
- /package/dist/socials/{meta-webhook.d.mts → meta/webhook.d.mts} +0 -0
- /package/dist/socials/{meta-webhook.d.ts → meta/webhook.d.ts} +0 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { GraphParams, ContainerState } from './types.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Polling settings for a media container.
|
|
5
|
+
*
|
|
6
|
+
* @property intervalMS - Delay between status checks. Default: `5000`.
|
|
7
|
+
* @property timeoutMS - Give up after this long. Default: `300000` (Meta stops processing after ~5 min).
|
|
8
|
+
*
|
|
9
|
+
* @category Socials
|
|
10
|
+
*/
|
|
11
|
+
type WaitForContainerOptions = {
|
|
12
|
+
intervalMS?: number;
|
|
13
|
+
timeoutMS?: number;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Wires up the create → wait → publish flow Meta platforms share. Instagram and
|
|
17
|
+
* Threads differ only in their endpoints, so each builds one publisher and every
|
|
18
|
+
* post shape goes through it.
|
|
19
|
+
*
|
|
20
|
+
* @param platform.name - Used in error logs, e.g. `"Instagram"`.
|
|
21
|
+
* @param platform.createContainer - Creates a container, resolving to its id.
|
|
22
|
+
* @param platform.getStatus - Reads a container's state by id.
|
|
23
|
+
* @param platform.publish - Publishes a finished container, resolving to the post id.
|
|
24
|
+
* @returns `{ publish, createChildren }`.
|
|
25
|
+
*/
|
|
26
|
+
declare function createPublisher(platform: {
|
|
27
|
+
name: string;
|
|
28
|
+
createContainer: (token: string, params: GraphParams) => Promise<string | null>;
|
|
29
|
+
getStatus: (token: string, id: string) => Promise<ContainerState | null>;
|
|
30
|
+
publish: (token: string, creationID: string) => Promise<string | null>;
|
|
31
|
+
}): {
|
|
32
|
+
/** Creates a container, waits for it to finish processing, then publishes it. */
|
|
33
|
+
publish: (token: string, params: GraphParams, wait?: WaitForContainerOptions) => Promise<string | null>;
|
|
34
|
+
/** Creates and awaits every carousel child, resolving to their ids — or `null` if any failed. */
|
|
35
|
+
createChildren: (token: string, items: GraphParams[], wait?: WaitForContainerOptions) => Promise<string[] | null>;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export { type WaitForContainerOptions, createPublisher };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// src/socials/meta/container.ts
|
|
2
|
+
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
3
|
+
async function waitForContainer(getState, { intervalMS = 5e3, timeoutMS = 3e5 } = {}) {
|
|
4
|
+
const deadline = Date.now() + timeoutMS;
|
|
5
|
+
let state = await getState();
|
|
6
|
+
if (!state) {
|
|
7
|
+
await sleep(2e3);
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
while (state?.status === "IN_PROGRESS" && Date.now() < deadline) {
|
|
11
|
+
await sleep(intervalMS);
|
|
12
|
+
state = await getState();
|
|
13
|
+
}
|
|
14
|
+
return state;
|
|
15
|
+
}
|
|
16
|
+
function createPublisher(platform) {
|
|
17
|
+
const isReady = async (token, id, label, wait) => {
|
|
18
|
+
const state = await waitForContainer(
|
|
19
|
+
() => platform.getStatus(token, id),
|
|
20
|
+
wait
|
|
21
|
+
);
|
|
22
|
+
if (state && state.status !== "FINISHED" && state.status !== "PUBLISHED") {
|
|
23
|
+
console.error(
|
|
24
|
+
`[naystack] ${platform.name} ${label} ${id} is ${state.status}${state.error ? `: ${state.error}` : ""}`
|
|
25
|
+
);
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
return true;
|
|
29
|
+
};
|
|
30
|
+
return {
|
|
31
|
+
/** Creates a container, waits for it to finish processing, then publishes it. */
|
|
32
|
+
publish: async (token, params, wait) => {
|
|
33
|
+
const containerID = await platform.createContainer(token, params);
|
|
34
|
+
if (!containerID) return null;
|
|
35
|
+
if (!await isReady(token, containerID, "container", wait)) return null;
|
|
36
|
+
return platform.publish(token, containerID);
|
|
37
|
+
},
|
|
38
|
+
/** Creates and awaits every carousel child, resolving to their ids — or `null` if any failed. */
|
|
39
|
+
createChildren: async (token, items, wait) => {
|
|
40
|
+
const children = [];
|
|
41
|
+
for (const item of items) {
|
|
42
|
+
const childID = await platform.createContainer(token, {
|
|
43
|
+
...item,
|
|
44
|
+
is_carousel_item: true
|
|
45
|
+
});
|
|
46
|
+
if (!childID) return null;
|
|
47
|
+
if (!await isReady(token, childID, "carousel item", wait))
|
|
48
|
+
return null;
|
|
49
|
+
children.push(childID);
|
|
50
|
+
}
|
|
51
|
+
return children;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
export {
|
|
56
|
+
createPublisher
|
|
57
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/socials/meta/request.ts
|
|
21
|
+
var request_exports = {};
|
|
22
|
+
__export(request_exports, {
|
|
23
|
+
createGraphClient: () => createGraphClient,
|
|
24
|
+
readGraphID: () => readGraphID
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(request_exports);
|
|
27
|
+
function createGraphClient(baseURL) {
|
|
28
|
+
const buildURL = (token, path, params = {}) => {
|
|
29
|
+
const search = new URLSearchParams();
|
|
30
|
+
for (const [key, value] of Object.entries(params)) {
|
|
31
|
+
if (value !== void 0) search.set(key, String(value));
|
|
32
|
+
}
|
|
33
|
+
search.set("access_token", token);
|
|
34
|
+
return `${baseURL}/${path}?${search.toString()}`;
|
|
35
|
+
};
|
|
36
|
+
const request = async (token, path, options = {}) => {
|
|
37
|
+
const response = await fetch(buildURL(token, path, options.params), {
|
|
38
|
+
method: options.method || (options.body ? "POST" : "GET"),
|
|
39
|
+
headers: {
|
|
40
|
+
Authorization: `Bearer ${token}`,
|
|
41
|
+
...options.body ? { "Content-Type": "application/json" } : {}
|
|
42
|
+
},
|
|
43
|
+
...options.body ? { body: JSON.stringify(options.body) } : {}
|
|
44
|
+
});
|
|
45
|
+
return response.json().catch(() => null);
|
|
46
|
+
};
|
|
47
|
+
return { buildURL, request };
|
|
48
|
+
}
|
|
49
|
+
function readGraphID(label, result) {
|
|
50
|
+
if (result?.error) {
|
|
51
|
+
console.error(`[naystack] ${label} failed: ${result.error.message}`);
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
return result?.id || null;
|
|
55
|
+
}
|
|
56
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
57
|
+
0 && (module.exports = {
|
|
58
|
+
createGraphClient,
|
|
59
|
+
readGraphID
|
|
60
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { GraphParams, GraphError } from './types.mjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Options for a single Graph API request.
|
|
5
|
+
*
|
|
6
|
+
* @property params - Query parameters. Most Graph mutations take their arguments here, not in a body.
|
|
7
|
+
* @property method - Defaults to `"POST"` when `body` is set, `"GET"` otherwise.
|
|
8
|
+
* @property body - JSON body, for the few endpoints that need one (e.g. Instagram messaging).
|
|
9
|
+
*
|
|
10
|
+
* @category Socials
|
|
11
|
+
*/
|
|
12
|
+
type GraphRequestOptions = {
|
|
13
|
+
params?: GraphParams;
|
|
14
|
+
method?: "GET" | "POST";
|
|
15
|
+
body?: object;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* A Graph API client bound to one platform's base URL.
|
|
19
|
+
*
|
|
20
|
+
* @category Socials
|
|
21
|
+
*/
|
|
22
|
+
type GraphClient = {
|
|
23
|
+
buildURL: (token: string, path: string, params?: GraphParams) => string;
|
|
24
|
+
request: <T>(token: string, path: string, options?: GraphRequestOptions) => Promise<(T & GraphError) | null>;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Creates a Graph API client for a base URL (Instagram, Threads — same protocol,
|
|
28
|
+
* different host and version).
|
|
29
|
+
*
|
|
30
|
+
* Every param is URL-encoded, so captions may contain spaces, `&`, `#` and newlines.
|
|
31
|
+
*
|
|
32
|
+
* @param baseURL - Versioned API root, e.g. `"https://graph.instagram.com/v23.0"`.
|
|
33
|
+
* @returns `{ buildURL, request }`.
|
|
34
|
+
* @category Socials
|
|
35
|
+
*/
|
|
36
|
+
declare function createGraphClient(baseURL: string): GraphClient;
|
|
37
|
+
/**
|
|
38
|
+
* Unwraps the `id` from a Graph API response, logging the API's own message
|
|
39
|
+
* when the call failed. Keeps publishing helpers to a single `null` return.
|
|
40
|
+
*
|
|
41
|
+
* @param label - Name used in the error log, e.g. `"Instagram media container"`.
|
|
42
|
+
* @param result - Raw Graph API response.
|
|
43
|
+
* @returns The id, or `null` on error.
|
|
44
|
+
* @category Socials
|
|
45
|
+
*/
|
|
46
|
+
declare function readGraphID(label: string, result: ({
|
|
47
|
+
id?: string;
|
|
48
|
+
} & GraphError) | null): string | null;
|
|
49
|
+
|
|
50
|
+
export { type GraphClient, type GraphRequestOptions, createGraphClient, readGraphID };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { GraphParams, GraphError } from './types.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Options for a single Graph API request.
|
|
5
|
+
*
|
|
6
|
+
* @property params - Query parameters. Most Graph mutations take their arguments here, not in a body.
|
|
7
|
+
* @property method - Defaults to `"POST"` when `body` is set, `"GET"` otherwise.
|
|
8
|
+
* @property body - JSON body, for the few endpoints that need one (e.g. Instagram messaging).
|
|
9
|
+
*
|
|
10
|
+
* @category Socials
|
|
11
|
+
*/
|
|
12
|
+
type GraphRequestOptions = {
|
|
13
|
+
params?: GraphParams;
|
|
14
|
+
method?: "GET" | "POST";
|
|
15
|
+
body?: object;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* A Graph API client bound to one platform's base URL.
|
|
19
|
+
*
|
|
20
|
+
* @category Socials
|
|
21
|
+
*/
|
|
22
|
+
type GraphClient = {
|
|
23
|
+
buildURL: (token: string, path: string, params?: GraphParams) => string;
|
|
24
|
+
request: <T>(token: string, path: string, options?: GraphRequestOptions) => Promise<(T & GraphError) | null>;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Creates a Graph API client for a base URL (Instagram, Threads — same protocol,
|
|
28
|
+
* different host and version).
|
|
29
|
+
*
|
|
30
|
+
* Every param is URL-encoded, so captions may contain spaces, `&`, `#` and newlines.
|
|
31
|
+
*
|
|
32
|
+
* @param baseURL - Versioned API root, e.g. `"https://graph.instagram.com/v23.0"`.
|
|
33
|
+
* @returns `{ buildURL, request }`.
|
|
34
|
+
* @category Socials
|
|
35
|
+
*/
|
|
36
|
+
declare function createGraphClient(baseURL: string): GraphClient;
|
|
37
|
+
/**
|
|
38
|
+
* Unwraps the `id` from a Graph API response, logging the API's own message
|
|
39
|
+
* when the call failed. Keeps publishing helpers to a single `null` return.
|
|
40
|
+
*
|
|
41
|
+
* @param label - Name used in the error log, e.g. `"Instagram media container"`.
|
|
42
|
+
* @param result - Raw Graph API response.
|
|
43
|
+
* @returns The id, or `null` on error.
|
|
44
|
+
* @category Socials
|
|
45
|
+
*/
|
|
46
|
+
declare function readGraphID(label: string, result: ({
|
|
47
|
+
id?: string;
|
|
48
|
+
} & GraphError) | null): string | null;
|
|
49
|
+
|
|
50
|
+
export { type GraphClient, type GraphRequestOptions, createGraphClient, readGraphID };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// src/socials/meta/request.ts
|
|
2
|
+
function createGraphClient(baseURL) {
|
|
3
|
+
const buildURL = (token, path, params = {}) => {
|
|
4
|
+
const search = new URLSearchParams();
|
|
5
|
+
for (const [key, value] of Object.entries(params)) {
|
|
6
|
+
if (value !== void 0) search.set(key, String(value));
|
|
7
|
+
}
|
|
8
|
+
search.set("access_token", token);
|
|
9
|
+
return `${baseURL}/${path}?${search.toString()}`;
|
|
10
|
+
};
|
|
11
|
+
const request = async (token, path, options = {}) => {
|
|
12
|
+
const response = await fetch(buildURL(token, path, options.params), {
|
|
13
|
+
method: options.method || (options.body ? "POST" : "GET"),
|
|
14
|
+
headers: {
|
|
15
|
+
Authorization: `Bearer ${token}`,
|
|
16
|
+
...options.body ? { "Content-Type": "application/json" } : {}
|
|
17
|
+
},
|
|
18
|
+
...options.body ? { body: JSON.stringify(options.body) } : {}
|
|
19
|
+
});
|
|
20
|
+
return response.json().catch(() => null);
|
|
21
|
+
};
|
|
22
|
+
return { buildURL, request };
|
|
23
|
+
}
|
|
24
|
+
function readGraphID(label, result) {
|
|
25
|
+
if (result?.error) {
|
|
26
|
+
console.error(`[naystack] ${label} failed: ${result.error.message}`);
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
return result?.id || null;
|
|
30
|
+
}
|
|
31
|
+
export {
|
|
32
|
+
createGraphClient,
|
|
33
|
+
readGraphID
|
|
34
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/socials/meta/types.ts
|
|
21
|
+
var types_exports = {};
|
|
22
|
+
__export(types_exports, {
|
|
23
|
+
MetaMediaType: () => MetaMediaType
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(types_exports);
|
|
26
|
+
var MetaMediaType = /* @__PURE__ */ ((MetaMediaType2) => {
|
|
27
|
+
MetaMediaType2["Photo"] = "photo";
|
|
28
|
+
MetaMediaType2["Video"] = "video";
|
|
29
|
+
return MetaMediaType2;
|
|
30
|
+
})(MetaMediaType || {});
|
|
31
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
32
|
+
0 && (module.exports = {
|
|
33
|
+
MetaMediaType
|
|
34
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for Meta's Graph protocol — the request/response shape Instagram and
|
|
3
|
+
* Threads share. Platforms outside Meta don't use these.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Query parameters for a Graph API request. Values are stringified and URL-encoded;
|
|
9
|
+
* `undefined` entries are dropped, so optional params can be passed inline.
|
|
10
|
+
*
|
|
11
|
+
* @category Socials
|
|
12
|
+
*/
|
|
13
|
+
type GraphParams = Record<string, string | number | boolean | undefined>;
|
|
14
|
+
/**
|
|
15
|
+
* Meta Graph API error response shape (Instagram, Threads).
|
|
16
|
+
*
|
|
17
|
+
* @property error - Error details from the API (message, type, code, subcode, trace id).
|
|
18
|
+
*
|
|
19
|
+
* @category Socials
|
|
20
|
+
*/
|
|
21
|
+
type GraphError = {
|
|
22
|
+
error?: {
|
|
23
|
+
message: string;
|
|
24
|
+
type: string;
|
|
25
|
+
code: number;
|
|
26
|
+
error_subcode: number;
|
|
27
|
+
fbtrace_id: string;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Processing status of a media container, before it can be published.
|
|
32
|
+
* Shared vocabulary across Instagram (`status_code`) and Threads (`status`).
|
|
33
|
+
*
|
|
34
|
+
* @category Socials
|
|
35
|
+
*/
|
|
36
|
+
type ContainerStatus = "EXPIRED" | "ERROR" | "FINISHED" | "IN_PROGRESS" | "PUBLISHED";
|
|
37
|
+
/**
|
|
38
|
+
* A container's processing status plus the API's reason when it failed.
|
|
39
|
+
*
|
|
40
|
+
* @category Socials
|
|
41
|
+
*/
|
|
42
|
+
type ContainerState = {
|
|
43
|
+
status: ContainerStatus;
|
|
44
|
+
error?: string;
|
|
45
|
+
};
|
|
46
|
+
declare enum MetaMediaType {
|
|
47
|
+
Photo = "photo",
|
|
48
|
+
Video = "video"
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export { type ContainerState, type ContainerStatus, type GraphError, type GraphParams, MetaMediaType };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for Meta's Graph protocol — the request/response shape Instagram and
|
|
3
|
+
* Threads share. Platforms outside Meta don't use these.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Query parameters for a Graph API request. Values are stringified and URL-encoded;
|
|
9
|
+
* `undefined` entries are dropped, so optional params can be passed inline.
|
|
10
|
+
*
|
|
11
|
+
* @category Socials
|
|
12
|
+
*/
|
|
13
|
+
type GraphParams = Record<string, string | number | boolean | undefined>;
|
|
14
|
+
/**
|
|
15
|
+
* Meta Graph API error response shape (Instagram, Threads).
|
|
16
|
+
*
|
|
17
|
+
* @property error - Error details from the API (message, type, code, subcode, trace id).
|
|
18
|
+
*
|
|
19
|
+
* @category Socials
|
|
20
|
+
*/
|
|
21
|
+
type GraphError = {
|
|
22
|
+
error?: {
|
|
23
|
+
message: string;
|
|
24
|
+
type: string;
|
|
25
|
+
code: number;
|
|
26
|
+
error_subcode: number;
|
|
27
|
+
fbtrace_id: string;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Processing status of a media container, before it can be published.
|
|
32
|
+
* Shared vocabulary across Instagram (`status_code`) and Threads (`status`).
|
|
33
|
+
*
|
|
34
|
+
* @category Socials
|
|
35
|
+
*/
|
|
36
|
+
type ContainerStatus = "EXPIRED" | "ERROR" | "FINISHED" | "IN_PROGRESS" | "PUBLISHED";
|
|
37
|
+
/**
|
|
38
|
+
* A container's processing status plus the API's reason when it failed.
|
|
39
|
+
*
|
|
40
|
+
* @category Socials
|
|
41
|
+
*/
|
|
42
|
+
type ContainerState = {
|
|
43
|
+
status: ContainerStatus;
|
|
44
|
+
error?: string;
|
|
45
|
+
};
|
|
46
|
+
declare enum MetaMediaType {
|
|
47
|
+
Photo = "photo",
|
|
48
|
+
Video = "video"
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export { type ContainerState, type ContainerStatus, type GraphError, type GraphParams, MetaMediaType };
|
|
@@ -17,12 +17,12 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
17
|
};
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
|
|
20
|
-
// src/socials/meta
|
|
21
|
-
var
|
|
22
|
-
__export(
|
|
20
|
+
// src/socials/meta/webhook.ts
|
|
21
|
+
var webhook_exports = {};
|
|
22
|
+
__export(webhook_exports, {
|
|
23
23
|
verifyWebhook: () => verifyWebhook
|
|
24
24
|
});
|
|
25
|
-
module.exports = __toCommonJS(
|
|
25
|
+
module.exports = __toCommonJS(webhook_exports);
|
|
26
26
|
var import_server = require("next/server");
|
|
27
27
|
var verifyWebhook = (secret) => (req) => {
|
|
28
28
|
const params = req.nextUrl.searchParams;
|
|
@@ -22,39 +22,64 @@ var getters_exports = {};
|
|
|
22
22
|
__export(getters_exports, {
|
|
23
23
|
getThread: () => getThread,
|
|
24
24
|
getThreads: () => getThreads,
|
|
25
|
+
getThreadsContainerStatus: () => getThreadsContainerStatus,
|
|
25
26
|
getThreadsReplies: () => getThreadsReplies
|
|
26
27
|
});
|
|
27
28
|
module.exports = __toCommonJS(getters_exports);
|
|
28
29
|
|
|
29
|
-
// src/socials/
|
|
30
|
-
function
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
30
|
+
// src/socials/meta/request.ts
|
|
31
|
+
function createGraphClient(baseURL) {
|
|
32
|
+
const buildURL = (token, path, params = {}) => {
|
|
33
|
+
const search = new URLSearchParams();
|
|
34
|
+
for (const [key, value] of Object.entries(params)) {
|
|
35
|
+
if (value !== void 0) search.set(key, String(value));
|
|
36
|
+
}
|
|
37
|
+
search.set("access_token", token);
|
|
38
|
+
return `${baseURL}/${path}?${search.toString()}`;
|
|
39
|
+
};
|
|
40
|
+
const request = async (token, path, options = {}) => {
|
|
41
|
+
const response = await fetch(buildURL(token, path, options.params), {
|
|
42
|
+
method: options.method || (options.body ? "POST" : "GET"),
|
|
43
|
+
headers: {
|
|
44
|
+
Authorization: `Bearer ${token}`,
|
|
45
|
+
...options.body ? { "Content-Type": "application/json" } : {}
|
|
46
|
+
},
|
|
47
|
+
...options.body ? { body: JSON.stringify(options.body) } : {}
|
|
48
|
+
});
|
|
49
|
+
return response.json().catch(() => null);
|
|
50
|
+
};
|
|
51
|
+
return { buildURL, request };
|
|
37
52
|
}
|
|
38
53
|
|
|
54
|
+
// src/socials/threads/utils.ts
|
|
55
|
+
var client = createGraphClient("https://graph.threads.net/v1.0");
|
|
56
|
+
var getThreadsData = client.request;
|
|
57
|
+
|
|
39
58
|
// src/socials/threads/getters.ts
|
|
40
59
|
var getThread = (token, id, fields) => {
|
|
41
60
|
return getThreadsData(token, id, {
|
|
42
|
-
fields: fields ? fields.join(",") : "text,permalink,username"
|
|
61
|
+
params: { fields: fields ? fields.join(",") : "text,permalink,username" }
|
|
43
62
|
});
|
|
44
63
|
};
|
|
45
64
|
var getThreads = (token, fields) => {
|
|
46
65
|
return getThreadsData(token, "me/threads", {
|
|
47
|
-
fields: fields ? fields.join(",") : "text,permalink,username"
|
|
66
|
+
params: { fields: fields ? fields.join(",") : "text,permalink,username" }
|
|
48
67
|
}).then((res) => res?.data);
|
|
49
68
|
};
|
|
50
69
|
var getThreadsReplies = (token, id, fields) => {
|
|
51
70
|
return getThreadsData(token, `${id}/replies`, {
|
|
52
|
-
fields: fields ? fields.join(",") : "text,username,permalink"
|
|
71
|
+
params: { fields: fields ? fields.join(",") : "text,username,permalink" }
|
|
53
72
|
}).then((res) => res?.data);
|
|
54
73
|
};
|
|
74
|
+
var getThreadsContainerStatus = async (token, id) => {
|
|
75
|
+
const result = await getThreadsData(token, id, { params: { fields: "status,error_message" } });
|
|
76
|
+
if (!result?.status) return null;
|
|
77
|
+
return { status: result.status, error: result.error_message };
|
|
78
|
+
};
|
|
55
79
|
// Annotate the CommonJS export names for ESM import in node:
|
|
56
80
|
0 && (module.exports = {
|
|
57
81
|
getThread,
|
|
58
82
|
getThreads,
|
|
83
|
+
getThreadsContainerStatus,
|
|
59
84
|
getThreadsReplies
|
|
60
85
|
});
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { GraphError, ContainerState } from '../meta/types.mjs';
|
|
1
2
|
import { ThreadsPost } from './types.mjs';
|
|
3
|
+
import '../meta/container.mjs';
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
* Fetches a single Threads post by id.
|
|
@@ -18,7 +20,7 @@ import { ThreadsPost } from './types.mjs';
|
|
|
18
20
|
*
|
|
19
21
|
* @category Socials
|
|
20
22
|
*/
|
|
21
|
-
declare const getThread: <T = ThreadsPost>(token: string, id: string, fields?: string[]) => Promise<T | null>;
|
|
23
|
+
declare const getThread: <T = ThreadsPost>(token: string, id: string, fields?: string[]) => Promise<(T & GraphError) | null>;
|
|
22
24
|
/**
|
|
23
25
|
* Fetches the authenticated user's Threads posts.
|
|
24
26
|
*
|
|
@@ -60,5 +62,24 @@ declare const getThreads: <T = ThreadsPost>(token: string, fields?: string[]) =>
|
|
|
60
62
|
* @category Socials
|
|
61
63
|
*/
|
|
62
64
|
declare const getThreadsReplies: <T = ThreadsPost>(token: string, id: string, fields?: string[]) => Promise<T[] | undefined>;
|
|
65
|
+
/**
|
|
66
|
+
* Reads a media container's processing status. Image, video and carousel
|
|
67
|
+
* containers must reach `FINISHED` before they can be published.
|
|
68
|
+
*
|
|
69
|
+
* @param token - Threads access token.
|
|
70
|
+
* @param id - Container id from `createThreadsContainer`.
|
|
71
|
+
* @returns Promise of `{ status, error? }`, or `null` if the status was unreadable.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```ts
|
|
75
|
+
* import { getThreadsContainerStatus } from "naystack/socials";
|
|
76
|
+
*
|
|
77
|
+
* const state = await getThreadsContainerStatus(accessToken, containerId);
|
|
78
|
+
* if (state?.status === "FINISHED") await publishThreadsContainer(accessToken, containerId);
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* @category Socials
|
|
82
|
+
*/
|
|
83
|
+
declare const getThreadsContainerStatus: (token: string, id: string) => Promise<ContainerState | null>;
|
|
63
84
|
|
|
64
|
-
export { getThread, getThreads, getThreadsReplies };
|
|
85
|
+
export { getThread, getThreads, getThreadsContainerStatus, getThreadsReplies };
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { GraphError, ContainerState } from '../meta/types.js';
|
|
1
2
|
import { ThreadsPost } from './types.js';
|
|
3
|
+
import '../meta/container.js';
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
* Fetches a single Threads post by id.
|
|
@@ -18,7 +20,7 @@ import { ThreadsPost } from './types.js';
|
|
|
18
20
|
*
|
|
19
21
|
* @category Socials
|
|
20
22
|
*/
|
|
21
|
-
declare const getThread: <T = ThreadsPost>(token: string, id: string, fields?: string[]) => Promise<T | null>;
|
|
23
|
+
declare const getThread: <T = ThreadsPost>(token: string, id: string, fields?: string[]) => Promise<(T & GraphError) | null>;
|
|
22
24
|
/**
|
|
23
25
|
* Fetches the authenticated user's Threads posts.
|
|
24
26
|
*
|
|
@@ -60,5 +62,24 @@ declare const getThreads: <T = ThreadsPost>(token: string, fields?: string[]) =>
|
|
|
60
62
|
* @category Socials
|
|
61
63
|
*/
|
|
62
64
|
declare const getThreadsReplies: <T = ThreadsPost>(token: string, id: string, fields?: string[]) => Promise<T[] | undefined>;
|
|
65
|
+
/**
|
|
66
|
+
* Reads a media container's processing status. Image, video and carousel
|
|
67
|
+
* containers must reach `FINISHED` before they can be published.
|
|
68
|
+
*
|
|
69
|
+
* @param token - Threads access token.
|
|
70
|
+
* @param id - Container id from `createThreadsContainer`.
|
|
71
|
+
* @returns Promise of `{ status, error? }`, or `null` if the status was unreadable.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```ts
|
|
75
|
+
* import { getThreadsContainerStatus } from "naystack/socials";
|
|
76
|
+
*
|
|
77
|
+
* const state = await getThreadsContainerStatus(accessToken, containerId);
|
|
78
|
+
* if (state?.status === "FINISHED") await publishThreadsContainer(accessToken, containerId);
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* @category Socials
|
|
82
|
+
*/
|
|
83
|
+
declare const getThreadsContainerStatus: (token: string, id: string) => Promise<ContainerState | null>;
|
|
63
84
|
|
|
64
|
-
export { getThread, getThreads, getThreadsReplies };
|
|
85
|
+
export { getThread, getThreads, getThreadsContainerStatus, getThreadsReplies };
|