Add, list and tick off Google Tasks by sending /add, /list and /done to your Telegram bot.
Uses
Google Tasks
Telegram
Run your Google Tasks list from Telegram
Whenever a message arrives in your Telegram chat, the bot checks whether it is one of three commands and acts on one Google Tasks list for you. Send /add and a title to file a task with exactly that title, /list to see everything still open with its ID, and /done with a title or ID to tick one off. Messages that are not commands are ignored.
Ticking a task off cannot be undone from the chat, so the match is strict: the words after /done must be a task's whole title or its ID, and only open tasks count. If two open tasks share a name, nothing is ticked off and the bot replies with both IDs so you can choose. No AI reads or rewrites your message, so what you type is exactly what is stored, and a long list is cut short with a note of how many tasks were left out.
You need a Telegram bot in a private chat, since anyone who can message it can change the list, and the name of a Google Tasks list on your account. If no list matches, the run stops and lists the names it found.
incomingMessage.When a new message is received. Save it as incomingMessage.taskListName to blank.Set taskListName to blank.maxTasksListed to 20.Set maxTasksListed to 20.messageText to blank.Set messageText to blank.noTextErrorIf a step below fails, save the error as noTextErrorincomingMessage.text and save it as messageText.Trim incomingMessage.text and save it as messageText.messageText is emptyIf messageText is emptymessageText doesn't start with /If messageText doesn't start with /chatId to incomingMessage.chat_id.Set chatId to incomingMessage.chat_id.messageText by a space and save it as words.Split messageText by a space and save it as words.words and save it as firstWord.Get the first item of words and save it as firstWord.firstWord split by @ lowercase and save it as command.Make the first item of firstWord split by @ lowercase and save it as command./ with in command and save it as verb.Replace / with in command and save it as verb.words joined by a space and save it as commandArgument.Trim the items from index 1 onward of words joined by a space and save it as commandArgument.isKnownCommand to verb is add or verb is list or verb is done.Set isKnownCommand to verb is add or verb is list or verb is done.isKnownCommand is noIf isKnownCommand is nohelpIntro to:Set helpIntro to:I look after your Google Tasks list. Send me one of these:helpAdd to:Set helpAdd to:/add Call the dentist
adds a taskhelpList to:Set helpList to:/list
shows what is still open, with each task's IDhelpDone to:Set helpDone to:/done Call the dentist
ticks off the open task with exactly that namehelpNote to If two open tasks share a name I will not guess between them - send /done with the ID from /list instead..Set helpNote to If two open tasks share a name I will not guess between them - send /done with the ID from /list instead..helpText to helpIntro plus helpAdd plus helpList plus helpDone plus helpNote.Set helpText to helpIntro plus helpAdd plus helpList plus helpDone plus helpNote.chatId.Send a message to chat chatId.helpTexttaskListsResult.List lists. Save it as taskListsResult.taskLists to taskListsResult.task_lists.Set taskLists to taskListsResult.task_lists.taskListName lowercase and save it as wantedList.Make taskListName lowercase and save it as wantedList.taskListId to blank.Set taskListId to blank.knownListNames to an empty list.Set knownListNames to an empty list.taskList in taskLists:For each taskList in taskLists:candidateListName to blank.Set candidateListName to blank.listNameErrorIf a step below fails, save the error as listNameErrortaskList.title and save it as candidateListName.Trim taskList.title and save it as candidateListName.candidateListName isn't emptyIf candidateListName isn't emptycandidateListName to the end of knownListNames and save it as knownListNames.Add candidateListName to the end of knownListNames and save it as knownListNames.candidateListName in lowercase is wantedList and taskListId is emptyIf candidateListName in lowercase is wantedList and taskListId is emptylistIdErrorIf a step below fails, save the error as listIdErrortaskList.id and save it as taskListId.Trim taskList.id and save it as taskListId.taskListId is emptyIf taskListId is emptyknownListNames with , and save it as knownLists.Join knownListNames with , and save it as knownLists.noListText to I could not find a Google Tasks list called '@taskListName'. The lists on this account are: knownLists.Set noListText to I could not find a Google Tasks list called '@taskListName'. The lists on this account are: knownLists.chatId.Send a message to chat chatId.noListTextverb is addIf verb is addcommandArgument is emptyIf commandArgument is emptychatId.Send a message to chat chatId.Send the task after the command, like this:
/add Call the dentistcommandArgument in Google Tasks list taskListId.Create task commandArgument in Google Tasks list taskListId.addedText to Added to taskListName: commandArgument.Set addedText to Added to taskListName: commandArgument.chatId.Send a message to chat chatId.addedTextverb is listIf verb is listtaskListId. Save it as openTasksResult.List tasks in Google Tasks list taskListId. Save it as openTasksResult.openTasks to openTasksResult.tasks.Set openTasks to openTasksResult.tasks.openTaskCount to 0.Set openTaskCount to 0.openCountErrorIf a step below fails, save the error as openCountErroropenTasks and save it as openTaskCount.Count the items in openTasks and save it as openTaskCount.taskLines to an empty list.Set taskLines to an empty list.listedCount to 0.Set listedCount to 0.task in openTasks:For each task in openTasks:listedCount multiplied by 1 is greater than or equal to maxTasksListed… If listedCount multiplied by 1 is greater than or equal to maxTasksListed…lineId to blank. Set lineId to blank.lineIdError If a step below fails, save the error as lineIdErrortask.id and save it as lineId.Trim task.id and save it as lineId.lineTitle to blank. Set lineTitle to blank.lineTitleError If a step below fails, save the error as lineTitleErrortask.title and save it as lineTitle.Trim task.title and save it as lineTitle.lineId isn't empty If lineId isn't emptylineTitle is emptyIf lineTitle is emptylineTitle to (this task has no title).Change lineTitle to (this task has no title).lineTitleAdd lineTitle
ID: lineId to the end of taskLines and save it as taskLines.listedCount.Add 1 to listedCount.taskLines is emptyIf taskLines is emptynothingOpenText to Nothing is open in taskListName right now.Set nothingOpenText to Nothing is open in taskListName right now.chatId.Send a message to chat chatId.nothingOpenTextlistHeading to Open in taskListName:Set listHeading to Open in taskListName:
.taskLines with a blank line and save it as listBody.Join taskLines with a blank line and save it as listBody.listFooter to blank.Set listFooter to blank.openTaskCount multiplied by 1 is greater than listedCount multiplied by 1If openTaskCount multiplied by 1 is greater than listedCount multiplied by 1listFooter to Change listFooter to
Showing the first listedCount of openTaskCount open tasks.listText to listHeading plus listBody plus listFooter.Set listText to listHeading plus listBody plus listFooter.chatId.Send a message to chat chatId.listTextverb is doneIf verb is donecommandArgument is emptyIf commandArgument is emptychatId.Send a message to chat chatId.Say which task to tick off, like this:
/done Call the dentist
Or send /done with the task's ID from /list.taskListId. Save it as candidateResult.List tasks in Google Tasks list taskListId. Save it as candidateResult.candidateTasks to candidateResult.tasks.Set candidateTasks to candidateResult.tasks.commandArgument lowercase and save it as wantedTask.Make commandArgument lowercase and save it as wantedTask.matchedIds to an empty list.Set matchedIds to an empty list.matchedTitles to an empty list.Set matchedTitles to an empty list.candidate in candidateTasks:For each candidate in candidateTasks:candidateId to blank. Set candidateId to blank.candidateIdError If a step below fails, save the error as candidateIdErrorcandidate.id and save it as candidateId.Trim candidate.id and save it as candidateId.candidateTitle to blank. Set candidateTitle to blank.candidateTitleError If a step below fails, save the error as candidateTitleErrorcandidate.title and save it as candidateTitle.Trim candidate.title and save it as candidateTitle.candidateId isn't empty If candidateId isn't emptyidMatches to candidateId is commandArgument.Set idMatches to candidateId is commandArgument.titleMatches to the length of candidateTitle is greater than 0 and candidateTitle in lowercase is wantedTask.Set titleMatches to the length of candidateTitle is greater than 0 and candidateTitle in lowercase is wantedTask.idMatches is yes or titleMatches is yesIf idMatches is yes or titleMatches is yescandidateId to the end of matchedIds and save it as matchedIds.Add candidateId to the end of matchedIds and save it as matchedIds.candidateTitle to the end of matchedTitles and save it as matchedTitles.Add candidateTitle to the end of matchedTitles and save it as matchedTitles.matchedIds is emptyIf matchedIds is emptynoMatchText to Nothing open in taskListName is called '@commandArgument', so nothing was ticked off. Send /list to see what is open.Set noMatchText to Nothing open in taskListName is called '@commandArgument', so nothing was ticked off. Send /list to see what is open.chatId.Send a message to chat chatId.noMatchTextmatchedIds is greater than 1If the length of matchedIds is greater than 1matchedIds with "Join matchedIds with
ID: and save it as ambiguousIds.ambiguousIntro to More than one open task is called '@commandArgument', so nothing was ticked off.Set ambiguousIntro to More than one open task is called '@commandArgument', so nothing was ticked off.ambiguousText to ambiguousIntro Send /done with one of these IDs instead:Set ambiguousText to ambiguousIntro Send /done with one of these IDs instead:
ID: ambiguousIds.chatId.Send a message to chat chatId.ambiguousTextmatchedIds is 1If the length of matchedIds is 1matchedIds and save it as targetId.Get the first item of matchedIds and save it as targetId.matchedTitles and save it as targetTitle.Get the first item of matchedTitles and save it as targetTitle.targetTitle is emptyIf targetTitle is emptytargetTitle to targetId.Change targetTitle to targetId.targetId in Google Tasks list taskListId.Complete task targetId in Google Tasks list taskListId.doneText to Ticked off: targetTitle.Set doneText to Ticked off: targetTitle.chatId.Send a message to chat chatId.doneText