How we automatically share new content on social media

Published on by

How we automatically share new content on social media image

When we publish a new post here on Laravel News, many things happen in the background for it to be automatically sent out to all the places around the internet. In this post, let's look at how we share it with all the services.

Here is a basic flowchart of what happens on Laravel News when a post is published showing all the services involved:

As you can see, we utilize many different services, but once they are set up, it's not something we've had too much trouble with, and it all happens automatically.

Starting from left to right, let's go through each section and cover how it's setup:

Laravel Notification Channels

Laravel Notification Channels are fantastic, and the community has created many different providers for use. We utilize one for our Twitter account, and another for our read-only Telegram account.

For Telegram, we have an older, but still accurate write-up on auto publishing to Telegram

Here is the code for our PostPublished notification:

class PostPublished extends Notification
{
public function via($notifiable)
{
return [TelegramChannel::class, TwitterChannel::class];
}
 
public function toTelegram($post)
{
return TelegramMessage::create()
->to('@laravelnews')
->content($post->routes['title'].' https://laravel-news.com/'.$post->routes['uri']);
}
 
public function toTwitter($post)
{
$tweet = $post->routes['title'].' https://laravel-news.com/'.$post->routes['uri'];
if ($post->routes['category'] == 'sponsor') {
$tweet = $post->routes['title'].' [SPONSOR] https://laravel-news.com/'.$post->routes['uri'];
} else if ($handle = $this->twitterHandle($post->routes['twitter_handle'])) {
$tweet = $tweet.' posted by '.$handle;
}
return new TwitterStatusUpdate($tweet);
}
 
/**
* Add the twitter handle is they are not a mod.
*/
protected function twitterHandle($twitter)
{
if (! $twitter) {
return false;
}
 
if ($twitter and ! Str::startsWith($twitter, '@')) {
$twitter = '@'.$twitter;
}
 
return $twitter;
}
}

Emails

We have two primary email lists. One is sent every day, and it includes any new posts and new community links. Then a second list for a weekly email that is sent every Sunday that is currently manually built. You can subscriber to them on our Newsletter page.

The daily is entirely automated and how it works is by utilizing a scheduled console command that queries our Statamic backend for new posts and builds out a complete HTML email in a blade file. From this, we use the Campaign Monitor API to create a draft, then instantly send the email.

protected function schedule(Schedule $schedule)
{
$schedule->command('ln:daily')->daily()->at('15:00');

Here is the code for doing the actual sending...

protected function sendEmail($posts)
{
$auth = ['api_key' => config('services.campaign-monitor.key')];
$cm = new CS_REST_Campaigns(null, $auth);
 
// Create a draft from the API
$draft = $cm->create(config('services.campaign-monitor.client_id'), [
'Subject' => $posts[0]['title']->raw(), // first post of the day, usually only one.
'Name' => 'Laravel News Daily ('.date('Y-m-d').')',
'FromName' => 'Laravel News',
'FromEmail' => 'hello@laravel-news.com',
'ReplyTo' => 'hello@laravel-news.com',
'HtmlUrl' => '/full/path/to/daily/html/file',
'ListIDs' => [config('services.campaign-monitor.daily_id')],
]);
 
// grab the draft id and set it to the campaign
$cm->set_campaign_id($draft->response);
 
// now send it
$cm->send([
'ConfirmationEmail' => 'hello@laravel-news.com',
'SendDate' => 'immediately',
]);
}

RSS Feed

The RSS feed is manually built using the same method as outlined in our tutorial on creating an RSS feed from scratch, but we take it a step further and use a 3rd party service named Feedpress.

By using the third party, we get some stats around RSS readership, which, in theory, is beneficial but not something we check very often.

RSS to Zapier

The next main section utilizes Zapier to read from new items in an RSS feed, then sends the post off to other services.

Facebook and LinkedIn Zaps both get sent to Buffer and then shared from Buffer. We initially used Buffer here because our community links section can have many approved on the same day at the same time, so instead of sharing all those at once, we can utilize more fine-grained scheduling.

For the Mastodon part, I used this tutorial a few weeks ago, and it's been running smoothly since.

JSON Feed

JSON Feeds was a hot topic a few years ago, so we had to have it. This is pretty simple to build, and we have a full tutorial on generating a JSON feed here.

Google News Feed

The final feed is for Google News, which was tricky to set up because they have a lot of restrictions on what they consider news and if you share something to this that they don't consider news, they can block you.

The basics of submitting are you need to give them a special XML feed, but it can only have items published in the past two days and can only be news items.

Here is our controller for setting up all this data from our Statamic backend:

public function news()
{
$posts = Collection::find('articles')
->queryEntries()
->where('date', '>', Carbon::now()->subDays(2)->startOfDay())
->where('date', '<', Carbon::now())
->where('published', true)
->get()
->toAugmentedArray();
 
return response()->view('sitemap.google.news', [
'posts' => $posts,
])->header('Content-Type', 'text/xml');
}

Then the Blade view file:

<?php echo '<?xml version="1.0" encoding="UTF-8"?>'; ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:news="http://www.google.com/schemas/sitemap-news/0.9">
 
@foreach ($posts as $post)
<url>
<loc>{{ $post['permalink'] }}</loc>
<news:news>
<news:publication>
<news:name>Laravel News</news:name>
<news:language>en</news:language>
</news:publication>
<news:genres>Blog</news:genres>
<news:publication_date>{{ $post['date']->raw()->format("Y-m-d") }}</news:publication_date>
<news:title>{{ $post['title'] }}</news:title>
@if ($post['tag']->raw())
<news:keywords>{{ implode(',', $post['tag']->raw()) }}</news:keywords>
@endif
<news:stock_tickers></news:stock_tickers>
</news:news>
</url>
@endforeach
</urlset>

Closing

This is how we share with many different services when a new post is published. This setup has been in production for almost a decade and has been solid. While writing this out, I noticed how we could possibly simplify some of these because of newer Notification Channels and could remove the Buffer step totally. Of course, one could also use various APIs directly, but I've found going through Zapier passes on API changes to them instead of something I need to worry about.

If you'd like to follow us at any of the services mentioned, here are our pages:

Eric L. Barnes photo

Eric is the creator of Laravel News and has been covering Laravel since 2012.

Cube

Laravel Newsletter

Join 40k+ other developers and never miss out on new tips, tutorials, and more.

Laravel Forge logo

Laravel Forge

Easily create and manage your servers and deploy your Laravel applications in seconds.

Laravel Forge
Tinkerwell logo

Tinkerwell

The must-have code runner for Laravel developers. Tinker with AI, autocompletion and instant feedback on local and production environments.

Tinkerwell
No Compromises logo

No Compromises

Joel and Aaron, the two seasoned devs from the No Compromises podcast, are now available to hire for your Laravel project. ⬧ Flat rate of $7500/mo. ⬧ No lengthy sales process. ⬧ No contracts. ⬧ 100% money back guarantee.

No Compromises
Kirschbaum logo

Kirschbaum

Providing innovation and stability to ensure your web application succeeds.

Kirschbaum
Shift logo

Shift

Running an old Laravel version? Instant, automated Laravel upgrades and code modernization to keep your applications fresh.

Shift
Bacancy logo

Bacancy

Supercharge your project with a seasoned Laravel developer with 4-6 years of experience for just $2500/month. Get 160 hours of dedicated expertise & a risk-free 15-day trial. Schedule a call now!

Bacancy
Lucky Media logo

Lucky Media

Get Lucky Now - the ideal choice for Laravel Development, with over a decade of experience!

Lucky Media
Lunar: Laravel E-Commerce logo

Lunar: Laravel E-Commerce

E-Commerce for Laravel. An open-source package that brings the power of modern headless e-commerce functionality to Laravel.

Lunar: Laravel E-Commerce
LaraJobs logo

LaraJobs

The official Laravel job board

LaraJobs
SaaSykit: Laravel SaaS Starter Kit logo

SaaSykit: Laravel SaaS Starter Kit

SaaSykit is a Laravel SaaS Starter Kit that comes with all features required to run a modern SaaS. Payments, Beautiful Checkout, Admin Panel, User dashboard, Auth, Ready Components, Stats, Blog, Docs and more.

SaaSykit: Laravel SaaS Starter Kit
Rector logo

Rector

Your partner for seamless Laravel upgrades, cutting costs, and accelerating innovation for successful companies

Rector
MongoDB logo

MongoDB

Enhance your PHP applications with the powerful integration of MongoDB and Laravel, empowering developers to build applications with ease and efficiency. Support transactional, search, analytics and mobile use cases while using the familiar Eloquent APIs. Discover how MongoDB's flexible, modern database can transform your Laravel applications.

MongoDB

The latest

View all →
Add Comments to your Laravel Application with the Commenter Package image

Add Comments to your Laravel Application with the Commenter Package

Read article
Laravel Advanced String Package image

Laravel Advanced String Package

Read article
Take the Annual State of Laravel 2024 Survey image

Take the Annual State of Laravel 2024 Survey

Read article
Upload Files Using Filepond in Livewire Components image

Upload Files Using Filepond in Livewire Components

Read article
The Best Laravel Tutorials and Resources for Developers image

The Best Laravel Tutorials and Resources for Developers

Read article
Introducing Built with Laravel image

Introducing Built with Laravel

Read article