Failed sending mail through google api in nodejs - javascript

I'm trying to send an email through Google API.
I'm using googleapis for Google API access in node.js .
My issue is that when I try to send a simple mail with no attachments, I get the following error:
'raw' RFC822 payload message string or uploading message via /upload/* URL required
I didn't define in my request that there is an attachment and I don't see any error in the email addresses.
Please help.
My code:
var google = require('googleapis');
var gmailClass = google.gmail('v1');
var email_lines = [];
email_lines.push("From: \"Some Name Here\" <rootyadaim#gmail.com>");
email_lines.push("To: hanochg#gmail.com");
email_lines.push('Content-type: text/html;charset=iso-8859-1');
email_lines.push('MIME-Version: 1.0');
email_lines.push("Subject: New future subject here");
email_lines.push("");
email_lines.push("And the body text goes here");
email_lines.push("<b>And the bold text goes here</b>");
var email =email_lines.join("\r\n").trim();
var base64EncodedEmail = new Buffer(email).toString('base64');
gmailClass.users.messages.send({
auth: OAuth2Client,
userId: "me",
message:
{
raw: base64EncodedEmail
}
},
function(err, results){});

Changes were made to version 1.0.3 of the google api. Try using the following syntax:
gmailClass.users.messages.send({
auth: OAuth2Client,
userId: "me",
resource:
{
raw: base64EncodedEmail
}
}
Make sure that base64EncodedEmail is url safe. You can use the base64EncodedEmail.replace(/\+/g, '-').replace(/\//g, '_') code posted by mscdex. This syntax worked for v. 1.0.11

Related

Send email to a specific email using mailchimp

I know about the mail chimp JSON based API. However, I'm not sure if there is any way to use it to send an email to a specific recipient using javascript.
Any ideas on how to do this?
Following steps you have to take:
I assume you already created a mail template in mail chimp
I am using mandrill to send mail through mail chimp. Install node package manager mandrill-api
npm install mandrill-api
Call package in top of your code
var mandrill = require('mandrill-api/mandrill');
var mandrill_client = new mandrill.Mandrill('YOUR_API_KEY');
In your method define message variable
var message = {
"from_email": send_as_email,
"from_name": send_as_name,
"merge_language": "mailchimp",
"global_merge_vars": null
};
message.to = [{
"email":'SENDER_EMAIL',
"name":'SENDER_NAME',
"type": "to"
}];
message.subject ='SUBJECT OF MAIL';
mandrill_client.messages.sendTemplate({
"template_name":'NAME_OF_MAILCHIMP_TEMPLATE',
"template_content": null,
"message": message
}, function (result) {
//DO ON RESPONSE
}, function (e) {
//TRACE Your Error
});

Meteor.users.findOne() returns undefined but it's still working

I am gettin' into touch with meteor.js and I am quite confused about some things.
I wrote a new collection :
sendEmailAfterNotification = function(comment) {
var post = Posts.findOne(comment.postId);
if (comment.userId !== post.userId) {
Meteor.call('sendEmail',
Meteor.users.findOne(post.userId).emails[0].address,
'automailer#yourdomain.com',
comment.author + ' answered on your post : ' + post.title,
'random bodytext');
}
};
my meteor console output is totally fine I'll get :
I20160424-16:00:54.758(2)? ====== BEGIN MAIL #0 ======
I20160424-16:00:54.766(2)? (Mail not sent; to enable sending, set the MAIL_URL environment variable.)
I20160424-16:00:54.767(2)? MIME-Version: 1.0
I20160424-16:00:54.767(2)? From: automailer#yourdomain.com
I20160424-16:00:54.767(2)? To: test#testdomain.com
I20160424-16:00:54.767(2)? Subject: testuser answered on your post : foobar
I20160424-16:00:54.767(2)? Content-Type: text/plain; charset=utf-8
I20160424-16:00:54.767(2)? Content-Transfer-Encoding: quoted-printable
I20160424-16:00:54.767(2)?
I20160424-16:00:54.768(2)? random body text
I20160424-16:00:54.768(2)? ====== END MAIL #0 ======
but in my browser I still get an errorcode :
Exception while simulating the effect of invoking 'commentInsert' TypeError: Cannot read property 'emails' of undefined(…) TypeError: Cannot read property 'emails' of undefined
the function gets called here :
comments.js
Comments = new Mongo.Collection('comments');
Meteor.methods({
commentInsert: function(commentAttributes) {
check(this.userId, String);
check(commentAttributes, {
postId: String,
body: String
});
var user = Meteor.user();
var post = Posts.findOne(commentAttributes.postId);
if (!post)
throw new Meteor.Error('invalid-comment', 'You must comment on a post');
comment = _.extend(commentAttributes, {
userId: user._id,
author: user.username,
submitted: new Date()
});
// update the post with the number of comments
Posts.update(comment.postId, {$inc: {commentsCount: 1}});
// create the comment, save the id
comment._id = Comments.insert(comment);
// now create a notification, informing the user that there's been a comment
createCommentNotification(comment);
// send an email to the post owner - if it's not the owner
sendEmailAfterNotification(comment);
return comment._id;
}
});
Meteor.users.findOne(post.userId) doesn't work on the client, since the client only has the current user's data in Meteor.users collection. Make sure your server-side sendEmail is the one that queries Meteor.users, and not the client.
Meteor.users works on the client, just ensure you have published and subscribed to Meteor.users.find({},{}) manually.

How to send email using MailChimp API

I'm creating an app in nodejs to send an email using MailChimp. I've tried to use https://apidocs.mailchimp.com/sts/1.0/sendemail.func.php but changed it to use 3.0 api because 1.0 seems to no longer work (big surprise). I've setup my app with
var apiKey = '<<apiKey>>',
toEmail = '<<emailAddress>>',
toNames = '<<myName>>',
message = {
'html': 'Yo, this is the <b>html</b> portion',
'text': 'Yo, this is the *text* portion',
'subject': 'This is the subject',
'from_name': 'Me!',
'from_email': '',
'to_email': toEmail,
'to_name': toNames
},
tags = ['HelloWorld'],
params = {
'apikey': apiKey,
'message': message,
'track_opens': true,
'track_clicks': false,
'tags': tags
},
url = 'https://us13.api.mailchimp.com/3.0/SendEmail';
needle.post(url, params, function(err, headers) {
if (err) {
console.error(err);
}
console.log(headers);
}
});
I keep getting a 401 response (not authorized because I'm not sending the API key properly)
I have to use needle due to the constraints on the server.
There is no "SendEmail" endpoint in API v3.0. MailChimp's STS was a pre-cursor to its Mandrill transactional service and may only still work for user accounts that have existing STS campaigns. No new STS campaigns can be created. If you have a monthly, paid MailChimp account, you should look into Mandrill. If not, I've had good luck with Mailgun.
You should use HTTP Basic authentication in MailChimp API 3.0.
needle.get('https://<dc>.api.mailchimp.com/3.0/<endpoint>', { username: 'anystring', password: 'your_apikey' },
function(err, resp) {
// your code here...
});
EDIT
#TooMuchPete is right, the SendMail endpoint is not valid in MailChimp API v3.0. I didn't notice that and I've edited my answer.

"Error no label add or removes specified" when trying to modify labels using Gmail's Node.js API

I'm trying to modify the labels of emails in my inbox using gmail's Node.js API. My function to mark an email as read and star it is:
function markAsRead(auth, req, res)
{
var gmail = google.gmail('v1');
console.log(req.body.id);
gmail.users.messages.modify({
auth: auth,
id: req.body.id,
userId: 'me',
resouce:
{
"addLabelIds": [
"STARRED"
],
"removeLabelIds": [
"UNREAD"
]
}
}, function(err, response) {
if (err)
{
console.log('...The API returned an error: ' + err);
return;
}
console.log("Success???");
});
}
It gives an error saying No label add or removes specified. I've checked the email objects coming in and in their labelIds attributes "UNREAD" and "STARRED" appear so they're valid labelIds.
I seem to be doing what the docs for the API say is correct but it keeps giving that same error.
It looks good. I think it's just a typo. resouce should be resource.

Is it possible to create a meeting request for outlook with nodeJS?

I am developing a very basic calendar with Angular and Node and I haven't found any code on this.
Workflow is the following : create an event, input the recipient's e-mail address, validate the event.
This triggers an e-mail sent to the recipient. The mail should be in the outlook meeting request format (not an attached object).
This means that when received in outlook the meeting is automatically added in the calendar.
Is this possible? If yes is it possible with only javascript on Node side?
For those still looking for an answer, here's how I managed to get the perfect solution for me.
I used iCalToolkit to create a calendar object.
It's important to make sure all the relevant fields are set up (organizer and attendees with RSVP).
Initially I was using the Postmark API service to send my emails but this solution was only working by sending an ics.file attachment.
I switched to the Postmark SMTP service where you can embed the iCal data inside the message and for that I used nodemailer.
This is what it looks like :
var icalToolkit = require('ical-toolkit');
var postmark = require('postmark');
var client = new postmark.Client('xxxxxxxKeyxxxxxxxxxxxx');
var nodemailer = require('nodemailer');
var smtpTransport = require('nodemailer-smtp-transport');
//Create a iCal object
var builder = icalToolkit.createIcsFileBuilder();
builder.method = meeting.method;
//Add the event data
var icsFileContent = builder.toString();
var smtpOptions = {
host:'smtp.postmarkapp.com',
port: 2525,
secureConnection: true,
auth:{
user:'xxxxxxxKeyxxxxxxxxxxxx',
pass:'xxxxxxxPassxxxxxxxxxxx'
}
};
var transporter = nodemailer.createTransport(smtpTransport(smtpOptions));
var mailOptions = {
from: 'message#domain.com',
to: meeting.events[0].attendees[i].email,
subject: 'Meeting to attend',
html: "Anything here",
text: "Anything here",
alternatives: [{
contentType: 'text/calendar; charset="utf-8"; method=REQUEST',
content: icsFileContent.toString()
}]
};
//send mail with defined transport object
transporter.sendMail(mailOptions, function(error, info){
if(error){
console.log(error);
}
else{
console.log('Message sent: ' + info.response);
}
});
This sends a real meeting request with the Accept, decline and Reject button.
It's really unbelievable the amount of work you need to go through for such a trivial functionality and how all of this not well documented.
Hope this helps.
If you do not want to use smtp server approach in earlier accepted solution, you have Exchange focused solution available. Whats wrong in current accepted answer? it does not create a meeting in sender's Calendar, you do not have ownership of the meeting item for further modification by the sender Outlook/OWA.
here is code snippet in javascript using npm package ews-javascript-api
var ews = require("ews-javascript-api");
var credentials = require("../credentials");
ews.EwsLogging.DebugLogEnabled = false;
var exch = new ews.ExchangeService(ews.ExchangeVersion.Exchange2013);
exch.Credentials = new ews.ExchangeCredentials(credentials.userName, credentials.password);
exch.Url = new ews.Uri("https://outlook.office365.com/Ews/Exchange.asmx");
var appointment = new ews.Appointment(exch);
appointment.Subject = "Dentist Appointment";
appointment.Body = new ews.TextBody("The appointment is with Dr. Smith.");
appointment.Start = new ews.DateTime("20170502T130000");
appointment.End = appointment.Start.Add(1, "h");
appointment.Location = "Conf Room";
appointment.RequiredAttendees.Add("user1#constoso.com");
appointment.RequiredAttendees.Add("user2#constoso.com");
appointment.OptionalAttendees.Add("user3#constoso.com");
appointment.Save(ews.SendInvitationsMode.SendToAllAndSaveCopy).then(function () {
console.log("done - check email");
}, function (error) {
console.log(error);
});
Instead of using 'ical-generator', I used 'ical-toolkit' to build a calender invite event.
Using this, the invite directly gets appended in the email instead of the attached .ics file object.
Here is a sample code:
const icalToolkit = require("ical-toolkit");
//Create a builder
var builder = icalToolkit.createIcsFileBuilder();
builder.method = "REQUEST"; // The method of the request that you want, could be REQUEST, PUBLISH, etc
//Add events
builder.events.push({
start: new Date(2020, 09, 28, 10, 30),
end: new Date(2020, 09, 28, 12, 30),
timestamp: new Date(),
summary: "My Event",
uid: uuidv4(), // a random UUID
categories: [{ name: "MEETING" }],
attendees: [
{
rsvp: true,
name: "Akarsh ****",
email: "Akarsh **** <akarsh.***#abc.com>"
},
{
rsvp: true,
name: "**** RANA",
email: "**** RANA <****.rana1#abc.com>"
}
],
organizer: {
name: "A****a N****i",
email: "A****a N****i <a****a.r.n****i#abc.com>"
}
});
//Try to build
var icsFileContent = builder.toString();
//Check if there was an error (Only required if yu configured to return error, else error will be thrown.)
if (icsFileContent instanceof Error) {
console.log("Returned Error, you can also configure to throw errors!");
//handle error
}
var mailOptions = { // Set the values you want. In the alternative section, set the calender file
from: obj.from,
to: obj.to,
cc: obj.cc,
subject: result.email.subject,
html: result.email.html,
text: result.email.text,
alternatives: [
{
contentType: 'text/calendar; charset="utf-8"; method=REQUEST',
content: icsFileContent.toString()
}
]
}
//send mail with defined transport object
transporter.sendMail(mailOptions, function(error, info){
if(error){
console.log(error);
}
else{
console.log('Message sent: ' + info.response);
}
});
It should be possible as long as you can use SOAP in Node and also if you can use NTLM authentication for Exchange with Node. I believe there are modules for each.
I found this blog very helpful when designing a similar system using PHP
Please check the following sample:
const options = {
authProvider,
};
const client = Client.init(options);
const onlineMeeting = {
startDateTime: '2019-07-12T14:30:34.2444915-07:00',
endDateTime: '2019-07-12T15:00:34.2464912-07:00',
subject: 'User Token Meeting'
};
await client.api('/me/onlineMeetings')
.post(onlineMeeting);
More Information: https://learn.microsoft.com/en-us/graph/api/application-post-onlinemeetings?view=graph-rest-1.0&tabs=http

Categories