Hey there, fellow JavaScript devs! Ready to dive into the world of Ghost API integration? Let's get our hands dirty with some code and learn how to sync data for a user-facing integration. Buckle up!
First things first, you'll need to grab your API credentials. Head over to your Ghost admin panel, navigate to "Integrations," and create a new custom integration. You'll get a shiny new API key and secret. Guard these with your life!
Now, let's install the Ghost API client:
npm install @tryghost/content-api
Set it up like this:
const GhostContentAPI = require('@tryghost/content-api'); const api = new GhostContentAPI({ url: 'https://your-ghost-site.com', key: 'YOUR_CONTENT_API_KEY', version: 'v3' });
Time to fetch some data! Here's how you can grab your recent posts:
async function getRecentPosts() { try { const posts = await api.posts .browse({limit: 5, include: 'tags,authors'}); return posts; } catch (error) { console.error(error); } }
Easy peasy, right? You can also fetch authors, tags, and more. Just check out the Ghost API docs for all the juicy details.
Now, let's create a new post:
async function createPost(title, content, tags) { try { const newPost = await api.posts.add({ title, content, tags: tags.map(name => ({name})), status: 'published' }, {source: 'html'}); return newPost; } catch (error) { console.error(error); } }
When it comes to syncing, you'll want to implement a strategy that works for your use case. Here's a simple example of syncing user-generated content:
async function syncUserContent(userId, content) { try { const existingPost = await api.posts.read({slug: `user-${userId}`}); if (existingPost) { return await api.posts.edit({ id: existingPost.id, content: existingPost.content + '\n\n' + content }); } else { return await createPost(`User ${userId} Content`, content, ['user-generated']); } } catch (error) { console.error(error); } }
Don't forget to handle those pesky errors and respect rate limits:
async function fetchWithRetry(apiCall, maxRetries = 3) { for (let i = 0; i < maxRetries; i++) { try { return await apiCall(); } catch (error) { if (error.response && error.response.status === 429) { const retryAfter = error.response.headers['retry-after'] || 5; await new Promise(resolve => setTimeout(resolve, retryAfter * 1000)); } else if (i === maxRetries - 1) { throw error; } } } }
Want to keep your app up-to-date in real-time? Set up webhooks in your Ghost admin panel and handle them like this:
app.post('/ghost-webhook', (req, res) => { const event = req.body; if (event.event === 'post.published') { // Do something with the new post console.log('New post published:', event.post.current.title); } res.sendStatus(200); });
Remember to cache aggressively, batch your operations when possible, and minimize API calls. Your future self (and your users) will thank you!
const cache = new Map(); async function getCachedPosts() { if (!cache.has('recentPosts') || Date.now() - cache.get('recentPosts').timestamp > 300000) { const posts = await getRecentPosts(); cache.set('recentPosts', { data: posts, timestamp: Date.now() }); } return cache.get('recentPosts').data; }
And there you have it! You're now armed with the knowledge to read and write data using the Ghost API like a pro. Go forth and build amazing integrations! Remember, the Ghost API documentation is your best friend for diving deeper into specific features. Happy coding!