Message your Telegram bot in plain words and it becomes a Todoist task, due when you said - using only the words you typed.

UsesClaudeTelegramTodoist

Text a task to Todoist

Whenever you message your Telegram bot in plain words, the message becomes a Todoist task in the project you name, due when you said.

The AI reads the message only to split it into the task and the timing words, and what it hands back is checked against your original message before anything is created. The task text must appear in what you sent, and so must the due phrase; anything that has drifted is thrown away, so a task can only ever contain words you typed and never gets a deadline you did not mention. A message with no timing becomes a task with no due date. If the named project does not exist the run stops and tells you which projects the account does have. Every task is confirmed back in the chat, with the due date it was given.

Before the first run you need a Telegram bot in a chat you use only for capture, since every message becomes a task, and a Todoist project to file into.

TelegramTelegramWhen a new message is received. Save it as incomingMessage.When a new message is received. Save it as incomingMessage.
ValuesSet projectName to blank.Set projectName to blank.
ValuesSet messageText to blank.Set messageText to blank.
Decisions & LoopsIf a step below fails, save the error as noTextErrorIf a step below fails, save the error as noTextError
Try
TextTrim incomingMessage.text and save it as messageText.Trim incomingMessage.text and save it as messageText.
On error
No steps
Decisions & LoopsIf messageText is emptyIf messageText is empty
Yes
Decisions & LoopsFinish the run: That message carried no text, so no task was created.Finish the run: That message carried no text, so no task was created.
No
No steps
TodoistTodoistList projects. Save it as todoistProjects.List projects. Save it as todoistProjects.
TextMake projectName lowercase and save it as wantedProject.Make projectName lowercase and save it as wantedProject.
ValuesSet projectId to blank.Set projectId to blank.
ValuesSet knownProjectNames to an empty list.Set knownProjectNames to an empty list.
Decisions & LoopsFor each project in todoistProjects:For each project in todoistProjects:
ValuesSet candidateName to blank.Set candidateName to blank.
Decisions & LoopsIf a step below fails, save the error as projectNameErrorIf a step below fails, save the error as projectNameError
Try
TextTrim project.name and save it as candidateName.Trim project.name and save it as candidateName.
On error
No steps
Decisions & LoopsIf candidateName isn't emptyIf candidateName isn't empty
Yes
ListsAdd candidateName to the end of knownProjectNames and save it as knownProjectNames.Add candidateName to the end of knownProjectNames and save it as knownProjectNames.
Decisions & LoopsIf candidateName in lowercase is wantedProject and projectId is emptyIf candidateName in lowercase is wantedProject and projectId is empty
Yes
Decisions & LoopsIf a step below fails, save the error as projectIdErrorIf a step below fails, save the error as projectIdError
Try
TextTrim project.id and save it as projectId.Trim project.id and save it as projectId.
On error
No steps
No
No steps
No
No steps
Decisions & LoopsIf projectId is emptyIf projectId is empty
Yes
TextJoin knownProjectNames with , and save it as knownProjects.Join knownProjectNames with , and save it as knownProjects.
Decisions & LoopsStop and report a problem: No Todoist project is named '@projectName'. The projects on this account are: knownProjects. Correct the 'projectName' step to match one of them.Stop and report a problem: No Todoist project is named '@projectName'. The projects on this account are: knownProjects. Correct the 'projectName' step to match one of them.
No
No steps
ValuesSet splitPrompt to You are splitting one short message into a task and, if the message says when, a due date.Set splitPrompt to You are splitting one short message into a task and, if the message says when, a due date. Reply with exactly two lines and nothing else: TASK: <what to do> WHEN: <when it is due, or the single word none> Copy both lines word for word out of the message. Do not invent, rephrase, translate, correct or add anything the message does not already say. TASK must be one unbroken run of words taken from the message. If the timing words sit in the middle of the sentence and taking them out would break it up, copy the whole message into TASK and still report the timing words in WHEN. If the message says nothing about when, write WHEN: none. Message: messageText.
ValuesSet modelReply to blank.Set modelReply to blank.
Decisions & LoopsIf a step below fails, save the error as modelErrorIf a step below fails, save the error as modelError
Try
ClaudeClaudeAsk Claude: splitPrompt. Save it as splitResult.Ask Claude: splitPrompt. Save it as splitResult. Maximum response length: 200
TextTrim splitResult.response_text and save it as modelReply.Trim splitResult.response_text and save it as modelReply.
On error
No steps
ValuesSet taskText to messageText.Set taskText to messageText.
ValuesSet duePhrase to blank.Set duePhrase to blank.
Decisions & LoopsIf modelReply isn't emptyIf modelReply isn't empty
Yes
ListsGet the last item of modelReply split by TASK: and save it as afterTaskMarker.Get the last item of modelReply split by TASK: and save it as afterTaskMarker.
TextTrim the first item of afterTaskMarker split by WHEN: and save it as proposedTask.Trim the first item of afterTaskMarker split by WHEN: and save it as proposedTask.
Decisions & LoopsIf proposedTask isn't empty and messageText contains proposedTask (ignoring…If proposedTask isn't empty and messageText contains proposedTask (ignoring…
Yes
ValuesChange taskText to proposedTask.Change taskText to proposedTask.
No
No steps
TextTrim the last item of modelReply split by WHEN: and save it as proposedWhen.Trim the last item of modelReply split by WHEN: and save it as proposedWhen.
Decisions & LoopsIf proposedWhen isn't empty and proposedWhen in lowercase is not none and…If proposedWhen isn't empty and proposedWhen in lowercase is not none and…
Yes
ValuesChange duePhrase to proposedWhen.Change duePhrase to proposedWhen.
No
No steps
No
No steps
TodoistTodoistCreate task taskText.Create task taskText. Project ID: projectId Due date: duePhrase
ValuesSet confirmation to Added to projectName: taskText.Set confirmation to Added to projectName: taskText.
Decisions & LoopsIf duePhrase isn't emptyIf duePhrase isn't empty
Yes
ValuesChange confirmation to confirmation (due duePhrase).Change confirmation to confirmation (due duePhrase).
No
No steps
TelegramTelegramSend a message to chat incomingMessage.chat_id.Send a message to chat incomingMessage.chat_id.confirmation