PitchHut logo
A type-safe Haskell SDK for the Todoist REST API.
Pitch

TodoistSDK is an unofficial Haskell SDK designed for seamless interaction with the Todoist REST API. With features like complete API coverage, type safety, and ergonomic functions, it simplifies managing projects, tasks, and labels. Enhance productivity and ensure error-free interactions with Haskell's robust type system, tailored for Todoist users.

Description

TodoistSDK

TodoistSDK is an unofficial Haskell SDK designed for seamless interaction with the Todoist REST API. This library enables users to manage projects, tasks, comments, sections, and labels through type-safe and ergonomic Haskell functions.

Key Features

  • Comprehensive API Coverage: Complete support for managing Projects, Tasks, Comments, Sections, and Labels.
  • Type-Safe Operations: Utilizes Haskell's robust type system to minimize common errors.
  • Getter-Only Lenses: Offers read-only lenses for easy field access and composition.
  • Ergonomic Builder Pattern: Create API requests effortlessly with support for optional fields.
  • Automatic Pagination: Simplifies fetching multiple pages for list operations.
  • Flexible Error Handling: Operations return Either TodoistError a, facilitating explicit error management.
  • Testing Support: Features include a Trace interpreter for API call-free testing (in progress).

Quick Start

To begin using TodoistSDK, obtain your API token from Todoist Settings → Integrations → Developer.

Example Usage

Working in the REPL:

$ stack repl
>>> import Web.Todoist
>>> let config = newTodoistConfig "your-api-token-here"
>>> result <- todoist config getAllProjects
>>> case result of
      Left err -> print err
      Right projects -> mapM_ print projects

Complete Example: Create a file named example.hs:

#!/usr/bin/env stack
-- stack --resolver lts-24.7 script --package todoist-sdk --package text

{-# LANGUAGE OverloadedStrings #-}

import Web.Todoist

main :: IO ()
main = do
    let config = newTodoistConfig "your-api-token-here"
    result <- todoist config $ do
        let newProj = runBuilder (createProjectBuilder "My Haskell Project")
                      (withDescription "Learning Haskell SDK" <> withViewStyle Board)
        project <- addProject newProj
        let newTask = runBuilder (newTaskBuilder "Read documentation")
                      (withProjectId (_id project) <> withPriority 2)
        task <- createTask newTask
        tasks <- getTasks taskParamBuilder
        pure (project, task, tasks)
    case result of
        Left err -> putStrLn $ "Error: " ++ show err
        Right (proj, task, tasks) -> do
            putStrLn $ "Created project: " ++ show (_name proj)
            putStrLn $ "Created task: " ++ show (_content task)
            putStrLn $ "Total tasks: " ++ show (length tasks)

Run the example script:

chmod +x example.hs
./example.hs

Common Usage Examples

Projects:

import Web.Todoist

let config = newTodoistConfig "your-api-token"

-- Fetch all projects
result <- todoist config getAllProjects

-- Create a new project
let newProject = runBuilder (createProjectBuilder "Shopping List")
                 (withColor "blue" <> withViewStyle List <> withIsFavorite True)
project <- todoist config (addProject createProjectBuilder)

-- Update a project
let update = runBuilder emptyProjectUpdate (withName "Updated Name")
updated <- todoist config (updateProject update projectId)

-- Delete a project
todoist config (deleteProject projectId)

Tasks:

-- Create a task with a due date
let task = runBuilder (newTaskBuilder "Buy milk")
           (withProjectId "project-123"
            <> withDueString "tomorrow"
            <> withPriority 3
            <> withLabels ["grocery", "urgent"])
result <- todoist config (createTask task)

-- Fetch tasks with filters
let params = TaskParam
    { project_id = Just "project-123"
    , filter = Nothing
    , label_id = Nothing
    , cursor = Nothing
    , limit = Nothing
    }
tasks <- todoist config (getTasks params)

-- Complete a task
todoist config (closeTask taskId)

-- Update a task
let update = runBuilder updateTaskBuilder (withContent "Buy 2% milk")
updated <- todoist config (updateTask update taskId)

Comments:

-- Add a comment to a task
let comment = runBuilder (newCommentBuilder "Don't forget organic!")
              (withTaskId "task-456")
result <- todoist config (addComment comment)

-- Retrieve all comments for a project
let params = CommentParam
    { project_id = Just "project-123"
    , task_id = Nothing
    , cursor = Nothing
    , limit = Nothing
    , public_key = Nothing
    }
comments <- todoist config (getComments params)

Sections and Labels can also be managed effectively using the same approach.

Error Handling

All operations return an Either TodoistError a, making error management straightforward:

result <- todoist config (getProject projectId)
case result of
    Left BadRequest -> putStrLn "Invalid project ID"
    Left Unauthorized -> putStrLn "Check your API token"
    Left NotFound -> putStrLn "Project not found"
    Left (HttpError msg) -> putStrLn $ "HTTP error: " ++ msg
    Right project -> print project

Documentation

For complete API documentation, visit Hackage. To explore the Todoist REST API, see the official documentation.

Contribution

Contributions to enhance this SDK are welcome. The project is open for collaboration and improvement.

0 comments

No comments yet.

Sign in to be the first to comment.