diff --git a/lib/controllers/reader.js b/lib/controllers/reader.js index 7fcda50..608165f 100644 --- a/lib/controllers/reader.js +++ b/lib/controllers/reader.js @@ -315,6 +315,38 @@ function ensureString(value) { return String(value); } +/** + * Fetch syndication targets from Micropub config + * @param {object} application - Indiekit application + * @param {string} token - Auth token + * @returns {Promise} Syndication targets + */ +async function getSyndicationTargets(application, token) { + try { + const micropubEndpoint = application.micropubEndpoint; + if (!micropubEndpoint) return []; + + const micropubUrl = micropubEndpoint.startsWith("http") + ? micropubEndpoint + : new URL(micropubEndpoint, application.url).href; + + const configUrl = `${micropubUrl}?q=config`; + const configResponse = await fetch(configUrl, { + headers: { + Authorization: `Bearer ${token}`, + Accept: "application/json", + }, + }); + + if (!configResponse.ok) return []; + + const config = await configResponse.json(); + return config["syndicate-to"] || []; + } catch { + return []; + } +} + /** * Compose response form * @param {object} request - Express request @@ -322,6 +354,8 @@ function ensureString(value) { * @returns {Promise} */ export async function compose(request, response) { + const { application } = request.app.locals; + // Support both long-form (replyTo) and short-form (reply) query params const { replyTo, @@ -334,12 +368,19 @@ export async function compose(request, response) { bookmark, } = request.query; + // Fetch syndication targets if user is authenticated + const token = request.session?.access_token; + const syndicationTargets = token + ? await getSyndicationTargets(application, token) + : []; + response.render("compose", { title: request.__("microsub.compose.title"), replyTo: ensureString(replyTo || reply), likeOf: ensureString(likeOf || like), repostOf: ensureString(repostOf || repost), bookmarkOf: ensureString(bookmarkOf || bookmark), + syndicationTargets, baseUrl: request.baseUrl, }); } @@ -357,6 +398,7 @@ export async function submitCompose(request, response) { const likeOf = request.body["like-of"]; const repostOf = request.body["repost-of"]; const bookmarkOf = request.body["bookmark-of"]; + const syndicateTo = request.body["mp-syndicate-to"]; // Debug logging console.info( @@ -369,6 +411,7 @@ export async function submitCompose(request, response) { likeOf, repostOf, bookmarkOf, + syndicateTo, }); // Get Micropub endpoint @@ -396,16 +439,22 @@ export async function submitCompose(request, response) { micropubData.append("h", "entry"); if (likeOf) { - // Like post (no content needed) + // Like post - content is optional comment micropubData.append("like-of", likeOf); + if (content && content.trim()) { + micropubData.append("content", content.trim()); + } } else if (repostOf) { - // Repost (no content needed) + // Repost - content is optional comment micropubData.append("repost-of", repostOf); + if (content && content.trim()) { + micropubData.append("content", content.trim()); + } } else if (bookmarkOf) { - // Bookmark (content optional) + // Bookmark - content is optional comment micropubData.append("bookmark-of", bookmarkOf); - if (content) { - micropubData.append("content", content); + if (content && content.trim()) { + micropubData.append("content", content.trim()); } } else if (inReplyTo) { // Reply @@ -416,6 +465,14 @@ export async function submitCompose(request, response) { micropubData.append("content", content || ""); } + // Add syndication targets + if (syndicateTo) { + const targets = Array.isArray(syndicateTo) ? syndicateTo : [syndicateTo]; + for (const target of targets) { + micropubData.append("mp-syndicate-to", target); + } + } + // Debug: log what we're sending console.info("[Microsub] Sending to Micropub:", { url: micropubUrl, diff --git a/locales/en.json b/locales/en.json index 8598b99..a10b441 100644 --- a/locales/en.json +++ b/locales/en.json @@ -45,6 +45,8 @@ "content": "What's on your mind?", "comment": "Add a comment (optional)", "commentHint": "Your comment will be included when this is syndicated", + "syndicateTo": "Syndicate to", + "syndicateHint": "Select where to cross-post this", "submit": "Post", "cancel": "Cancel", "replyTo": "Replying to", diff --git a/package.json b/package.json index 0344a8f..46aa30c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@rmdes/indiekit-endpoint-microsub", - "version": "1.0.14", + "version": "1.0.15", "description": "Microsub endpoint for Indiekit. Enables subscribing to feeds and reading content using the Microsub protocol.", "keywords": [ "indiekit", diff --git a/views/compose.njk b/views/compose.njk index 95a4e49..4a040be 100644 --- a/views/compose.njk +++ b/views/compose.njk @@ -72,6 +72,20 @@ 0 characters + {# Syndication targets #} + {% if syndicationTargets and syndicationTargets.length %} + + {% endif %} +
{{ button({ text: __("microsub.compose.submit")