automate notion and todoist: a guide to syncing your to-do list with lambda and webhooks 🔥
Tags: automation, lambda, productivity, notion
Published: 2023-04-24 01:39:51

### Introductions 👨‍💻

I use Notion to keep track of all my todos inside of a database. However, if you’re on your phone, Notion doesn’t provide an easy way for user to easily add todos into the database without clicking multiple things and the loading takes annoyingly forever. This is where Todoist comes in. I can easily click on the app and press the plus button and it will create a todo for me. However, I don’t want to use two applications to track the same thing, so I wanted to sync my Todoist with Notion. 

I see that there are automations existed already with applications like `Zapier` but there are limitations to it. So I thought I could go ahead and automate the system myself. And this blog aims to help out others who want to do the same.

#### Requirements

- You will need to have an AWS account for this tutorial as we will be creating a Function URL with AWS Lambda. (Don’t worry it won’t cost you anything, you will not exceed the Free Tier)

Todoist and Notion both have APIs that we can use have them sync with each and it is not hard to work with at all. 

##### Step 1
Head to Notion API and create a new integration: https://www.notion.so/my-integrations


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b1jf9hlhi9o1w9sube2w.png)

##### Step 2
Copy the `Internal Integration Token`

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0zjvos9d8zp9k6irgc7q.png)

##### Step 3
Copy the `Notion Database ID` that you want to create the task in. You can get the `Notion Database ID` by heading to Notion online and view the database as a full page and in the URL, you will see the database ID. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cn3wj2p5x8u5uye9llvc.png)

##### Step 4
You need to allow your database to connect with the Notion Integration that we just created

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ve93kdjth97t7q5h4g4m.png)


##### Step 5
Head to AWS console and Create a Python Lambda Function

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qrm7vo4u3vntty6lui61.png)

Make sure to choose `Python 3.9`

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0bf59qjtgri2k1q14g5t.png)

##### Step 6
Create Function URL and select Auth type as NONE

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/440s4pgyjg0mxh1ugzwu.png)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v9tjri8kkf2k314g6ouh.png)


##### Step 7
Add Layer to the Lambda

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3wpp26gxtwlyguxybb10.png)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vy12pz2vkgx81s5vw2fn.png)

##### Step 8
Copy the following code. You will need to change three things

1. Add the `Internal Integration Token`
2. Add the `Notion Database ID`
3. Add the field name of your database where you want the task name to be. E.g Name

Then deploy it.

```
import json
import requests

url = "https://api.notion.com/v1/pages"
headers = {
    "Authorization": "Bearer <Internal Integration Token>",
    "Content-Type": "application/json",
    "Notion-Version": "2022-06-28"
}

def lambda_handler(event, context):
    content = json.loads(event['body'])['event_data']['content']
    
    data = {
        "parent": {
            "type": "database_id",
            "database_id": "<Notion Database Id>"
        },
        "properties": {
            "<field name your database for title>": {
                "type": "title",
                "title": [
                    {
                        "type": "text",
                        "text": {
                            "content": content
                        }
                    }
                ]
            }
        }
    }
        
    
    response = requests.post(url, headers=headers, data=json.dumps(data))
    
    return {
        'statusCode': 200,
        'body': 'success',
    }
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3953rem5awz23b2923t0.png)


What we have done so far is create a Lambda Function that will create an item in the database whenever it gets called by Todoist Webhook. 

Now we have to configure Todoist for it to make a make a request to that Function whenever there is a new item created.

##### Step 9

Head to Todoist Developer console to create a new app: [https://developer.todoist.com/appconsole.html](https://developer.todoist.com/appconsole.html)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bewp5oik4l5l4329h3yh.png)


##### Step 10

Go back to our Lambda and copy our Function URL. Paste it in the Webhook callback url in Todoist App. Also select the `item:added` Watched Events. Then click on `Activate webhook`.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q5xtik2oql52xrise3mk.png)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gsoz09riu7dj2y6h9zcf.png)

Step 11

So Webhook doesn’t activate by default until we complete OAuth process with the account. For more information here: [https://developer.todoist.com/sync/v8/#webhooks](https://developer.todoist.com/sync/v8/#webhooks)

First add the OAuth redirect URL as our Function URL in the Todoist App

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1dt5g9b27ag486xhj4zi.png)

Now to complete the OAuth process for the account. Below are two CURL command, but you can do it with Postman or other HTTP clients as well.

```
curl "https://todoist.com/oauth/authorize?client_id=<client_id>&scope=data:read&state=secretstring"
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9kfwj105magonk6ok5bx.png)

Click on the link and follow the instruction and it should redirect you to the Function URL. DO NOT close out of this tab as the URL will have the code that we need.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z47l0nygkwfmg7ulzksy.png)


```
curl "https://todoist.com/oauth/access_token" \
    -d "client_id=<client_id>" \
    -d "client_secret=<client_secret>" \
    -d "code=<code received from the first curl command>" \
    -d "redirect_uri=<function url>"
```

That is all. Now whenever you create an item inside of your Todoist, it will create a row inside of your Notion database.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/925gzgnwoof7ygmcj45u.png)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l17jb0y63x7m4wtunvr9.png)




#### Conclusion 🎯
Hope this helps you guys out. Let me know if you have any questions ✌️