A Convex-powered agent that automatically processes bookmarks saved to Todoist. When you add a URL to a specific Todoist project, it:
- Scrapes the webpage content using Firecrawl
- Generates a summary using Google Gemini
- Updates the task with the article title and summary
- Prevents bookmarks getting buried under
Completed Tasksby recreating them without due dates
You add URL to Todoist → Webhook triggers → Agent scrapes & summarizes → Task updated with summary
When you complete a processed bookmark, the agent automatically re-creates it (without a due date) so your bookmarks are preserved.
- Bun or Node.js
- A Convex account
- A Todoist account with a registered app
- A Firecrawl API key
- A Gemini API key (Use Google AI Studio)
git clone <repo-url>
cd todoist-bookmark-agent
bun install- Go to the Todoist App Console
- Click "Create a new app"
- Fill in the app details
- Note down your Client ID and Client Secret
- You'll configure the OAuth redirect URI after deploying Convex
npx convex devThis will prompt you to create a new Convex project. Once deployed, note your deployment URL (e.g., https://your-project-123.convex.site).
Back in the Todoist App Console, add this OAuth redirect URI:
https://your-project-123.convex.site/oauth/todoist/callback
- Open Todoist and go to the project you want to use for bookmarks
- Look at the URL:
https://todoist.com/app/project/1234567890 - The number at the end is your project ID
Set these environment variables in your Convex dashboard (Settings → Environment Variables) or via CLI:
npx convex env set TODOIST_CLIENT_ID "your_client_id"
npx convex env set TODOIST_CLIENT_SECRET "your_client_secret"
npx convex env set TODOIST_PROJECT_ID "your_project_id"
npx convex env set FIRECRAWL_API_KEY "your_firecrawl_api_key"
npx convex env set GOOGLE_GENERATIVE_AI_API_KEY "your_google_api_key"| Variable | Description |
|---|---|
TODOIST_CLIENT_ID |
From Todoist App Console |
TODOIST_CLIENT_SECRET |
From Todoist App Console (used for OAuth token exchange and webhook signature verification) |
TODOIST_PROJECT_ID |
The Todoist project ID where bookmarks are stored |
FIRECRAWL_API_KEY |
API key from Firecrawl |
GOOGLE_GENERATIVE_AI_API_KEY |
API key from Google AI Studio |
In the Todoist App Console, configure webhooks:
- Set the webhook URL to:
https://your-project-123.convex.site/webhook/todoist - Subscribe to these events:
item:addeditem:completed
Visit this URL in your browser to connect your Todoist account:
https://your-project-123.convex.site/oauth/todoist/authorize
This grants the app permission to:
- Read and write your tasks
- Receive webhook events for your account
You'll see a success page once authorized.
- Add a task to your designated Todoist project with a URL in the title or description
- The agent will:
- Show "Crawling..." status
- Scrape the page content
- Generate a summary
- Update the task with the article title and summary
- If you complete a processed bookmark, it will be re-created automatically
convex/
├── bookmarks.ts # Core logic: scraping, summarizing, task updates
├── http.ts # HTTP endpoints: OAuth flow, webhook handler
├── scheduler.ts # Background job scheduling
├── users.ts # User token storage (multi-user support)
└── schema.ts # Database schema
This app supports multiple users. Each user who authorizes via the OAuth flow gets their own access token stored in the database. Webhooks are processed using each user's individual token.
Webhook not triggering?
- Ensure you've completed the OAuth authorization step
- Check that webhook events are configured in Todoist App Console
- Verify the webhook URL is correct
Task not being processed?
- Make sure the task is in the correct project (matching
TODOIST_PROJECT_ID) - Check that the task contains a valid URL
- Look at Convex logs for errors
OAuth callback failing?
- Verify the redirect URI in Todoist App Console matches exactly
- Check that
TODOIST_CLIENT_IDandTODOIST_CLIENT_SECRETare set correctly
MIT