In the Following tutorial we will create cloud function that will post blogs from notion database to dev.to. We will use serverless cloud function which will be triggered every 1 hour and will go through a notion database to check for our changes.
Features that we want are :
Draft - writing articles in notion
Publish articles : publishing them on dev.to from notion itself
Update articles : update the articles
Here is the notion template that we will be using to posting blogs here
Creating a notion template for blogs
We will create a simple notion table inline database for keeping a record of our blogs. Here are the columns that i have made.
Pages - For the blog content.
Tags
PublicationStatus
Draft
: Some uncomplete blogs
toPublish
: blogs that are ready to be published
toUpdate
: blogs that are to be updated
Published
: toPublish and toUpdate will convert to Published status.
DevUrl - url of the published blogs
PostId - post id that we will receive from dev.to, useful to update a blog post.
[Here](https://www.notion.so/sharmapratik/fe958c446e9046e88b54efa4509de3ee?v=f76cc9f149db4e3eb0dae032af2d96a3) is the template that i made for my blogs.
-
Create an integration token for notion and connect it to the notion template.
Go here > New Integration > internal token
You can copy your integration token.
Duplicate the Template that i have given to you above.Go to share and Paste your integration token in the input tab. Give the integration access to edit.
-
Create a dev.to access token
Go to home page > click your profile > settings > account> scroll to DEV Community API Keys. Create an access token for integration.
if you want to read more about the dev api go api here
-
Write some code
Before writing code. Let me explain what my bloging workflow would look like and how the cloud function should work.
When i am done writing a blog i will give it a tag
Draft
. Then i will review it and give it a tagtoPublish
. The cloud function will fetch the pages withtoPublish
tag and publish them on dev community. Then we will have another function that will change the tag fromtoPublish
toPublished
, with DevUrl and postId from dev community api.Publish to dev community function
const axios = require('axios') const apiUrl = 'https://dev.to/api' const apiToken = 'YOUR_ACCESS_TOKEN'; const postToDev = async ( apiUrl, apiToken, title, bodyMarkdown, tags, ) => { const post = await axios({ url: apiUrl + '/articles', headers: { 'api-key': apiToken, }, method: 'POST', data: { article: { title: title, published: true, body_markdown: bodyMarkdown, tags: tags, }, }, }); return post; };
Getting the database from notion
That would require database id. You can get the database id from the url of your database.
https://www.notion.so/{$username}/${databaseId}
mine looks like this
https://www.notion.so/sharmapratik/fe958c446e9046e88b54efa4509de3ee?v=f76cc9f149db4e3eb0dae032af2d96a3
Code would look like this for getting the Pages with
toPublish
tag from the database.
// install @notionhq/client npm package const { Client } = require("@notionhq/client"); const notion = new Client({ auth: "YOUR_NOTION_INTEGRATION_TOKEN", }); const databaseId = 'YOUR_DATABAS' async function getDatabase () { //getting the id of the pages that we want to publish const response = await notion.databases.query({ database_id: databaseId, filter: { property: 'PublishStatus', 'select': { equals: "toPublish" } } }); if(response.results.length === 0) { console.log('No article to publish') } else { console.log('article that we want to publish') response.results.map((result) => { console.log('article details', result) }) } };
We would have to convert the Notion page to markdown. There is a npm package available for that would take the pageId and convert the page to makdown.
const notion2md = require("notion-to-md"); // We have already define notion in the above code. const n2m = new notion2md({ notionClient: notion }); const getMarkdown = async(pageId) => { const mdblocks = await n2m.pageToMarkdown(pageId); const mdString = n2m.toMarkdownString(mdblocks); return mdString; }
We will update your getDatabase function
async function getDatabase () { // rest of the code else { response.results.map((result) => { //returns an array of tag names const tags = result.properties.Tags.multi_select.map(tag => tag.name) const title = result.properties.Pages.title[0].plain_text; getMarkdown(result.id) .then(function(res) { postToDev(apiUrl, apiToken, title, res, tags) .then(function(post) { if(post.status=== 200 || post.status === 201) { // updating the notion page properties. notion.pages.update({ page_id: result.id, properties: { //changing page properties 'PublishStatus': { select: { name: 'Published' } }, 'DevUrl': { url: post.data.url }, 'PostId': { number: Number(post.data.id) } } }).then(updated => console.log(updated)) } }) }); }) }; };
Similar to get the
toUpdate
tags
const responseUpdate = await notion.databases.query({ database_id: databaseId, filter: { property: 'PublishStatus', 'select': { equals: "toUpdate" } } });
Updating the blogs on dev community then changing the tag to published on notion.
if(responseUpdate.results.length !== 0) { responseUpdate.results.map((result) => { const postId = result.properties.PostId.number const newTags = result.properties.Tags.multi_select.map(tag => tag.name) const newTitle = result.properties.Pages.title[0].plain_text; getMarkdown(result.id) .then(function (res) { UpdateToDev(postId, apiUrl, apiToken, newTitle, res, newTags) .then(function(update) { if(update.status === 200 || update.status === 201) { notion.pages.update({ page_id: result.id, properties: { 'PublishStatus': { select: { name: 'Published' } }, 'DevUrl': { url: update.data.url }, 'PostId': { number: Number(update.data.id) } } }).then((updated) => console.log(updated)) } else { console.log('post not found') } }) }) }) } const UpdateToDev = async ( id, apiUrl, apiToken, title, bodyMarkdown, tags, ) => { const update = await axios({ url : apiUrl+ "/articles/" + id, headers: { 'api-key': apiToken, }, method: 'PUT', data: { article: { title: title, body_markdown: bodyMarkdown, tags: tags, }, } }) return update; }
Here is a complete code.
Go to Gist : here
You can run the node in terminal using node notionToDev.js
. After putting your details.
- Deploy your function on Mongodb Realm
It is very easy to publish your function on Mongodb Realm.
Sign in to mongodb website.
Go to Realm tab.
Add a new app.
Go to functions under your newapp.
We will be using the following packages in our function. Add the dependencies.
Add New Dependency > paste the package name
- notion-to-md
- @notionhq/client
- axios
Create a new function > name it ‘notionToDev’
Copy paste the code using the function Editor.
Click review draft & deploy.
- Creating a trigger schedule event for our function.
Just right under the function tag is the trigger tab in the sidebase. Click on Add a Trigger.
Create a trigger type of Scheduled.
Give it a name
Schedule type of once per hour.
Add you notionToDev function in function.
Save and you are done.
Top comments (4)
Have you thought about making the domain variable in addition to the API key so this tool could be compatible with all forems? Since DEV is based on the same API as community.webmonetization.org/, etc. it could work across the whole ecosystem?
i can do that. Didn't know all the forems having the same api. But do they give access token or we can use the same access token as of dev community.
This is a pretty cool use-case! Integrating Notion and DEV would definitely make writing posts easier - Notion's a tool I'm using more and more these days. Great work!
Thanks Buddy !!!