DEV Community

Pratik sharma
Pratik sharma

Posted on

Notion to Dev integration Using Mongodb Realm

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. 
Enter fullscreen mode Exit fullscreen mode
  1. 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.

  2. 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

  3. 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 tag toPublish . The cloud function will fetch the pages with toPublish tag and publish them on dev community. Then we will have another function that will change the tag from toPublish to Published , 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.

  1. 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 
Enter fullscreen mode Exit fullscreen mode

Create a new function > name it ‘notionToDev’

Copy paste the code using the function Editor.

Click review draft & deploy.

  1. 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)

Collapse
 
ben profile image
Ben Halpern

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?

Collapse
 
biomathcode profile image
Pratik sharma

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.

Collapse
 
nandanv2702 profile image
Nandan V

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!

Collapse
 
biomathcode profile image
Pratik sharma

Thanks Buddy !!!