How to Use GMAIL-API with Node.js Part-2
I hope you have successfully connected the API with your gmail account. If not read ‘How to Use Gmail-API with Node.js Part-1'
To begin with, create a new file createMail.js, and install nodemailer.
npm install nodemailer --saveNodemailer will help us to encode and create the mail body.
First, we import the libraries and then we create a class CreateMail in the createMail.js file and declare the class constructor. This constructor will take the following parameters and will be called whenever a new instance of the class is created.
const {google} = require('googleapis');
const mailComposer = require('nodemailer/lib/mail-composer');
class CreateMail{
constructor(auth, to, sub, body, task, attachmentSrc=[]){
this.me = 'Enter your email id.';
this.task = task;
this.auth = auth;
this.to = to;
this.sub = sub;
this.body = body;
this.gmail = google.gmail({version: 'v1', auth});
this.attachment = attachmentSrc;
}
}Note: All parameters here are strings, except auth and attachmentSrc, which are object and an array of strings respectively.
Now we create a makeBody function in CreateMail class which will create the mail body and encode it in base64 format.
makeBody(){
var arr = [];
for(var i=0;i<this.attachment.length;i++){
arr[i] = {
path: this.attachment[i],
encoding: 'base64'
}
}
//Mail Body is created.
if(this.attachment.length){
let mail = new mailComposer({
to: this.to,
text: this.body,
subject: this.sub,
textEncoding: "base64",
attachments: arr
});
}
else{
let mail = new mailComposer({
to: this.to,
text: this.body,
subject: this.sub,
textEncoding: "base64"
});
}
//Compiles and encodes the mail.
mail.compile().build((err, msg) => {
if (err){
return console.log('Error compiling email ' + error);
}
const encodedMessage = Buffer.from(msg)
.toString('base64')
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '');
if(this.task === 'mail'){
this.sendMail(encodedMessage);
}
else{
this.saveDraft(encodedMessage);
}
});
}We create a new array “arr” to store the attachments in encoded format.
If the user wants to send the mail, we call sendmail. Else we save the mail as a draft by calling the saveDraft function.
//Send the message to specified receiver.
sendMail(encodedMessage){
this.gmail.users.messages.send({
userId: this.me,
resource: {
raw: encodedMessage,
}
}, (err, result) => {
if(err){
return console.log('NODEMAILER - The API returned an error: ' + err);
}
console.log("NODEMAILER - Sending email reply from server:", result.data);
});
}
//Saves the draft.
saveDraft(encodedMessage){
this.gmail.users.drafts.create({
'userId': this.me,
'resource': {
'message': {
'raw': encodedMessage
}
}
})
}
The sendMail and saveDraft take the encodedMessage as parameter.
this.gmail.users.messages.send() sends a request object to the gmail server which either sends a message or throws an error.The request object has many properties, but we use only two for simplicity. userId stores the user’s gmail id and resource object stores the encoded message.
We now create our last two functions- to list and to delete drafts.
//Deletes the draft.
deleteDraft(id){
this.attachment.gmail.users.drafts.delete({
id: id,
userId: this.me
});
}
//Lists all drafts.
listAllDrafts(){
this.gmail.users.drafts.list({
userId: this.me
}, (err, res) => {
if(err){
console.log(err);
}
else{
console.log(res.data);
}
});
}The deleteDraft function will delete the mail with the id passed in as parameter.
So our final code should like something like this:
const {google} = require('googleapis');
const mailComposer = require('nodemailer/lib/mail-composer');
class CreateMail{
constructor(auth, to, sub, body, task, attachmentSrc){
this.me = 'Enter your email id.';
this.task = task;
this.auth = auth;
this.to = to;
this.sub = sub;
this.body = body;
this.gmail = google.gmail({version: 'v1', auth});
this.attatchment = attatchmentSrc;
}
//Creates the mail body and encodes it to base64 format.
makeBody(){
var arr = [];
for(var i=0;i<this.attachment.length;i++){
arr[i] = {
path: this.attachment[i],
encoding: 'base64'
}
}
let mail;
//Mail Body is created.
if(this.attachment.length){
mail = new mailComposer({
to: this.to,
text: this.body,
subject: this.sub,
textEncoding: "base64",
attachments: arr
});
}
else{
mail = new mailComposer({
to: this.to,
text: this.body,
subject: this.sub,
textEncoding: "base64"
});
}
//Compiles and encodes the mail.
mail.compile().build((err, msg) => {
if (err){
return console.log('Error compiling email ' + error);
}
const encodedMessage = Buffer.from(msg)
.toString('base64')
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '');
if(this.task === 'mail'){
this.sendMail(encodedMessage);
}
else{
this.saveDraft(encodedMessage);
}
});
}
//Send the message to specified receiver.
sendMail(encodedMessage){
this.gmail.users.messages.send({
userId: this.me,
resource: {
raw: encodedMessage,
}
}, (err, result) => {
if(err){
return console.log('NODEMAILER - The API returned an error: ' + err);
}
console.log("NODEMAILER - Sending email reply from server:", result.data);
});
}
//Saves the draft.
saveDraft(encodedMessage){
this.gmail.users.drafts.create({
'userId': this.me,
'resource': {
'message': {
'raw': encodedMessage
}
}
})
}
//Deletes the draft.
deleteDraft(id){
this.attachment.gmail.users.drafts.delete({
id: id,
userId: this.me
});
}
//Lists all drafts.
listAllDrafts(){
this.gmail.users.drafts.list({
userId: this.me
}, (err, res) => {
if(err){
console.log(err);
}
else{
console.log(res.data);
}
});
}
}
module.exports = CreateMail;We can now send emails and save drafts from our terminal!
If you want to test your application, simply import createMail.js in your index.js . Create a new instance of the class and then call makebody function.
To test the application, execute the command given below in your terminal
node index.jsGood Job!
See you in the final article!