social-mcp 2.5.0 → 2.7.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/README.md +64 -28
- package/dist/index.js +37 -29
- package/dist/index.js.map +1 -1
- package/dist/lib/http.d.ts +5 -1
- package/dist/lib/http.js.map +1 -1
- package/dist/lib/proxy.d.ts +4 -0
- package/dist/lib/proxy.js +13 -0
- package/dist/lib/proxy.js.map +1 -0
- package/dist/services/bluesky-service.d.ts +7 -1
- package/dist/services/bluesky-service.js +17 -2
- package/dist/services/bluesky-service.js.map +1 -1
- package/dist/services/discord-service.d.ts +24 -1
- package/dist/services/discord-service.js +46 -5
- package/dist/services/discord-service.js.map +1 -1
- package/dist/services/facebook-service.d.ts +17 -1
- package/dist/services/facebook-service.js +63 -5
- package/dist/services/facebook-service.js.map +1 -1
- package/dist/services/ghost-service.d.ts +4 -1
- package/dist/services/ghost-service.js +55 -9
- package/dist/services/ghost-service.js.map +1 -1
- package/dist/services/instagram-service.d.ts +6 -1
- package/dist/services/instagram-service.js +40 -3
- package/dist/services/instagram-service.js.map +1 -1
- package/dist/services/linkedin-service.d.ts +9 -1
- package/dist/services/linkedin-service.js +65 -8
- package/dist/services/linkedin-service.js.map +1 -1
- package/dist/services/mastodon-service.d.ts +10 -1
- package/dist/services/mastodon-service.js +35 -6
- package/dist/services/mastodon-service.js.map +1 -1
- package/dist/services/pinterest-service.d.ts +28 -2
- package/dist/services/pinterest-service.js +32 -8
- package/dist/services/pinterest-service.js.map +1 -1
- package/dist/services/reddit-service.d.ts +10 -1
- package/dist/services/reddit-service.js +62 -5
- package/dist/services/reddit-service.js.map +1 -1
- package/dist/services/slack-service.d.ts +14 -1
- package/dist/services/slack-service.js +22 -2
- package/dist/services/slack-service.js.map +1 -1
- package/dist/services/telegram-service.d.ts +4 -0
- package/dist/services/telegram-service.js +60 -1
- package/dist/services/telegram-service.js.map +1 -1
- package/dist/services/threads-service.d.ts +8 -1
- package/dist/services/threads-service.js +46 -7
- package/dist/services/threads-service.js.map +1 -1
- package/dist/services/tumblr-service.d.ts +25 -5
- package/dist/services/tumblr-service.js +51 -8
- package/dist/services/tumblr-service.js.map +1 -1
- package/dist/services/twitter-service.d.ts +13 -5
- package/dist/services/twitter-service.js +24 -3
- package/dist/services/twitter-service.js.map +1 -1
- package/dist/services/whatsapp-service.d.ts +10 -1
- package/dist/services/whatsapp-service.js +60 -9
- package/dist/services/whatsapp-service.js.map +1 -1
- package/dist/services/youtube-service.d.ts +21 -0
- package/dist/services/youtube-service.js +57 -7
- package/dist/services/youtube-service.js.map +1 -1
- package/dist/tools/bluesky-tools/create-post.d.ts +11 -1
- package/dist/tools/bluesky-tools/create-post.js +11 -2
- package/dist/tools/bluesky-tools/create-post.js.map +1 -1
- package/dist/tools/discord-tools/get-messages.js +6 -1
- package/dist/tools/discord-tools/get-messages.js.map +1 -1
- package/dist/tools/discord-tools/send-message.d.ts +11 -1
- package/dist/tools/discord-tools/send-message.js +17 -3
- package/dist/tools/discord-tools/send-message.js.map +1 -1
- package/dist/tools/facebook-tools/create-post.d.ts +5 -1
- package/dist/tools/facebook-tools/create-post.js +12 -2
- package/dist/tools/facebook-tools/create-post.js.map +1 -1
- package/dist/tools/facebook-tools/create-video-post.d.ts +20 -0
- package/dist/tools/facebook-tools/create-video-post.js +31 -0
- package/dist/tools/facebook-tools/create-video-post.js.map +1 -0
- package/dist/tools/ghost-tools/create-post.d.ts +4 -0
- package/dist/tools/ghost-tools/create-post.js +27 -4
- package/dist/tools/ghost-tools/create-post.js.map +1 -1
- package/dist/tools/instagram-tools/create-post.d.ts +11 -1
- package/dist/tools/instagram-tools/create-post.js +8 -3
- package/dist/tools/instagram-tools/create-post.js.map +1 -1
- package/dist/tools/linkedin-tools/create-post.d.ts +5 -1
- package/dist/tools/linkedin-tools/create-post.js +9 -2
- package/dist/tools/linkedin-tools/create-post.js.map +1 -1
- package/dist/tools/mastodon-tools/create-post.d.ts +11 -1
- package/dist/tools/mastodon-tools/create-post.js +18 -2
- package/dist/tools/mastodon-tools/create-post.js.map +1 -1
- package/dist/tools/medium-tools/create-post.d.ts +2 -2
- package/dist/tools/pinterest-tools/create-pin.d.ts +4 -2
- package/dist/tools/pinterest-tools/create-pin.js +8 -2
- package/dist/tools/pinterest-tools/create-pin.js.map +1 -1
- package/dist/tools/reddit-tools/submit-post.d.ts +9 -1
- package/dist/tools/reddit-tools/submit-post.js +19 -4
- package/dist/tools/reddit-tools/submit-post.js.map +1 -1
- package/dist/tools/slack-tools/send-message.d.ts +9 -1
- package/dist/tools/slack-tools/send-message.js +9 -2
- package/dist/tools/slack-tools/send-message.js.map +1 -1
- package/dist/tools/telegram-tools/send-document.d.ts +20 -0
- package/dist/tools/telegram-tools/send-document.js +33 -0
- package/dist/tools/telegram-tools/send-document.js.map +1 -0
- package/dist/tools/telegram-tools/send-photo.d.ts +20 -0
- package/dist/tools/telegram-tools/send-photo.js +33 -0
- package/dist/tools/telegram-tools/send-photo.js.map +1 -0
- package/dist/tools/threads-tools/create-post.d.ts +13 -1
- package/dist/tools/threads-tools/create-post.js +14 -2
- package/dist/tools/threads-tools/create-post.js.map +1 -1
- package/dist/tools/tumblr-tools/create-post.d.ts +6 -2
- package/dist/tools/tumblr-tools/create-post.js +39 -8
- package/dist/tools/tumblr-tools/create-post.js.map +1 -1
- package/dist/tools/tumblr-tools/get-posts.d.ts +2 -2
- package/dist/tools/twitter-tools/send-tweet.d.ts +9 -1
- package/dist/tools/twitter-tools/send-tweet.js +10 -2
- package/dist/tools/twitter-tools/send-tweet.js.map +1 -1
- package/dist/tools/whatsapp-tools/send-message.d.ts +19 -3
- package/dist/tools/whatsapp-tools/send-message.js +29 -3
- package/dist/tools/whatsapp-tools/send-message.js.map +1 -1
- package/dist/tools/youtube-tools/upload-video.d.ts +34 -0
- package/dist/tools/youtube-tools/upload-video.js +39 -0
- package/dist/tools/youtube-tools/upload-video.js.map +1 -0
- package/package.json +3 -1
|
@@ -2,16 +2,26 @@ import { z } from "zod";
|
|
|
2
2
|
import { config } from "../lib/config.js";
|
|
3
3
|
import { CredentialsError } from "../lib/errors.js";
|
|
4
4
|
import { fetchJson } from "../lib/http.js";
|
|
5
|
+
import { createProxyDispatcher } from "../lib/proxy.js";
|
|
6
|
+
const discordAttachmentSchema = z.object({
|
|
7
|
+
id: z.string(),
|
|
8
|
+
filename: z.string(),
|
|
9
|
+
url: z.string(),
|
|
10
|
+
content_type: z.string().optional(),
|
|
11
|
+
size: z.number().optional(),
|
|
12
|
+
});
|
|
5
13
|
const discordMessageSchema = z.object({
|
|
6
14
|
id: z.string(),
|
|
7
15
|
channel_id: z.string(),
|
|
8
16
|
content: z.string(),
|
|
9
17
|
timestamp: z.string(),
|
|
18
|
+
attachments: z.array(discordAttachmentSchema).optional(),
|
|
10
19
|
});
|
|
11
20
|
const discordMessagesSchema = z.array(discordMessageSchema);
|
|
12
21
|
export class DiscordService {
|
|
13
22
|
baseUrl = config.discord.baseUrl;
|
|
14
23
|
headers;
|
|
24
|
+
dispatcher;
|
|
15
25
|
constructor(credentials) {
|
|
16
26
|
const botToken = credentials?.botToken ?? config.discord.botToken;
|
|
17
27
|
if (!botToken) {
|
|
@@ -21,18 +31,49 @@ export class DiscordService {
|
|
|
21
31
|
"Content-Type": "application/json",
|
|
22
32
|
Authorization: `Bot ${botToken}`,
|
|
23
33
|
};
|
|
34
|
+
this.dispatcher = createProxyDispatcher(credentials?.proxyUrl);
|
|
24
35
|
}
|
|
25
|
-
async sendMessage(channelId, content) {
|
|
26
|
-
|
|
36
|
+
async sendMessage(channelId, content, attachments) {
|
|
37
|
+
if (!attachments?.length) {
|
|
38
|
+
return fetchJson(`${this.baseUrl}/channels/${channelId}/messages`, {
|
|
39
|
+
method: "POST",
|
|
40
|
+
headers: this.headers,
|
|
41
|
+
body: JSON.stringify({ content }),
|
|
42
|
+
dispatcher: this.dispatcher,
|
|
43
|
+
}, discordMessageSchema);
|
|
44
|
+
}
|
|
45
|
+
// Attachments require multipart/form-data — a JSON body can't carry file bytes.
|
|
46
|
+
// payload_json + files[n] is Discord's documented shape for this.
|
|
47
|
+
const formData = new FormData();
|
|
48
|
+
formData.append("payload_json", JSON.stringify({
|
|
49
|
+
content,
|
|
50
|
+
attachments: attachments.map((attachment, index) => ({
|
|
51
|
+
id: index,
|
|
52
|
+
filename: attachment.filename,
|
|
53
|
+
})),
|
|
54
|
+
}));
|
|
55
|
+
attachments.forEach((attachment, index) => {
|
|
56
|
+
const buffer = Buffer.from(attachment.content, "base64");
|
|
57
|
+
formData.append(`files[${index}]`, new Blob([buffer], {
|
|
58
|
+
type: attachment.contentType || "application/octet-stream",
|
|
59
|
+
}), attachment.filename);
|
|
60
|
+
});
|
|
61
|
+
const response = await fetch(`${this.baseUrl}/channels/${channelId}/messages`, {
|
|
27
62
|
method: "POST",
|
|
28
|
-
headers: this.headers,
|
|
29
|
-
body:
|
|
30
|
-
|
|
63
|
+
headers: { Authorization: this.headers.Authorization ?? "" },
|
|
64
|
+
body: formData,
|
|
65
|
+
dispatcher: this.dispatcher,
|
|
66
|
+
});
|
|
67
|
+
if (!response.ok) {
|
|
68
|
+
throw new Error(`Discord API error (${response.status}): ${await response.text()}`);
|
|
69
|
+
}
|
|
70
|
+
return discordMessageSchema.parse(await response.json());
|
|
31
71
|
}
|
|
32
72
|
async getMessages(channelId, limit = 50) {
|
|
33
73
|
return fetchJson(`${this.baseUrl}/channels/${channelId}/messages?limit=${limit}`, {
|
|
34
74
|
method: "GET",
|
|
35
75
|
headers: this.headers,
|
|
76
|
+
dispatcher: this.dispatcher,
|
|
36
77
|
}, discordMessagesSchema);
|
|
37
78
|
}
|
|
38
79
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discord-service.js","sourceRoot":"","sources":["../../src/services/discord-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"discord-service.js","sourceRoot":"","sources":["../../src/services/discord-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,27 @@
|
|
|
1
1
|
export interface FacebookCredentials {
|
|
2
2
|
accessToken: string;
|
|
3
|
+
proxyUrl?: string;
|
|
4
|
+
}
|
|
5
|
+
export interface FacebookImage {
|
|
6
|
+
/** Public image URL, or base64-encoded image bytes. */
|
|
7
|
+
image: string;
|
|
8
|
+
filename?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface FacebookVideo {
|
|
11
|
+
/** Public video URL, or base64-encoded video bytes. */
|
|
12
|
+
video: string;
|
|
13
|
+
filename?: string;
|
|
3
14
|
}
|
|
4
15
|
export declare class FacebookService {
|
|
5
16
|
private baseUrl;
|
|
6
17
|
private headers;
|
|
18
|
+
private dispatcher?;
|
|
7
19
|
constructor(credentials?: FacebookCredentials);
|
|
8
|
-
createPost(pageId: string, message: string): Promise<{
|
|
20
|
+
createPost(pageId: string, message: string, image?: FacebookImage): Promise<{
|
|
21
|
+
id: string;
|
|
22
|
+
post_id?: string | undefined;
|
|
23
|
+
}>;
|
|
24
|
+
createVideoPost(pageId: string, description: string, video: FacebookVideo): Promise<{
|
|
9
25
|
id: string;
|
|
10
26
|
post_id?: string | undefined;
|
|
11
27
|
}>;
|
|
@@ -2,6 +2,7 @@ import { z } from "zod";
|
|
|
2
2
|
import { config } from "../lib/config.js";
|
|
3
3
|
import { CredentialsError } from "../lib/errors.js";
|
|
4
4
|
import { fetchJson } from "../lib/http.js";
|
|
5
|
+
import { createProxyDispatcher } from "../lib/proxy.js";
|
|
5
6
|
const facebookPostSchema = z.object({
|
|
6
7
|
id: z.string(),
|
|
7
8
|
post_id: z.string().optional(),
|
|
@@ -17,6 +18,7 @@ const facebookPostsResponseSchema = z.object({
|
|
|
17
18
|
export class FacebookService {
|
|
18
19
|
baseUrl = config.facebook.baseUrl;
|
|
19
20
|
headers;
|
|
21
|
+
dispatcher;
|
|
20
22
|
constructor(credentials) {
|
|
21
23
|
const accessToken = credentials?.accessToken ?? config.facebook.accessToken;
|
|
22
24
|
if (!accessToken) {
|
|
@@ -26,21 +28,77 @@ export class FacebookService {
|
|
|
26
28
|
"Content-Type": "application/json",
|
|
27
29
|
Authorization: `Bearer ${accessToken}`,
|
|
28
30
|
};
|
|
31
|
+
this.dispatcher = createProxyDispatcher(credentials?.proxyUrl);
|
|
29
32
|
}
|
|
30
|
-
async createPost(pageId, message) {
|
|
31
|
-
|
|
33
|
+
async createPost(pageId, message, image) {
|
|
34
|
+
if (!image) {
|
|
35
|
+
return fetchJson(`${this.baseUrl}/${pageId}/feed`, {
|
|
36
|
+
method: "POST",
|
|
37
|
+
headers: this.headers,
|
|
38
|
+
body: JSON.stringify({ message }),
|
|
39
|
+
dispatcher: this.dispatcher,
|
|
40
|
+
}, facebookPostSchema);
|
|
41
|
+
}
|
|
42
|
+
// The Graph API's /photos endpoint accepts either a `url` it fetches itself,
|
|
43
|
+
// or a real multipart upload via `source` — same endpoint, two input shapes.
|
|
44
|
+
if (isHttpUrl(image.image)) {
|
|
45
|
+
return fetchJson(`${this.baseUrl}/${pageId}/photos`, {
|
|
46
|
+
method: "POST",
|
|
47
|
+
headers: this.headers,
|
|
48
|
+
body: JSON.stringify({ url: image.image, caption: message }),
|
|
49
|
+
dispatcher: this.dispatcher,
|
|
50
|
+
}, facebookPostSchema);
|
|
51
|
+
}
|
|
52
|
+
const formData = new FormData();
|
|
53
|
+
formData.append("caption", message);
|
|
54
|
+
const buffer = Buffer.from(image.image, "base64");
|
|
55
|
+
formData.append("source", new Blob([buffer]), image.filename ?? "photo.jpg");
|
|
56
|
+
const response = await fetch(`${this.baseUrl}/${pageId}/photos`, {
|
|
32
57
|
method: "POST",
|
|
33
|
-
headers: this.headers,
|
|
34
|
-
body:
|
|
35
|
-
|
|
58
|
+
headers: { Authorization: this.headers.Authorization ?? "" },
|
|
59
|
+
body: formData,
|
|
60
|
+
dispatcher: this.dispatcher,
|
|
61
|
+
});
|
|
62
|
+
if (!response.ok) {
|
|
63
|
+
throw new Error(`Facebook API error (${response.status}): ${await response.text()}`);
|
|
64
|
+
}
|
|
65
|
+
return facebookPostSchema.parse(await response.json());
|
|
66
|
+
}
|
|
67
|
+
async createVideoPost(pageId, description, video) {
|
|
68
|
+
if (isHttpUrl(video.video)) {
|
|
69
|
+
return fetchJson(`${this.baseUrl}/${pageId}/videos`, {
|
|
70
|
+
method: "POST",
|
|
71
|
+
headers: this.headers,
|
|
72
|
+
body: JSON.stringify({ file_url: video.video, description }),
|
|
73
|
+
dispatcher: this.dispatcher,
|
|
74
|
+
}, facebookPostSchema);
|
|
75
|
+
}
|
|
76
|
+
const formData = new FormData();
|
|
77
|
+
formData.append("description", description);
|
|
78
|
+
const buffer = Buffer.from(video.video, "base64");
|
|
79
|
+
formData.append("source", new Blob([buffer]), video.filename ?? "video.mp4");
|
|
80
|
+
const response = await fetch(`${this.baseUrl}/${pageId}/videos`, {
|
|
81
|
+
method: "POST",
|
|
82
|
+
headers: { Authorization: this.headers.Authorization ?? "" },
|
|
83
|
+
body: formData,
|
|
84
|
+
dispatcher: this.dispatcher,
|
|
85
|
+
});
|
|
86
|
+
if (!response.ok) {
|
|
87
|
+
throw new Error(`Facebook API error (${response.status}): ${await response.text()}`);
|
|
88
|
+
}
|
|
89
|
+
return facebookPostSchema.parse(await response.json());
|
|
36
90
|
}
|
|
37
91
|
async getPosts(pageId, limit = 10) {
|
|
38
92
|
return fetchJson(`${this.baseUrl}/${pageId}/posts?fields=id,message,created_time&limit=${limit}`, {
|
|
39
93
|
method: "GET",
|
|
40
94
|
headers: this.headers,
|
|
95
|
+
dispatcher: this.dispatcher,
|
|
41
96
|
}, facebookPostsResponseSchema);
|
|
42
97
|
}
|
|
43
98
|
}
|
|
99
|
+
function isHttpUrl(value) {
|
|
100
|
+
return value.startsWith("http://") || value.startsWith("https://");
|
|
101
|
+
}
|
|
44
102
|
let _instance;
|
|
45
103
|
export function getFacebookService() {
|
|
46
104
|
if (!_instance)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"facebook-service.js","sourceRoot":"","sources":["../../src/services/facebook-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"facebook-service.js","sourceRoot":"","sources":["../../src/services/facebook-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
export interface GhostCredentials {
|
|
2
2
|
siteUrl: string;
|
|
3
3
|
adminApiKey: string;
|
|
4
|
+
proxyUrl?: string;
|
|
4
5
|
}
|
|
5
6
|
export declare class GhostService {
|
|
6
7
|
private siteUrl;
|
|
7
8
|
private keyId;
|
|
8
9
|
private keySecret;
|
|
10
|
+
private dispatcher?;
|
|
9
11
|
constructor(credentials?: GhostCredentials);
|
|
10
12
|
private generateJwt;
|
|
11
13
|
private get headers();
|
|
@@ -35,7 +37,8 @@ export declare class GhostService {
|
|
|
35
37
|
} | undefined;
|
|
36
38
|
} | undefined;
|
|
37
39
|
}>;
|
|
38
|
-
|
|
40
|
+
uploadImage(content: string, filename?: string): Promise<string>;
|
|
41
|
+
createPost(title: string, html?: string, lexical?: string, status?: "draft" | "published" | "scheduled", tags?: string[], excerpt?: string, publishedAt?: string, featureImage?: string): Promise<{
|
|
39
42
|
posts: {
|
|
40
43
|
id: string;
|
|
41
44
|
title?: string | undefined;
|
|
@@ -3,6 +3,10 @@ import { z } from "zod";
|
|
|
3
3
|
import { config } from "../lib/config.js";
|
|
4
4
|
import { CredentialsError } from "../lib/errors.js";
|
|
5
5
|
import { fetchJson } from "../lib/http.js";
|
|
6
|
+
import { createProxyDispatcher } from "../lib/proxy.js";
|
|
7
|
+
const imageUploadSchema = z.object({
|
|
8
|
+
images: z.array(z.object({ url: z.string() })),
|
|
9
|
+
});
|
|
6
10
|
const postSchema = z.object({
|
|
7
11
|
id: z.string(),
|
|
8
12
|
title: z.string().optional(),
|
|
@@ -12,18 +16,24 @@ const postSchema = z.object({
|
|
|
12
16
|
published_at: z.string().nullable().optional(),
|
|
13
17
|
updated_at: z.string().nullable().optional(),
|
|
14
18
|
excerpt: z.string().nullable().optional(),
|
|
15
|
-
tags: z
|
|
19
|
+
tags: z
|
|
20
|
+
.array(z.object({ id: z.string(), name: z.string(), slug: z.string() }))
|
|
21
|
+
.optional(),
|
|
16
22
|
});
|
|
17
23
|
const postsResponseSchema = z.object({
|
|
18
24
|
posts: z.array(postSchema),
|
|
19
|
-
meta: z
|
|
20
|
-
|
|
25
|
+
meta: z
|
|
26
|
+
.object({
|
|
27
|
+
pagination: z
|
|
28
|
+
.object({
|
|
21
29
|
page: z.number(),
|
|
22
30
|
limit: z.number(),
|
|
23
31
|
pages: z.number(),
|
|
24
32
|
total: z.number(),
|
|
25
|
-
})
|
|
26
|
-
|
|
33
|
+
})
|
|
34
|
+
.optional(),
|
|
35
|
+
})
|
|
36
|
+
.optional(),
|
|
27
37
|
});
|
|
28
38
|
const singlePostResponseSchema = z.object({
|
|
29
39
|
posts: z.array(postSchema),
|
|
@@ -32,11 +42,15 @@ export class GhostService {
|
|
|
32
42
|
siteUrl;
|
|
33
43
|
keyId;
|
|
34
44
|
keySecret;
|
|
45
|
+
dispatcher;
|
|
35
46
|
constructor(credentials) {
|
|
36
47
|
const siteUrl = credentials?.siteUrl ?? config.ghost.siteUrl;
|
|
37
48
|
const adminApiKey = credentials?.adminApiKey ?? config.ghost.adminApiKey;
|
|
38
49
|
if (!siteUrl || !adminApiKey) {
|
|
39
|
-
throw new CredentialsError("Ghost", [
|
|
50
|
+
throw new CredentialsError("Ghost", [
|
|
51
|
+
"GHOST_SITE_URL",
|
|
52
|
+
"GHOST_ADMIN_API_KEY",
|
|
53
|
+
]);
|
|
40
54
|
}
|
|
41
55
|
const parts = adminApiKey.split(":");
|
|
42
56
|
if (parts.length !== 2) {
|
|
@@ -45,6 +59,7 @@ export class GhostService {
|
|
|
45
59
|
this.siteUrl = siteUrl.replace(/\/$/, "");
|
|
46
60
|
this.keyId = parts[0];
|
|
47
61
|
this.keySecret = parts[1];
|
|
62
|
+
this.dispatcher = createProxyDispatcher(credentials?.proxyUrl);
|
|
48
63
|
}
|
|
49
64
|
generateJwt() {
|
|
50
65
|
const now = Math.floor(Date.now() / 1000);
|
|
@@ -67,14 +82,40 @@ export class GhostService {
|
|
|
67
82
|
return `${this.siteUrl}/ghost/api/admin`;
|
|
68
83
|
}
|
|
69
84
|
async getPosts(page = 1, limit = 10, status = "all") {
|
|
70
|
-
const params = new URLSearchParams({
|
|
85
|
+
const params = new URLSearchParams({
|
|
86
|
+
page: String(page),
|
|
87
|
+
limit: String(limit),
|
|
88
|
+
filter: `status:${status}`,
|
|
89
|
+
});
|
|
71
90
|
if (status === "all")
|
|
72
91
|
params.delete("filter");
|
|
73
92
|
else
|
|
74
93
|
params.set("filter", `status:${status}`);
|
|
75
|
-
return fetchJson(`${this.adminBase}/posts?${params}`, { method: "GET", headers: this.headers }, postsResponseSchema);
|
|
94
|
+
return fetchJson(`${this.adminBase}/posts?${params}`, { method: "GET", headers: this.headers, dispatcher: this.dispatcher }, postsResponseSchema);
|
|
95
|
+
}
|
|
96
|
+
// Ghost's Admin API supports image upload as its own endpoint — the returned
|
|
97
|
+
// URL is then just set on `feature_image` (or embedded in html/lexical) like any
|
|
98
|
+
// other image, no special reference type needed elsewhere.
|
|
99
|
+
async uploadImage(content, filename = "image.jpg") {
|
|
100
|
+
const formData = new FormData();
|
|
101
|
+
const buffer = Buffer.from(content, "base64");
|
|
102
|
+
formData.append("file", new Blob([buffer]), filename);
|
|
103
|
+
formData.append("purpose", "image");
|
|
104
|
+
const response = await fetch(`${this.adminBase}/images/upload/`, {
|
|
105
|
+
method: "POST",
|
|
106
|
+
headers: {
|
|
107
|
+
Authorization: this.headers.Authorization ?? "",
|
|
108
|
+
"Accept-Version": "v5.0",
|
|
109
|
+
},
|
|
110
|
+
body: formData,
|
|
111
|
+
dispatcher: this.dispatcher,
|
|
112
|
+
});
|
|
113
|
+
if (!response.ok) {
|
|
114
|
+
throw new Error(`Ghost image upload error (${response.status}): ${await response.text()}`);
|
|
115
|
+
}
|
|
116
|
+
return imageUploadSchema.parse(await response.json()).images[0]?.url ?? "";
|
|
76
117
|
}
|
|
77
|
-
async createPost(title, html, lexical, status = "draft", tags = [], excerpt, publishedAt) {
|
|
118
|
+
async createPost(title, html, lexical, status = "draft", tags = [], excerpt, publishedAt, featureImage) {
|
|
78
119
|
const post = {
|
|
79
120
|
title,
|
|
80
121
|
status,
|
|
@@ -88,10 +129,13 @@ export class GhostService {
|
|
|
88
129
|
post.custom_excerpt = excerpt;
|
|
89
130
|
if (publishedAt)
|
|
90
131
|
post.published_at = publishedAt;
|
|
132
|
+
if (featureImage)
|
|
133
|
+
post.feature_image = featureImage;
|
|
91
134
|
return fetchJson(`${this.adminBase}/posts`, {
|
|
92
135
|
method: "POST",
|
|
93
136
|
headers: this.headers,
|
|
94
137
|
body: JSON.stringify({ posts: [post] }),
|
|
138
|
+
dispatcher: this.dispatcher,
|
|
95
139
|
}, singlePostResponseSchema);
|
|
96
140
|
}
|
|
97
141
|
async updatePost(id, updatedAt, updates) {
|
|
@@ -102,12 +146,14 @@ export class GhostService {
|
|
|
102
146
|
method: "PUT",
|
|
103
147
|
headers: this.headers,
|
|
104
148
|
body: JSON.stringify({ posts: [body] }),
|
|
149
|
+
dispatcher: this.dispatcher,
|
|
105
150
|
}, singlePostResponseSchema);
|
|
106
151
|
}
|
|
107
152
|
async deletePost(id) {
|
|
108
153
|
const response = await fetch(`${this.adminBase}/posts/${id}`, {
|
|
109
154
|
method: "DELETE",
|
|
110
155
|
headers: this.headers,
|
|
156
|
+
dispatcher: this.dispatcher,
|
|
111
157
|
});
|
|
112
158
|
if (!response.ok) {
|
|
113
159
|
throw new Error(`Ghost API error ${response.status}: ${response.statusText}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ghost-service.js","sourceRoot":"","sources":["../../src/services/ghost-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"ghost-service.js","sourceRoot":"","sources":["../../src/services/ghost-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
export interface InstagramCredentials {
|
|
2
2
|
accessToken: string;
|
|
3
|
+
proxyUrl?: string;
|
|
3
4
|
}
|
|
4
5
|
export declare class InstagramService {
|
|
5
6
|
private baseUrl;
|
|
6
7
|
private headers;
|
|
8
|
+
private dispatcher?;
|
|
7
9
|
constructor(credentials?: InstagramCredentials);
|
|
8
|
-
|
|
10
|
+
private waitUntilReady;
|
|
11
|
+
createPost(userId: string, mediaUrl: string, caption: string, mediaType?: "IMAGE" | "VIDEO" | "REELS"): Promise<{
|
|
9
12
|
id: string;
|
|
10
13
|
}>;
|
|
11
14
|
getPosts(userId: string, limit?: number): Promise<{
|
|
@@ -14,6 +17,8 @@ export declare class InstagramService {
|
|
|
14
17
|
media_type: string;
|
|
15
18
|
timestamp: string;
|
|
16
19
|
caption?: string | undefined;
|
|
20
|
+
media_url?: string | undefined;
|
|
21
|
+
permalink?: string | undefined;
|
|
17
22
|
}[];
|
|
18
23
|
}>;
|
|
19
24
|
}
|
|
@@ -2,6 +2,7 @@ import { z } from "zod";
|
|
|
2
2
|
import { config } from "../lib/config.js";
|
|
3
3
|
import { CredentialsError } from "../lib/errors.js";
|
|
4
4
|
import { fetchJson } from "../lib/http.js";
|
|
5
|
+
import { createProxyDispatcher } from "../lib/proxy.js";
|
|
5
6
|
const instagramMediaSchema = z.object({
|
|
6
7
|
id: z.string(),
|
|
7
8
|
});
|
|
@@ -9,14 +10,20 @@ const instagramMediaDetailSchema = z.object({
|
|
|
9
10
|
id: z.string(),
|
|
10
11
|
caption: z.string().optional(),
|
|
11
12
|
media_type: z.string(),
|
|
13
|
+
media_url: z.string().optional(),
|
|
14
|
+
permalink: z.string().optional(),
|
|
12
15
|
timestamp: z.string(),
|
|
13
16
|
});
|
|
14
17
|
const instagramMediaListSchema = z.object({
|
|
15
18
|
data: z.array(instagramMediaDetailSchema),
|
|
16
19
|
});
|
|
20
|
+
const containerStatusSchema = z.object({
|
|
21
|
+
status_code: z.string(),
|
|
22
|
+
});
|
|
17
23
|
export class InstagramService {
|
|
18
24
|
baseUrl = config.instagram.baseUrl;
|
|
19
25
|
headers;
|
|
26
|
+
dispatcher;
|
|
20
27
|
constructor(credentials) {
|
|
21
28
|
const accessToken = credentials?.accessToken ?? config.instagram.accessToken;
|
|
22
29
|
if (!accessToken) {
|
|
@@ -26,23 +33,53 @@ export class InstagramService {
|
|
|
26
33
|
"Content-Type": "application/json",
|
|
27
34
|
Authorization: `Bearer ${accessToken}`,
|
|
28
35
|
};
|
|
36
|
+
this.dispatcher = createProxyDispatcher(credentials?.proxyUrl);
|
|
37
|
+
}
|
|
38
|
+
// Video/Reels containers process asynchronously — publishing before status_code
|
|
39
|
+
// reaches FINISHED fails the publish call outright rather than just being slow.
|
|
40
|
+
async waitUntilReady(containerId, timeoutMs = 90_000) {
|
|
41
|
+
const start = Date.now();
|
|
42
|
+
while (Date.now() - start < timeoutMs) {
|
|
43
|
+
const status = await fetchJson(`${this.baseUrl}/${containerId}?fields=status_code`, { method: "GET", headers: this.headers, dispatcher: this.dispatcher }, containerStatusSchema);
|
|
44
|
+
if (status.status_code === "FINISHED")
|
|
45
|
+
return;
|
|
46
|
+
if (status.status_code === "ERROR" || status.status_code === "EXPIRED") {
|
|
47
|
+
throw new Error(`Instagram media container failed to process (${status.status_code})`);
|
|
48
|
+
}
|
|
49
|
+
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
50
|
+
}
|
|
51
|
+
throw new Error("Timed out waiting for Instagram media container to finish processing");
|
|
29
52
|
}
|
|
30
|
-
async createPost(userId,
|
|
53
|
+
async createPost(userId, mediaUrl, caption, mediaType = "IMAGE") {
|
|
54
|
+
const body = { caption };
|
|
55
|
+
if (mediaType === "IMAGE") {
|
|
56
|
+
body.image_url = mediaUrl;
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
body.media_type = mediaType;
|
|
60
|
+
body.video_url = mediaUrl;
|
|
61
|
+
}
|
|
31
62
|
const containerResponse = await fetchJson(`${this.baseUrl}/${userId}/media`, {
|
|
32
63
|
method: "POST",
|
|
33
64
|
headers: this.headers,
|
|
34
|
-
body: JSON.stringify(
|
|
65
|
+
body: JSON.stringify(body),
|
|
66
|
+
dispatcher: this.dispatcher,
|
|
35
67
|
}, z.object({ id: z.string() }));
|
|
68
|
+
if (mediaType !== "IMAGE") {
|
|
69
|
+
await this.waitUntilReady(containerResponse.id);
|
|
70
|
+
}
|
|
36
71
|
return fetchJson(`${this.baseUrl}/${userId}/media_publish`, {
|
|
37
72
|
method: "POST",
|
|
38
73
|
headers: this.headers,
|
|
39
74
|
body: JSON.stringify({ creation_id: containerResponse.id }),
|
|
75
|
+
dispatcher: this.dispatcher,
|
|
40
76
|
}, instagramMediaSchema);
|
|
41
77
|
}
|
|
42
78
|
async getPosts(userId, limit = 10) {
|
|
43
|
-
return fetchJson(`${this.baseUrl}/${userId}/media?fields=id,caption,media_type,timestamp&limit=${limit}`, {
|
|
79
|
+
return fetchJson(`${this.baseUrl}/${userId}/media?fields=id,caption,media_type,media_url,permalink,timestamp&limit=${limit}`, {
|
|
44
80
|
method: "GET",
|
|
45
81
|
headers: this.headers,
|
|
82
|
+
dispatcher: this.dispatcher,
|
|
46
83
|
}, instagramMediaListSchema);
|
|
47
84
|
}
|
|
48
85
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instagram-service.js","sourceRoot":"","sources":["../../src/services/instagram-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"instagram-service.js","sourceRoot":"","sources":["../../src/services/instagram-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
export interface LinkedInCredentials {
|
|
2
2
|
accessToken: string;
|
|
3
|
+
proxyUrl?: string;
|
|
4
|
+
}
|
|
5
|
+
export interface LinkedInImage {
|
|
6
|
+
/** Base64-encoded image bytes. */
|
|
7
|
+
content: string;
|
|
8
|
+
title?: string;
|
|
3
9
|
}
|
|
4
10
|
export declare class LinkedInService {
|
|
5
11
|
private baseUrl;
|
|
6
12
|
private headers;
|
|
13
|
+
private dispatcher?;
|
|
7
14
|
constructor(credentials?: LinkedInCredentials);
|
|
8
15
|
getProfile(): Promise<{
|
|
9
16
|
id: string;
|
|
@@ -11,7 +18,8 @@ export declare class LinkedInService {
|
|
|
11
18
|
localizedLastName?: string | undefined;
|
|
12
19
|
localizedHeadline?: string | undefined;
|
|
13
20
|
}>;
|
|
14
|
-
|
|
21
|
+
private uploadImage;
|
|
22
|
+
createPost(authorUrn: string, text: string, visibility?: string, image?: LinkedInImage): Promise<{
|
|
15
23
|
id: string;
|
|
16
24
|
}>;
|
|
17
25
|
getPosts(authorUrn: string, count?: number): Promise<{
|