Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 在Google云函数中从电子邮件上载和解压.zip文件完成后删除.zip节点JS_Node.js_Google Cloud Platform_Google Cloud Functions_Google Cloud Storage_Node Modules - Fatal编程技术网

Node.js 在Google云函数中从电子邮件上载和解压.zip文件完成后删除.zip节点JS

Node.js 在Google云函数中从电子邮件上载和解压.zip文件完成后删除.zip节点JS,node.js,google-cloud-platform,google-cloud-functions,google-cloud-storage,node-modules,Node.js,Google Cloud Platform,Google Cloud Functions,Google Cloud Storage,Node Modules,我收到一封包含一个.zip文件的电子邮件。现在我正试图上传到地面军事系统,并处理(大容量解压缩)到自己的文件夹文件。对我来说,为这样一个小动作运行大容量数据流似乎有些过头了 我曾考虑使用“解压流”包,但直到现在,我还没有想出一个有效的解决方案来解决我的问题 甚至可以在云函数中处理这样的文件吗?或者,如果没有一个专门的服务器来处理解压缩,然后将内容上传到GCS,那就没有办法了 这是我的密码: const os = require('os'); const fs = require('fs'); c

我收到一封包含一个.zip文件的电子邮件。现在我正试图上传到地面军事系统,并处理(大容量解压缩)到自己的文件夹文件。对我来说,为这样一个小动作运行大容量数据流似乎有些过头了

我曾考虑使用“解压流”包,但直到现在,我还没有想出一个有效的解决方案来解决我的问题

甚至可以在云函数中处理这样的文件吗?或者,如果没有一个专门的服务器来处理解压缩,然后将内容上传到GCS,那就没有办法了

这是我的密码:

const os = require('os');
const fs = require('fs');
const { Storage } = require('@google-cloud/storage');
const storage = new Storage();

// Node.js doesn't have a built-in multipart/form-data parsing library.
// Instead, we can use the 'busboy' library from NPM to parse these requests.
const Busboy = require('busboy');

exports.uploadZIPFile = (req, res) => {
  if (req.method !== 'POST') {
    // Return a "method not allowed" error
    return res.status(405).end();
  }
  const busboy = new Busboy({ headers: req.headers });
  const tmpdir = os.tmpdir();

  for (a in req.headers) {
    console.log(`Header: ${a}`);
  }

  // This object will accumulate all the fields, keyed by their name
  const fields = {};

  // This code will process each non-file field in the form.
  busboy.on('field', (fieldname, val) => {
    // TODO(developer): Process submitted field values here
    console.log(`Processed field ${fieldname}: ${val}.`);
    fields[fieldname] = val;
  });

  // This object will accumulate all the uploaded files, keyed by their name.
  const uploads = {};
  const fileWrites = [];

  // This code will process each file uploaded.
  busboy.on('file', (fieldname, file, filename) => {
    // Note: os.tmpdir() points to an in-memory file system on GCF
    // Thus, any files in it must fit in the instance's memory.

    console.log(`Processed file ${filename} - ${fieldname} - ${file}`);

    const filepath = path.join(tmpdir, filename);
    uploads[fieldname] = filepath;

    const writeStream = fs.createWriteStream(filepath);

    file.pipe(writeStream);

    // File was processed by Busboy; wait for it to be written to disk.
    const promise = new Promise((resolve, reject) => {
      file.on('end', () => {
        writeStream.end();
      });
      writeStream.on('finish', resolve);
      writeStream.on('error', reject);
    });

    fileWrites.push(promise);
  });

  // Triggered once all uploaded files are processed by Busboy.
  // We still need to wait for the disk writes (saves) to complete.
  busboy.on('finish', async () => {
    await Promise.all(fileWrites);

    // TODO(developer): Process saved files here
      for (const file in uploads) {
        
      async function upload2bucket() {
        // Uploads a local file to the bucket
        const bucketName = 'myBucket';
        const todayDate = new Date().toISOString().slice(0, 10);

        await storage.bucket(bucketName).upload(uploads[file], {
          // Support for HTTP requests made with `Accept-Encoding: gzip`
          gzip: true,
          // By setting the option `destination`, you can change the name of the
          // object you are uploading to a bucket.
          destination:
            'zip-inbox/' + todayDate + '_' + uploads[file].substring(5),
          metadata: {
            // Enable long-lived HTTP caching headers
            // Use only if the contents of the file will never change
            // (If the contents will change, use cacheControl: 'no-cache')
            cacheControl: 'no-cache',
          },
        });
        console.log(`${filename} uploaded to ${bucketName}.`);
      }
      if (uploads[file].endsWith('.zip')) {
        await upload2bucket();
      }

      console.log(`${file}: ${uploads[file]}`);
      //fs.unlinkSync(file);
    }
    res.status(200).send('Success');
  });

  busboy.end(req.rawBody);
};

云功能非常适用于小任务,这些小任务花费的时间很少。如果您有类似的需求—您只想在需要时为工作单元旋转一个实例,但无法预测执行它的时间,我建议使用Cloud Run,看看这个

云函数对于花费时间很短的小任务非常有用。如果您有类似的需求-您只想在需要时为一个工作单元旋转一个实例,但无法预测执行它的时间,我建议使用Cloud Run,看看这个

您可以用几个函数替换您的“无所不能”云函数,并用消息或(2021年1月发布)创建一个管道

我还建议使用包来简化云函数定义

管道可以是这样的:

  • 创建并计划一个从邮箱获取附件并将其上载到Google存储的函数。上传每个附件后,它将发送一条带有filepath有效负载的PubSub消息到下一步
  • 创建另一个函数,该函数根据来自PubSub的消息执行,并解压缩先前上传的文件
  • 注意:一个函数的执行时间不超过9分钟。如果花费的时间超过限制,则拆分函数

    以下是拟建管道的伪代码:

    import*作为“firebase函数”中的函数;
    从'@googlecloud/PubSub'导入{PubSub};
    const REGION='您的谷歌云区域';//e、 g.欧洲-西方1
    const PUBSUB_TOPIC_UNPACK_ZIP='your-TOPIC-name-for-step-2';
    /**
    *第一步。
    */
    exports.getFromEmailAndUploadToStorage=函数
    .地区(地区)
    .朗威({
    内存:“256MB”,
    timeoutSeconds:540,//最大执行持续时间为9分钟
    最大实例:1
    })
    pubsub.先生
    .时间表(每15分钟一次)
    .时区(“亚洲/海参崴”)
    .onRun(异步){
    const filepath=等待您的逻辑发送电子邮件并上载到存储();
    if(文件路径){
    const messagePayload={filepath};
    log('将消息发布到主题:',PUBSUB_topic_UNPACK_ZIP);
    log('Payload:',JSON.stringify(messagePayload));
    等待新的PubSub().topic(PubSub_topic_UNPACK_ZIP)。publishMessage({
    json:messagePayload
    });
    }
    });
    /**
    *第二步。
    */
    exports.unzipFilesInStorage=函数
    .地区(地区)
    .朗威({
    内存:“256MB”,
    timeoutSeconds:540,//最大执行持续时间为9分钟
    最大实例:1
    })
    pubsub.先生
    .topic(PUBSUB\u topic\u UNPACK\u ZIP)
    .onPublish(异步(消息、上下文)=>{
    const{filepath}=message?.json;
    如果(!filepath){
    抛出新错误('未设置文件路径');
    }
    //你的解压逻辑在这里。
    //解压后,您可以通过PubSub消息进一步传递结果。
    });
    
    您可以使用多个函数替换“无所不能”云函数,并使用消息或(2021年1月发布)创建管道

    我还建议使用包来简化云函数定义

    管道可以是这样的:

  • 创建并计划一个从邮箱获取附件并将其上载到Google存储的函数。上传每个附件后,它将发送一条带有filepath有效负载的PubSub消息到下一步
  • 创建另一个函数,该函数根据来自PubSub的消息执行,并解压缩先前上传的文件
  • 注意:一个函数的执行时间不超过9分钟。如果花费的时间超过限制,则拆分函数

    以下是拟建管道的伪代码:

    import*作为“firebase函数”中的函数;
    从'@googlecloud/PubSub'导入{PubSub};
    const REGION='您的谷歌云区域';//e、 g.欧洲-西方1
    const PUBSUB_TOPIC_UNPACK_ZIP='your-TOPIC-name-for-step-2';
    /**
    *第一步。
    */
    exports.getFromEmailAndUploadToStorage=函数
    .地区(地区)
    .朗威({
    内存:“256MB”,
    timeoutSeconds:540,//最大执行持续时间为9分钟
    最大实例:1
    })
    pubsub.先生
    .时间表(每15分钟一次)
    .时区(“亚洲/海参崴”)
    .onRun(异步){
    const filepath=等待您的逻辑发送电子邮件并上载到存储();
    if(文件路径){
    const messagePayload={filepath};
    log('将消息发布到主题:',PUBSUB_topic_UNPACK_ZIP);
    log('Payload:',JSON.stringify(messagePayload));
    等待新的PubSub().topic(PubSub_topic_UNPACK_ZIP)。publishMessage({
    json:messagePayload
    });
    }
    });
    /**
    *第二步。
    */
    exports.unzipFilesInStorage=函数
    .地区(地区)
    .朗威({
    内存:“256MB”,
    timeoutSeconds:540,//最大执行持续时间为9分钟
    最大实例:1
    })
    pubsub.先生
    .topic(PUBSUB\u topic\u UNPACK\u ZIP)
    .onPublish(异步(消息、上下文)=>{
    const{filepath}=message?.json;
    如果(!filepath){
    抛出新错误('未设置文件路径');
    }
    //你的解压逻辑在这里。
    //解压后,您可以通过PubSub消息进一步传递结果。
    });
    
    此过程完全可以预测。看见9分钟是一个非常消耗的时间。电子邮件服务器对附件有严格的限制,邮件大小约为10-20-30兆。每个电子邮件附件下载并上传到谷歌存储不能/不应该超过9分钟。每一个这样大小的拉链也不能/sho