I’m trying to do this workflow with Pipedream:
- A Gmail account receives an email.
- The message from the email is decoded, using the “text/plain” part (if it doesn’t exist, I use the “text/html”).
- Create a ClickUp task or update an existing one with that message.
- Download attachments (not the embedded images, if i include them and upload those too, the task ended up with signatures images, logos, etc as upload files, when i need them to be in the description of the task ).
- Upload those attachments.
The thing is that decoding messages with embedded images is not working properly because embedded images can’t be decoded with base64.
Is there a way to create the task with the description being the exact same email, with embedded images and all those kinds of things? Like i said before, i’ve tried to download those images as attachments and upload them, but the task ended up with those images as uploaded files; I need them to be in the description as embedded images.
This is how I decode the email:
import { htmlToText } from "html-to-text";
const decodeBase64 = (data) => {
const normalizedBase64 = data.replace(/-/g, '+').replace(/_/g, '/');
const padding = normalizedBase64.length % 4;
if (padding > 0) {
normalizedBase64 += '='.repeat(4 - padding);
}
return Buffer.from(normalizedBase64, 'base64').toString('utf-8');
};
export default defineComponent({
async run({ steps, $ }) {
const email = steps.trigger.event.payload;
const text = {
mimeType: "",
data: "",
}
const parts = email.parts;
if(email.mimeType.includes("multipart")){
function findEmailText(parts){
for(const part of parts){
const subParts = part.parts;
if(subParts){
findEmailText(subParts);
}
if(part.mimeType === "text/plain" || part.mimeType === "text.html"){
text.mimeType = part.mimeType;
text.data = part.body.data;
break;
}
}
}
findEmailText(parts);
} else {
text.mimeType = email.mimeType;
text.data = email.body.data;
}
text.decodedMessage = text.mimeType !== "text/html" ? decodeBase64(text.data) : htmlToText(decodeBase64(text.data), { wordwrap: 130 });
return text.decodedMessage;
},
})
And how i upload the attachments:
import { axios } from "@pipedream/platform"
import fs from "fs";
import FormData from "form-data";
export default defineComponent({
props: {
clickup: {
type: "app",
app: "clickup",
}
},
async run({ steps, $ }) {
const { TMP_DIR } = steps.define_constants.$return_value;
const taskId = steps.if_task.$return_value;
const files = steps.download_attachments.$return_value;
for (let i = 0; i < files.length; i++) {
const file = files[i];
const filePath = `${TMP_DIR}/${file.filename}`;
const fileStream = fs.createReadStream(filePath);
const formData = new FormData();
formData.append(`attachment`, fileStream);
try {
await axios($, {
method: 'POST',
url: `https://api.clickup.com/api/v2/task/${taskId}/attachment`,
headers: {
Authorization: `${this.clickup.$auth.oauth_access_token}`,
...formData.getHeaders(),
},
data: formData,
});
} catch (error) {
console.error('Error message:', error.message);
}
}
return `Uploaded ${files.length} files successfully.`;
}
})