I'm trying to reply to an existing email with Gmail API:
Since I don't have in the existing mail that i want to reply to the headers of References, In-Reply-To then i'm using the Message-ID instead to fill what I'm sending
DB5PR03MB1206D3A24F124BDF43A5C6E683D60#DB5PR03MB1206.eurprd03.prod.outlook.com is the Message-ID header of existing mail.
I've created the following RFC-802:
Content-Type: text/plain; charset="UTF-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
References: <DB5PR03MB1206D3A24F124BDF43A5C6E683D60#DB5PR03MB1206.eurprd03.prod.outlook.com>
In-Reply-To: <DB5PR03MB1206D3A24F124BDF43A5C6E683D60#DB5PR03MB1206.eurprd03.prod.outlook.com>
Subject: sdfasdf
to: "xxx#gmail.com" <aaa#gmail.com>,<xxxx#xxx.me>
from: aaa#gmail.com
aaaaaaaaa
then i get an error:
that an error occured the message wasn't sent.
I read this post but this post presumes that always i have the following two headers:
References
In-Reply-To
Remove References and set In-Reply-To : Message-ID
Content-Type: text/plain; charset="UTF-8" <br />
MIME-Version: 1.0<br />
Content-Transfer-Encoding: 7bit<br />
In-Reply-To: Message-ID<br />
Subject: sdfasdf<br />
to: "xxx#gmail.com" <aaa#gmail.com>,<xxxx#xxx.me><br />
from: aaa#gmail.com<br />
aaaaaaaaa
Related
I am sending emails using the Gmail NodeJS API using these code snippet (leaving auth out of it)
const headers: any = {
'To': event.to,
'Subject': event.subject,
"Content-Type": "text/html; charset='UTF-8'",
"Content-Transfer-Encoding": "base64"
}
let email = ''
for (let header in headers) {
email += header += ": " + headers[header] + "\r\n";
}
email += "\r\n" + event.body;
const theMessage = {
'userId': "me",
'resource': {
'raw': _btoa(unescape(encodeURIComponent(email))).replace(/\+/g, '-').replace(/\//g, '_')
}
}
const auth = new google.auth.OAuth2(
webAppClientId, this.clientSecret, "https://docs-n-data......");
const gmail = google.gmail({version: 'v1', auth})
gmail.users.messages.send(theMessage)
The email renders correctly on most email clients, except the ios email client on iphone. It looks like "chinese" in that client. Please see the attached image, following the suggestion by #DalmTo:
Some articles on the web hint that this might be due to the email being interpreted as UTF-16 instead of UTF-8, but none of them explain what to do.
I am trying to state that the encoding is UTF-8 in the above code, so am not sure whats wrong. Please help, thanks!
Update Maybe the content of the email body is important. The content comes from this template:
const emailBody = `<html>
<body>
<p>Hi {{Customer.First name}},</p>
<p>Your booking is confirmed for {{Date}} at {{Time}} and we have charged you the
amount of £{{Paid}}</p>
<p>Your booking reference is {{Booking number}}.</p>
<p>Use this link to cancel your booking, should you wish to.</p>
<p>Use this link to amend your booking, should you wish to.</p>
</body>
</html>`
Update 2 I changed the template for the email to:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<p>Hi {{Customer.First name}},</p>
<p>Your booking with The Smart Wash Ltd is confirmed for {{Date}} at {{Time}} and we have charged you the
amount of £{{Paid}}</p>
<p>Your booking reference is {{Booking number}}.</p>
</body>
</html>
And now I get this rendering on iphone mail client. On the ipad mail client and gmail, it renders correctly:
When I view the same email in gmail, and "Show original", I see this:
Not sure who or what is putting the text/plain version in there, but including this detail in case it helps.
I setted "Content-Transfer-Encoding": "8bit" and it worked for me!
I am using the AWS.SES (simple email service) kit in my Node.js Lambda function.
I can send emails just fine, but if I try to include a simple hyperlink in the email, it displays just plain text instead of a clickable hyperlink.
This is the code I'm using to send the email.
function sendVerificationEmail(userinfo, vKey, after) {
var params = {
Destination: {
ToAddresses: [userinfo.email]
},
Message: {
Body: {
Html: {
Charset: "UTF-8",
Data: "<html><body>Hey " + userinfo.name + ", <a href='https://s3.amazonaws.com/xxxx/xxxx.html?v=" + vKey + "'>Click here to validate this email address.</a></body></html>"
},
Text: {
Charset: "UTF-8",
Data: "Hey " + userinfo.name + ",\n\nOpen this link in your web browser to validate this email address:\nhttps://s3.amazonaws.com/xxxx/xxxx.html?v=" + vKey
}
},
Subject: { Data: "Scheduler - Verify Your Email Address" }
},
Source: "xxxx#gmail.com"
};
ses.sendEmail(params, function(err, data) {
after(err, data);
});
}
As you can see in the HTML, I have included an <a> tag. However, The link is displayed as unclickable plaintext in the email.
Edit: Gmail's "Show Original" feature displays the following:
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 7bit
Hey TestName,
Open this link in your web browser to validate this email address:
https://s3.amazonaws.com/xxxx/xxxx.html?v=xxxxxxxxxxxxxxxxxxxxxxxxxxxx
---------------------------------------------------
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: 7bit
<html><body>Hey TestName, <a href='https://s3.amazonaws.com/xxxx/xxxx.html?v=xxxxxxxxxxxxx'>Click here to validate this email address.</a></body></html>
If you observe the raw email contents you will observe that it misses the = sign between in href=<link>. This is because the '=' symbol is used as a line break in the smtp protocol messages(I think).
Anyways, the way to fix this is to add the unicode for the '=' symbol which is U+003D
Try this:-
${text}
The =3D is interpreted as the = symbol and the content encoding is done correctly.
Is it possible to add/update boundary headers via PHPmailer for the code
$mail->addStringAttachment($test, 'test.txt', 'quoted-printable');
I need to add/update
--b1_KyZbvbrSl55hdWoQf7uUOwdfF2oGjqnCyP6rqNmlA
Content-Type: text/plain; name="test.txt"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename=test.txt
to looks like
--b1_KyZbvbrSl55hdWoQf7uUOwdfF2oGjqnCyP6rqNmlA
Content-Type: text/plain; name="test.txt"; charset=utf-8
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename=test.txt
Content-ID: 20cca107-2625-49ce-9357-95254a59147f#127.0.0.1
so for the Content-Type header was added charset parameter and then added new header Content-ID
Any tips on that?
After further investigation it came up that
The addStringEmbeddedImage method lets you set a cid for the
attachment which will set that header for you. You can ignore the
"image" in the method name - it doesn't care what type of content you
attach really.
So in my case it will be
$mail->addStringEmbeddedImage(file_get_contents($file_name, FILE_USE_INCLUDE_PATH), $uuid, $file_name, 'base64', '', 'attachment');
Regarding adding charset parameter to the Content-Type boundary header
quoted-printable transfer encoding is ASCII 7bit safe, so the default
will work fine and it doesn't need an extra charset clause.
For transfer-encoding and charset
$mail->Encoding = 'quoted-printable';
$mail->CharSet = 'UTF-8';
For content-id check addEmbeddedImage method or try adding directly the header like this:
$mail->addCustomHeader('Content-ID', '20cca107-2625-49ce-9357-95254a59147f#127.0.0.1');
I'm using ServiceStack with the Razor plugin and returning response objects from my service methods. If the service uses a default view then the response is fine, but if I specify a View in the service method then the http response includes additional data surrounding the content.
Here's a test service class:
[DefaultView("TestView")]
public class TestService : RestServiceBase<Req>
{
public override object OnGet(Req request)
{
var response = new Req { Data = "Hello" };
if (string.IsNullOrEmpty(request.Data))
{
return response;
}
return new HttpResult(response) { View = "TestView" };
}
}
An example raw response including the additional content data looks like this:
HTTP/1.1 200 OK
Server: nginx/1.2.3
Date: Thu, 03 Jan 2013 12:46:33 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
X-Powered-By: ServiceStack/3.928 Unix/Mono
X-AspNet-Version: 4.0.30319
Cache-Control: private
Set-Cookie: ss-id=KvFQKAyOkkKMajEFeaLiKQ==; path=/
Set-Cookie: ss-pid=nrv3gwEL6EuRE9B8VpAWZA==; path=/; expires=Mon, 03 Jan 2033 12:43:57 GMT
b1
a4
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Test page</title>
</head>
<body>
<h1>Test page</h1>
<p>Hello</p>
</body>
</html>
0
0
They look like content length values and end markers. I guess I have something mis-configured, but don't know what. Any ideas?
Is there a Node.js library for generating multipart/form-data content in the following form?
------------------------------7a9cd2dc11c1
Content-Disposition: form-data; name="to"
destination#email.com
------------------------------7a9cd2dc11c1
Content-Disposition: form-data; name="from"
recipient#email.com
------------------------------7a9cd2dc11c1
Content-Disposition: form-data; name="subject"
subject line
------------------------------7a9cd2dc11c1
Content-Disposition: form-data; name="text"
This content does not matter.
------------------------------7a9cd2dc11c1--
fermata looks like it might be what you're looking for. From the github page:
fermata.json("http://example.com/some/action").post({
'Content-Type':"multipart/form-data"
}, {
fileField: form.input.file || {data:nodeBuffer, name:"", type:""}
}, callback)
request supports multipart/form-data or if you're just looking to create the content body, try form-data
I know this is old but I recently needed to generate a form's multipart/form-data body string and came across this thread.
I was unable to find any modules out there that did this in a simple way so I made my own module: https://github.com/kodie/form-data-body
You can use it like so:
const formDataBody = require('form-data-body')
// Specify form fields
const fields = {
name: 'My test post',
description: 'This is just a test post',
items: ['First Item', 'Second Item'],
// Files should be an object with the name, type, and data set to strings
image: {
name: 'hello.jpg',
type: 'image/jpeg',
data: binaryImageData
}
}
const boundary = formDataBody.generateBoundary()
const header = {
'Content-Type': `multipart/form-data; boundary=${boundary}`
}
const body = formDataBody(fields, boundary)
Example Output:
----------------------------071517909670537006900435
Content-Disposition: form-data; name="name"
My test post
----------------------------071517909670537006900435
Content-Disposition: form-data; name="description"
This is just a test post
----------------------------071517909670537006900435
Content-Disposition: form-data; name="items[]"
First Item
----------------------------071517909670537006900435
Content-Disposition: form-data; name="items[]"
Second Item
----------------------------071517909670537006900435
Content-Disposition: form-data; name="image"; filename="hello.jpg"
Content-Type: image/jpeg
[BINARY IMAGE DATA]
----------------------------071517909670537006900435--