post-tools.ts•6.76 kB
import { getRedditClient } from "../client/reddit-client";
import { formatPostInfo, formatCommentInfo } from "../utils/formatters";
import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
export async function getRedditPost(params: {
subreddit: string;
post_id: string;
}) {
const { subreddit, post_id } = params;
const client = getRedditClient();
if (!client) {
throw new McpError(
ErrorCode.InternalError,
"Reddit client not initialized"
);
}
try {
console.log(`[Tool] Getting post ${post_id} from r/${subreddit}`);
const post = await client.getPost(post_id, subreddit);
const formattedPost = formatPostInfo(post);
return {
content: [
{
type: "text",
text: `
# Post from r/${formattedPost.subreddit}
## Post Details
- Title: ${formattedPost.title}
- Type: ${formattedPost.type}
- Author: u/${formattedPost.author}
## Content
${formattedPost.content}
## Stats
- Score: ${formattedPost.stats.score.toLocaleString()}
- Upvote Ratio: ${(formattedPost.stats.upvoteRatio * 100).toFixed(1)}%
- Comments: ${formattedPost.stats.comments.toLocaleString()}
## Metadata
- Posted: ${formattedPost.metadata.posted}
- Flags: ${
formattedPost.metadata.flags.length
? formattedPost.metadata.flags.join(", ")
: "None"
}
- Flair: ${formattedPost.metadata.flair}
## Links
- Full Post: ${formattedPost.links.fullPost}
- Short Link: ${formattedPost.links.shortLink}
## Engagement Analysis
- ${formattedPost.engagementAnalysis.replace(/\n - /g, "\n- ")}
## Best Time to Engage
${formattedPost.bestTimeToEngage}
`,
},
],
};
} catch (error) {
console.error(`[Error] Error getting post: ${error}`);
throw new McpError(
ErrorCode.InternalError,
`Failed to fetch post data: ${error}`
);
}
}
export async function getTopPosts(params: {
subreddit: string;
time_filter?: string;
limit?: number;
}) {
const { subreddit, time_filter = "week", limit = 10 } = params;
const client = getRedditClient();
if (!client) {
throw new McpError(
ErrorCode.InternalError,
"Reddit client not initialized"
);
}
try {
console.log(`[Tool] Getting top posts from r/${subreddit}`);
const posts = await client.getTopPosts(subreddit, time_filter, limit);
const formattedPosts = posts.map(formatPostInfo);
const postSummaries = formattedPosts
.map(
(post, index) => `
### ${index + 1}. ${post.title}
- Author: u/${post.author}
- Score: ${post.stats.score.toLocaleString()} (${(
post.stats.upvoteRatio * 100
).toFixed(1)}% upvoted)
- Comments: ${post.stats.comments.toLocaleString()}
- Posted: ${post.metadata.posted}
- Link: ${post.links.shortLink}
`
)
.join("\n");
return {
content: [
{
type: "text",
text: `
# Top Posts from r/${subreddit} (${time_filter})
${postSummaries}
`,
},
],
};
} catch (error) {
console.error(`[Error] Error getting top posts: ${error}`);
throw new McpError(
ErrorCode.InternalError,
`Failed to fetch top posts: ${error}`
);
}
}
export async function createPost(params: {
subreddit: string;
title: string;
content: string;
is_self?: boolean;
}) {
const { subreddit, title, content, is_self = true } = params;
const client = getRedditClient();
if (!client) {
throw new McpError(
ErrorCode.InternalError,
"Reddit client not initialized"
);
}
try {
console.log(
`[Tool] Creating ${is_self ? "text" : "link"} post in r/${subreddit}: "${title}"`
);
const startTime = Date.now();
const post = await client.createPost(subreddit, title, content, is_self);
const endTime = Date.now();
console.log(`[Tool] Post creation took ${endTime - startTime}ms`);
const formattedPost = formatPostInfo(post);
return {
content: [
{
type: "text",
text: `
# ✅ Post créé avec succès !
## 📝 Détails du post
- **Titre**: ${formattedPost.title}
- **Subreddit**: r/${formattedPost.subreddit}
- **Type**: ${formattedPost.type}
- **ID**: ${post.id}
- **Auteur**: u/${formattedPost.author}
## 🔗 Liens
- **Lien complet**: ${formattedPost.links.fullPost}
- **Permalink**: https://reddit.com${post.permalink}
## ⏰ Statut
Votre post a été **publié avec succès** sur r/${formattedPost.subreddit} !
${is_self ?
`**Contenu**: ${content.substring(0, 200)}${content.length > 200 ? '...' : ''}` :
`**URL**: ${content}`
}
`,
},
],
};
} catch (error: any) {
console.error(`[Error] Error creating post: ${error}`);
// Provide more specific error messages
let errorMessage = `Échec de la création du post: ${error.message}`;
if (error.message.includes('timeout')) {
errorMessage = `⏰ Timeout lors de la création du post. Le post a peut-être été créé malgré tout - vérifiez votre profil Reddit.`;
} else if (error.message.includes('authentication')) {
errorMessage = `🔐 Problème d'authentification. Vérifiez vos credentials Reddit dans le fichier .env`;
} else if (error.message.includes('rate limit')) {
errorMessage = `⏱️ Limite de fréquence atteinte. Attendez quelques minutes avant de réessayer.`;
} else if (error.message.includes('submission')) {
errorMessage = `📝 Erreur de soumission. Vérifiez que le subreddit existe et que vous avez les permissions.`;
}
throw new McpError(
ErrorCode.InternalError,
errorMessage
);
}
}
export async function replyToPost(params: {
post_id: string;
content: string;
subreddit?: string;
}) {
const { post_id, content, subreddit } = params;
const client = getRedditClient();
if (!client) {
throw new McpError(
ErrorCode.InternalError,
"Reddit client not initialized"
);
}
try {
console.log(`[Tool] Replying to post ${post_id}`);
const comment = await client.replyToPost(post_id, content);
const formattedComment = formatCommentInfo(comment);
return {
content: [
{
type: "text",
text: `
# Reply Posted Successfully
## Comment Details
- Author: u/${formattedComment.author}
- Subreddit: r/${formattedComment.context.subreddit}
- Thread: ${formattedComment.context.thread}
- Link: ${formattedComment.link}
Your reply has been successfully posted.
`,
},
],
};
} catch (error) {
console.error(`[Error] Error replying to post: ${error}`);
throw new McpError(
ErrorCode.InternalError,
`Failed to reply to post: ${error}`
);
}
}