muratgozel / mimetext Goto Github PK
View Code? Open in Web Editor NEWRFC-2822, RFC-2045 and RFC-2049 compliant raw email message generator.
Home Page: https://muratgozel.github.io/MIMEText/
License: MIT License
RFC-2822, RFC-2045 and RFC-2049 compliant raw email message generator.
Home Page: https://muratgozel.github.io/MIMEText/
License: MIT License
for automated testing purposes, it'd be great to be able to parse a raw string into a MIMEMessage
instance so we can easily write test assertions.
When using a MimeText built email with AWS SES, I get the following error message when attempting to send to origins with special characters in the name:
{"message":"Missing '\"'"}
Related to:
aws/aws-sdk-php#1196
https://stackoverflow.com/questions/41291378/boto3-ses-invalidparametervalue-error-due-to-unicode-characters
The current implementation allows a single Mailbox as Reply-To value:
https://github.com/muratgozel/MIMEText/blob/master/src/MIMEMessageHeader.ts#L30
but some emails providers such as Amazon SES allow multiple.
I would be great to allow an Array of Mailbox.
Hi, @muratgozel I've started using MIMEText and I'm enjoying how simple is to create email messages using it.
I have a question, is there a plan to include cc
and bcc
recipient options? If so, when is this planned to be released?
Also, is there any chance to manually set message-ID
for reply option?
I'll be glad to open a PR for adding this requirements if you like the idea.
Thanks in advance
Hi,
with version 3.07 the cjs import gives error on startup. 3.06 is ok
// cjs const {createMimeMessage} = require('mimetext')
bye
Would be nice if there was a way to access the MIMEMessage class from the npm module.
for example:
import MIMEMessage from "mimetext/MIMEMessage"
let envctx = { ... }
let message = new MIMEMessage(envctx)
would be nice for environments like cloudflare workers where node builtins do not exist. Also could have advantages for advanced customisation:
text/plain alternative part disappears when adding inline Image
const x = createMimeMessage();
x.setSender({name: "Test", addr: "[email protected]"});
x.setRecipient("[email protected]");
x.setSubject("This is a test");
x.addMessage({
contentType: 'text/html',
data: "<h1>Lorem ipsum dolor sit amet...</h1>"
});
x.addMessage({
contentType: 'text/plain',
data: "Lorem ipsum dolor sit amet..."
});
x.addAttachment({
inline: true,
filename: "test.png",
contentType: "image/png",
data: "dGVzdA==",
headers: { "Content-ID": "test" }
});
x.addAttachment({
filename: "test.pdf",
contentType: "application/pdf",
data: "dGVzdA=="
});
console.log(x.asRaw());
Output:
Date: Wed, 06 Mar 2024 08:25:38 +0000
From: =?utf-8?B?VGVzdA==?= <[email protected]>
To: <[email protected]>
Message-ID: <[email protected]>
Subject: =?utf-8?B?VGhpcyBpcyBhIHRlc3Q=?=
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary=lu9hrte8tx
--lu9hrte8tx
Content-Type: multipart/related; boundary=11ntqiz482y
--11ntqiz482y
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: 7bit
<h1>Lorem ipsum dolor sit amet...</h1>
--11ntqiz482y
Content-ID: <test>
Content-Type: image/png; name="test.png"
Content-Transfer-Encoding: base64
Content-Disposition: inline; filename="test.png"
dGVzdA==
--11ntqiz482y--
--lu9hrte8tx
Content-Type: application/pdf; name="test.pdf"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="test.pdf"
dGVzdA==
--lu9hrte8tx--
Output without "inline: true":
Date: Wed, 06 Mar 2024 08:27:31 +0000
From: =?utf-8?B?VGVzdA==?= <[email protected]>
To: <[email protected]>
Message-ID: <[email protected]>
Subject: =?utf-8?B?VGhpcyBpcyBhIHRlc3Q=?=
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary=5fll5crxif3
--5fll5crxif3
Content-Type: multipart/alternative; boundary=qqzy1z2de9f
--qqzy1z2de9f
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 7bit
Lorem ipsum dolor sit amet...
--qqzy1z2de9f
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: 7bit
<h1>Lorem ipsum dolor sit amet...</h1>
--qqzy1z2de9f--
--5fll5crxif3
Content-ID: <test>
Content-Type: image/png; name="test.png"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="test.png"
dGVzdA==
--5fll5crxif3
Content-Type: application/pdf; name="test.pdf"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="test.pdf"
dGVzdA==
--5fll5crxif3--
The release of v2.1.0 included chunking messages. One issue with this is that it seems to be adding newlines in the middle of content where there are side effects. For example, when a chunk happens in the middle of a link like https://place-puppy.com/public-images/index-page/image1/210x280-lg.jpg
, it will show up in the original message like:
(.... some long text) <img src=3D"https://place-puppy.com/public-images/index-pa
ge/image1/210x280-lg.jpg"/>
When this is loaded into the email client (gmail in this case), it is interpreted as:
(.... some long text) <img src="https://place-puppy.com/public-images/index-pa%0Dge/image1/210x280-lg.jpg"/>
Which does not load.
The RFC for Mails requires all lines in the Message to not be longer than 1000 characters (including CR+LF).
If I create a Message with this library, I would expect line-breaks to be added automatically to conform to the standard.
But the library does not add line-breaks to the message body and this emails are rejected by many mail servers with the error "501: line too long"
Example code:
const mimeText = require('mimetext')
const msg = mimeText.createMimeMessage()
msg.setSender('[email protected]')
msg.setTo('[email protected]')
msg.setSubject('This message will be rejected')
msg.addMessage({ contentType: 'text/html', data: 'x'.repeat(2000) })
console.log(msg.asRaw())
This message will contain a single line with 2000 characters, breaking the spec.
We have noticed some issues with sending emails with emojis in the from name. With some trial and error, we were able to send emails successfully by manually encoding this string before using setSender
. I think the raw representation of the message should be updated in this package to automatically encode the From
field similar to how the Subject
field already does.
Hi,
I'm having issues viewing attachments I've added to my email. I load the files locally from my pc (Mac) and after creating the message I write it back to my system to view it in Microsoft Outlook. I however get corrupted files/ no pdf/jpg file errors... Sending a text file as attachment works (testRaw). "dataRaw" gives the corrupted error messages
import { createMimeMessage } from "mimetext";
import fs from "fs";
export const dummyMime = () => {
const msg = createMimeMessage();
msg.setSender({ name: "Dummy", addr: "[email protected]" });
msg.setRecipient("[email protected]");
msg.setSubject("A dummy email to test with");
msg.addMessage({
contentType: "text/plain",
data: `Hello, my name is Dummy and this is a dummy email to test the email parsed with - I enjoy typescript!`,
});
const dataRaw = fs.readFileSync('dummy2.jpg', {encoding: 'base64'});
const testRaw = Buffer.from("this is a text!").toString('base64');
msg.addAttachment({
filename: "dummy2.jpg",
contentType: "image/jpg",
data: `${dataRaw}`,
});
fs.writeFile("dummyEmail.eml", msg.asRaw(), (err) => {
if (!err) {
console.log("email succesfully generated");
console.log(msg.asRaw());
}
});
return msg.asRaw();
};
dummyMime();
I cannot find any support for adding attachments that are compressed as zip files but this is a valid option when creating a raw email string.
Have a I missed something?
Hi Great work. I need to clone emails to forward for content investigation. Is there a way to replicate the order of an email headers exactly. When I parse an email and set from, to, and subject then additional headers it will order the headers as date, from, to, message-id, subject, mime-version then addition headers. I understand this library is meant to create and send emails, I was just wondering if there is a way to add in an object of headers as intended order whereas there may be header keys like recieved, authentications-results, received-sfp, dkim-signature, x-google-dkim-signature etc ordered before date, from and to. Thank you.
Do the following:
npm install mimetext
node
require('mimetext')
And I see:
var _MIMEMessage = require("../MIMEMessage.js");
^
Uncaught:
Error [ERR_REQUIRE_ESM]: require() of ES Module C:\...\node_modules\mimetext\build\MIMEMessage.js from C:\...\Downloads\node_modules\mimetext\build\entrypoints\node.cjs not supported.
Instead change the require of MIMEMessage.js in C:\...\Downloads\node_modules\mimetext\build\entrypoints\node.cjs to a dynamic import() which is available in all CommonJS modules.
at Object.<anonymous> (C:\...\Downloads\node_modules\mimetext\build\entrypoints\node.cjs:42:20)
at REPL1:1:1
at Script.runInThisContext (node:vm:123:12)
at REPLServer.defaultEval (node:repl:569:29)
at bound (node:domain:433:15)
at REPLServer.runBound [as eval] (node:domain:444:12)
at REPLServer.onLine (node:repl:899:10)
at REPLServer.emit (node:events:526:35)
at REPLServer.emit (node:domain:489:12)
at REPLServer.self._ttyWrite (node:repl:994:9)
at ReadStream.emit (node:events:514:28)
at ReadStream.emit (node:domain:489:12)
at emitKeys.next (<anonymous>)
at ReadStream.emit (node:events:514:28)
at ReadStream.emit (node:domain:489:12) {
code: 'ERR_REQUIRE_ESM'
}
Seems as if build/entrypoints/node.cjs
is require
ing build/MIMEMessage.js
when it should be require
ing build/MIMEMessage.cjs
.
[email protected]
worked.
2.1.1. Line Length Limits
There are two limits that this standard places on the number of
characters in a line. Each line of characters MUST be no more than
998 characters, and SHOULD be no more than 78 characters, excluding
the CRLF.The 998 character limit is due to limitations in many implementations
which send, receive, or store Internet Message Format messages that
simply cannot handle more than 998 characters on a line. Receiving
implementations would do well to handle an arbitrarily large number
of characters in a line for robustness sake. However, there are so
many implementations which (in compliance with the transport
requirements of [RFC2821]) do not accept messages containing more
than 1000 character including the CR and LF per line, it is important
for implementations not to create such messages.The more conservative 78 character recommendation is to accommodate
the many implementations of user interfaces that display these
messages which may truncate, or disastrously wrap, the display of
more than 78 characters per line, in spite of the fact that such
implementations are non-conformant to the intent of this
specification (and that of [RFC2821] if they actually cause
information to be lost). Again, even though this limitation is put on
messages, it is encumbant upon implementations which display messages
The recommendation is for the line lengths to not exceed 78, but there is hard limit on the 998 characters.
From my observations of the popular mail clients like Gmail and Outlook, the content and subject is folded at 78 characters.
@muratgozel What do you think of accepting this recommendation into the library?
We just ran into issues when deploying our application:
Error: Cannot find module '/app/node_modules/mimetext/dist/node/cjs/index.js'
Checking it locally it looks like the dist
folder is not being included when installing v2.0.8
of the lib.
npm install [email protected]
npm install [email protected]
We locked the version on 2.0.7 and all is well for us.
Just a heads up! :)
The default implementation of envctx using btoa
function to encode base64 string, which may cause runtime error in some browser environment, make this library not working at all. There is many third modules can replace this function, so it may be good to have a choice to build custom envctx.
const message = createMimeMessage(); message.setSender('[email protected]'); message.setTo('[email protected]'); message.setSubject('Test Email Please Ignore'); //message.setMessage('text/plain', 'yo'); // setMessage is not a function //@ts-expect-error // addMessage works just fine, but typescript doesn't know about it message.addMessage({ contentType: 'text/plain', data: 'Yo', }); const res = await gmailFetch( 'https://gmail.googleapis.com/gmail/v1/users/me/messages/send', { method: 'POST', body: JSON.stringify({ raw: message.asEncoded() }) }, );
TLDR: the docs suggest using addMessage, but it's not a valid type. setMessage is a valid type, but doesn't actually exist on the message object. There may be other mismatches, but this is the only one I've run into thus far.
Hi,
Below my code to generate an email and add an attachment. I can open the email and view the image in Apple Mail. I however get an corrupted/damage file error when attempting to open the file in MS Outlook.
import { createMimeMessage } from "mimetext";
import fs from "fs";
export const dummyMime = () => {
const msg = createMimeMessage();
msg.setSender({ name: "Dummy", addr: "[email protected]" });
msg.setRecipient("[email protected]");
msg.setSubject("A dummy email to test with");
msg.addMessage({
contentType: "text/plain",
data: `Hello, my name is Dummy and this is a dummy email to test the email parsed with - I enjoy typescript!`,
});
const dataRaw = fs.readFileSync('test.jpg', {encoding: 'base64'});
// const testRaw = Buffer.from("this is a text!").toString('base64');
msg.addAttachment({
filename: "test.jpg",
contentType: "image/jpg",
data: `${dataRaw}`,
});
const rawMsg = msg.asRaw();
fs.writeFile("testEmailWithImage.eml", rawMsg, (err) => {
if (!err) {
console.log("email succesfully generated");
console.log(msg.asRaw());
}
});
return msg.asRaw();
};
dummyMime();
Hey! How can we fix this issue in the package?
Cloudflare in their documentation propose to use mimetext
for sending emails in their Cloudflare Workers and Cloudflare Email Workers.
Since updating to version 3.0.21
(although it could be any version after 3.0.16
, as it worked previously), the library does not work natively in the Cloudflare Workers environment. By saying natively, I mean without transpiling code or enabling Node.js compatibility modes or flags.
Currently, I found two possible solutions:
mimetext
: import { createMimeMessage } from 'mimetext/browser';
;node_compat = true
in wrangler.toml
to turn on Node.js polyfills.cloudflare/wrangler-action
Node.js version: 18.19.0
NPM version: 10.2.3
Hi!
In RFC-2822 section 3.6. Field definitions, it says that the To header is optional. However, when creating a mime message without setting the To Header, and applying the asRaw() or asEncoded() function, an error is returned that the To Header must not empty.
This is the code to reproduce:
const msg = createMimeMessage()
msg.setSender({name: 'Lorem Ipsum', addr: '[email protected]'})
msg.setSubject('π Issue 49!')
msg.setMessage('text/plain', `Hi,
I'm a simple text.`)
msg.asRaw()
Not setting the To header will result in a INVALID_MAILBOX error being thrown. Thus the To header is not optional.
Hi! I was peeking through your source code and noticed this:
Line 38 in 25c534b
text.trim()
on its own does nothing. Was this meant to be text = text.trim()
?
Hi,
It seems that we are struggling to add a "Reply-To" header (which is different from the "From" header). What is the best way to define a "Reply-To"?
const message = createMimeMessage();
message.setHeader('Reply-To', contact.email);
generate the following message:
MIMETEXT_INVALID_HEADER_VALUE: You specified an invalid value for the header Reply-To
Thanks!
below is the code:
import { Injectable } from '@nestjs/common';
import { SES, SESClient } from '@aws-sdk/client-ses';
import { SendEmailCommand } from "@aws-sdk/client-ses";
const {fromIni} = require("@aws-sdk/credential-providers");
const fs = require('fs');
const request = require('request');
const nodemailer = require("nodemailer");
const {createMimeMessage} = require('mimetext');
@Injectable()
export class EmailAdapter {
constructor() {
}
async sendEmail (name: string, recipients: string, subject: string, content: string) {
const REGION = "us-east-1";
const ses = new SES({
region: REGION,
credentials: {
accessKeyId: 'XXXX',
secretAccessKey: 'XXXX',
}
});
// console.log ('ses: ', ses.config.credentials.toString());
// const sesClient = new SESClient({ region: REGION });
// console.log ('sesClient: ', sesClient);
const message = createMimeMessage();
message.setSender({name: 'GuruQ Support Team', addr: '[email protected]'});
console.log ('message.getSender(): ', message.getSender());
message.setTo({name: 'Foo Bar', addr: '[email protected]'});
console.log ('message.getTo(): ', message.getRecipients());
message.setSubject(subject)
console.log ('message.getSubject(): ', message.getSubject());
message.setAttachment('invoice.pdf', 'application/pdf', message.toBase64(fs.readFileSync('/Users/atulmala/guruq/media/media/7/2022/9/invoice_Q22OR14673.pdf')));
console.log ('message.getAttachment(): ', message.getAttachments());
const encoded = message.toBase64('This is <strong>html</strong>.')
const headers = {'Content-Transfer-Encoding': 'base64'}
message.setMessage('text/html', encoded, headers);
message.setMessage("text/plain", encoded, headers);
console.log ('message.getMessage(): ', message.getMessageByType('text/plain'));
const params = {
Destinations: message.getRecipients({type: 'to'}).map(mailbox => mailbox.addr),
RawMessage: {
Data: message.asRaw() // aws-sdk does the base64 encoding
},
Source: message.getSender().addr
}
console.log ('params.Destinaations = ', params.Destinations);
ses.send
ses.sendRawEmail(params, function(err, result) {
if (err) {
console.log ('error:', err.message)
}
if (result) {
console.log ('result: ', result.MessageId);
}
// err or result.MessageId
})
const command = new SendEmailCommand({
Destination: {
/* required */
CcAddresses: [
/* more items */
],
ToAddresses: [
recipients,
/* more To-email addresses */
],
},
Message: {
/* required */
Body: {
/* required */
Html: {
Charset: "UTF-8",
Data: content,
},
Text: {
Charset: "UTF-8",
Data: "TEXT_FORMAT_BODY",
},
},
Subject: {
Charset: "UTF-8",
Data: subject,
},
},
Source: "[email protected]",
ReplyToAddresses: [
/* more items */
],
});
// try {
// return await sesClient.send(command);
// } catch (e) {
// console.error("Failed to send email.");
// console.log(e);
// return e;
// }
}
I import createMimeMessage
import {createMimeMessage} from 'mimetext'
It was working with v3.0.16.
Starting with v3.0.17 the Typescript compiler yields an error:
Could not find a declaration file for module 'mimetext'. '[path]/node_modules/mimetext/dist/node/mimetext.cjs' implicitly has an 'any' type.
Trynpm i --save-dev @types/mimetext
if it exists or add a new declaration (.d.ts) file containingdeclare module 'mimetext';
ts(7016)
Last version tested: v3.0.20. It still yields the above error.
Problem:
Upgrading from mimetext version 3.0.16 to 3.0.21 causes a test failure when trying to use CommonJS require:
const { createMimeMessage } = require('mimetext');
Throwing the following error:
Details:
/#################/node_modules/mimetext/build/MIMEMessage.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import { MIMETextError }
from './MIMETextError.js';
^^^^^^
SyntaxError: Cannot use import statement outside a module
> 1 | const { createMimeMessage } = require('mimetext');
Currently pinning to 3.0.16 to get build working again.
We were using SESV2 with this library in this way:
const { createMimeMessage } = require('mimetext')
const { mailClient } = require('../config/s3.config.js')
exports.sendEmail = async function (from, to, subject, html, text, attachment) {
const params = {
Content: {
Raw: {
Data: getMultipartEmail(from, to, subject, html, text, attachment)
},
},
FromEmailAddress: from,
};
await mailClient.sendEmail(params).promise();
}
function getMultipartEmail(from, to, subject, html, text, attachment) {
const msg = createMimeMessage()
msg.setSender({ name: 'Sender', addr: from })
msg.setRecipient(to)
msg.setSubject(subject)
msg.setMessage('text/plain', msg.toBase64(text), { 'Content-Transfer-Encoding': 'base64' })
msg.setMessage('text/html', msg.toBase64(html), { 'Content-Transfer-Encoding': 'base64' })
if (attachment)
msg.setAttachment(attachment.name, attachment.type, msg.toBase64(attachment.buffer))
return msg.asRaw()
}
After library upgrade to 3.0 we modified code of getMultipartEmail function in this way but is not working with aws, problem I think rely on the headers management. The only way would be to revert to aws SES V1 that has sendRawEmail, but considering that now aws released V3 sdk would be a bit strange..
function getMultipartEmail(from, to, subject, html, text, attachment) {
const msg = createMimeMessage()
msg.setSender({ name: 'Sender', addr: from })
msg.setRecipient(to)
msg.setSubject(subject)
msg.addMessage({
contentType: 'text/plain',
data: text
})
msg.addMessage({
contentType: 'text/html',
data: html
})
//msg.addMessage('text/plain', msg.toBase64(text), { 'Content-Transfer-Encoding': 'base64' })
//msg.addMessage('text/html', msg.toBase64(html), { 'Content-Transfer-Encoding': 'base64' })
if (attachment) {
//msg.setAttachment(attachment.name, attachment.type, msg.toBase64(attachment.buffer))
msg.addAttachment({
filename: attachment.name,
contentType: attachment.type,
data: msg.toBase64(attachment.buffer)
})
}
return msg.asRaw()
}
So for now we had to revert library to version 2
According to RFC 2047 an encoded word cannot be longer than 76 characters (including everything). So a longer subject line should be split and encoded into multiple encoded words.
Using the library mgs.setSubject('x'.repeat(100))
results in a single standard breaking encoded word. This leads to some Mail-Servers rejecting this message with an error.
The encoding should split and wrap longer encoded words to match the standard.
Hi,
I'm trying to send ical invites through e-mail, but I'm not able to add custom messages because the classes aren't exported / exposed. Could you add this?
I can see from the issue history there have been some typing issues beyond 3.0.16. I was seeing issues similar to others from 3.0.17 to 3.0.20 but these have been resolved in 3.0.21 but replaced by another problem.
Mailbox.getRecipients() used to return Mailbox | Mailbox[] | undefined
.
It now returns string | Mailbox | undefined
.
Mailbox.getSender() used to return Mailbox | undefined
It now returns string | Mailbox | undefined
.
These changes are causing TypeScript errors in our builds.
Node version 20.11.0.
Nx version 18.0.4.
Typescript version 5.3.3.
Happy to provide any further information required.
Greetings,
Is it possible to create a MIME message object from an RFC-2822 compliant email message (e.g. the output of the asRaw()
method)? How?
Thank you for the information,
Giacomo
Sometimes, one wants to have an attachment with Content-Disposition
set to inline
, so that the files don't show up in the "Attachments" view in the e-mail client. Unfortunately, it's currently hard-coded to only ever be attachment
for attachments. The moreHeaders
optional param of .setAttachment()
doesn't help here, because the Content-Disposition
header is overriden anyways.
The only way to do it at the moment is as follows:
msg.setAttachment('something.jpg', 'image/jpeg', contentBase64, { 'Content-ID': 'something.jpg' );
const attachment = msg.getAttachments().at(-1);
attachment.setHeader('Content-Disposition', 'inline;name=something.jpg');
attachment.isAttachment = () => true;
That's pretty unwieldy, especially when using TypeScript. Is there a chance such functionality could be added?
thanks for wonderful library. Is there a way to add bcc and cc recipients
Hey, we have used this implementation for a while now for sending emails through AWS SES. It worked flawlessly until we tried adding attachments to our emails.
This is an example setup:
const mimeMessage = createMimeMessage();
mimeMessage.setSender({ name: 'Sender', addr: 'app@[...]' });
mimeMessage.setTo('rec@[...]');
mimeMessage.setSubject('no subject defined');
mimeMessage.setAttachment('test.txt', 'text/plain', Buffer.from('This is a test!').toString('base64'));
const mailRequest: SendRawEmailRequest = {
RawMessage: {
Data: mimeMessage.asRaw(),
},
};
Without mimeMessage.setAttachment
sending through SES works fine. But adding it results in an Invalid Base64 stream
error from the AWS SDK.
The output of mimeMessage.asRaw()
looks like this:
Date: Fri, 03 Feb 2023 09:10:14 +0000
From: [...] <[...]>
To: <[...]>
Message-ID: <leif09vb1nr-1675415414574@[...]>
Subject: [...]
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary=ndvh1dnwcae
--ndvh1dnwcae
Content-Type: multipart/alternative; boundary=lurrh6lqibe
--lurrh6lqibe
--ndvh1dnwcae
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: base64
Content-Disposition: attachment;filename="test.txt"
VGhpcyBpcyBhIHRlc3Qh
--lurrh6lqibe
Content-Type: text/html; charset=UTF-8
<strong>Test</strong>
--lurrh6lqibe--
--ndvh1dnwcae
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: base64
Content-Disposition: attachment;filename="test.txt"
VGhpcyBpcyBhIHRlc3Qh
--ndvh1dnwcae--
It seems like the attachment gets inserted two times. To be honest I lack the proper understanding of MIME to fully understand why the resulting output is not valid.
We already tried not transforming the attachment to Base64. We tried the included toBase64
method, but did not use it further since it is not included in the TypeScript declaration.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.