Cilj ovog blog posta je pokazati kako napraviti API za slanje emaila. To ću postići koristeći NodeJS, ExpressJS, Nodemailer i naravno Gmail.
Postavljanje projekta
Kreiram mapu za projekt i unutar nje pokrećem naredbu
1 |
$ npm init --yes |
i odmah nakon toga instaliram potrebne NPM pakete:
– Express.js:
$ npm install express --save
– Nodemailer:
$ npm install nodemailer--save
– bodyParser:
$ npm install body-parser -save
Struktura projekta prema package.json sada izgleda ovako:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
{ "name": "NodemailerAPI", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "Tomislav Stanković", "license": "ISC", "dependencies": { "body-parser": "^1.18.3", "express": "^4.16.3", "nodemailer": "^4.6.7" } } |
Sada imam sve spremno za kreiranje datoteke unutar koje će se nalaziti logika API-ja.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
'use strict'; var nodemailer = require('nodemailer'); var express = require('express'); var app = express(); var bodyParser = require('body-parser'); app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json()); var port = process.env.PORT || 8080; var apiRoutes = express.Router(); apiRoutes.get('/', function(req, res) { res.json({ message: 'API radi!' }); //ako je sve ispravno postavljeno kao odgovor dobijem ovu poruku }); app.use('/api', apiRoutes); app.listen(port); console.log('API je pokrenut na portu:' + ' ' + port); |
API sada mogu i pokrenuti te se uvjeriti da radi. Pokrećem ga naredbom u kojoj riječ “index” označava naziv .js datoteke.
1 |
$ node index |
To je mogla biti i npr. server.js datoteka. U tom bi slučaju API pokrenuo naredbom $ node server.
Na adresi http://localhost:8080/api mogu vidjeti da je API uspješno pokrenut.
Slanje testnog e-maila
Unutar datoteke index.js sada ću kreirati API za slanje e-maila.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
var transporter = nodemailer.createTransport('smtps://GmailKorisnickoIme:GmailLozinka@smtp.gmail.com'); apiRoutes.post('/posaljiEmail', function(req, res) { nodemailer.createTestAccount((err, account) => { var smtpTransport = nodemailer.createTransport({ host: "smtp.gmail.com", secureConnection: false, port: 587, auth: { user: "GmailKorisnickoIme", pass: "GmailLozinka" } }); let mailOptions = { from: '"NodemailerAPI" <demo@example.com>', // pošiljatelj to: '*s*a*k*@efos.hr, t*m*s*a*s*a*k*v*c*@gmail.com', // popis primatelja subject: 'Email poslam putem Nodemailera', // naslov text: 'Ovo je sadržaj maila.', // sadržaj poruke html: '<h2>Pozdrav!</h2><br><b>Ovo je formatiran sadržaj maila!</b>' // formatiran sadržaj poruke }; transporter.sendMail(mailOptions, (error, info) => { if (error) { return console.log(error); } console.log('E-mail poslan: %s', info.messageId); }); }); }); |
S obzirom na parametar secureConnection: false vrlo je važno da omogućim dopuštanje nesigurnijim aplikacijama da pristupe računu na adresi https://myaccount.google.com/security?pli=1
Jer ako to ne napravim dobit ću poruku o grešci što znači da e-mail neće biti poslan/primljen. Ovaj dio mi je zadavao najviše problema prije dvije godine kada sam prvi put radio Nodemailer API. U pitanju je bila funkcionalnost vezana uz resetiranje lozinke.
Ako sada putem Postmana pokrenem POST zahtjev na adresu http://localhost:8080/api/posaljiEmail vrlo brzo će mi stići e-mail.
Zašto se u slici iznad kao adresa primatelja nalazi drugačija adresa od one navedene gore u API-ju? To je zbog postavki unutar Gmaila gdje je navedeno da je adresa k*n*a*t@tomislavstankovic.com zadana adresa pošiljatelja. S obzirom da ovdje koristim Gmail kao servis za slanje e-maila jasno je da će on uzeti te zadane postavke.
E-mail sa “pravim” podacima
U gornjem sam se primjeru uvjerio da moj Nodemailer API uredno radi, a sada želim imati mogućnost određivanja na koju adresu i koji sadržaj želim poslati.
API sada izgleda ovako:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
apiRoutes.post('/posaljiEmail', function(req, res) { if(req.body.emailPrimatelj == "" || req.body.naslov == "" || req.body.poruka == ""){ return false; } else { nodemailer.createTestAccount((err, account) => { var smtpTransport = nodemailer.createTransport({ host: "smtp.gmail.com", secureConnection: false, port: 587, auth: { user: "GmailKorisnickoIme", pass: "GmailLozinka" } }); let mailOptions = { from: '"NodemailerAPI" <demo@example.com>', // pošiljatelj to: req.body.emailPrimatelj, // popis primatelja subject: req.body.naslov, // naslov text: req.body.poruka, // sadržaj poruke html: '<b>' + req.body.poruka + '</b>' // formatiran sadržaj poruke }; transporter.sendMail(mailOptions, (error, info) => { if (error) { res.json({ poruka: "Nisu uneseni potrebni podaci! E-mail nije poslan!", greska: error, status: false }); return console.log(error); } else { return console.log(info); } console.log('E-mail poslan: %s', info.messageId); }); }); } }); |
Ovdje se može vidjeti da podatke šaljem kroz req.body i upravo je to razlog zbog kojeg koristim body-parser. U slučaju da nisam koristio body-parser dobio bi sljedeću grešku.
Također, ako ne unesem sve potrebne podatke body-parser neće imati s čime raditi i opet ću dobiti grešku. U ovom slučaju nisam poslao e-mail adresu primatelja.
Nakon što unesem sve potrebne podatke, body-parser će odraditi svoje i e-mail će biti uspješno poslan/primljen.