---
title: "How to Automate Blog Sharing on Social Media Using .NET Core"  
description: "Learn how to automate blog post sharing to Twitter/X, LinkedIn, and Facebook using .NET Core, Hangfire, and social media APIs. Full guide with code examples."  
author: "Manish Kumar"  
published: 2026-07-01  
updated: 2026-07-01  
canonical: https://answers.mindstick.com/blog/464/how-to-automate-blog-sharing-on-social-media-using-dot-net-core  
category: "asp.net"  
tags: ["asp.net mvc"]  
reading_time: 6 minutes  

---

# How to Automate Blog Sharing on Social Media Using .NET Core

Publishing a great blog post is only half the job — getting eyes on it is the other half. Manually copying a title, writing a caption, and posting it to Twitter/X, LinkedIn, and Facebook every single time you publish is repetitive, error-prone, and easy to forget. This is exactly the kind of task that should be automated.

In this guide, we'll build a lightweight **automated blog-sharing pipeline in .NET Core** that detects new blog posts and automatically shares them across social media platforms.

## Why Automate Blog Sharing?

- **Consistency** – Every post gets promoted, every time, with no manual step skipped.
- **Speed** – Content goes live on social channels within minutes of publishing.
- **Scalability** – Works whether you publish once a week or fifty times a day.
- **Multi-platform reach** – One trigger, many destinations (Twitter/X, LinkedIn, Facebook, even Slack/Discord).
- **Reduced human error** – No more mismatched links, missing hashtags, or forgotten posts.

## Architecture Overview

A simple, reliable automation pipeline looks like this:

```plaintext
[Blog CMS / RSS Feed]
        │
        ▼
[Trigger: Webhook or Scheduled Poller]
        │
        ▼
[.NET Core Worker Service]
        │
   ┌────┼────────────┐
   ▼    ▼             ▼
[Twitter/X API] [LinkedIn API] [Facebook Graph API]
```

Two common trigger strategies:

1. **Webhook-based** – Your CMS (WordPress, Ghost, custom CMS) calls a `.NET Core` Web API endpoint the moment a post is published.
2. **Poll-based (RSS)** – A background job checks your blog's RSS/Atom feed every few minutes for new entries. This works even if your CMS has no webhook support.

We'll build the poll-based approach since it works with almost any blogging platform, then show how to swap in a webhook trigger.

## Step 1: Set Up the .NET Core Project

```plaintext
dotnet new worker -n BlogSocialAutomation
cd BlogSocialAutomation
dotnet add package Hangfire.Core
dotnet add package Hangfire.MemoryStorage
dotnet add package System.ServiceModel.Syndication
```

We're using a **Worker Service** because this automation runs in the background with no UI, and **Hangfire** to handle reliable, recurring job scheduling (with retry support built in).

## Step 2: Poll the RSS Feed for New Posts

```cs
public class BlogFeedService
{
    private readonly HttpClient _httpClient;
    private readonly string _feedUrl = "https://yourblog.com/rss";

    public BlogFeedService(HttpClient httpClient) => _httpClient = httpClient;

    public async Task<List<BlogPost>> GetLatestPostsAsync(DateTime since)
    {
        using var xmlReader = XmlReader.Create(await _httpClient.GetStreamAsync(_feedUrl));
        var feed = SyndicationFeed.Load(xmlReader);

        return feed.Items
            .Where(item => item.PublishDate.UtcDateTime > since)
            .Select(item => new BlogPost
            {
                Title = item.Title.Text,
                Url = item.Links.First().Uri.ToString(),
                PublishedAt = item.PublishDate.UtcDateTime,
                Summary = item.Summary?.Text ?? string.Empty
            })
            .ToList();
    }
}
```

## Step 3: Post to Twitter/X (API v2)

```cs
public class TwitterPublisher
{
    private readonly HttpClient _httpClient;

    public TwitterPublisher(HttpClient httpClient, string bearerToken)
    {
        _httpClient = httpClient;
        _httpClient.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Bearer", bearerToken);
    }

    public async Task PostTweetAsync(string text)
    {
        var payload = new { text };
        var content = new StringContent(JsonSerializer.Serialize(payload),
            Encoding.UTF8, "application/json");

        var response = await _httpClient.PostAsync(
            "https://api.twitter.com/2/tweets", content);

        response.EnsureSuccessStatusCode();
    }
}
```

> Note: Posting on behalf of a user requires OAuth 1.0a user-context authentication for the free tier, or OAuth 2.0 with the appropriate scopes on paid tiers. Store tokens securely (e.g., Azure Key Vault or user secrets — never hardcode them).

## Step 4: Post to LinkedIn

```cs
public class LinkedInPublisher
{
    private readonly HttpClient _httpClient;
    private readonly string _authorUrn;

    public LinkedInPublisher(HttpClient httpClient, string accessToken, string authorUrn)
    {
        _httpClient = httpClient;
        _authorUrn = authorUrn;
        _httpClient.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Bearer", accessToken);
    }

    public async Task ShareArticleAsync(string title, string url)
    {
        var payload = new
        {
            author = _authorUrn,
            lifecycleState = "PUBLISHED",
            specificContent = new Dictionary<string, object>
            {
                ["com.linkedin.ugc.ShareContent"] = new
                {
                    shareCommentary = new { text = $"New post: {title}" },
                    shareMediaCategory = "ARTICLE",
                    media = new[] { new { status = "READY", originalUrl = url } }
                }
            },
            visibility = new Dictionary<string, object>
            {
                ["com.linkedin.ugc.MemberNetworkVisibility"] = "PUBLIC"
            }
        };

        var content = new StringContent(JsonSerializer.Serialize(payload),
            Encoding.UTF8, "application/json");

        var response = await _httpClient.PostAsync(
            "https://api.linkedin.com/v2/ugcPosts", content);

        response.EnsureSuccessStatusCode();
    }
}
```

## Step 5: Post to Facebook (Graph API)

```cs
public class FacebookPublisher
{
    private readonly HttpClient _httpClient;
    private readonly string _pageId;
    private readonly string _pageAccessToken;

    public FacebookPublisher(HttpClient httpClient, string pageId, string pageAccessToken)
    {
        _httpClient = httpClient;
        _pageId = pageId;
        _pageAccessToken = pageAccessToken;
    }

    public async Task PostLinkAsync(string message, string link)
    {
        var url = $"https://graph.facebook.com/v19.0/{_pageId}/feed" +
                   $"?message={Uri.EscapeDataString(message)}" +
                   $"&link={Uri.EscapeDataString(link)}" +
                   $"&access_token={_pageAccessToken}";

        var response = await _httpClient.PostAsync(url, null);
        response.EnsureSuccessStatusCode();
    }
}
```

## Step 6: Orchestrate Everything with Hangfire

```cs
public class BlogSharingJob
{
    private readonly BlogFeedService _feedService;
    private readonly TwitterPublisher _twitter;
    private readonly LinkedInPublisher _linkedIn;
    private readonly FacebookPublisher _facebook;
    private readonly IPostTracker _tracker; // Tracks last-shared timestamp

    public BlogSharingJob(BlogFeedService feedService, TwitterPublisher twitter,
        LinkedInPublisher linkedIn, FacebookPublisher facebook, IPostTracker tracker)
    {
        _feedService = feedService;
        _twitter = twitter;
        _linkedIn = linkedIn;
        _facebook = facebook;
        _tracker = tracker;
    }

    public async Task RunAsync()
    {
        var lastChecked = await _tracker.GetLastCheckedAsync();
        var newPosts = await _feedService.GetLatestPostsAsync(lastChecked);

        foreach (var post in newPosts)
        {
            var caption = $"📝 New blog post: {post.Title}\n{post.Url} #blog #tech";

            await _twitter.PostTweetAsync(caption);
            await _linkedIn.ShareArticleAsync(post.Title, post.Url);
            await _facebook.PostLinkAsync(post.Title, post.Url);
        }

        await _tracker.UpdateLastCheckedAsync(DateTime.UtcNow);
    }
}
```

Register a recurring job in `Program.cs`:

```cs
RecurringJob.AddOrUpdate<BlogSharingJob>(
    "share-new-blog-posts",
    job => job.RunAsync(),
    Cron.Minutely);
```

This checks for new posts every minute and pushes them to all three platforms automatically.

## Step 7: Handle Errors and Rate Limits Gracefully

Social APIs throttle aggressively, so wrap each publish call with retry logic (Polly is a great fit):

```cs
dotnet add package Polly

var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .WaitAndRetryAsync(3, attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt)));

await retryPolicy.ExecuteAsync(() => _twitter.PostTweetAsync(caption));
```

Also log failures to a database or Application Insights so a failed post to one platform doesn't silently vanish.

## Bonus: Switching to a Webhook Trigger

If your CMS supports webhooks (e.g., WordPress via a plugin, or a headless CMS like Contentful/Strapi), expose a minimal API endpoint instead of polling:

```cs
app.MapPost("/webhook/new-post", async (BlogPost post, BlogSharingJob job) =>
{
    await job.ShareSinglePostAsync(post);
    return Results.Ok();
});
```

This eliminates polling delay entirely — posts go live on social media within seconds of publishing.

## Best Practices

- **Never hardcode API keys** — use `appsettings.json` with user secrets locally and Azure Key Vault / AWS Secrets Manager in production.
- **Idempotency** — track already-shared post URLs so a job re-run doesn't double-post.
- **Custom captions per platform** — Twitter/X favors short, hashtag-driven text; LinkedIn favors a professional tone; Facebook allows longer descriptions.
- **Monitor job health** — use the Hangfire dashboard (`app.UseHangfireDashboard()`) to track job success/failure history.
- **Respect API rate limits** — batch posts and add delays if publishing many articles at once.

## Conclusion

With just a handful of C# classes and a Hangfire recurring job, you can turn a manual, easy-to-forget task into a fully automated pipeline that shares every new blog post across Twitter/X, LinkedIn, and Facebook — reliably and consistently. From here, you can extend the system to Instagram, Discord, Slack, or even generate AI-written captions using the Anthropic API for more engaging social copy.

---

Original Source: https://answers.mindstick.com/blog/464/how-to-automate-blog-sharing-on-social-media-using-dot-net-core

Copyright © MindStick Software Pvt. Ltd. This Markdown version is provided for developers, AI systems, and offline reading.
