Back

Reading and Writing Data Using the Tumblr API

Aug 2, 20246 minute read

Hey there, fellow JavaScript enthusiasts! Ready to dive into the world of Tumblr API integration? Let's get our hands dirty with some code and learn how to sync data for a user-facing integration. Buckle up!

Setting Up the Tumblr API

First things first, let's get our API credentials sorted. Head over to the Tumblr API console and grab your OAuth keys. Once you've got those, we'll use the handy Tumblr.js library to make our lives easier.

npm install tumblr.js

Now, let's set up our client:

const Tumblr = require('tumblr.js'); const client = new Tumblr.Client({ consumer_key: 'YOUR_CONSUMER_KEY', consumer_secret: 'YOUR_CONSUMER_SECRET', token: 'USER_TOKEN', token_secret: 'USER_TOKEN_SECRET' });

Reading Data from Tumblr

Time to fetch some data! Let's grab the user's recent posts:

async function getRecentPosts(blogIdentifier, limit = 20) { try { const response = await client.blogPosts(blogIdentifier, { limit }); return response.posts; } catch (error) { console.error('Error fetching posts:', error); throw error; } }

Writing Data to Tumblr

Creating a new post is a breeze:

async function createTextPost(blogIdentifier, title, body, tags = []) { try { const response = await client.createTextPost(blogIdentifier, { title, body, tags }); return response; } catch (error) { console.error('Error creating post:', error); throw error; } }

Implementing Data Syncing

Now for the fun part – let's create a basic sync function:

async function syncPosts(blogIdentifier, localPosts) { const remotePosts = await getRecentPosts(blogIdentifier); for (const localPost of localPosts) { const remotePost = remotePosts.find(p => p.id === localPost.id); if (!remotePost) { await createTextPost(blogIdentifier, localPost.title, localPost.body, localPost.tags); } else if (localPost.updated > remotePost.updated) { await client.editPost(blogIdentifier, localPost.id, { title: localPost.title, body: localPost.body, tags: localPost.tags }); } } }

Error Handling and Edge Cases

Let's wrap our API calls with some error handling magic:

async function apiWrapper(apiCall) { try { return await apiCall(); } catch (error) { if (error.status === 429) { console.log('Rate limit hit. Retrying in 60 seconds...'); await new Promise(resolve => setTimeout(resolve, 60000)); return apiWrapper(apiCall); } throw error; } }

Optimizing Performance

Caching can be a game-changer. Here's a simple in-memory cache:

const cache = new Map(); function getCachedData(key, ttl, fetchFunction) { if (cache.has(key) && Date.now() - cache.get(key).timestamp < ttl) { return cache.get(key).data; } const data = fetchFunction(); cache.set(key, { data, timestamp: Date.now() }); return data; }

Security Considerations

Always keep those OAuth tokens safe! Store them securely and never expose them in client-side code:

const crypto = require('crypto'); function encryptToken(token, secretKey) { const iv = crypto.randomBytes(16); const cipher = crypto.createCipheriv('aes-256-cbc', secretKey, iv); let encrypted = cipher.update(token, 'utf8', 'hex'); encrypted += cipher.final('hex'); return iv.toString('hex') + ':' + encrypted; }

Testing and Debugging

Don't forget to test! Here's a quick example using Jest:

jest.mock('tumblr.js'); test('syncPosts creates new posts', async () => { const mockCreate = jest.fn().mockResolvedValue({ id: 'new-post-id' }); Tumblr.Client.mockImplementation(() => ({ blogPosts: jest.fn().mockResolvedValue({ posts: [] }), createTextPost: mockCreate })); await syncPosts('blog.tumblr.com', [{ title: 'New Post', body: 'Content' }]); expect(mockCreate).toHaveBeenCalled(); });

Wrapping Up

And there you have it! We've covered the essentials of working with the Tumblr API for data syncing. Remember to always respect rate limits, handle errors gracefully, and keep your users' data secure.

Keep experimenting and building awesome integrations. The Tumblr community is waiting for your creative genius!

Happy coding, and may your API calls always return 200 OK! 🚀