Sendgrid change href of link - node.js

I am using Nodejs with Express and I am sending an email through Sendgrid, but Sendgrid is changing the href link
var emailText = '<!DOCTYPE html><html><head><meta charset="UTF-8"></head><body>Here</body></html>'
var from_email = new helper.Email('contact#test.com');
var to_email = new helper.Email('contact#test2.com');
var subject = 'Test';
var content = new helper.Content("text/html", emailText)
var mail = new helper.Mail(from_email, subject, to_email, content);
var request = sg.emptyRequest({
method: 'POST',
path: '/v3/mail/send',
body: mail.toJSON(),
});
sg.API(request, function(error, response) {
if (error) {
console.log('Error response received');
}
console.log(response.statusCode);
console.log(response.body);
console.log(response.headers);
});
When the email arrives the following link appears:
https://u4006412.ct.sendgrid.net/wf/click?upn=rOQ9fjZGp5r0JyNfoC02LbL.....
Could someone help me solve this problem?

I believe this is caused by the URL click-tracking feature of sendgrid. It will redirect to your intended resource, but does not look pretty. You can turn it off in sendgrid, but it will disable URL tracking on all emails sent by that account. If you are integrating with a 3rd-party link-tracker such as bit.ly or have your GA on lock-down, this may not bother you.
Here's more information on the feature in sendgrid: https://sendgrid.com/docs/User_Guide/Settings/tracking.html
Turn that off and see how your emails look.
UPDATE: Whitelabeling in Sendgrid
Sendgrid also has a whitelabeling feature, allowing you to serve URLs from one of your subdomains while still tracking clicks/opens through their servers. If you are concerned about the prettiness of your links or perceived security from a UX perspective, this may be the way to go.
Check out their overview of whitelabeling and
link whitelabeling doc pages. Be sure to follow sendgrid's recommendations on domain usage in emails. This ensures a high success rate on delivery.

You can off the Sendgrid tracking for one link specifically.
To do so, You have to add clicktracking="off" before your href tag
Do it like this
<a clicktracking="off" href='https://mysite/auth/'>My Site</a>

Similar to #israa-saifullah said, you can state clicktracking="off" directly in an html link, but if you're sending through the sg api, there is a trackingSettings property that you can set on an individual message where you can specify if you want click and open-tracking enabled. clickTracking is what re-writes your URL's, and you can specify it at the HTML or Text based level. For example this disables all tracking and therefore leaves the URL's in the email untouched.
const msg = {
to: TO_ADDRESSS,
from: {
name: FROM_NAME,
email: FROM_ADDRESSS,
},
subject: SUBJECT,
text: TEXT_VERSION,
html: HTML_VERSION,
trackingSettings: {
clickTracking: {
enable: false,
enableText: false
},
openTracking: {
enable: false
}
}
This is helpful if you don't want to override tracking at the account level (in the SG Dashboard), but just for a specific use case.
Documentation here.

It is possible to change through the sendgrid settings, access the path: settingns -> tracking -> click tracking -> disabled

Related

Slack reply to response_url with ephemeral message not working

I'm working on an interactive Slack app written in Node.js with Express. When the user clicks a button on an interactive message, I want to post an ephemeral message; however, the replies always appear publicly in the channel. Furthermore, whether or not I set the response_type, the original message with the interactive elements that the user clicked on disappears. My code looks like this:
const request = require('request');
app.post('/slack-interactivity', async function(req, res) {
const payload = JSON.parse(req.body.payload);
sendResponse(payload.response_url, 'you clicked');
res.send('received');
});
function sendResponse(responseUrl, response) {
request.post({url: responseUrl,
method: 'POST',
json: {
response_type: "ephemeral",
text: response}});
}
When I click on a button in an interactive slack message, I see "you clicked" written publicly to the channel, but I want it to be ephemeral.
Any ideas why this could be happening?
This isn't possible (as of 5/17/2019)
A message will retain its visibility for life. Meaning you can't go from in_channel to ephemeral (or vice versa).
You can include: replace_original: false and the ephemeral message will display.
Behind the scenes replace_original is acting like an update, not delete and create new message.
Your code defaults to replace_original: true which preforms an update and thus is not going to work.

Twilio Function to send VoiceMail or Recording to Email

Twilio Stuido does not provide a native way to email a recording therefore this needs to be coded. In this example, a voicemail has been taken of a users call. Now that we have the recording a Twilio Function is created (NodeJS) to send this recording to email.
In the sample code below the function is failing however there is no available debug tool inside the Twilio Console for dealing with functions. NodeJS is fairly new to us so this maybe easy for someone to spot.
Possible other errors may be however:
Incorrect gmail authentication (although the details are correct in terms of username and password, perhaps this is not how you configure google apps to send the email)
Inability to import or incorrectly importation of the nodemailer dependency into Twilio
Bad NodeJS skills
The input variables are:
attachment
{{widgets.Voicemail_Recording.RecordingUrl}}
- which contains the URL to the voicemail recording.
lang
- the language of the caller (based on IVR choices earlier).
phone_number
{{trigger.call.From}}
NodeJS Twilio Function
var mailer = require('nodemailer');
mailer.SMTP = {
host: 'smtp.gmail.com',
port:587,
use_authentication: true,
user: 'info#example.com',
pass: '*********'
};
exports.handler = function(context, event, callback) {
mailer.send_mail({
sender: event.phone_number + '<info#example.com>',
to: 'info#example.com',
subject: 'Voicemail (' + event.lang + ')',
body: 'mail content...',
attachments: [{'filename': event.attachment, 'content': data}]
}), function(err, success) {
if (err) {
}
}
};
Sam here from Twilio's support team - I just released a blog post that should help with this. It shows how to forward voicemails with Studio, Functions, and SendGrid. Check it out here: https://www.twilio.com/blog/forward-voicemail-recordings-to-email

Email send through nodemailer goes into spam for gmail

I am sending email through nodemailer it goes into inbox of gmail if i run from local server but goes into spam of gmail if i run script from microsoft azure server.
following is my script
var nodemailer = require('nodemailer');
var EmailTemplates = require('swig-email-templates');
var smtpConfig = {
service: 'smtp.office365.com',
host: 'smtp.office365.com',
port: 587,
starttls: {
enable: true
},
secureConnection: true,
auth: {
user: 'xxxxx#yyyy.com',
pass: 'zzzzzz'
}
}
var templates = new EmailTemplates();
var transporter = nodemailer.createTransport(smtpConfig);
var context = {
username:'Rajesh',
email:'xxxxx#gmail.com',
link : 'www.google.co.in'
};
templates.render('activate_email.html', context, function(err, html,text, subject) {
transporter.sendMail({
from: '"Product Name👥" <no-reply#xxxxx.com>', // sender address
to: 'xxxx#gmail.com',
subject: 'Account activation',
html: html,
text:text
});
});
The truth is there is no simple one line solutions for your problem :) There are numerous reasons why this can happen, and here are some of them:
Your host is marked as a spam - this happens if you have not verified your e-mail or you are sending too much e-mails from the same host. Shared hosting is commonly marked as such, and therefore mail server will regularly mark them as a spam
Your from field is different than the one you're allowed to use - as I see you're using smtp, there are strict rules for the mail you can send. Of course you can always send e-mail from mark#facebook.com, but since your SMTP's host is not facebook.com, your e-mail will pretty sure marked as spam
You can sign your e-mail in many various mails, assuring the servers that this e-mail is send from you and it has proper signature. Check online for the ways to do so.
While developing you have sent numerous alike e-mails - sending the very same "test" e-mail is a common reason for your e-mails to get blacklisted
There are emojis in your subject - that is not a 100% reason, but servers are often marking such e-mails as spams, especially in other fields (like from)
Unfortunately as I said there is no one real reason, there could be many of them. I hope this helps at least a little :)
in my case i needed to specify the form, the from need to be = to user mail
auth: {
user: "xxx#yyy.com",
pass: "password",
},
from: xxx#yyy.com,
Please get rid of the 👥 and try sending it again. I read in a article once that email clients don't like those icons because a lot of spammers are using them.
Try sending it to multiple gmail accounts. Other than that there's nothing wrong with the code. If you're on a shared hosting or local host it could also go into the junk folder. In that case you would have to look into sending the emails from a different IP, preferred in the same country as where you will send the emails to.
But first try to remove that icon!
PS. I would make this answer as a comment but I can't due to low rep.
For those who are still struggling for this problem. I suggest the following.
Make sure you add from field that matches with auth.user
let transporter = nodemailer.createTransport({
host: "smtp-mail.outlook.com",
secureConnection: false,
port: 587,
tls: {
ciphers: "SSLv3",
},
auth: {
user: <YOUR_EMAIL_ACCOUNT>,
pass: <YOUR_EMAIL_PASSWORD>,
},
from: <YOUR_EMAIL_ACCOUNT>,
});
Add text field describing your intent for the email in options payload
const mailOptions = {
from: `myCompany <mycompanyemail#gmail.com>`,
to: "recipient#gmail.com",
subject: "[MYCOMPANY] YOUR EMAIL VERIFICATION",
text: "Hello. This email is for your email verification.",
html: <h1>Hello</h1>,
};
If #1 or #2 doesn't solve your problem. Try using test-mailer and send email to their provided test email address. It will show you where your vulnerabilities are especially the part where you have to setup SPF, DKIM, and DMARC.
If you are using a custom domain setup SPF, DKIM, DMARC following this article.
Late to the party..
Try adding both HTML and Text Versions both in your emailConfig as below. That way the email will land up in the inbox. It worked for me.
var emailOptions = {
from: 'cxxxxxkxxxxx#xxxxx.com',
to: 'xxxx#xxxxxx.com',
cc:'sxxxxxxsh#xxxx.com, xxxa#xxx.com, aaaxxxx#xxxx.com',
bcc:'xxxxx.wrxxxk#xxxx.com',
subject: 'xxxxxxxxxx',
/* Adding HTML and Text Version, so the email will not land up in the Spam folder */
html: 'Hello Team! <br><br>Please find attached...<br><br>Thanks,<br>XXXXX',
text: 'Hello Team! <br><br>Please find attached...<br><br>Thanks,<br>XXXXX',
attachments: [{
// file on disk as an attachment, concatenating the file extension separately since NODE is not renaming the file properly with fs.renameSync
filename: finalFileNameWithoutExt + '.xlsx',
path: reportsLocationPathWithYearMonth + finalFileNameWithoutExt + '.xlsx' // stream this file
}]
};
HTML goes to junk, plain text doesn't

Google Docs embed answering form

I want to embed a form in an email that works both in a web browser and the gmail app, using google docs.
I have been able to embed it and use it in different browsers with the following code, but I can't use it in the app.
The problem is that I want the user to respond by ticking either Yes or No, and clicking an Accept button.
Could you please help me?
Thanks in advance
form.setRequireLogin(false);
var url = form.getPublishedUrl();
var response = UrlFetchApp.fetch(url);
var htmlBody = HtmlService.createHtmlOutput(response).getContent();
MailApp.sendEmail(responsableDirecto,
"Course request",
"",
{
name: 'Course request confirmation'+""+program+""+name,
htmlBody: htmlBody,
attachments: [documetoDatos],
});

Stripe module issues at Parse

I am developing a project which integrates Stripe + Parse for iOS. It uses web hooks and Cloud code via node js. Currently i am in need of implementing a couple of functions:
cancel user subscription with flag atPeriodEnd;
subscribe cancelled customer once again (named multiple subscriptions via Stripe docs).
As for the first one: I'm sending a request as follows in Parse's API -
Stripe.Customers.cancelSubscription(request.params.customerID, 1, null)
but the second parameter, i.e. atPeriodEnd remains 0 when i receive Stripe's response and my webhook catches request for cancelling user immediately. Also i have checked Stripe's dashboard to see parameters that i pass and it says 'No query parameters'. Hope you can help me with this one out.
Second one: as i mentioned earlier user needs to have ability to subscribe once again after cancellation. That means that i already have a valid customer saved at Stripe and all i need is to 'attach' to him a new subscription. There is a method for this at Stripe docs:
stripe.customers.createSubscription("cus_00000000000", { plan: "planName" }, function(err, subscription) {
});
But i can't find similar to this in Parse's API. Hope you can help with this one out.
Sorry if there are some mistakes or misunderstandings for you - feel free to ask, i will answer as much clear as i can. Thanks!
Here is a workaround to #1 - make an http call directly to the stripe endpoint using Parse.Cloud.httpRequest. (I agree that Stripe.Customers.cancelSubscription in the Parse cloud module does not seem to be working)
Parse.Cloud.define("cancel", function(request, response) {
var user = request.user;
var customerStripeId = user.get("stripeId");
var key = "<stripe_api_key>"
var url = "https://api.stripe.com/v1/customers/" + customerStripeId + "/subscription"
Parse.Cloud.httpRequest({
method: 'DELETE',
params: { at_period_end: true, key: key },
url: url,
success: function() {
response.success()
},
error: function(httpResponse) {
console.error('Delete failed with response code ' + httpResponse.status);
response.failure()
}
});
});

Resources