crosslink Todoist task & DTTG document

Posted by @FlohGro, Last update 4 months ago


4 months ago

name updated

crosslink to DTTG document and Todoist

  • this action will create a new markdown item in DTTG (DEVONthink To Go) from the content of the current draft
  • the first line of the draft will be used as title of the DT item
  • the DT item will be created in the global inbox. While directly creating the item in another group is possible, I didn’t include it here since it would need individual configuration - this can be added easily if you need it - just reach out in the Drafts forum
  • after creating the DT item, the action will add a new taks to the inbox of your Todoist account. the title of the draft will be the name of the task with a click-/tapable link to the craft document
  • after the task in todoist is created, the action will prepend a link to the todoist task into the previously created DT item.
  • known “issue”: if you quickly open the link to the todoist task after the action prepended the link to the task to the DT item, your todoist app may show an error telling you that the task could not be found. The reason for this is, that todoist needs to sync the created task to your app first (the task is created via the REST API). After the task was synced, the error won’t occur again.


  • there is no configuration needed this action just works if you have DTTG installed on your iOS / iPadOS device

if you find this useful you can Buy Me A Coffee


  • script

    // cross linked DEVONthink item and todoist task
    let title = draft.displayTitle
    let encodedTitle = encodeURIComponent(title)
    let content = draft.content
    content = encodeURIComponent(content)
    var proceed = true;
    const dttgCreateMarkdownBaseURL = "x-devonthink://x-callback-url/createmarkdown?"
    const dttgUpdateDocumentBaseURL = "x-devonthink://x-callback-url/update?"
    var cbCreateDttgDoc = CallbackURL.create()
    cbCreateDttgDoc.baseURL = dttgCreateMarkdownBaseURL
    // unused - will be sent to global inbox cbCreateDttgDoc.addParameter("destintaion", destinationUUID)
    cbCreateDttgDoc.addParameter("title", title)
    cbCreateDttgDoc.addParameter("text", content)
    cbCreateDttgDoc.waitForResponse = true
    let dttgCreateReturn =
    if (dttgCreateReturn == true) {
        console.log("DTTG document successfully created")
    } else {
        proceed = false
        console.log("DTTG create document result:" + cb.status + " " + cb.callbackResponse)
        if (cb.status == "cancelled") {
        } else {
    // craft note is created, now create the todoist task by using the REST API
    if (proceed) {
        // retrieve info from craftCreateResult
        let dttgCreateReturn = cbCreateDttgDoc.callbackResponse
        var dttgDocumentLink = dttgCreateReturn["text"]
        let taskNoteStr = "DTTG Document: " + dttgDocumentLink
        let taskTitle = "[" + title + "](" + dttgDocumentLink + ")"
        let todoist = Todoist.create();
        var todoistAddResult = todoist.quickAdd(taskTitle);
        if (!todoistAddResult) {
            let message = "Failed to add Task to todoist: " + todoist.lastError;
            proceed = false
        } else {
            console.log("Successfully created todoist Task")
    // things task added now prepend the link to the previously created craft note
    if (proceed) {
        // retrieve info from todoistAddResult
        let taskID = todoistAddResult["id"]
        let showTaskUrl = "todoist://task?id=" + taskID
        let openTaskStr = "> Task in Todoist: [" + title + "](" + showTaskUrl + ")"
        let encodedBlockContent = encodeURIComponent(openTaskStr)
        dttgDocumentUUID = dttgDocumentLink.replace("x-devonthink-item://", "")
        let newContent = draft.title + "\n\n" + openTaskStr + "\n\n" + draft.processTemplate("[[body]]")
        let encodedContent = encodeURIComponent(newContent)
        var cbUpdateDTTGDocument = CallbackURL.create()
        cbUpdateDTTGDocument.baseURL = dttgUpdateDocumentBaseURL
        cbUpdateDTTGDocument.addParameter("uuid", dttgDocumentUUID)
        cbUpdateDTTGDocument.addParameter("text", newContent)
        cbUpdateDTTGDocument.waitForResponse = true
        dttgUpdateReturn =
        if (dttgUpdateReturn == true) {
            console.log("DTTG document successfully updated")
        } else {
            proceed = false
            console.log("DTTG document update failed: " + cb.status + " " + cb.callbackResponse)
            if (cb.status == "cancelled") {
            } else {


  • After Success Default
    Notification Info
    Log Level Info
Items available in the Drafts Directory are uploaded by community members. Use appropriate caution reviewing downloaded items before use.