How to Fix Errors While Integrating Google Tasks Update Upon Modification in Notion Using Node.js Code?

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

I’m working on a workflow that will update my google tasks lists when I update my tasks in notion. (I’m using Thomas Frank’s Ultimate Brain for reference). With Leo and 's help, I was able to insert a node.js code that worked for completing tasks when I completed them in my notion database, but I can’t get the code to work for either adding a separate step when I change the due date or for combining a due date change and a completing a task change into one code. I keep getting errors on it.

It sounds like you’re trying to update Google Tasks when you make changes to your tasks in Notion. To help you with this, I’ll need more information about your current workflow and the specific errors you’re encountering. 1. What is the trigger for your workflow? Is it a Notion event, like updating a task? 2. What are the specific actions you want to perform in Google Tasks when a task is updated in Notion? 3. Can you share the Node.js code you’re currently using and the error messages you’re encountering? Once I have this information, I’ll be able to provide more guidance on how to achieve your desired outcome.

  • I’ll answer your questions in order
  1. What is the trigger for your workflow? Is it a Notion event, like updating a task? It is a notion database page update - like updating a task’s due date.

  2. What are the specific actions you want to perform in Google Tasks when a task is updated in Notion? I would like for Google Tasks due date for the same task to change to the due date that I updated in Notion.

  3. Can you share the Node.js code you’re currently using and the error messages you’re encountering? Yes, here’s the code: import { axios } from@pipedream/platform”
    export default defineComponent({
    props: {
    google_tasks: {
    type: “app”,
    app: “google_tasks”,
    }
    },
    async run({steps, $}) {
    const tasks = steps.list_tasks.$return_value;
    const updatedTasks = [];

    for (const task of tasks) {
    // Update the task with Completed set to true
    task.status = “completed”;

    // Update the due date if it has changed
    // Replace “newDueDate” with the updated due date value
    const newDueDate = “steps.get_time_in_specific_timezone.$return_value”;
    if (task.due !== newDueDate) {
    task.due = newDueDate;
    }

    // Update the task using Google Tasks API
    const taskId = task.id;
    const taskListId = task.taskListId;
    const accessToken = this.google_tasks.$auth.oauth_access_token;
    await axios($, {
    method: “PUT”,
    url: https://www.googleapis.com/tasks/v1/lists/${taskListId}/tasks/${taskId},
    headers: {
    Authorization: Bearer ${accessToken},
    “Content-Type”: “application/json”,
    },
    data: task,
    });

    updatedTasks.push(task);
    }

    return updatedTasks;
    },
    });

Here’s the error: Error - Request failed with status code 400
{“error”:{“code”:400,“message”:“Request contains an invalid argument.”,“errors”:[{“message”:“Request contains an invalid argument.”,“domain”:“global”,“reason”:“badRequest”}],“status”:“INVALID_ARGUMENT”}}
at null.createError (/tmp/pdg/dist/code/288c916fca25fdcae005450d0aeba734639db798e9a7178de5839c0813d3fe8c/node_modules/.pnpm/axios@0.21.4/node_modules/axios/lib/core/createError.js:16:15)
at null.settle (/tmp/pdg/dist/code/288c916fca25fdcae005450d0aeba734639db798e9a7178de5839c0813d3fe8c/node_modules/.pnpm/axios@0.21.4/node_modules/axios/lib/core/settle.js:17:12)
at IncomingMessage.handleStreamEnd (/tmp/pdg/dist/code/288c916fca25fdcae005450d0aeba734639db798e9a7178de5839c0813d3fe8c/node_modules/.pnpm/axios@0.21.4/node_modules/axios/lib/adapters/http.js:269:11)
at IncomingMessage.emit (node:events:525:35)
at null.endReadableNT (node:internal/streams/readable:1359:12)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21)

Thank you for providing the details. I noticed a couple of issues in your code that might be causing the error. First, you’re using steps.get_time_in_specific_timezone.$return_value as the new due date, but it seems like this step is not defined in your workflow. You should replace this with the actual updated due date value from the Notion event. Second, the Google Tasks API expects the due date to be in RFC 3339 format, which includes both date and time. Make sure the updated due date from Notion is in the correct format. Here’s the updated code: import { axios } from "@pipedream/platform"; export default defineComponent({ props: { google_tasks: { type: "app", app: "google_tasks", }, notion_updated_due_date: { type: "string", label: "Updated Due Date from Notion", }, }, async run({ steps, $ }) { const tasks = steps.list_tasks.$return_value; const updatedTasks = []; for (const task of tasks) { // Update the due date if it has changed const newDueDate = this.notion_updated_due_date; if (task.due !== newDueDate) { task.due = newDueDate; } // Update the task using Google Tasks API const taskId = task.id; const taskListId = task.taskListId; const accessToken = this.google_tasks.$auth.oauth_access_token; await axios($, { method: "PUT", url: `https://www.googleapis.com/tasks/v1/lists/${taskListId}/tasks/${taskId}`, headers: { Authorization: `Bearer ${accessToken}`, "Content-Type": "application/json", }, data: task, }); updatedTasks.push(task); } return updatedTasks; }, }); Make sure to pass the updated due date from Notion as a prop (notion_updated_due_date) when using this code in your workflow. If you still encounter any issues, please let me know.

'm using the steps.get_time_in_specific_timezone.$return_value as the new due date because the date from notion is not in rfc339 format, so I added a step in my workflow to change the time from notion to the rfc339 format. Is there a way to to do that some thing in the coding of this step?

I see, you’re converting the Notion date to RFC 3339 format using a separate step. You can incorporate that conversion directly into the component code using JavaScript. Here’s an updated version of the code that converts the Notion date to RFC 3339 format: import { axios } from "@pipedream/platform"; export default defineComponent({ props: { google_tasks: { type: "app", app: "google_tasks", }, notion_due_date: { type: "string", label: "Due Date from Notion", }, }, async run({ steps, $ }) { const tasks = steps.list_tasks.$return_value; const updatedTasks = []; // Convert Notion date to RFC 3339 format const notionDate = new Date(this.notion_due_date); const rfc3339Date = notionDate.toISOString(); for (const task of tasks) { // Update the due date if it has changed if (task.due !== rfc3339Date) { task.due = rfc3339Date; } // Update the task using Google Tasks API const taskId = task.id; const taskListId = task.taskListId; const accessToken = this.google_tasks.$auth.oauth_access_token; await axios($, { method: "PUT", url: `https://www.googleapis.com/tasks/v1/lists/${taskListId}/tasks/${taskId}`, headers: { Authorization: `Bearer ${accessToken}`, "Content-Type": "application/json", }, data: task, }); updatedTasks.push(task); } return updatedTasks; }, }); Make sure to pass the due date from Notion as a prop (notion_due_date) when using this code in your workflow. If you have any questions or need further assistance, please let me know.

The code you just gave me returned this error: Error - Request failed with status code 400
{“error”:{“code”:400,“message”:“Invalid task list ID”,“errors”:[{“message”:“Invalid task list ID”,“domain”:“global”,“reason”:“invalid”}]}}, with these details:

at null.createError (/tmp/__pdg__/dist/code/4b6586be09dcd7a283ea64bcfd52fee12cd02c74d0cef0d752bad4f7f029e309/node_modules/.pnpm/axios@0.21.4/node_modules/axios/lib/core/createError.js:16:15)
    at null.settle (/tmp/__pdg__/dist/code/4b6586be09dcd7a283ea64bcfd52fee12cd02c74d0cef0d752bad4f7f029e309/node_modules/.pnpm/axios@0.21.4/node_modules/axios/lib/core/settle.js:17:12)
    at IncomingMessage.handleStreamEnd (/tmp/__pdg__/dist/code/4b6586be09dcd7a283ea64bcfd52fee12cd02c74d0cef0d752bad4f7f029e309/node_modules/.pnpm/axios@0.21.4/node_modules/axios/lib/adapters/http.js:269:11)
    at IncomingMessage.emit (node:events:525:35)
    at null.endReadableNT (node:internal/streams/readable:1359:12)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21)

What can I do to fix it?

I apologize for the issue you’re facing. It seems like the task list ID might be incorrect or missing. To help you better, I’ll need more information about how you’re obtaining the task list ID and the tasks. Can you please provide the code or steps you’re using to fetch the task list ID and tasks before running the provided component code? This will help me identify the issue and provide a solution.

Yes, I’m using the list_tasks step. My task list’s name is “Reclaim” and the id is VjcycjMyLUx2eldpRmgtbQ.

Thank you for providing the task list ID and name. Based on the error you encountered, it seems that the task list ID might not be properly set in the code. Let’s modify the code to use the provided task list ID: import { axios } from "@pipedream/platform"; export default defineComponent({ props: { google_tasks: { type: "app", app: "google_tasks", }, notion_due_date: { type: "string", label: "Due Date from Notion", }, task_list_id: { type: "string", label: "Task List ID", default: "VjcycjMyLUx2eldpRmgtbQ", }, }, async run({ steps, $ }) { const tasks = steps.list_tasks.$return_value; const updatedTasks = []; const notionDate = new Date(this.notion_due_date); const rfc3339Date = notionDate.toISOString(); for (const task of tasks) { if (task.due !== rfc3339Date) { task.due = rfc3339Date; } const taskId = task.id; const taskListId = this.task_list_id; const accessToken = this.google_tasks.$auth.oauth_access_token; await axios($, { method: "PUT", url: `https://www.googleapis.com/tasks/v1/lists/${taskListId}/tasks/${taskId}`, headers: { Authorization: `Bearer ${accessToken}`, "Content-Type": "application/json", }, data: task, }); updatedTasks.push(task); } return updatedTasks; }, }); I’ve added a new prop task_list_id with a default value set to your provided task list ID “VjcycjMyLUx2eldpRmgtbQ”. Make sure to use this updated code in your workflow and let me know if it resolves the issue or if you need further assistance.

The only issue I have with the code now is that it gave me a timeout error.

I apologize for the inconvenience caused by the timeout error. It’s possible that the code is taking too long to execute due to the number of tasks being processed. To address this issue, you can try processing the tasks in smaller batches or using asynchronous processing with Promise.all(). Here’s an updated version of the code that processes tasks in parallel using Promise.all(): ```
import { axios } from “@pipedream/platform”; export default defineComponent({ props: { google_tasks: { type: “app”, app: “google_tasks”, }, notion_due_date: { type: “string”, label: “Due Date from Notion”, }, task_list_id: { type: “string”, label: “Task List ID”, default: “VjcycjMyLUx2eldpRmgtbQ”, }, }, async run({ steps, $ }) { const tasks = steps.list_tasks.$return_value; const updatedTasks = []; const notionDate = new Date(this.notion_due_date); const rfc3339Date = notionDate.toISOString(); const updateTaskPromises = tasks.map(async (task) => { if (task.due !== rfc3339Date) { task.due = rfc3339Date; } const taskId = task.id; const taskListId = this.task_list_id; const accessToken = this.google_tasks.$auth.oauth_access_token; await axios($, { method: “PUT”, url: https://www.googleapis.com/tasks/v1/lists/${taskListId}/tasks/${taskId}, headers: { Authorization: Bearer ${accessToken}, “Content-Type”: “application/json”, }, data: task, }); updatedTasks.push(task); }); await Promise.all(updateTaskPromises); return updatedTasks; }, });

Now I have this error: Error - Request failed with status code 503
{“error”:{“code”:503,“message”:“The service is currently unavailable.”,“errors”:[{“message”:“The service is currently unavailable.”,“domain”:“global”,“reason”:“backendError”}],“status”:“UNAVAILABLE”}}
DETAILS

steps.Updating_Due_Dates{1}
debug{5}
status:
503
statusText:
Service Unavailable
headers{10}config{12}data{1}

I apologize for the inconvenience caused by the 503 error. This error indicates that the service you’re trying to connect to is temporarily unavailable. It could be due to server-side issues or rate limiting. I recommend implementing error handling and retry logic in your code to handle such situations. Here’s an example of how you can add error handling and retry logic using a for loop: ```
import { axios } from “@pipedream/platform”; export default defineComponent({ // …props definition… async run({ steps, $ }) { // …previous code… const updateTaskPromises = tasks.map(async (task) => { // …previous code… for (let i = 0; i < 3; i++) { try { await axios($, { method: “PUT”, url: https://www.googleapis.com/tasks/v1/lists/${taskListId}/tasks/${taskId}, headers: { Authorization: Bearer ${accessToken}, “Content-Type”: “application/json”, }, data: task, }); updatedTasks.push(task); break; } catch (error) { if (error.response && error.response.status === 503) { console.log(Attempt ${i + 1}: Service unavailable, retrying...); await new Promise((resolve) => setTimeout(resolve, 1000 * (i + 1))); } else { console.error(Error updating task: ${error}); break; } } } }); await Promise.all(updateTaskPromises); return updatedTasks; }, });

How can I add this code, to the previous code?

I understand you want to merge the error handling and retry logic code with the previous code. Here’s the combined code: ```
import { axios } from “@pipedream/platform”; export default defineComponent({ props: { google_tasks: { type: “app”, app: “google_tasks”, }, notion_due_date: { type: “string”, label: “Due Date from Notion”, }, task_list_id: { type: “string”, label: “Task List ID”, default: “VjcycjMyLUx2eldpRmgtbQ”, }, }, async run({ steps, $ }) { const tasks = steps.list_tasks.$return_value; const updatedTasks = []; const notionDate = new Date(this.notion_due_date); const rfc3339Date = notionDate.toISOString(); const updateTaskPromises = tasks.map(async (task) => { if (task.due !== rfc3339Date) { task.due = rfc3339Date; } const taskId = task.id; const taskListId = this.task_list_id; const accessToken = this.google_tasks.$auth.oauth_access_token; for (let i = 0; i < 3; i++) { try { await axios($, { method: “PUT”, url: https://www.googleapis.com/tasks/v1/lists/${taskListId}/tasks/${taskId}, headers: { Authorization: Bearer ${accessToken}, “Content-Type”: “application/json”, }, data: task, }); updatedTasks.push(task); break; } catch (error) { if (error.response && error.response.status === 503) { console.log(Attempt ${i + 1}: Service unavailable, retrying...); await new Promise((resolve) => setTimeout(resolve, 1000 * (i + 1))); } else { console.error(Error updating task: ${error}); break; } } } }); await Promise.all(updateTaskPromises); return updatedTasks; }, });

What does this error mean in my workflow step? Error updating task: Error - Request failed with status code 403: {“error”:{“code”:403,“message”:“Quota Exceeded”,“errors”:[{“message”:“Quota Exceeded”,“domain”:“usageLimits”,“reason”:“quotaExceeded”}]}}

The error you’re encountering is a “Quota Exceeded” error. This means that you’ve reached the daily credit limit for your Pipedream account on the Free tier. When you hit this limit, your workflow will not be able to execute further until the next day when the quota resets. If you need more credits, you can consider upgrading to a paid plan which doesn’t have a credit limit. You can find more information on pricing and plans at https://pipedream.com/pricing.

What does this error mean? Error updating task: Error: socket hang up

The “socket hang up” error typically occurs when the server-side of a connection abruptly closes the connection before the client has finished sending its request. This can happen for various reasons, such as server timeouts, network issues, or the server encountering an error while processing the request. To handle this error, you can implement retry logic in your code to attempt the request again after a short delay. This can help to overcome temporary network issues or server-side problems. If the error persists, you may need to investigate further by checking the server logs or contacting the API provider for assistance.