Back to Skills

social-media

sgcarstrends
Updated Today
18 views
9
1
9
View on GitHub
Metaaiautomation

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

  1. Create integration file (e.g., instagram.ts)
  2. Implement posting function with authentication
  3. Add environment variables for credentials
  4. Create message template
  5. Add to workflow that triggers posting
  6. Test with development credentials

Debugging Posting Failures

Check these common issues:

  1. Authentication errors:

    • Verify environment variables are set
    • Check token expiration (especially OAuth)
    • Validate API credentials in platform console
  2. API rate limits:

    • Check platform rate limit documentation
    • Implement retry logic with backoff
    • Add rate limit tracking
  3. Message formatting:

    • Verify character limits (Twitter: 280, LinkedIn: 3000)
    • Check for invalid characters or formatting
    • Test markdown/HTML support
  4. Network issues:

    • Add timeout handling
    • Implement retry logic
    • Log full error responses

Updating Message Templates

  1. Locate template function
  2. Update message structure
  3. Test with sample data
  4. 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 @BotFather
  • TELEGRAM_CHAT_ID - Channel or group chat ID

Twitter

  • TWITTER_BEARER_TOKEN - OAuth 2.0 bearer token
  • TWITTER_API_KEY - API key (if using OAuth 1.0a)
  • TWITTER_API_SECRET - API secret

LinkedIn

  • LINKEDIN_ACCESS_TOKEN - OAuth 2.0 access token
  • LINKEDIN_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 integrations
    • apps/api/src/routes/workflows.ts - Workflow routes
    • apps/api/CLAUDE.md - API service documentation

Best Practices

  1. Error Handling: Always handle API failures gracefully
  2. Rate Limiting: Implement rate limits to avoid bans
  3. Credentials: Never commit API keys or tokens
  4. Testing: Test on sandbox/dev accounts first
  5. Monitoring: Track posting success rates
  6. Formatting: Preview messages on each platform
  7. Compliance: Follow platform posting guidelines
  8. Retries: Implement exponential backoff for retries

Quick Install

/plugin add https://github.com/sgcarstrends/sgcarstrends/tree/main/social-media

Copy and paste this command in Claude Code to install this skill

GitHub 仓库

sgcarstrends/sgcarstrends
Path: .claude/skills/social-media
apiaws-lambdabackendhonojob-schedulerneon-postgres

Related Skills

sglang

Meta

SGLang 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.

View skill

evaluating-llms-harness

Testing

This 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.

View skill

llamaguard

Other

LlamaGuard 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.

View skill

langchain

Meta

LangChain 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.

View skill