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.
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.
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()
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()```
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
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.