Metadata-Version: 2.4
Name: todoist-digest
Version: 0.13.0
Summary: Generate a digest of comments that occurred since the last checked in date. Useful for including in an email.
Keywords: todoist,digest,task,management
Author: Michael Bianco
Author-email: Michael Bianco <mike@mikebian.co>
License-Expression: MIT
Requires-Dist: apscheduler>=3.11.0
Requires-Dist: backoff>=2.2.1
Requires-Dist: click>=8.2.1
Requires-Dist: css-inline>=0.17.0
Requires-Dist: funcy-pipe>=0.11.1
Requires-Dist: jinja2>=3.1.6
Requires-Dist: markdown2>=2.5.4
Requires-Dist: pyjson5>=1.6.9
Requires-Dist: python-dateutil>=2.9.0.post0
Requires-Dist: python-decouple-typed>=3.11.0
Requires-Dist: requests>=2.32.0
Requires-Dist: structlog>=25.4.0
Requires-Dist: structlog-config>=0.1.1
Requires-Dist: todoist-api-python>=3.1.0
Requires-Dist: whatever>=0.7
Requires-Dist: whenever>=0.9.2
Requires-Python: >=3.11
Description-Content-Type: text/markdown

[![Release Notes](https://img.shields.io/github/release/iloveitaly/todoist-digest)](https://github.com/iloveitaly/todoist-digest/releases) [![Downloads](https://static.pepy.tech/badge/todoist-digest/month)](https://pepy.tech/project/todoist-digest) [![Python Versions](https://img.shields.io/pypi/pyversions/todoist-digest)](https://pypi.org/project/todoist-digest) ![GitHub CI Status](https://github.com/iloveitaly/todoist-digest/actions/workflows/build_and_publish.yml/badge.svg) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

# Todoist Project Digest

[Todoist](https://mikebian.co/todoist) doesn't have a way to generate a digest of all recent comments in a project created by a specific user. This makes it challenging to see what changed and what requires your action if you are collaborating with someone on a project.

This is a simple project which generates a digest of all comments by a particular user on a particular project.

This project was also a good excuse to play around and test some functional programming/data manipulation tooling I've been messing with ([funcy](https://github.com/Suor/funcy), [funcy-pipe](https://github.com/iloveitaly/funcy-pipe), and [whatever](https://github.com/Suor/whatever)).

## Features

* Can send an email digest if auth is provided
* Retrieves comments on completed tasks
* Target projects by ID or name
* Optional heartbeat URL for uptime monitoring
* Automatic internet connectivity checking with retry logic

## Usage

### Docker

```shell
docker pull ghcr.io/iloveitaly/todoist-digest:latest
docker run --env-file .env ghcr.io/iloveitaly/todoist-digest:latest
```

Want to run a one off execution?

```shell
docker run --env-file .env ghcr.io/iloveitaly/todoist-digest:latest todoist-digest --help
```

Want to inspect the docker container?

```shell
docker run -it ghcr.io/iloveitaly/todoist-digest:latest bash
```

Or, just use the [docker compose file](docker-compose.yml).

### Heartbeat Monitoring

The digest supports heartbeat URLs for uptime monitoring services like [Healthchecks.io](https://healthchecks.io/), [UptimeRobot](https://uptimerobot.com/), or similar services. When configured, the digest will ping the heartbeat URL after each successful job execution.

To enable heartbeat monitoring, set the `HEARTBEAT_URL` environment variable:

```shell
export HEARTBEAT_URL="https://hc-ping.com/your-unique-id"
```

Or in your `.env` file for Docker:

```
HEARTBEAT_URL=https://hc-ping.com/your-unique-id
```

The heartbeat ping happens automatically after each successful digest generation. If the ping fails, the error is silently ignored so it doesn't affect the digest execution.

### Internet Connection Resilience

The scheduled job includes automatic internet connectivity checking with exponential backoff retry logic (up to 8 hours). This ensures the digest runs successfully even if there are temporary network issues, such as overnight router disconnections.

### Locally


Run this locally using:

```shell
bin/local-digest-html
```

If you need a tty, you can copy the `todoist-digest` execution line and run it manually in a shell.

Or run directly:

```shell
uv run todoist-digest \
  --last-synced "2023-12-04T15:52:48Z" \
  --target-user user@gmail.com \
  --target-project ProjectName
```

Quick tip: using raycast, you can quickly generate an ISO timestamp `2 days ago as iso`

Or, email yourself the digest:

```shell
uv run todoist-digest \
  --last-synced $LAST_SYNC \
  --target-user $TARGET_USER \
  --target-project $TARGET_PROJECT \
  --email-auth $EMAIL_AUTH \
  --email-to $EMAIL_TO
```

## Development

### Manual API Calls

```
http --auth-type bearer --auth $TODOIST_API_KEY https://api.todoist.com/rest/v2/projects 'Content-Type: application/json'
```

### Docker Build

This repo uses [nixpacks](https://nixpacks.com/docs/getting-started) for building a Dockerfile. Why? Because I like trying new things.

[Asdf support](https://github.com/railwayapp/nixpacks/pull/1026) is built into nixpacks, so it will automatically pick up python and uv versions.

### Playground

ipython shell with some helpful variables defined:

```shell
./playground.py
```

### Run with ipdb

Open up an exception when there's an exception:

```shell
ipdb3 $(which todoist-digest) --last-synced 2023-12-14T13:38:25Z ...
```

## Related

* https://www.smashlists.com ([discovered here](https://www.reddit.com/r/todoist/comments/l7mhfq/how_to_track_weekly_goals/))