Sync your Alexa/Todoist shopping list to the Home Assistant shopping list!

I followed this instruction and I got it to work. I had a couple problems because I wasn’t putting the files in the specified folders, but now it propagates changes both ways from and to the alexa shopping list.

The same happens to me. let’s see if someone can help us
Thank you

Got this working after a few false starts.
First: when you create the first .py file there are two lines you need to update - the API goes in quotation marks on the line for token and the project ID has no quotation marks and neither should have the <> symbols there once you fill the required info.

Creating an automation - Ive never used webhooks before so I didn’t set the trigger as a webhooks. I had tried similar trick to the project ID above just tacking on the number in the url when I was looking at the automation.

Creating the project in todolist: you need a name but you don’t need the app url. Skip that and do the webhooks further down, use v9 and pay attention to the different save buttons.

It all works a treat now, thanks for creating it!

1 Like

Hi! Can you please especify what quotation was that? The service pyscript_sync_shpping_list simply doesn’t apear for me whatsoever.

is anyone having issues syncing alexa shopping list with to do ist list? I cant get them to sync :frowning:

The same thing has been happening to me for a few days.

The things that I add in HA are not synchronized with TODOIS and therefore with Alexa.

And what I add to Alexa is added to TODOIST but it doesn’t get updated in HA.

It seems as if HA is isolated.

1 Like

Oh yeah. Hadn’t noticed but this is happening to me too. Hoping for a solution or alternative - don’t think I have the skills to fix much code myself.

So turns out I do have the skills. Guessed a Todoist API update was the cause. You can see the details here: Migrating from v1

V2 of the API has some differences, but fortunately not many that seem to affect the pyscript.

To fix, do the following:

  1. Update all instances of ‘v1’ in the shopping_list_sync.py file to ‘v2’. These are the API call URLs.

  2. On line 93 of the same file, change ‘completed’ to ‘is_completed’. This attribute was renamed for v2 of the todoist API.

Really keen to hear if this fixes for anyone else.

4 Likes

My alexa list is not syncing with to do is list. Is there some setting that I am missing?

That worked perfectly for me! Thank you!

I have not had luck.

I have changed 4 “v1” to “v2” and in line 93 I changed “complete” to “is_complete” and to “is_completed” but it has not worked for me with any of the options.

I leave you my code in case you see any errors.

Thanks for your time.

import requests
import sys
import time
from importlib import reload
if "/config/pyscript_modules" not in sys.path:
    sys.path.append("/config/pyscript_modules")

import write_file

write_file = reload(write_file)
TODOIST_TOKEN = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
TODOIST_PROJECT_ID = XXXXXXXXXXXXXX

def get_tasks():
    get_tasks_url =f"https://api.todoist.com/rest/v2/tasks?project_id={TODOIST_PROJECT_ID}"
    headers = {"Authorization" : f"Bearer {TODOIST_TOKEN}"}

    status_code = 500

    while status_code is not 200:
        response = task.executor(requests.get, get_tasks_url, headers = headers)
        status_code = response.status_code
        time.sleep(1)
    json = response.json()
    return json

def add_task(item):
    url = "https://api.todoist.com/rest/v2/tasks"
    headers = {"Authorization" : f"Bearer {TODOIST_TOKEN}", "Content-Type" : "application/json"}
    body = {"content" : item, "project_id" : TODOIST_PROJECT_ID}
    status_code = 500

    while status_code is not 200:
        response = task.executor(requests.post, url, headers = headers, json=body)
        status_code = response.status_code
        time.sleep(1)
    if status_code == 200:
        return True
    else:
        return False

def update_task(id, content):
    url = f"https://api.todoist.com/rest/v2/tasks/{id}"
    headers = {"Authorization" : f"Bearer {TODOIST_TOKEN}", "Content-Type" : "application/json"}
    body = {"content" : content}
    status_code = 500

    counter = 0
    while status_code is not 204 and counter < 10:
        response = task.executor(requests.post, url, headers = headers, json=body)
        status_code = response.status_code
        time.sleep(1)
        counter += 1
    if status_code == 204:
        return True
    else:
        return False

def complete_task(id):
    url = f"https://api.todoist.com/rest/v2/tasks/{id}/close"
    headers = {"Authorization" : f"Bearer {TODOIST_TOKEN}"}
    status_code = 500

    counter = 0
    while status_code is not 204 and counter < 10:
        response = task.executor(requests.post, url, headers = headers)
        status_code = response.status_code
        time.sleep(1)
        counter += 1
    if status_code == 204:
        return True
    else:
        return False

@service
def sync_shopping_list():
    tasks = []
    json = get_tasks()
    for item in json:
        tasks.append({"name" : item["content"], "id" : str(item["id"]), "complete" : item["completed"]})

    task.executor(write_file.write_json, filename = "/config/.shopping_list.json", content=tasks)
    hass.data["shopping_list"].async_load()

@event_trigger('shopping_list_updated')
def update_shopping_list(action=None, item=None):
    if action == "add":
        add_task(item["name"])
        sync_shopping_list()
    if action == "update" and item["complete"] == False:
        update_task(item["id"],item["name"])
        sync_shopping_list()
    if action == "update" and item["is_completed"] == True:
        complete_task(item["id"])
        sync_shopping_list()

you should change item["completed"] to item["is_completed"] in this line:

and change item["is_completed"] back to item["complete"] in this line:

This worked for me!

1 Like

for me “completed” was on line 81, not 93. Anyway it worked, thank you very much!

2 Likes

Now WORKS AGAIN!

Thank You! :gift_heart:

Can someone help me reviewing mine?

Amazon Echo and Todois work flawlessly (even HA updates when adding from both services) but when I add, delete or update my list from HA i get this error

WARNING (MainThread) [homeassistant.util.async_] Detected blocking call to sleep inside the event loop. This is causing stability issues. Please report issue to the custom integration author for pyscript doing blocking calls at custom_components/pyscript/eval.py, line 1906: return func(*args, **kwargs)

import requests
import sys
import time
from importlib import reload
if "/config/pyscript_modules" not in sys.path:
    sys.path.append("/config/pyscript_modules")

import write_file

write_file = reload(write_file)

TODOIST_TOKEN = "74d00fa66d414292c9cf027c165351b47e8d6fc3"
TODOIST_PROJECT_ID = "2300057472"

def get_tasks():
    get_tasks_url =f"https://api.todoist.com/rest/v2/tasks?project_id={TODOIST_PROJECT_ID}"
    headers = {"Authorization" : f"Bearer {TODOIST_TOKEN}"}

    status_code = 500

    while status_code is not 200:
        response = task.executor(requests.get, get_tasks_url, headers = headers)
        status_code = response.status_code
        time.sleep(1)
    json = response.json()
    return json

def add_task(item):
    url = "https://api.todoist.com/rest/v2/tasks"
    headers = {"Authorization" : f"Bearer {TODOIST_TOKEN}", "Content-Type" : "application/json"}
    body = {"content" : item, "project_id" : TODOIST_PROJECT_ID}
    status_code = 500

    while status_code is not 200:
        response = task.executor(requests.post, url, headers = headers, json=body)
        status_code = response.status_code
        time.sleep(1)
    if status_code == 200:
        return True
    else:
        return False

def update_task(id, content):
    url = f"https://api.todoist.com/rest/v2/tasks/{id}"
    headers = {"Authorization" : f"Bearer {TODOIST_TOKEN}", "Content-Type" : "application/json"}
    body = {"content" : content}
    status_code = 500

    counter = 0
    while status_code is not 204 and counter < 10:
        response = task.executor(requests.post, url, headers = headers, json=body)
        status_code = response.status_code
        time.sleep(1)
        counter += 1
    if status_code == 204:
        return True
    else:
        return False

def complete_task(id):
    url = f"https://api.todoist.com/rest/v2/tasks/{id}/close"
    headers = {"Authorization" : f"Bearer {TODOIST_TOKEN}"}
    status_code = 500

    counter = 0
    while status_code is not 204 and counter < 10:
        response = task.executor(requests.post, url, headers = headers)
        status_code = response.status_code
        time.sleep(1)
        counter += 1
    if status_code == 204:
        return True
    else:
        return False

@service
def sync_shopping_list():
    tasks = []
    json = get_tasks()
    for item in json:
        tasks.append({"name" : item["content"], "id" : str(item["id"]), "complete" : item["is_completed"]})

    task.executor(write_file.write_json, filename = "/config/.shopping_list.json", content=tasks)
    hass.data["shopping_list"].async_load()

@event_trigger('shopping_list_updated')
def update_shopping_list(action=None, item=None):
    if action == "add":
        add_task(item["name"])
        sync_shopping_list()
    if action == "update" and item["complete"] == False:
        update_task(item["id"],item["name"])
        sync_shopping_list()
    if action == "update" and item["complete"] == True:
        complete_task(item["id"])
        sync_shopping_list()```

See earlier in this thread. That error was fixed by @alexismadd - Sync your Alexa/Todoist shopping list to the Home Assistant shopping list! - #73 by alexismadd

You’ll need to check the code differences to yours, or start again and make the above v2 API changes to his version. Although the blocking call error that I used to get didn’t prevent any syncing.

hey @fenty17 everything works for me i.e. I can sync my shopping list from todoist to HA and also from Alexa to todoist. However I cannot sync whatever I have added to my todoist from Alexa onto my HA shopping list.

What am I doing wrong with this, its making me pull my hair :frowning:

But on @alexismadd the code is the old /v1/ on, I thoutgh I had to change that to /v2/

sorry, im not an expert, im following the stepts, but im getting the following error:

Exception in <file.shopping_list_sync.sync_shopping_list> line 26: json = response.json() ^ ContentTypeError: 0, message='Attempt to decode JSON with unexpected mimetype: text/plain; charset=utf-8', url=URL('https://api.todoist.com/rest/v1/tasks?project_id=2303489826')

i can sync alexa with todoist but im still no able to sync todoist with HA.

please help!

There’s been a couple of fixes made during the course of this thread for updated v2 api calls and blocking error.

I’ve popped the latest shopping_list_sync.py code into github. Use this insetead of the one in OP, add your todoist project id and api token. Rest of the instructions as in the OP.

9 Likes