Does Pipedream Have an App to Save Image URLs to Google Drive?

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

Is there an app in Pipedream to take an image URL and save it to Google Drive?

To achieve the task of taking an image URL and saving it to Google Drive using Pipedream, you can follow these steps. While there isn’t a direct pre-built component for this specific task, you can use a combination of Node.js code and the Google Drive API to accomplish it. First, ensure you have connected your Google account to Pipedream, which will allow you to make authenticated requests to Google Drive. Here’s an example Pipedream component that downloads an image from a URL and uploads it to Google Drive: import { axios } from "@pipedream/platform"; import stream from "stream"; import { promisify } from "util"; import fs from "fs"; import got from "got"; export default defineComponent({ props: { google: { type: "app", app: "google", }, }, async run({ steps, $ }) { const imageUrl = "YOUR_IMAGE_URL_HERE"; // Replace with your image URL const filename = "image.png"; // Replace with your desired file name // Download the image and save it to the /tmp directory const pipeline = promisify(stream.pipeline); await pipeline( got.stream(imageUrl), fs.createWriteStream(`/tmp/${filename}`) ); // Read the file from the /tmp directory const fileContent = fs.createReadStream(`/tmp/${filename}`); // Upload the file to Google Drive const uploadResponse = await axios($, { method: "POST", url: "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart", headers: { Authorization: `Bearer ${this.google.$auth.oauth_access_token}`, "Content-Type": "multipart/related; boundary=foo_bar_baz", }, data: ` --foo_bar_baz Content-Type: application/json; charset=UTF-8 { "name": "${filename}" } --foo_bar_baz Content-Type: image/png ${fileContent} --foo_bar_baz-- `, }); return uploadResponse; }, }); Please note, you need to replace "YOUR_IMAGE_URL_HERE" with the actual URL of the image you want to download and save to Google Drive. Also, adjust the "image.png" filename as needed. This code does the following: 1. Downloads the image from the specified URL and saves it to the /tmp

Can you rewrite this code to use FIELD inputs for the URLs?

Certainly! To rewrite the code to use FIELD inputs for the URLs, you’ll need to define these URLs as properties within the props object of your Pipedream component. This allows you to specify the URLs as inputs in the Pipedream UI when configuring the step. Here’s an example of how you could structure this: import { axios } from "@pipedream/platform"; export default defineComponent({ props: { url1: { type: "string", label: "First URL", description: "Enter the first URL to make the HTTP request to.", }, url2: { type: "string", label: "Second URL", description: "Enter the second URL to make the HTTP request to.", }, }, async run({ steps, $ }) { // Example HTTP request to the first URL const response1 = await axios($, { url: this.url1, method: "GET", }); // Example HTTP request to the second URL const response2 = await axios($, { url: this.url2, method: "GET", }); // Returning the responses from both URLs return { response1: response1, response2: response2, }; }, }); In this example, url1 and url2 are defined as string properties under props, allowing you to input the URLs directly in the Pipedream UI when you add this code step to your workflow. The label and description for each prop help guide you in the UI, making it clear what each field is for. This structure enables you to dynamically change the URLs without modifying the code, making your component more flexible and easier to reuse.

I am getting an error when replacing the variable. Here is the line I have:

const imageUrl = '${steps.convert_cover_artwork_url.$return_value}'; // Replace with your image URL

It seems like you’re trying to use a template literal in JavaScript but are using single quotes (') instead of backticks (`). Template literals allow you to embed expressions, but they must be enclosed in backticks. Here’s how you can correct the line of code: const imageUrl = `${steps.convert_cover_artwork_url.$return_value}`; // Replace with your image URL This should correctly replace the variable with the value of steps.convert_cover_artwork_url.$return_value.

I need to rewrite this code.

Write the application to have a field for the IMAGE URL to pull from and another field for where to save the IMAGE on Google Drive.

 import { axios } from "@pipedream/platform";  export default defineComponent({   props: {     google: {       type: "app",       app: "google",     },     imageUrl: {       type: "string",       label: "Image URL",       description: "The URL of the image to download",     },     savePath: {       type: "string",       label: "Save Path on Google Drive",       description: "The path where the image should be saved on Google Drive. Example: 'folder/image.png'",     },   },   async run({ steps, $ }) {     // First, download the image from the provided URL     const imageResponse = await axios($, {       url: this.imageUrl,       responseType: "arraybuffer",     });      // Convert the downloaded image to a Blob     const blob = new Blob([imageResponse.data], { type: "image/png" });          // Prepare the metadata for the Google Drive file     const metadata = {       name: this.savePath.split('/').pop(), // Extract the file name from the save path       mimeType: 'image/png',       parents: [this.savePath.split('/').slice(0, -1).join('/')], // Extract the folder ID from the save path     };      // Prepare the form data with the metadata and the image blob     const formData = new FormData();     formData.append('metadata', new Blob([JSON.stringify(metadata)], { type: 'application/json' }));     formData.append('file', blob);      // Upload the image to Google Drive     return await axios($, {       method: "POST",       url: `https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart`,       headers: {         Authorization: `Bearer ${this.google.$auth.oauth_access_token}`,         'Content-Type': 'multipart/related; boundary=foo_bar_baz'       },       data: formData,     });   }, }); 
```  This Pipedream component code snippet allows you to specify an image URL and a save path on Google Drive. It downloads the image from the provided URL and uploads it to the specified location on Google Drive. Please note that the `savePath` should include the full path where you want to save the image, including the file name and extension (e.g., 'folder/image.png'). The folder path is extracted from the `save

I need to rewrite this code.

Write the application to have a field for the IMAGE URL to pull from and another field for the GOOGLE DRIVE FOLDER ID where to store the IMAGE.

 import { axios } from "@pipedream/platform"  export default defineComponent({   props: {     google: {       type: "app",       app: "google",     },     imageUrl: {       type: "string",       label: "Image URL",       description: "URL of the image to pull from",     },     folderId: {       type: "string",       label: "Google Drive Folder ID",       description: "ID of the Google Drive folder where to store the image",     },   },   async run({ steps, $ }) {     // First, download the image from the provided URL     const imageResponse = await axios($, {       url: this.imageUrl,       responseType: "arraybuffer",     });      // Convert the image data to a Blob     const blob = new Blob([imageResponse.data], { type: "image/jpeg" });          // Prepare the metadata for the Google Drive file     const metadata = {       name: 'uploaded_image.jpg', // You can customize this filename       mimeType: 'image/jpeg',       parents: [this.folderId], // Folder ID where the file will be stored     };      // Prepare the form data with the metadata and the image blob     const formData = new FormData();     formData.append('metadata', new Blob([JSON.stringify(metadata)], { type: 'application/json' }));     formData.append('file', blob);      // Upload the image to Google Drive     return await axios($, {       method: "POST",       url: `https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart`,       headers: {         Authorization: `Bearer ${this.google.$auth.oauth_access_token}`,         'Content-Type': 'multipart/related; boundary=foo_bar_baz',       },       data: formData,     });   }, }) 
```  This Pipedream component code snippet allows you to upload an image from a specified URL to a specified Google Drive folder. Please ensure that the Google Drive API is enabled and that you have the necessary permissions to upload files to the target folder.

I am getting the following error:

AxiosError - Request failed with status code 404
{"type":"Buffer","data":[60,104,116,109,108,62,13,10,60,104,101,97,100,62,60,116,105,116,108,101,62,52,48,52,32,78,111,116,32,70,111,117,110,100,60,47,116,105,116,108,101,62,60,47,104,101,97,100,62,13,10,60,98,111,100,121,62,13,10,60,99,101,110,116,101,114,62,60,104,49,62,52,48,52,32,78,111,116,32,70,111,117,110,100,60,47,104,49,62,60,47,99,101,110,116,101,114,62,13,10,60,104,114,62,60,99,101,110,116,101,114,62,110,103,105,110,120,60,47,99,101,110,116,101,114,62,13,10,60,47,98,111,100,121,62,13,10,60,47,104,116,109,108,62,13,10]}
DETAILS

    at null.settle (/tmp/__pdg__/dist/code/5e0ccdb9feba3828611e4ffc45d6e6fb8f8bc62554a7e06fd5962539f69bb7ac/node_modules/.pnpm/axios@1.6.8/node_modules/axios/dist/node/axios.cjs:1966:12)
    at BrotliDecompress.handleStreamEnd (/tmp/__pdg__/dist/code/5e0ccdb9feba3828611e4ffc45d6e6fb8f8bc62554a7e06fd5962539f69bb7ac/node_modules/.pnpm/axios@1.6.8/node_modules/axios/dist/node/axios.cjs:3065:11)
    at BrotliDecompress.emit (node:events:530:35)
    at null.endReadableNT (node:internal/streams/readable:1696:12)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21)

    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at null.callAxios (/tmp/__pdg__/dist/code/5e0ccdb9feba3828611e4ffc45d6e6fb8f8bc62554a7e06fd5962539f69bb7ac/node_modules/.pnpm/@pipedream+platform@1.6.0/node_modules/@pipedream/platform/dist/axios.js:110:26)
    at Object.run (file:///tmp/__pdg__/dist/code/5e0ccdb9feba3828611e4ffc45d6e6fb8f8bc62554a7e06fd5962539f69bb7ac/component.mjs:22:27)
    at null.executeComponent (/var/task/launch_worker.js:287:22)
    at MessagePort.messageHandler (/var/task/launch_worker.js:786:28)

steps.upload_cover
{1}

debug
{5}

I’m sorry to hear you’re encountering a 404 Not Found error with your Axios request. This error typically indicates that the URL you’re trying to access does not exist on the server. Here are a few steps you can take to troubleshoot and resolve this issue: 1. Verify the URL: Ensure that the URL you are trying to access is correct. Typos or incorrect paths can lead to a 404 error. 2. Check the Server Configuration: If you have control over the server, ensure that the endpoint you’re trying to access is correctly configured and that the server is running. 3. Review the Request Method: Make sure you’re using the correct HTTP method (GET, POST, PUT, DELETE, etc.) for the request. Some endpoints only respond to specific methods. 4. Inspect the Axios Request: Double-check the Axios request in your code to ensure it’s correctly formatted and includes all necessary headers or parameters. Here’s a basic example of an Axios request using the @pipedream/platform axios wrapper, which provides better error handling and debugging information: import { axios } from "@pipedream/platform"; export default defineComponent({ async run({ steps, $ }) { try { return await axios($, { url: "https://your-api-endpoint.com/resource", method: "GET", // Adjust the method according to your needs headers: { "Content-Type": "application/json", // Include other headers as required }, }); } catch (error) { // This will help you understand the error better console.log(error.response); throw error; // Rethrowing the error for Pipedream to handle } }, }); Please replace "https://your-api-endpoint.com/resource" with the actual URL you’re trying to access and adjust the HTTP method and headers as needed. If you continue to experience issues, it might be helpful to share more details about the request you’re trying to make or check the server logs for more insights. For further assistance, you can also visit Pipedream’s support.

This is the URL of the image I am attempting to pull.

And it’s still coming up with that error.

It seems like you’re encountering an error when trying to pull an image from a URL, but you haven’t specified the context in which this error occurs or what the error message is. To provide you with the most accurate assistance, could you please provide more details about the following: 1. How are you attempting to pull the image? Are you using a Pipedream workflow or a specific code step within a workflow? 2. What is the exact error message you’re receiving? 3. Are you trying to download the image to process it within a workflow, or are you trying to forward it to another service? With more context, I’ll be better equipped to offer specific guidance or a solution.

  1. The URL to the image is stored in a spreadsheet.

  2. The exact error message is:
    {“error”:{“code”:404,“message”:“File not found: 1a2qEEBzPwHw6gPf9A8rs_y1Oehj7n7SL.”,“errors”:[{“message”:“File not found: 1a2qEEBzPwHw6gPf9A8rs_y1Oehj7n7SL.”,“domain”:“global”,“reason”:“notFound”,“location”:“fileId”,“locationType”:“parameter”}]}}

  3. I just want to download the image from the URL and store it to my Google Drive.

Based on the error message you’ve received, it appears that the file you’re trying to access on Google Drive is not found. This could be due to several reasons such as the file not existing, the file ID being incorrect, or your app not having the necessary permissions to access the file. To download an image from a URL and store it in your Google Drive, you would typically need to do the following steps: 1. Retrieve the URL of the image from your spreadsheet. 2. Download the image from the URL. 3. Upload the downloaded image to Google Drive. Here’s an example Pipedream component that demonstrates how you might download an image from a URL and upload it to Google Drive. This example assumes you have the URL of the image you want to download: ```
import { axios } from “@pipedream/platform”; import fs from “fs”; import stream from “stream”; import { promisify } from “util”; export default defineComponent({ props: { google: { type: “app”, app: “google”, }, }, async run({ steps, $ }) { // Replace this with the URL of the image you want to download const imageUrl = “YOUR_IMAGE_URL_HERE”; // Download the image const response = await axios($, { url: imageUrl, responseType: “stream”, }); const pipeline = promisify(stream.pipeline); const tempFilePath = /tmp/downloaded_image; await pipeline(response.data, fs.createWriteStream(tempFilePath)); // Upload the image to Google Drive const fileMetadata = { name: ‘uploaded_image.jpg’, parents: [‘YOUR_FOLDER_ID’] // Optional: Specify the folder ID if you want to upload to a specific folder }; const media = { mimeType: ‘image/jpeg’, body: fs.createReadStream(tempFilePath), }; const driveResponse = await axios($, { method: ‘post’, url: ‘https://www.googleapis.com/upload/drive/v3/files’, params: { uploadType: ‘multipart’, }, headers: { Authorization: Bearer ${this.google.$auth.oauth_access_token}, ‘Content-Type’: ‘multipart/related’, }, data: { fileMetadata, media, }, }); return driveResponse.data; }, });

Please make input fields for: ImageURL and FOLDER ID, for the following script:

import { axios } from "@pipedream/platform";
import fs from "fs";
import stream from "stream";
import { promisify } from "util";

export default defineComponent({
  props: {
    google: {
      type: "app",
      app: "google",
    },
  },
  async run({ steps, $ }) {
    // Replace this with the URL of the image you want to download
    const imageUrl = "YOUR_IMAGE_URL_HERE";
    
    // Download the image
    const response = await axios($, {
      url: imageUrl,
      responseType: "stream",
    });
    
    const pipeline = promisify(stream.pipeline);
    const tempFilePath = `/tmp/downloaded_image`;
    await pipeline(response.data, fs.createWriteStream(tempFilePath));
    
    // Upload the image to Google Drive
    const fileMetadata = {
      name: 'uploaded_image.jpg',
      parents: ['YOUR_FOLDER_ID'] // Optional: Specify the folder ID if you want to upload to a specific folder
    };
    const media = {
      mimeType: 'image/jpeg',
      body: fs.createReadStream(tempFilePath),
    };
    const driveResponse = await axios($, {
      method: 'post',
      url: 'https://www.googleapis.com/upload/drive/v3/files',
      params: {
        uploadType: 'multipart',
      },
      headers: {
        Authorization: `Bearer ${this.google.$auth.oauth_access_token}`,
        'Content-Type': 'multipart/related',
      },
      data: {
        fileMetadata,
        media,
      },
    });
    
    return driveResponse.data;
  },
});

To modify the provided script to include input fields for ImageURL and FOLDER ID, you can add these as props in the defineComponent function. Here’s how you can do it: import { axios } from "@pipedream/platform"; import fs from "fs"; import stream from "stream"; import { promisify } from "util"; export default defineComponent({ props: { google: { type: "app", app: "google", }, imageUrl: { type: "string", label: "Image URL", description: "Enter the URL of the image you want to download", }, folderId: { type: "string", label: "Folder ID", description: "Enter the Google Drive Folder ID where the image will be uploaded", optional: true, // Make this optional in case the user wants to upload to the root directory }, }, async run({ steps, $ }) { // Use the imageUrl prop const response = await axios($, { url: this.imageUrl, responseType: "stream", }); const pipeline = promisify(stream.pipeline); const tempFilePath = `/tmp/downloaded_image`; await pipeline(response.data, fs.createWriteStream(tempFilePath)); // Use the folderId prop const fileMetadata = { name: 'uploaded_image.jpg', parents: this.folderId ? [this.folderId] : [], // Use the folder ID if provided }; const media = { mimeType: 'image/jpeg', body: fs.createReadStream(tempFilePath), }; const driveResponse = await axios($, { method: 'post', url: 'https://www.googleapis.com/upload/drive/v3/files', params: { uploadType: 'multipart', }, headers: { Authorization: `Bearer ${this.google.$auth.oauth_access_token}`, 'Content-Type': 'multipart/related', }, data: { fileMetadata, media, }, }); return driveResponse.data; }, }); This modification introduces two new props, imageUrl and folderId, which allow you to input the URL of the image you want to download and the ID of the folder where you want to upload the image, respectively. The folderId prop is marked as optional, allowing

I am getting the following error:

TypeError
The "body" argument must be of type function or an instance of Blob, ReadableStream, WritableStream, Stream, Iterable, AsyncIterable, or Promise or { readable, writable } pair. Received undefined

It appears you’re encountering a TypeError related to the “body” argument in a function call, which must be of a specific type but was received as undefined. This error typically occurs when making HTTP requests or working with streams, and you’re expected to provide a “body” argument that matches one of the required types, but instead, undefined was passed. Without specific details on where this error is occurring in your Pipedream workflow or code, I can offer a general approach to troubleshooting and resolving this issue: 1. Check the Function Call: Review the function or API call that is generating this error. Ensure that you are passing a “body” argument when required and that the value is not undefined. 2. Validate the “body” Argument: Before making the call, add a validation step to ensure the “body” argument is not undefined and conforms to one of the acceptable types (function, Blob, ReadableStream, WritableStream, Stream, Iterable, AsyncIterable, Promise, or { readable, writable } pair). 3. Debugging: Temporarily add logging statements before the function call to inspect the value of the “body” argument. This can help you identify why it’s undefined. 4. Review Documentation: If this error is related to an external API or library you’re using in your Pipedream workflow, review their documentation to understand the expected format and type of the “body” argument. If you’re working with HTTP requests in Pipedream and encountering this issue, ensure you’re correctly setting up the request body. Here’s a generic example of making an HTTP POST request with a JSON body using Pipedream’s axios: import { axios } from "@pipedream/platform"; export default defineComponent({ async run({ steps, $ }) { const data = { key: "value", // Replace with your actual data }; // Ensure data is not undefined if (!data) { throw new Error("Data is undefined"); } return await axios($, { method: "post", url: "https://example.com/endpoint", // Replace with your actual URL data, }); }, }); In this example, we’re making sure the data variable is not undefined before making the request. Replace "https://example.com/endpoint" and the data object