{"id":354641,"date":"2026-08-18T12:11:47","date_gmt":"2026-08-18T12:11:47","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/kobak-social-share-posts-to-mastodon-and-bluesky\/"},"modified":"2026-08-20T13:17:21","modified_gmt":"2026-08-20T13:17:21","slug":"kobak-social","status":"publish","type":"plugin","link":"https:\/\/pcd.wordpress.org\/plugins\/kobak-social\/","author":162203,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"2.0.1","stable_tag":"2.0.1","tested":"7.1","requires":"6.0","requires_php":"7.4","requires_plugins":null,"header_name":"kobak social: share posts to Mastodon and Bluesky","header_author":"Koren Bal\u00e1zs","header_description":"Automatically shares every new post to Bluesky and Mastodon, with optional LinkedIn support. Adds u-syndication links so Brid.gy can bring replies back.","assets_banners_color":"131017","last_updated":"2026-08-20 13:17:21","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/kobak.org\/plugins\/","header_author_uri":"","rating":0,"author_block_rating":0,"active_installs":0,"downloads":133,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.3.1":{"tag":"1.3.1","author":"kobak","date":"2026-08-18 12:11:24"},"1.3.2":{"tag":"1.3.2","author":"kobak","date":"2026-08-18 12:38:39"},"1.4.0":{"tag":"1.4.0","author":"kobak","date":"2026-08-19 12:41:13"},"2.0.0":{"tag":"2.0.0","author":"kobak","date":"2026-08-19 19:52:12"},"2.0.1":{"tag":"2.0.1","author":"kobak","date":"2026-08-20 13:17:21"}},"upgrade_notice":{"1.4.0":"<p>Security fix: tokens were readable in the settings page source. Failed shares are now retried per platform, and the post language follows your site language.<\/p>","1.3.0":"<p>First public release. If you used an earlier private build, check the new Mastodon username field under Settings \u2192 kobak social.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3652808,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3652808,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3652862,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3652862,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.3.1","1.3.2","1.4.0","2.0.0","2.0.1"],"block_files":[],"assets_screenshots":[],"screenshots":{"1":"The settings screen: Bluesky and Mastodon on top, LinkedIn as an optional section below.","2":"The syndication box under a published post.","3":"The log, showing what was sent where."}},"plugin_section":[],"plugin_tags":[223781,14242,139106,5699,36480],"plugin_category":[],"plugin_contributors":[276271],"plugin_business_model":[],"class_list":["post-354641","plugin","type-plugin","status-publish","hentry","plugin_tags-bluesky","plugin_tags-indieweb","plugin_tags-mastodon","plugin_tags-syndication","plugin_tags-webmention","plugin_contributors-kobak","plugin_committers-kobak"],"banners":{"banner":"https:\/\/ps.w.org\/kobak-social\/assets\/banner-772x250.png?rev=3652862","banner_2x":"https:\/\/ps.w.org\/kobak-social\/assets\/banner-1544x500.png?rev=3652862","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/kobak-social\/assets\/icon-128x128.png?rev=3652808","icon_2x":"https:\/\/ps.w.org\/kobak-social\/assets\/icon-256x256.png?rev=3652808","generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p>You write a post. It should appear on your social accounts. That used to be a solved problem, and then it wasn't.<\/p>\n\n<p>This plugin does the boring part: when a post is published for the first time, it posts a message to Bluesky and Mastodon, remembers the URLs it created, and lists them under the post with the <code>u-syndication<\/code> microformat.<\/p>\n\n<p>It only runs on the transition to published. Editing an old post never re-shares it.<\/p>\n\n<h4>About replies coming back<\/h4>\n\n<p>Be clear about what this plugin does and does not do. It <strong>publishes<\/strong> your posts and <strong>marks up<\/strong> the syndicated copies. It does <strong>not<\/strong> receive webmentions, and it does not talk to Brid.gy.<\/p>\n\n<p>Bringing replies back from Bluesky and Mastodon needs three separate pieces:<\/p>\n\n<ol>\n<li>The <code>u-syndication<\/code> links, so a service can tell which social post belongs to which article. <strong>This plugin provides that.<\/strong><\/li>\n<li>A webmention receiver on your site, for example the <a href=\"https:\/\/wordpress.org\/plugins\/webmention\/\">Webmention<\/a> plugin. <strong>Not included here.<\/strong><\/li>\n<li><a href=\"https:\/\/brid.gy\/\">Brid.gy<\/a>, a free external service you connect to your accounts, which watches for replies and sends them to your site as webmentions. <strong>Not included here, and not affiliated with this plugin.<\/strong><\/li>\n<\/ol>\n\n<p>Without the other two, this plugin still shares your posts perfectly well. You simply will not get replies back, and the syndication box is just a list of links.<\/p>\n\n<h4>What it does<\/h4>\n\n<ul>\n<li>Posts to <strong>Bluesky<\/strong> and <strong>Mastodon<\/strong> when a post is first published<\/li>\n<li>Handles the character limits (300 on Bluesky, 500 on Mastodon): the excerpt is shortened, the title and the link always survive<\/li>\n<li>Makes links in the Bluesky post clickable, using proper richtext facets<\/li>\n<li>Stores the URL of every copy it created and shows a syndication box under the post<\/li>\n<li>Can hide the local comment form <strong>without breaking webmentions<\/strong>, for people who collect replies on social instead<\/li>\n<li>Keeps a short log of what was sent and what came back<\/li>\n<li>Sends every request through the WordPress HTTP API, so it also works on hosts where <code>curl_exec()<\/code> is disabled<\/li>\n<\/ul>\n\n<h4>LinkedIn is optional<\/h4>\n\n<p>LinkedIn is deliberately a separate, opt-out-by-default section. Bluesky and Mastodon need nothing but an app password or a token, and take two minutes to set up. LinkedIn is a different story:<\/p>\n\n<ul>\n<li>You have to create your own LinkedIn app and request the <em>Share on LinkedIn<\/em> and <em>Sign In with LinkedIn using OpenID Connect<\/em> products<\/li>\n<li>You have to generate an access token yourself, with the <code>w_member_social<\/code>, <code>openid<\/code> and <code>profile<\/code> scopes<\/li>\n<li><strong>That token expires after roughly 60 days<\/strong> and has to be generated again by hand<\/li>\n<\/ul>\n\n<p>If that sounds like too much, leave the LinkedIn section switched off and ignore it. Everything else works without it. If you do turn it on, the post goes out as a link card with your featured image, and there are two buttons in the settings: one that checks the connection without posting anything, and one that posts a test to LinkedIn only.<\/p>\n\n<h4>What it is not<\/h4>\n\n<p>It is not a full social media scheduler. There is no queue, no analytics, no per-network message, no reposting of old content. It shares new posts, and that is all.<\/p>\n\n<h3>External services<\/h3>\n\n<p>This plugin sends data to third party services. Nothing is transmitted until you enter credentials for a service and enable sharing.<\/p>\n\n<p><strong>Bluesky (AT Protocol)<\/strong>\nUsed to publish your post to Bluesky. On each publish the plugin sends your handle and app password to <code>https:\/\/bsky.social\/xrpc\/com.atproto.server.createSession<\/code> to obtain a session, then sends the message text and your post URL to <code>https:\/\/bsky.social\/xrpc\/com.atproto.repo.createRecord<\/code>.\nTerms of service: https:\/\/bsky.social\/about\/support\/tos \u2014 Privacy policy: https:\/\/bsky.social\/about\/support\/privacy-policy<\/p>\n\n<p><strong>Mastodon<\/strong>\nUsed to publish your post to the Mastodon instance you configure. The plugin sends your access token, the message text and your post URL to <code>\/api\/v1\/statuses<\/code> on that instance. The instance is chosen by you, so its terms and privacy policy are those of that server. For the default suggestion, mastodon.social: https:\/\/mastodon.social\/terms-of-service and https:\/\/mastodon.social\/privacy-policy<\/p>\n\n<p><strong>LinkedIn (only if you enable it)<\/strong>\nUsed to publish your post to your LinkedIn profile. The plugin sends your access token to <code>https:\/\/api.linkedin.com\/v2\/userinfo<\/code> to look up your member URN, uploads your featured image to <code>https:\/\/api.linkedin.com\/rest\/images<\/code>, and sends the message text, post title, excerpt and URL to <code>https:\/\/api.linkedin.com\/rest\/posts<\/code>.\nTerms of service: https:\/\/www.linkedin.com\/legal\/user-agreement \u2014 Privacy policy: https:\/\/www.linkedin.com\/legal\/privacy-policy<\/p>\n\n<p>Credentials you enter are stored in your own WordPress database and are never sent anywhere except to the service they belong to.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Install and activate the plugin.<\/li>\n<li>Go to <strong>Settings \u2192 kobak social<\/strong>.<\/li>\n<li>Enter your Bluesky handle and an app password (Bluesky: Settings \u2192 Privacy and security \u2192 App passwords). Do not use your account password.<\/li>\n<li>Enter your Mastodon instance URL and an access token (Mastodon: Preferences \u2192 Development \u2192 New application, scope <code>write:statuses<\/code>).<\/li>\n<li>Tick <strong>Automatic sharing<\/strong>.<\/li>\n<li>Optional: set up LinkedIn as described in the FAQ.<\/li>\n<li>Publish a post, or use the test button to try it with your latest post.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"will%20it%20re-share%20my%20old%20posts%3F\"><h3>Will it re-share my old posts?<\/h3><\/dt>\n<dd><p>No. It only fires when a post moves from draft, pending or scheduled to published. Editing a published post does nothing.<\/p><\/dd>\n<dt id=\"can%20i%20change%20the%20message%3F\"><h3>Can I change the message?<\/h3><\/dt>\n<dd><p>Yes. The template supports <code>{title}<\/code>, <code>{excerpt}<\/code> and <code>{url}<\/code>. If the result is too long for a network, the excerpt is trimmed and the title and link are kept.<\/p><\/dd>\n<dt id=\"how%20do%20i%20set%20up%20linkedin%3F\"><h3>How do I set up LinkedIn?<\/h3><\/dt>\n<dd><p>Create an app at the LinkedIn developer portal, add the <em>Share on LinkedIn<\/em> and <em>Sign In with LinkedIn using OpenID Connect<\/em> products, then generate an access token with the <code>w_member_social<\/code>, <code>openid<\/code> and <code>profile<\/code> scopes. Paste the token, not the Client Secret, into the LinkedIn section. Use the <strong>Check the LinkedIn connection<\/strong> button first: it verifies the token and stores your author URN without posting anything.<\/p><\/dd>\n<dt id=\"my%20linkedin%20share%20stopped%20working\"><h3>My LinkedIn share stopped working<\/h3><\/dt>\n<dd><p>The token expired. LinkedIn tokens last about 60 days. The log will show a 401 error. Generate a new token and paste it in.<\/p><\/dd>\n<dt id=\"will%20this%20bring%20replies%20from%20bluesky%20and%20mastodon%20back%20to%20my%20site%3F\"><h3>Will this bring replies from Bluesky and Mastodon back to my site?<\/h3><\/dt>\n<dd><p>Not on its own. This plugin only publishes your posts and adds the <code>u-syndication<\/code> links. To actually receive replies you also need a webmention receiver, such as the Webmention plugin, and an external service like Brid.gy connected to your accounts. See the description for how the three pieces fit together.<\/p><\/dd>\n<dt id=\"does%20turning%20off%20local%20comments%20break%20webmentions%3F\"><h3>Does turning off local comments break webmentions?<\/h3><\/dt>\n<dd><p>No, and that is the point. Webmentions arrive over the REST API, where the plugin leaves <code>comments_open<\/code> alone. Only the visitor-facing comment form is hidden, so if you do run a webmention plugin, the replies it receives still appear under the post.<\/p><\/dd>\n<dt id=\"it%20does%20not%20post%20anything\"><h3>It does not post anything<\/h3><\/dt>\n<dd><p>Check the log at the bottom of the settings page: it records the result of every attempt. Sharing runs 30 seconds after publishing via WP-Cron, so if cron is disabled on your site, nothing will fire.<\/p><\/dd>\n<dt id=\"does%20it%20work%20if%20my%20host%20disabled%20curl_exec%28%29%3F\"><h3>Does it work if my host disabled curl_exec()?<\/h3><\/dt>\n<dd><p>Yes. Every request goes through <code>wp_remote_*<\/code>, which falls back to a stream based transport when cURL is unavailable.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>2.0.1<\/h4>\n\n<ul>\n<li>A network you have not set up is no longer reported as a failed share. Bluesky and Mastodon were attempted on every post even with no credentials at all, so anyone using just one of them collected a permanent red error notice in the admin for something they never wanted<\/li>\n<li>A network is now attempted once you have started setting it up, so a half-finished setup \u2014 a Bluesky handle with no app password \u2014 still tells you what is missing instead of going quiet<\/li>\n<li>Failed-share records left over from networks you do not use are cleared automatically<\/li>\n<li>Tested up to WordPress 7.1<\/li>\n<\/ul>\n\n<h4>2.0.0<\/h4>\n\n<ul>\n<li>Each network now lives in a single file behind a <code>Kobak_Social_Platform<\/code> interface, instead of being wired into four places. Adding a network no longer means editing existing code<\/li>\n<li>New filters for anyone extending the plugin: <code>kobak_social_platforms<\/code> to register a network, <code>kobak_social_message<\/code> to override the text per network, and <code>kobak_social_syndication_urls<\/code> to change the syndication links<\/li>\n<li>The plugin file is split into <code>includes\/<\/code>, with one file per network under <code>includes\/platforms\/<\/code><\/li>\n<li>The post types to share can now actually be chosen. The setting existed before but had no form field and always fell back to posts<\/li>\n<li>Failures that retrying cannot fix no longer run through three retry rounds. A missing or invalid credential, or any 4xx other than 408 and 429, is reported at once instead of a quarter of an hour later; timeouts, 5xx, 408 and 429 are retried as before<\/li>\n<li>Nothing else changed on purpose: the settings, the stored data and every message are the same as in 1.4.0<\/li>\n<\/ul>\n\n<h4>1.4.0<\/h4>\n\n<ul>\n<li>Security: saved tokens and app passwords are no longer written back into the settings page HTML<\/li>\n<li>Each platform now gets its own \"already shared\" marker, so a failed Mastodon post can be retried without posting to Bluesky twice<\/li>\n<li>Failed shares are retried automatically up to three times, and an admin notice points at the ones that gave up<\/li>\n<li>The post language is taken from the site language instead of being hardcoded to Hungarian, and can be overridden<\/li>\n<li>Saving the settings no longer discards values that are not on the form<\/li>\n<li>LinkedIn: the \"large\" image size is uploaded instead of the full-size original, and a warning appears before the token expires<\/li>\n<li>The Mastodon test button posts again instead of being silently deduplicated<\/li>\n<\/ul>\n\n<h4>1.3.2<\/h4>\n\n<ul>\n<li>Clearer wording about what the plugin does and does not do: it adds the u-syndication markup, but receiving replies also needs a webmention plugin and Brid.gy<\/li>\n<\/ul>\n\n<h4>1.3.1<\/h4>\n\n<ul>\n<li>Translations are handled through translate.wordpress.org, so bundled translation files were removed<\/li>\n<\/ul>\n\n<h4>1.3.0<\/h4>\n\n<ul>\n<li>Full internationalisation, Hungarian translation included<\/li>\n<li>Mastodon profile fallback link is now configurable instead of hardcoded<\/li>\n<li>Added uninstall cleanup<\/li>\n<li>First public release<\/li>\n<\/ul>\n\n<h4>1.2.2<\/h4>\n\n<ul>\n<li>Added a LinkedIn-only test button, so testing does not post to Bluesky and Mastodon<\/li>\n<\/ul>\n\n<h4>1.2.1<\/h4>\n\n<ul>\n<li>Added a LinkedIn connection check that stores the author URN without posting<\/li>\n<\/ul>\n\n<h4>1.2.0<\/h4>\n\n<ul>\n<li>Optional LinkedIn support: link card posts with the featured image<\/li>\n<\/ul>\n\n<h4>1.1.0<\/h4>\n\n<ul>\n<li>Syndication box with u-syndication links<\/li>\n<li>Option to hide the local comment form while keeping webmentions<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Bluesky and Mastodon sharing on publish<\/li>\n<\/ul>","raw_excerpt":"Publishes every new post to Bluesky and Mastodon and adds u-syndication links. LinkedIn support is optional.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/354641","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=354641"}],"author":[{"embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/kobak"}],"wp:attachment":[{"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=354641"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=354641"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=354641"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=354641"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=354641"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=354641"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}