Summary
This post covers the intake of emails w/attachments into Google Cloud Functions (GCF). The code here covers storing those attachments into a Cloud bucket.
There is no native SMTP trigger for GCF, so a 3rd party needs to be used to convert the email to an HTTP POST that can subsequently trigger a GCF. In this case, I used CloudMailin. They have a nice interface and are developer-friendly. The GCF then needs to process the multipart form data and write the file attachments to Cloud Storage.
Part 1: Inbound Email Handling with Google Cloud Functions
Part 2: Google Document AI
Architecture
Code Snippet - GCF Trigger
- exports.uploadRma = (req, res) => {
- if (req.method === 'POST') {
- if (req.query.key === process.env.API_KEY) {
- upload(req)
- .then(() => {
- res.status(200).send('');
Code Snippet - Upload function
The Busboy module is leveraged to do the heavy lifting of parsing the multi-part form. Each file is written to a UUID "folder" in Cloud Storage. Those writes are stored in a Promise array that is resolved when all the attachments of the form have been parsed.
- const busboy = new Busboy({headers: req.headers});
- const writes = [];
- const folder = uuidv4() + '/';
- busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
- console.log(`File received: ${filename}`);
- writes.push(save(folder + filename, file));
- });
- busboy.on('finish', async () => {
- console.log('Form parsed');
- await Promise.all(writes);
- resolve();
- });
- busboy.end(req.rawBody);
Code Snippet - Save function
A read stream for the file attachment is piped to a write stream to Cloud Storage.
- function save(name, file) {
- return new Promise((resolve, reject) => {
- file.pipe(bucket.file(name).createWriteStream())
- .on('error', reject)
- .on('finish', resolve);
- });
- }
Results
Original Email
Cloud Logs
Cloud Storage
Source
Copyright ©1993-2024 Joey E Whelan, All rights reserved.