Instantly share code, notes, and snippets.
Last active
November 2, 2022 19:56
-
Save mackenly/3d289416d345dfc121437a2e1c85477f to your computer and use it in GitHub Desktop.
Ghost to Ayrshare (social channel distribution) Integration
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
/* | |
* Name: Ghost-Ayrshare Integration | |
* Desc: CloudFlare Worker To Consume Ghost Webhooks and Share On Social With Ayrshare | |
* Created by: Mackenly Jones (mackenly.com) | |
* Date: 10/26/2021 | |
* Updated: 11/2/2022 | |
* Requres: Ghost CMS, CloudFlare Worker, and Ayrshare Account | |
* Variables: Store your Ayrshare API key as API_KEY and referal code as REF_CODE into your Worker's enviormental variables | |
* | |
* The referal code is just a basic way to make sure requests are from you. | |
* You should create an integration in Ghost with a post.published webhook that sends a request to your Worker. | |
* The URL should look like this: | |
* https://worker-name.username.workers.dev/api/post/referal=yourrefcode | |
*/ | |
// Create event listener to handle responses and requests | |
addEventListener('fetch', (event) => { | |
event.respondWith(handleRequest(event.request).catch((err) => new Response(err.stack, { status: 500 }))); | |
}); | |
/* Function to get the response from Ayrshare */ | |
async function gatherResponse(response) { | |
// Find out what content type the request wants | |
const { headers } = response; | |
const contentType = headers.get('content-type') || ''; | |
// Return json is it wants json, text if anything else | |
if (contentType.includes('application/json')) { | |
return JSON.stringify(await response.json()); | |
} else { | |
return await response.text(); | |
} | |
} | |
/** | |
* Handle the request, if it's to the API check if it's a post and HTTPS | |
* If it's not to the API return a fun error. | |
* @param {Request} request | |
* @returns {Promise<Response>} | |
*/ | |
async function handleRequest(request) { | |
const { pathname } = new URL(request.url); | |
// Check to see if the user is using https, if not throw 403.4 | |
if (!request.url.startsWith('https://')) { | |
return new Response('Error 403.4: SSL Required', { status: 403.4 }); | |
} | |
// Check to see if user is sending request to /api/post | |
if (pathname.startsWith('/api/post')) { | |
// Do things if the user is using the POST method | |
if (request.method === 'POST') { | |
// Extract the request body as json | |
const body = await request.json(); | |
// Get the referal code from the URL and validate it as acceptable | |
const { searchParams } = new URL(request.url); | |
let referal_key = searchParams.get('referal'); | |
if (referal_key !== REF_CODE) { | |
// If the referal code doesn't match throw error 401 | |
return new Response('Error 401: Unauthorized', { status: 401 }); | |
} | |
/** | |
* Visit the Ayrshare docs for more info: | |
* https://docs.ayrshare.com/ | |
*/ | |
// Set the API endpoint | |
const endpoint = 'https://app.ayrshare.com/api/post'; | |
// Build the text that the posts will contain | |
let postText = | |
body.post.current.title + ' \u2063\n\u2063\n' + body.post.current.excerpt + ' \u2063\n' + body.post.current.url; | |
// For Twitter if postText is longer than 280 characters, trim it down to 280 characters | |
if (postText.length > 280) { | |
postText = trimText(body.post.current.title, body.post.current.excerpt, body.post.current.url, 280); | |
} else { | |
postText = postText; | |
} | |
// Build the request body | |
function trimText(title, excerpt, link, length) { | |
let trimmedString = excerpt + ' \u2063\n' + link; | |
if (trimmedString.length > length - 4) { | |
return trimText(title, trimmedString.substr(0, excerpt.split(' ').slice(0, -1).join(' ').length), link, length); | |
} else { | |
return ( | |
trimmedString.split(' ', trimmedString.split(' ').length - 1).join(' ') + | |
'...\u2063\n' + | |
trimmedString.split(' ')[trimmedString.split(' ').length - 1] | |
); | |
} | |
} | |
// Create the meta data used by Ayrshare | |
const body_data = { | |
post: postText, | |
platforms: ['twitter', 'facebook', 'linkedin', 'fbg'], | |
}; | |
// Create the request | |
const init = { | |
body: JSON.stringify(body_data), | |
method: 'POST', | |
headers: { | |
'Content-Type': 'application/json', | |
Authorization: `Bearer ${API_KEY}`, | |
}, | |
}; | |
// Use fetch to send the request | |
const response = await fetch(endpoint, init); | |
// Wait for the response from Ayrshare | |
const results = await gatherResponse(response); | |
// Return Ayrshare's reponse to the client for debugging | |
return new Response(results, init); | |
} else if (request.method === 'GET' || request.method !== 'POST') { | |
// If the user isn't using POST throw error 405 | |
return new Response('Error 405: Method Not Allowed', { status: 405 }); | |
} | |
} else { | |
// If the request doesn't meet any of the conditions respond error 418 | |
return new Response("Error 418: I'm a teapot", { status: 418 }); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment