Issue with "from" field using gmail API in Node JS - node.js

I have a problem setting the author of a mail in the "from" field of the RFC2822 mail (here the detail).
The problem is that the author does not appear in the received mail. The "from" field I've set looks like this:
MyName: name.surname#gmail.com
But I also tried:
MyName <name.surname#gmail.com>
None of these work, in the received mail the name is still missing looking at the original mail.
This should work because using nodemailer (with Gmail) and the same value for "from" it works. Can someone explain me what's happening? How can I solve?
EDIT: I report the code I am using as asked in one comment.
I separated the call to the API from the part that generates the mail body, so the call is:
function gmailSend(auth, mail){
const gmail = google.gmail({version: 'v1', auth});
const b64mex=mail.b64enc();
return gmail.users.messages.send(
{auth: auth,
userId: 'me',
resource:
{raw: b64mex}
}
);
}
While the parameter "mail" is generated in this way:
function genMail(candidate, clerk_email, supervisor_email){
return new Mail({from: `MyName: name.surname#gmail.com`, to: candidate.email,
subject: "Test Mail", bcc: supervisor_email,
"reply-to": clerk_email}, genMessage(candidate));
}
Mail simply compose an object that has the properties given in its first parameter, while b64enc() puts all in a string respecting the RFC2822 and encodes it base64.
EDIT2: code for Mail class.
class Mail{
constructor(headers, body) {
if(!headers.to)
throw Error("Recipient missing");
if(headers.subject){
const b64subject=new Buffer(headers.subject).toString("base64")
.replace(/\+/g, '-').
replace(/\//g, '_');
headers.subject='=?utf-8?B?'+b64subject+"?=";
}
Object.assign(this, headers);
this.body = body;
}
b64enc(){
const fields = ["Content-Type: text/html; charset=\"UTF-8\"\n",
"MIME-Version: 1.0\n",
"Content-Transfer-Encoding: 7bit\n"];
for(const prop of Object.keys(this)){
if(prop!=="body")
fields.push(`${prop}: ${this[prop]}\n`);
}
fields.push("\n");
fields.push(this.body);
const str=fields.join('');
const encodedMail = new Buffer(str).toString("base64")
.replace(/\+/g, '-').
replace(/\//g, '_');
return encodedMail;
}
}
EDIT3: I add screenshots of desired and actual behaviour:
Desired behaviour, the hidden info are the sender's email and the receiver's one:
Actual behaviour. The difference is that here there is not "MyName".
What is shown in my email client of course is based on the content of "From:" in the plain email. In the first case it is "My name <email address>", in the second it is just "email address".

In order to show a name, and not just the email address, you can format the from field the following way:
from: '"MyName" <name.surname#gmail.com>'

Related

Missing part of content when automatic (crone) sending email by nodemailer

I have a strange problem. I made a small application in node.js, using nodemailer to send emails each day.
And it's working perfectly when I run it from the terminal (for testing).
But when I add a job to crontab, then emails are sent but there is missing some of the content inside.
This is my transporter conf:
// send mail with defined transport object
let info = await transporter.sendMail({
priority: 'high',
from: '"Example" <example#gmail.com>', // sender address
to: 'recip#gmail.com', // list of receivers
subject: 'Example title: '+currentDate, // Subject line
text: '', // plain text body
html: header + missing + carrierStatArr + ending,// html body
attachments: attachments
});
And code for variables to html field:
let carrierStatArr = [], attachments = [];
let header = `<h1>some text ${currentDate}</h1><div><i>some text</br>some text</i></div>`;
let missing = `<h3 style="color:red;">some text: <b>${missingArr}</b></h3>`;
for (let i in checkResultArr) {
let imgName = checkResultArr[i].file;
let correctedImgName = imgName.substring(0,16);
carrierStatArr.push(`<p>Some text <b>${checkResultArr[i].name}</b>,</br>
<span>Some text: <b>${checkResultArr[i].status}</b></span></br>
<span><img src="cid:${correctedImgName}" width="1000px"/></span>
</p>`);
}
//console.log(carrierStatArr);
attachments = checkResultArr.map((file)=>{
let pat = '/var/www/html/public_html/MM1_service/images/';
let fi = file.file;
let fit = fi.substring(0,16);
return {path: pat+file.file, cid: fit};
});
//console.log(attachments[0].path);
let ending = `<hr size="1" width="100%" color="gray"><p><i>some text</i></p>`;
Of course, there are all data in arrays. And as I wrote, when I run this code manually using terminal /node sendmail.js/ it works perfectly, email contains all the information's, text, and images.
But when the script is run automatically by the cron job, the email has only header, missing, and ending variables (and the content from arrays is there) but the rest: carrierStatArr, attachments are missing.
Why is that? Manually work, run by cron not exacly.
Note: I managed to solve my problem by using the 'node-cron' module instead of the system cron. The app is working correctly.
But still I'm curious, from an academic point, why that problem occurred.

SendGrid personalization when sending emails on N to N relationship

I'm trying to implement an email price alerts system. In my situation, one email can have multiple price alerts, thus, conflicting with SendGrid when sending the alert as it receives the following error:
message: 'Each email address in the personalization block should be ' +
'unique between to, cc, and bcc. We found the first duplicate ' +
'instance of [xxxxxxx#gmail.com] in the personalizations.0.to ' +
'field.',
field: 'personalizations.0',
help: 'http://sendgrid.com/docs/API_Reference/Web_API_v3/Mail/errors.html#message.recipient-errors'
I have not found anything that shows my use case. The best that I get is to send the same email to multiple different recipients such as: https://sendgrid.com/docs/for-developers/sending-email/personalizations/#sending-the-same-email-to-multiple-recipients
Is this something that can be achieved with SendGrid?!
My function:
function sendEmail (emailz, subject, body) {
const email = {
to: emailz,
from: 'salut#xxxxxxxxx.ro',
subject: subject,
text: body,
html: body
}
return sgMail.send(email)
.catch(error => {
console.error(error)
if (error.response) {
const {message, code, response} = error;
const {headers, body} = response;
console.error(body);
}
});
}
Actual email sending done:
try {
await sendEmail(
emailul,
'Alerta notificare pret!!!',
`Pretul produsului pe care il urmaresti este de ${pretulCurent} , sub alerta de pret setata de ${pretulDorit}. <br /> Produsul tau este: ${titlul} : ${link} `
)
} catch (e) {
await sendEmail('S-a produs o eroare', e.message)
throw e
}
Any help would be greatly appreciated. If this cannot be done using SendGrid, can you give me some pointers on other services where this situation might apply ?
Okay, if I understand you correctly, the problem here seems to be avoiding duplicates in your to email field. I suggest you check for duplicates before pushing to SendGrid (SendGrid won't do it for you) for each batch/job.
SendGrid accepts either an array of strings, or comma-delimited values, so you could try something like this:
var finalEmailul = [];
// for each email in the list, check - if it doesn't exist, push it in
if(finalEmailul.indexOf(emailul) < 0){
finalEmailul.push(emailul);
};
// then use 'finalEmailul' in your 'sendEmail' function
try {
await sendEmail(
finalEmailul, // <- use here. If you want it to be comma-delimited, use finalEmailul.join(",")
'Alerta notificare pret!!!',
`Pretul produsului pe care il urmaresti este de ${pretulCurent} , sub alerta de pret setata de ${pretulDorit}. <br /> Produsul tau este: ${titlul} : ${link} `
)
} catch (e) {
await sendEmail('S-a produs o eroare', e.message)
throw e
}

Telegram: Sen photo into a message without showing the photo link with Telegraf (NodeJs)

I'm on a channel that sends messages that contains a text, with a link (that link has not an image) and an image (tip product from amazon):
I tried with this code and it's similar:
bot.telegram.sendMessage('mychannel', `Hello https:/path/to/image.jpg`)
And it works it similar, but it remains the link. SO how can i put that way with image preview but not the link?
Thank you
One workaround(trick) would be to insert the link but use an empty character unicode (like from https://emptycharacter.com/)
Here is an example (I inserted the photo URL with an empty character)
some sample code to get you started:
const Telegraf = require("telegraf");
const bot = new Telegraf(" ... ");
const CHAT_ID = ... ;
function getHiddenLink(url, parse_mode = "markdown") {
const emptyChar = "‎"; // copied and pasted the char from https://emptycharacter.com/
switch (parse_mode) {
case "markdown":
return `[${emptyChar}](${url})`;
case "HTML":
return `${emptyChar}`;
default:
throw new Error("invalid parse_mode");
}
}
// Option 1: sending with MARKDOWN syntax
bot.telegram.sendMessage(
CHAT_ID,
`
some test text in markdown
${getHiddenLink("https://i.stack.imgur.com/TPKR5.png", "markdown")}
`,
{
parse_mode: "markdown",
}
);
// Another option: sending with HTML syntax
bot.telegram.sendMessage(
CHAT_ID,
`
some test text in HTML
${getHiddenLink("https://i.stack.imgur.com/TPKR5.png", "HTML")}
`,
{
parse_mode: "HTML",
}
);
Here we just create a new function getHiddenLink() that accepts the URL and parse_mode (HTML or markdown) and just craft a new URL representation with the empty character as the link-text and return it.
There is no way to send a preview without a link. You can try to have some by your own telegram account and you will see it is impossible.
Instead of preview, add some caption to photos.

Jenkins: how to set body content from a variable

I have a scripted pipeline. In one of my steps I want to send different mails based on test results. Here is how I do it now:
if (buildResult == 'SUCESSS'
def email_body="TEST_SUCESS.template"
else
def email_body="TEST_FAILURES.template"
emailext(
subject: "Job '${env.JOB_NAME} [${env.BUILD_NUMBER}] finished",
body: "${SCRIPT,template=$email_body}", // LINE A
recipientProviders: [[$class: 'DevelopersRecipientProvider']],
to: 'XXXX',
from: 'YYYY',
replyTo: 'ZZZZ',
mimeType: 'text/html',
)
I can't have Jenkins expand the value of the variable email_body. I've tried various approaches in the line A:
"${SCRIPT,template=$email_body}"
"${SCRIPT,template=${email_body}}"
'''${SCRIPT,template=$email_body}'''
'''${SCRIPT,template=${email_body}}'''
None of them works. All I get in the email is either:
Groovy Template file [$email_body] was not found in $JENKINS_HOME/email-templates.
or
${SCRIPT,template=$email_body}.
What is the correct way of setting email content if the email content is stored in a variable?
Try to use this example:
String subject = "${env.JOB_NAME} was " + currentBuild.result.toString();
String email_body="TEST_" + currentBuild.result.toString() + ".template"
String body = "SCRIPT,template=" + email_body;
String to="some_mail#mail.com"
String reply="ZZZ"
emailext(subject: subject, body: body, to: to, replyTo: reply);

node.js nodemailer subject issue

i'm using the nodemailer library to send emails to my users.
The problem is that some special charachter such us "è" or "à" are not visible.
Can i change the encoding of the subject? in the body is already working.
var mailOptionsUtente = {
from: 'my#email.it', // sender address
to: utente.email, // list of receivers
subject: "non è possibile", // Subject line
html: "HTML...."
};
i know you can add encoding option in your object.
See here
https://community.nodemailer.com/
You can add subject encoding options like that :
var subject = 'non è possibile';
var mail = {
...,
subject: {
prepared: true,
value: '=?UTF-8?B?'+new Buffer(subject).toString('base64')+'?='
},
...
};
source : https://github.com/nodemailer/nodemailer/issues/562

Resources