Publishing Facebook Instant Articles via RSS Feed with Laravel
If you want to publish your web articles to Facebook Instant Articles platform and looking for the best way to export your quality articles from your blog to Instant Articles platform without worrying much about configurations, then you're at the right place now.
In this post, I will show you how to automatically export articles whenever you publish a new article on your website. I recently built this feature for my own website, and it was built on top of Laravel framework.
If your website runs other than WordPress and you want to integrate the RSS feed, this post will help you to understand how to do that for your platform. If you would like to know about exporting the Instant Articles from WordPress website, you can read this doc from facebook developers platform.
Two different ways to export Instant Articles.
RSS Publishing, API Publishing
The easiest way is setting up RSS feed, which will be automatically ingested periodically by Facebook. So there will be no other configurations required to pull down your fresh articles from your CMS.
Let's begin to build RSS feed, to allow Facebook to read in XML version.
Adding new routes under routes/web.php
Route::get('blog/rss', [
'as' => 'app.blog.rss',
'uses' => 'BlogController@rss',
]);
Route::get('blog/{slug}', [
'as' => 'app.blog.view',
'uses' => 'BlogController@view',
]);
Adding new Blog model app/Blog.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
/**
* Class Blog
* @package App
*/
class Blog extends Model
{
const STATUS_ENABLED = 1;
const STATUS_DISABLED = 0;
/**
* @var string
*/
protected $table = 'blog';
/**
* @var array
*/
protected $dates = ['published_at', 'deleted_at'];
/**
* @var string
*/
protected $fillable = ['user_id', 'name', 'slug', 'guid', 'excerpt', 'content', 'status', 'published_at'];
/**
* @param Builder $query
* @return mixed
*/
public function scopePublished($query)
{
return $query->where('published_at', '<=', now());
}
/**
* @param Builder $query
* @return mixed
*/
public function scopeEnabled($query)
{
return $query->where('status', self::STATUS_ENABLED);
}
}
Adding new controller BlogController.php
<?php
namespace App\Http\Controllers;
use App\Blog;
use Illuminate\Support\Str;
/**
* Class BlogController
* @package App\Http\Controllers
*/
class BlogController extends Controller
{
public function rss()
{
$blogs = Blog::enabled()
->published()
->latest('published_at')
->get();
$blogs->map(function ($each) {
if (empty($each->guid)) {
$each->guid = Str::uuid();
}
});
return view('rss', [
'blogs' => $blogs,
'title' => 'Short title about your blog',
]);
}
/**
* @param $slug
*/
public function view($slug)
{
return Blog::where('slug', $slug)->first();
}
}
Str::uuid()
was introduced with Laravel v5.6, with lower versions you could use my simple package for creating guid.
composer require sudiptpa/guid
To discover the features, please through the github link.
Adding new view resources/rss.blade.php
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
<title>{{ $title }}</title>
<link>{{ url('/') }}</link>
<description>
A short description about your blog.
</description>
<language>en-us</language>
<lastBuildDate>{{ date('c') }}</lastBuildDate>
@forelse($blogs as $key => $blog)
<item>
<title><![CDATA[{{ $blog->name }}]]></title>
<link>{{ route('app.blog.view', ['slug' => $blog->slug]) }}</link>
<guid>{{ $blog->guid }}</guid>
<pubDate>{{ date('c', strtotime($blog->published_at)) }}</pubDate>
<author>Author Name</author>
<description><![CDATA[{{ $blog->excerpt }}]]></description>
<content:encoded>
<![CDATA[
@include('partials._rss')
]]>
</content:encoded>
</item>
@empty
<item>No feeds found</item>
@endforelse
</channel>
</rss>
Adding another partial file included with the above view. resources/partials/_rss.blade.php
<!doctype html>
<html lang="en" prefix="op: http://media.facebook.com/op#">
<head>
<meta charset="utf-8">
<meta property="op:markup_version" content="v1.0">
<meta property="fb:article_style" content="default"/>
<link rel="canonical" href="{{ route('app.blog.view', ['slug' => $blog->slug]) }}">
<title>{{ $blog->name }}</title>
</head>
<body>
<article>
<header>
<h1>{{ $blog->name }}</h1>
<h2> {{ $blog->excerpt }}</h2>
<h3 class="op-kicker">
PHP <!-- Replace with your category name-->
</h3>
<address>
Sujip Thapa <!-- Replace with your author name-->
</address>
<time class="op-published" dateTime="$blog->published_at->format('c') }}">{{ $blog->published_at->format('M d Y, h:i a') }}</time>
<time class="op-modified" dateTime="{{ $blog->updated_at->format('c') }}">{{ $blog->updated_at->format('M d Y, h:i a') }}</time>
</header>
{{ $blog->content }}
<footer>
<aside>
A short footer note for your each Instant Articles.
</aside>
<small>© Copyright {{ date('Y') }}</small>
</footer>
</article>
</body>
</html>
Note: After exporting articles to Instant Articles platform, you will need to share the post on your facebook page, after sharing on that page article will start appearing as Instant Article.
Finally, to implement the above feature, follow the below steps.
- Facebook Page
- Publishing Tools
- Instant Articles
- Configuration
- Production RSS Feed
in the input box paste the link ending with blog/rss: (example: https://sujipthapa.co/blog/rss)
After saving the RSS feed URL, Facebook will start to retrieve fresh articles periodically.
Conclusion
Thanks for reading the article up to the end, feel free to give your feedback below in the comment section if you like.
Happy Coding!