Скрипт node.js для загрузки pdf файла на диск Google иногда приводит к пустым страницам - PullRequest
0 голосов
/ 13 июня 2019

Я пытаюсь взять вложения в Gmail и загрузить их в Google Диск в определенное место.Поток у меня работает, но проблема в том, что для некоторых PDF-файлов загруженный файл содержит пустые страницы.Некоторые PDF-файлы могут быть правильно загружены на Google Drive и доступны для чтения.Это одинаково для всех файлов.Либо данный PDF-файл может быть загружен и доступен для чтения каждый раз, либо PDF-файл может быть загружен, но не для чтения каждый раз.

Если я записываю PDF-файл в локальную файловую систему, все они доступны для чтения.Так что я не уверен, где моя проблема.

const fs = require('fs');
const fileType = require('file-type');
const ga = require('./gapp/ga');

const {google} = require('googleapis');
const gmail = google.gmail('v1');

const label = 'mylabel';
const userId = 'me';

const folderId = 'folder id where file is to go';
const supportedFileTypes = ['application/pdf'];

const doMail = async () => {
  try {
    const auth = await ga.authorize();
    const msgs = await getEmailIds(
      {
        auth: auth,
        userId: userId,
        q: 'is:unread',
      },
      label
    );

    if (msgs) {
      for (const msg of msgs) {
        const msgId = msg.id;
        const data = await getEmailMsg({
          auth: auth,
          userId: userId,
          id: msgId,
        });
        for (part of data.payload.parts) {
          if (part.filename && part.filename.length > 0) {
            const fileName = `AN-${part.filename}`;
            const attachId = part.body.attachmentId;
            const attachData = await getAttachment({
              auth: auth,
              id: attachId,
              messageId: msgId,
              userId: userId,
            });
            const media = getMedia(attachData);
            const supported =
              supportedFileTypes.findIndex(ft => ft === media.mimeType) >= 0
                ? true
                : false;
            if (supported === true) {
              // This results in a usable / readable pdf file on local drive
              await fs.writeFileSync(`./${fileName}`, attachData, 'base64');

              // This some times will create pdf that is readable, sometimes not
              const resp = await createDriveResource(auth, {
                resource: {
                  name: fileName,
                  parents: [folderId],
                },
                media: media,
                properties: {
                  prop1: 'prop1',
                },
                fields: 'parents',
              });
              // console.log(`resp >${resp}<`);
            }
          }
        }
      }
    } else {
      console.log('no messages to process');
    }
    return 'doMail done';
  } catch (error) {
    throw new Error(error);
  }
};

function getMedia(data) {
  const buff = new Buffer(data, 'base64');
  const content = buff.toString();
  const ft = fileType(buff);
  return {
    mimeType: ft.mime,
    body: content,
  };
}

function createDriveResource(auth, params) {
  return new Promise((resolve, reject) => {
    const drive = google.drive({version: 'v3', auth});
    drive.files.create(params, (err, file) => {
      if (err) {
        reject(err);
      } else {
        resolve(file.data.id);
      }
    });
  });
}

const getLabelIdP = (params, label) => {
  return new Promise((resolve, reject) => {
    gmail.users.labels.list(params, (err, response) => {
      if (err) {
        reject(`getLableIdP labels.list failed : ${err}`);
      }
      const labels = response.data.labels;
      let id = undefined;
      const index = labels.findIndex(p => p.name === label);
      if (index >= 0) {
        id = labels[index].id;
      }
      resolve(id);
    });
  });
};

const getEmailMsg = params => {
  return new Promise((resolve, reject) => {
    gmail.users.messages.get(params, (err, response) => {
      if (err) {
        reject(`getEmailMsg() message.get failed :  ${err}`);
      }
      resolve(response.data);
    });
  });
};

const getAttachment = async params => {
  return new Promise((resolve, reject) => {
    gmail.users.messages.attachments.get(params, (err, response) => {
      if (err) {
        reject(`getAttachment() attachments.get failed : ${err}`);
      }
      resolve(response.data.data);
    });
  });
};

const getEmailIds = (params, label) => {
  return new Promise((resolve, reject) => {
    getLabelIdP(params, label).then(id => {
      if (!id) {
        reject(
          `Unable to find label id for label >${label}< in getEmailIds()... Unable to continue`
        );
      }
      params.labelIds = id;
      gmail.users.messages.list(params, (err, response) => {
        if (err) {
          reject(`getEmailIds() message.list failed : ${err}`);
        }
        resolve(response.data.messages);
      });
    });
  });
};

doMail()
  .then(r => {
    console.log(r);
  })
  .catch(e => {
    console.log(e);
  });

Я не уверен, что проблема заключается в следующем:

  • , как осуществляется доступ к вложению
  • , если PDF-файл в некотором роде плохой
  • если проблема в процессе загрузки на Google Диск.

Учитывая, как это работает для определенных файлов, я склоняюсь к тому, что в PDF есть что-то, что является ошибкой, но я не уверенчто искать, если это так.Отправляемые PDF-файлы поступают от разных отправителей, и PDF-файл будет создаваться разными способами, которые я не могу контролировать.

Мы будем благодарны за мысли о том, где искать, или об альтернативных обходных путях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...