social-media
About
This skill enables developers to add and manage social media integrations for Discord, LinkedIn, Telegram, and Twitter within workflows. It is used for incorporating new platforms, debugging posting failures, and modifying message templates. The skill provides capabilities to work with webhooks, API credentials, and the core integration files.
Documentation
Social Media Integration Skill
This skill helps you work with social media integrations in apps/api/src/lib/workflows/social/.
When to Use This Skill
- Adding new social media platforms
- Debugging posting failures
- Updating message templates and formatting
- Configuring webhook URLs and API credentials
- Testing social media workflows
Supported Platforms
Current integrations:
- Discord - Webhook-based posting
- LinkedIn - OAuth-based API posting
- Telegram - Bot API posting
- Twitter - API v2 posting
Architecture
apps/api/src/lib/workflows/social/
├── discord.ts # Discord webhook integration
├── linkedin.ts # LinkedIn API integration
├── telegram.ts # Telegram bot integration
└── twitter.ts # Twitter API integration
Key Patterns
1. Discord Integration
Discord uses webhooks for simple posting:
export async function postToDiscord(message: string, data: any) {
const webhookUrl = process.env.DISCORD_WEBHOOK_URL;
if (!webhookUrl) {
throw new Error("Discord webhook URL not configured");
}
const embed = {
title: "New Data Available",
description: message,
color: 0x00ff00,
fields: [
{ name: "Date", value: data.date, inline: true },
{ name: "Count", value: String(data.count), inline: true },
],
timestamp: new Date().toISOString(),
};
await fetch(webhookUrl, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ embeds: [embed] }),
});
}
2. Telegram Integration
Telegram uses Bot API with chat IDs:
export async function postToTelegram(message: string) {
const botToken = process.env.TELEGRAM_BOT_TOKEN;
const chatId = process.env.TELEGRAM_CHAT_ID;
if (!botToken || !chatId) {
throw new Error("Telegram credentials not configured");
}
const url = `https://api.telegram.org/bot${botToken}/sendMessage`;
await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
chat_id: chatId,
text: message,
parse_mode: "Markdown",
disable_web_page_preview: false,
}),
});
}
3. Twitter Integration
Twitter uses OAuth 2.0 with API v2:
export async function postToTwitter(message: string) {
const bearerToken = process.env.TWITTER_BEARER_TOKEN;
if (!bearerToken) {
throw new Error("Twitter bearer token not configured");
}
const url = "https://api.twitter.com/2/tweets";
const response = await fetch(url, {
method: "POST",
headers: {
"Authorization": `Bearer ${bearerToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ text: message }),
});
if (!response.ok) {
throw new Error(`Twitter API error: ${response.statusText}`);
}
return await response.json();
}
4. LinkedIn Integration
LinkedIn uses OAuth 2.0 with organization posting:
export async function postToLinkedIn(message: string) {
const accessToken = process.env.LINKEDIN_ACCESS_TOKEN;
const organizationId = process.env.LINKEDIN_ORG_ID;
if (!accessToken || !organizationId) {
throw new Error("LinkedIn credentials not configured");
}
const url = "https://api.linkedin.com/v2/ugcPosts";
await fetch(url, {
method: "POST",
headers: {
"Authorization": `Bearer ${accessToken}`,
"Content-Type": "application/json",
"X-Restli-Protocol-Version": "2.0.0",
},
body: JSON.stringify({
author: `urn:li:organization:${organizationId}`,
lifecycleState: "PUBLISHED",
specificContent: {
"com.linkedin.ugc.ShareContent": {
shareCommentary: { text: message },
shareMediaCategory: "NONE",
},
},
visibility: {
"com.linkedin.ugc.MemberNetworkVisibility": "PUBLIC",
},
}),
});
}
Message Templates
Create reusable message templates:
export function createCarDataMessage(data: CarRegistrationData) {
const { month, year, total, topMakes } = data;
return `🚗 Car Registration Update - ${month} ${year}
📊 Total Registrations: ${total.toLocaleString()}
🏆 Top Makes: ${topMakes.slice(0, 3).join(", ")}
📈 View detailed analysis: https://sgcarstrends.com/data/${year}/${month}
#SingaporeCars #CarRegistration #DataAnalytics`;
}
export function createCOEMessage(data: COEBiddingData) {
const { biddingNo, category, premium } = data;
return `💰 COE Bidding Results - Round ${biddingNo}
Category ${category}: $${premium.toLocaleString()}
Change: ${data.change > 0 ? "+" : ""}${data.change}%
Full results: https://sgcarstrends.com/coe/${biddingNo}
#COE #Singapore #CarPrices`;
}
Common Tasks
Adding a New Platform
- Create integration file (e.g.,
instagram.ts) - Implement posting function with authentication
- Add environment variables for credentials
- Create message template
- Add to workflow that triggers posting
- Test with development credentials
Debugging Posting Failures
Check these common issues:
-
Authentication errors:
- Verify environment variables are set
- Check token expiration (especially OAuth)
- Validate API credentials in platform console
-
API rate limits:
- Check platform rate limit documentation
- Implement retry logic with backoff
- Add rate limit tracking
-
Message formatting:
- Verify character limits (Twitter: 280, LinkedIn: 3000)
- Check for invalid characters or formatting
- Test markdown/HTML support
-
Network issues:
- Add timeout handling
- Implement retry logic
- Log full error responses
Updating Message Templates
- Locate template function
- Update message structure
- Test with sample data
- Verify formatting on each platform:
- Discord: Embeds and markdown
- Telegram: Markdown or HTML
- Twitter: Plain text, URLs, hashtags
- LinkedIn: Rich text, mentions
Rate Limiting
Implement rate limiting to avoid API restrictions:
import { Ratelimit } from "@upstash/ratelimit";
import { redis } from "@/config/redis";
const ratelimit = new Ratelimit({
redis,
limiter: Ratelimit.slidingWindow(10, "1 h"), // 10 posts per hour
});
export async function postToTwitter(message: string) {
const { success } = await ratelimit.limit("twitter-posts");
if (!success) {
throw new Error("Rate limit exceeded for Twitter");
}
// Post to Twitter...
}
Environment Variables
Discord
DISCORD_WEBHOOK_URL- Webhook URL from Discord channel settings
Telegram
TELEGRAM_BOT_TOKEN- Bot token from @BotFatherTELEGRAM_CHAT_ID- Channel or group chat ID
TWITTER_BEARER_TOKEN- OAuth 2.0 bearer tokenTWITTER_API_KEY- API key (if using OAuth 1.0a)TWITTER_API_SECRET- API secret
LINKEDIN_ACCESS_TOKEN- OAuth 2.0 access tokenLINKEDIN_ORG_ID- Organization ID for company pages
Testing Social Media Posts
Run integration tests:
pnpm -F @sgcarstrends/api test -- src/lib/workflows/social
Test individual platforms:
# Start dev server
pnpm dev
# Trigger social media workflow
curl -X POST http://localhost:3000/api/workflows/social/test \
-H "Content-Type: application/json" \
-d '{"platform": "discord", "message": "Test post"}'
Error Handling
Implement comprehensive error handling:
export async function postToAllPlatforms(message: string) {
const results = await Promise.allSettled([
postToDiscord(message).catch(err => ({ platform: "Discord", error: err })),
postToTelegram(message).catch(err => ({ platform: "Telegram", error: err })),
postToTwitter(message).catch(err => ({ platform: "Twitter", error: err })),
postToLinkedIn(message).catch(err => ({ platform: "LinkedIn", error: err })),
]);
const failures = results
.filter(r => r.status === "rejected")
.map(r => r.reason);
if (failures.length > 0) {
console.error("Social media posting failures:", failures);
}
return {
success: failures.length === 0,
failures,
};
}
Platform Character Limits
Respect platform limits:
- Twitter: 280 characters
- LinkedIn: 3,000 characters (posts), 700 (comments)
- Telegram: 4,096 characters
- Discord: 2,000 characters (message), 6,000 (embed total)
Implement truncation:
export function truncateMessage(message: string, limit: number): string {
if (message.length <= limit) return message;
return message.slice(0, limit - 3) + "...";
}
References
- Platform API docs: Use Context7 for latest documentation
- Related files:
apps/api/src/lib/workflows/social/- All integrationsapps/api/src/routes/workflows.ts- Workflow routesapps/api/CLAUDE.md- API service documentation
Best Practices
- Error Handling: Always handle API failures gracefully
- Rate Limiting: Implement rate limits to avoid bans
- Credentials: Never commit API keys or tokens
- Testing: Test on sandbox/dev accounts first
- Monitoring: Track posting success rates
- Formatting: Preview messages on each platform
- Compliance: Follow platform posting guidelines
- Retries: Implement exponential backoff for retries
Quick Install
/plugin add https://github.com/sgcarstrends/sgcarstrends/tree/main/social-mediaCopy and paste this command in Claude Code to install this skill
GitHub 仓库
Related Skills
sglang
MetaSGLang is a high-performance LLM serving framework that specializes in fast, structured generation for JSON, regex, and agentic workflows using its RadixAttention prefix caching. It delivers significantly faster inference, especially for tasks with repeated prefixes, making it ideal for complex, structured outputs and multi-turn conversations. Choose SGLang over alternatives like vLLM when you need constrained decoding or are building applications with extensive prefix sharing.
evaluating-llms-harness
TestingThis Claude Skill runs the lm-evaluation-harness to benchmark LLMs across 60+ standardized academic tasks like MMLU and GSM8K. It's designed for developers to compare model quality, track training progress, or report academic results. The tool supports various backends including HuggingFace and vLLM models.
llamaguard
OtherLlamaGuard is Meta's 7-8B parameter model for moderating LLM inputs and outputs across six safety categories like violence and hate speech. It offers 94-95% accuracy and can be deployed using vLLM, Hugging Face, or Amazon SageMaker. Use this skill to easily integrate content filtering and safety guardrails into your AI applications.
langchain
MetaLangChain is a framework for building LLM applications using agents, chains, and RAG pipelines. It supports multiple LLM providers, offers 500+ integrations, and includes features like tool calling and memory management. Use it for rapid prototyping and deploying production systems like chatbots, autonomous agents, and question-answering services.
