Created
February 1, 2024 07:53
-
-
Save agamm/db7f567ad8fcbdb703f266cf04863d91 to your computer and use it in GitHub Desktop.
Ghost Editor Link Fixer and ?ref= adder
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
This script helps fix links that have a prefix whitespace (sometimes when copying from google). | |
Also it allows to add a ?ref=yoursite to all links in the newsletter issue. | |
Worked with the latest ghost version up to now (Feb 2024) | |
*/ | |
const GhostAdminAPI = require("@tryghost/admin-api"); | |
const path = require("path"); | |
const BASE_URL = "unzip.dev"; // your domain | |
// Your API config | |
const api = new GhostAdminAPI({ | |
url: `https://${BASE_URL}`, | |
version: "v5.0", | |
key: "your-ghost-api-key-here", | |
}); | |
const POST_ID = "your-post-id-you-want-to-fix"; | |
function addRefToUrls(obj) { | |
const propertiesToModify = ["text", "calloutText", "url"]; | |
// Helper function to append 'ref=unzip' to a URL using the URL object | |
const appendRef = (urlString) => { | |
try { | |
let url = new URL(urlString); | |
const queryParams = new URLSearchParams(url.search); | |
// Check if 'ref' or any 'utm*' parameter already exists | |
const hasRefOrUtm = | |
queryParams.has("ref") || | |
Array.from(queryParams.keys()).some((key) => key.startsWith("utm")); | |
if (!hasRefOrUtm) { | |
queryParams.set("ref", "unzip"); | |
// Reconstruct the URL | |
url.search = queryParams.toString(); | |
} | |
return url.toString(); | |
} catch (error) { | |
console.error("Invalid URL encountered:", urlString); | |
return urlString; // Return the original string if it's not a valid URL | |
} | |
}; | |
// Helper function to modify URLs within a string | |
const modifyUrlsInString = (str) => { | |
return str.replace(/(https?:\/\/[^ "']+)/g, (match) => appendRef(match)); | |
}; | |
// Recursive function to traverse the object and modify URLs | |
const traverseAndModifyUrls = (node) => { | |
if (node === null || typeof node !== "object") { | |
return; // Early exit for non-objects | |
} | |
Object.keys(node).forEach((key) => { | |
if (propertiesToModify.includes(key) && typeof node[key] === "string") { | |
// Modify URLs in the specified properties | |
node[key] = modifyUrlsInString(node[key]); | |
} else if (typeof node[key] === "object") { | |
// Recursively apply for objects | |
traverseAndModifyUrls(node[key]); | |
} | |
}); | |
}; | |
traverseAndModifyUrls(obj); | |
} | |
function adjustWhitespaceInLinks(rootObj) { | |
const adjustChildren = (children) => { | |
let lastTextIndex = -1; | |
children.forEach((child, index) => { | |
if (child.type === "extended-text") { | |
lastTextIndex = index; // Update the last text index for non-link nodes | |
} | |
if ( | |
child.type === "link" && | |
child.children && | |
child.children.length > 0 | |
) { | |
// Scenario 1: The first child of a link is whitespace-only extended-text | |
if ( | |
child.children[0].type === "extended-text" && | |
!child.children[0].text.trim() | |
) { | |
if (lastTextIndex !== -1) { | |
children[lastTextIndex].text += child.children[0].text; | |
} | |
child.children.shift(); | |
} | |
// Scenario 2: The link text starts with a whitespace | |
else if ( | |
child.children[0].type === "extended-text" && | |
child.children[0].text.startsWith(" ") && | |
lastTextIndex !== -1 | |
) { | |
children[lastTextIndex].text += " "; | |
child.children[0].text = child.children[0].text.trimStart(); | |
} | |
} | |
// Recursively adjust any further nested children arrays | |
if (child.children && Array.isArray(child.children)) { | |
adjustChildren(child.children); | |
} | |
}); | |
}; | |
if (rootObj && rootObj.root && Array.isArray(rootObj.root.children)) { | |
adjustChildren(rootObj.root.children); | |
} | |
} | |
(async () => { | |
const res = await api.posts.read({ id: POST_ID }); | |
let lexical = JSON.parse(res.lexical); | |
addRefToUrls(lexical); | |
adjustWhitespaceInLinks(lexical); | |
// console.log(JSON.stringify(lexical.root.children[13], null, 2)); | |
// return; | |
lexical = JSON.stringify(lexical); | |
await api.posts.edit({ | |
id: POST_ID, | |
lexical, | |
updated_at: res.updated_at, | |
}); | |
console.log("Updated links successfully."); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment