Mastodon RSS Bookmarks

Mastodon considers your bookmark list to be private information. I'm happy to share mine. Plus, I wanted a way to add any bookmarks I make there into a 'Read later' category in my RSS reader (which is also where my phone and browser bookmarks go).

This was pretty simple, I create a PHP file that gets the latest 20 bookmarks (default API endpoint /api/v1/bookmarks) and takes an access token from your mastodon 'development' admin page.

Then I can give this URL to my RSS reader: https://neil.mckillop.org/stuff/mastodon_bookmarks.rss

get_mastodon_bookmarks.php
<?php
header('Content-Type: text/xml');
$bearer = "get your access token from the development page in the mastodon web client settings";
$instance = "glasgow.social";
$headers = [
  'Authorization: Bearer '.$bearer,
];
 
$ch_bookmarks = curl_init();
curl_setopt($ch_bookmarks, CURLOPT_URL, "https://$instance/api/v1/bookmarks");
curl_setopt($ch_bookmarks, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch_bookmarks, CURLOPT_HTTPHEADER, $headers);
 
$bookmarks = json_decode(curl_exec($ch_bookmarks), true);
 
curl_close ($ch_bookmarks);
 
$xml_header = <<<EOT
<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
        xmlns:content="http://purl.org/rss/1.0/modules/content/"
        xmlns:wfw="http://wellformedweb.org/CommentAPI/"
        xmlns:dc="http://purl.org/dc/elements/1.1/"
        xmlns:atom="http://www.w3.org/2005/Atom"
        xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
        xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
        >
 
<channel>
        <title>Neil's Mastodon Bookmarks</title>
 
EOT;
 
foreach($bookmarks as $k=>$v) {
        $xml_item[$k] = "\n\t<item>
                <title>{$v['card']['title']}</title>
                <link>{$v['url']}</link>
 
                <pubDate>".date("r", strtotime($v['created_at']))."</pubDate>
                <guid>{$v['url']}</guid>
 
                <description><![CDATA[<p>Short description here</p>
]]></description>
                <content:encoded><![CDATA[{$v['content']}
]]></content:encoded>
</item>\n";
}
 
echo $xml_header;
 
foreach($xml_item as $bookmark) {
        echo $bookmark;
}
 
echo "</channel>";
echo "</rss>";
?>