How to Write a Code to Retrieve an ID and Title from Google Tasks for Use in the Update_Task Step?

This topic was automatically generated from Slack. You can find the original thread here.

Could you write me a code to get an ID and title from google tasks so that I can use the google tasks update_task step?

Sure, here’s a Pipedream component that retrieves the ID and title of tasks from Google Tasks: import { axios } from "@pipedream/platform"; export default defineComponent({ props: { google: { type: "app", app: "google", }, taskListId: { type: "string", label: "Task List ID", description: "Enter the ID of the task list you want to retrieve tasks from.", }, }, async run({ steps, $ }) { const response = await axios($, { url: `https://www.googleapis.com/tasks/v1/lists/${this.taskListId}/tasks`, headers: { Authorization: `Bearer ${this.google.$auth.oauth_access_token}`, }, }); const tasks = response.items.map((task) => { return { id: task.id, title: task.title, }; }); return tasks; }, }); This component requires you to input the Task List ID. It will return an array of objects containing the ID and title of each task in the specified task list. You can then use the Google Tasks update_task step with the retrieved task IDs and titles.

I’m using this code,
import { axios } from@pipedream/platform”;

export default defineComponent({
props: {
google: {
type: “app”,
app: “google_tasks”,
},
taskListId: {
type: “string”,
label: “Task List ID”,
description: “Enter the ID of the task list you want to retrieve tasks from.“,
},
},
async run({ steps, $ }) {
const response = await axios($, {
url: https://www.googleapis.com/tasks/v1/lists/${**this**.taskListId}/tasks,
headers: {
Authorization: Bearer ${**this**.google_tasks.$auth.oauth_access_token},
},
});

**const** tasks = response.items.map((task) => {
  **return** {
    id: task.id,
    title: task.title,
  };
});

**return** tasks;

},
});

But I’m getting this error.
TypeError
Cannot read properties of undefined (reading ‘$auth’)
DETAILS

    at Object.run (file:///tmp/__pdg__/dist/code/18af3f6291c426f5ad622c72f159bc547d24d940f9dd54a54df109d788d9ff9d/component.mjs:19:52)
    at null.executeComponent (/var/task/launch_worker.js:229:53)
    at MessagePort.messageHandler (/var/task/launch_worker.js:726:28)

Detailed/code mode
Google Tasks Account
Google Tasks LiveIntegrity
Task List ID
Mk1hZng3dVdLeEJ6ZVZqUg

update_task

CONFIGURE

I apologize for the confusion. It looks like there’s a small issue with the code you provided. The app prop should be named google_tasks instead of google. Here’s the corrected code: ```
import { axios } from “@pipedream/platform”; export default defineComponent({ props: { google_tasks: { type: “app”, app: “google_tasks”, }, taskListId: { type: “string”, label: “Task List ID”, description: “Enter the ID of the task list you want to retrieve tasks from.”, }, }, async run({ steps, $ }) { const response = await axios($, { url: https://www.googleapis.com/tasks/v1/lists/${this.taskListId}/tasks, headers: { Authorization: Bearer ${this.google_tasks.$auth.oauth_access_token}, }, }); const tasks = response.data.items.map((task) => { return { id: task.id, title: task.title, }; }); return tasks; }, });

That worked. Thanks. Now, in the update_task google tasks step after that, what path do I use for the ID and the title?

After you’ve retrieved the tasks using the code I provided earlier, you can use the output of that step to update tasks in the update_task Google Tasks step. Assuming the previous step is named get_tasks, you can access the task ID and title using the following paths: - Task ID: steps.get_tasks.$return_value[index].id - Task Title: steps.get_tasks.$return_value[index].title Replace index with the index of the task you want to update in the array. For example, if you want to update the first task, use steps.get_tasks.$return_value[0].id and steps.get_tasks.$return_value[0].title. You can use these paths as inputs for the update_task step in your workflow.

Ok, so here’s what I’m trying to do in my workflow. I think I have some unnecessary steps that are making this more complex than it needs to be. I want to create a one way sync between my notion database called all tasks, so that when I update or create a task in that database, the google tasks list (called reclaim) either gets created or get updated.

I also want the google task to get updated and marked complete when I mark it complete in notion

To create a one-way sync between your Notion database called “All Tasks” and your Google Tasks list called “Reclaim”, you can follow these steps: 1. Use the “Updated Page in Database” trigger from the Notion app. Select your “All Tasks” database as the input. This will trigger the workflow whenever a task is updated or created in the Notion database. 2. Add the “Query Database” action from the Notion app to retrieve the updated or created task details. Use the output from the trigger step to filter the results. 3. Add the “List Task Lists” action from the Google Tasks app to get the ID of the “Reclaim” task list. 4. Add a custom code step to search for an existing task in the “Reclaim” list with the same title as the updated or created task in Notion. If a matching task is found, store its ID. 5. Add a conditional step to check if a matching task was found in the “Reclaim” list. 6. If a matching task was found, use the “Update Task” action from the Google Tasks app to update the task with the new details from Notion. If no matching task was found, use the “Create Task” action to create a new task in the “Reclaim” list with the details from Notion. This workflow will ensure that whenever a task is updated or created in your Notion “All Tasks” database, the corresponding task in the Google Tasks “Reclaim” list will be updated or created.

To achieve this, you can set up a Pipedream workflow with the following steps: 1. Use the “Updated Page in Database” trigger from the Notion app. This will trigger the workflow when a task is updated in your Notion database. 2. Add a code step to filter out only the tasks that have been marked complete in Notion. You can use the property name that represents the “completed” status in your Notion database. 3. Use the “Update Task” action from the Google Tasks app to update the task in your Google Tasks list and mark it as complete. Here’s a sample workflow: // Step 1: Notion - Updated Page in Database trigger // Configure this trigger with your Notion account and database ID // Step 2: Code step to filter out completed tasks export default defineComponent({ async run({ steps }) { const notionTask = steps.trigger.event; const isCompleted = notionTask.properties.YOUR_COMPLETED_PROPERTY_NAME; // Replace with the actual property name in your Notion database if (isCompleted) { return { id: notionTask.id, title: notionTask.properties.YOUR_TITLE_PROPERTY_NAME, // Replace with the actual property name in your Notion database }; } else { $.end("Task not marked as complete in Notion"); } }, }); // Step 3: Google Tasks - Update Task action // Configure this action with your Google Tasks account, task list ID, and task ID // Use the output from the previous code step for the task title and set "Completed" to true Replace YOUR_COMPLETED_PROPERTY_NAME and YOUR_TITLE_PROPERTY_NAME with the actual property names in your Notion database. This workflow will update the Google Task and mark it as complete when the corresponding task is marked complete in Notion.

Can I use the same workflow to sync creation, due date changes, and completion? What would that look like?

Yes, you can use the same workflow to sync creation, due date changes, and completion. Here’s a sample workflow to achieve this: 1. Use the “Updated Page in Database” trigger from the Notion app. This will trigger the workflow when a task is updated or created in your Notion database. 2. Add a code step to extract the task details and status (created, updated, or completed) from the trigger output. 3. Use the “List Task Lists” action from the Google Tasks app to get the ID of the “Reclaim” task list. 4. Add a custom code step to search for an existing task in the “Reclaim” list with the same title as the updated or created task in Notion. If a matching task is found, store its ID. 5. Add a conditional step to check the task status and perform the appropriate action in Google Tasks (create, update, or mark as complete). Here’s a high-level outline of the workflow: ```
// Step 1: Notion - Updated Page in Database trigger // Configure this trigger with your Notion account and database ID // Step 2: Code step to extract task details and status // … // Step 3: Google Tasks - List Task Lists action // Configure this action with your Google Tasks account // Step 4: Custom code step to search for existing task in “Reclaim” list // … // Step 5: Conditional step to perform the appropriate action in Google Tasks // - If task is created in Notion, create a task in Google Tasks // - If task is updated in Notion, update the task in Google Tasks // - If task is marked as complete in Notion, mark the task as complete in Google Tasks

Could you write a code step to extract the task details and status (created, updated, completed, the notion private url) from the trigger output.?

Could you write a code step to extract the task details and status (created, updated, completed, the notion private url) from the trigger output?

Sure! Here’s a code step that extracts the task details and status (created, updated, completed, and the Notion private URL) from the trigger output: export default defineComponent({ async run({ steps }) { const notionTask = steps.trigger.event; // Extract task details const taskId = notionTask.id; const taskTitle = notionTask.properties.YOUR_TITLE_PROPERTY_NAME; // Replace with the actual property name in your Notion database const taskStatus = notionTask.properties.YOUR_STATUS_PROPERTY_NAME; // Replace with the actual property name in your Notion database const taskDueDate = notionTask.properties.YOUR_DUE_DATE_PROPERTY_NAME; // Replace with the actual property name in your Notion database const notionPrivateUrl = notionTask.url; // Determine task status let status; if (taskStatus === "created") { status = "created"; } else if (taskStatus === "updated") { status = "updated"; } else if (taskStatus === "completed") { status = "completed"; } else { status = "unknown"; } return { taskId, taskTitle, taskStatus: status, taskDueDate, notionPrivateUrl, }; }, }); Replace YOUR_TITLE_PROPERTY_NAME, YOUR_STATUS_PROPERTY_NAME, and YOUR_DUE_DATE_PROPERTY_NAME with the actual property names in your Notion database. This code step will return an object containing the task details and status.

The task status is actually a checkbox called done that is marked if it’s completed. this is it in the code: const taskStatus = steps.trigger.event.properties.done.checkbox; // Replace with the actual property name in your Notion database.
Does that change anything in the code?

Yes, it changes the way we determine the task status in the code. Since the task status is determined by a checkbox called “done”, we can modify the code step to handle this: export default defineComponent({ async run({ steps }) { const notionTask = steps.trigger.event; // Extract task details const taskId = notionTask.id; const taskTitle = notionTask.properties.YOUR_TITLE_PROPERTY_NAME; const taskDueDate = notionTask.properties.YOUR_DUE_DATE_PROPERTY_NAME; const notionPrivateUrl = notionTask.url; // Determine task status using the "done" checkbox const taskDone = notionTask.properties.done.checkbox; let status; if (taskDone) { status = "completed"; } else { // You can set the status to "updated" or any other value you prefer when the task is not completed status = "updated"; } return { taskId, taskTitle, taskStatus: status, taskDueDate, notionPrivateUrl, }; }, }); Replace YOUR_TITLE_PROPERTY_NAME and YOUR_DUE_DATE_PROPERTY_NAME with the actual property names in your Notion database. This code step will now return an object containing the task details and status based on the “done” checkbox.

Here’s the custom code step I have for finding matching tasks based on the notion private url being in the notes of google tasks. I’m not sure how to do this part of your instructions though: If a matching task is found, store its ID.

export default defineComponent({
  props: {
    privateUrl: {
      type: "string",
      label: "Notion Private URL",
    },
  },
  async run({ steps }) {
    const notionPrivateUrl = new URL(this.privateUrl);
    const tasks = steps.list_tasks.$return_value;

    console.log("Notion Private URL:", notionPrivateUrl);
    
    const matchingTask = tasks.find((task) => {
      if (task.notes && task.notes.startsWith("http")) {
        try {
          const taskUrl = new URL(task.notes);
          return taskUrl.pathname === notionPrivateUrl.pathname;
        } catch (error) {
          console.error("Error parsing URL:", error);
        }
      }
      return false;
    });

    if (matchingTask) {
      console.log("Matching Task:", matchingTask);
      return { taskId: matchingTask.id, taskTitle: matchingTask.title, taskFound: true };
    } else {
      console.log("No matching task found");
      return { taskFound: false };
    }
  },
});

Your current code already stores the matching task’s ID when it’s found. The line return { taskId: matchingTask.id, taskTitle: matchingTask.title, taskFound: true }; returns an object containing the task ID, task title, and a taskFound flag set to true. If no matching task is found, it returns an object with taskFound set to false. You can use the returned object in the next steps of your workflow. For example, if this custom code step is named find_matching_task, you can access the task ID in the next step using steps.find_matching_task.taskId.

That’s great! The name of that step is Checking_if_Matching_Task_is_Found. How do I creat step 5? This one: Add a conditional step to check the task status and perform the appropriate action in Google Tasks (create, update, or mark as complete).