I am having issues sending email via nodemailer - SMTP(from another host) on production
i uploaded my API on a server(Scaleway Dev), i'm using Ubuntu Bionic and while testing noticed it is not sending emails(which i need for verification of a user).
at first i thought the request isn't getting to the server, but when i tried logging in i got a "confirm your password" response, i check the mongoDB database and the user is there, but still no confirmation email.
I tried checking it on localhost, thinking it might be the dotenv dependency, but it works there, what gives?
node version on my server is 8.10.0
and on my personal computer 11.12.0
these are my dependencies
enter code here
"dependencies": {
"bcrypt": "^3.0.6",
"body-parse": "^0.1.0",
"client-sessions": "^0.8.0",
"connect": "^3.6.6",
"cookie-parser": "~1.4.4",
"cors": "^2.8.5",
"debug": "~2.6.9",
"dotenv": "^8.0.0",
"express": "~4.16.1",
"express-session": "^1.16.1",
"express-validator": "^5.3.1",
"http-errors": "~1.6.3",
"moment": "^2.24.0",
"mongoose": "^5.5.8",
"morgan": "~1.9.1",
"nodemailer": "^6.1.1",
"nodemon": "^1.19.0",
"passport": "^0.4.0",
"pug": "2.0.0-beta11",
"randomstring": "^1.1.5",
"session": "^0.1.0",
"session-mongoose": "^0.5.2"
}
these options used are specified by the host that i'm using
//this is my transporter constant
const transporter = nodemailer.createTransport({
host: '*different host from the server*',
port: 465,
secure: true,
auth: {
user: my used email(hardcoded),
pass: process.env.EMAILPASS
},
tls: {
rejectUnauthorized: false
}
});
//my email options
let mailOptions ={
from: '"Company Name <noreply#*different host DNS*>',
to: req.body.email,
subject: *subject*
html: `Email Content with confirmation token`
}
//emailing the message itself
transporter.sendMail(mailOptions, (err, info) => {
if(err){
return console.log(err);
}
console.log("message sent");
});
i'm using this email generator(https://generator.email/) for fast throwaway emails. the mailing starts after i save the user.
I'm perplexed as to what should i do... any and all help is appreciated
I have had issues with nodemailer in the past. I'm using mailgun (https://www.mailgun.com/) to send my emails. They offer 10,000 emails a month for free. Here is a code that works with mailgun:
dependencies:
"express": "4.16.4",
"config": "3.0.1",
"nodemailer": "5.1.1",
"nodemailer-mailgun-transport": "1.4.0"
code (it is wrapped inside an express router) :
const config = require('config');
const nodemailer = require('nodemailer');
const mg = require('nodemailer-mailgun-transport');
const express = require('express');
const router = express.Router();
router.post('/', async (req, res) => {
//the data has to be an array. It will send as many emails as the number of items in the array
var emailsList = ["test#test.com"];
emailsList[0].name = "Test Name";
var auth = {
auth: {
api_key: config.get('mailgunApiKey'),
domain: config.get('mailgunDomain')
}
};
transporter = nodemailer.createTransport(mg(auth)),
EmailTemplate = require('email-templates').EmailTemplate,
path = require('path'),
Promise = require('bluebird');
function sendEmail (obj) {
return transporter.sendMail(obj);
}
function loadTemplate (templateName, contexts) {
let template = new EmailTemplate(path.join(__dirname, '../templates', templateName));
return Promise.all(contexts.map((context) => {
return new Promise((resolve, reject) => {
template.render(context, (err, result) => {
if (err) reject(err);
else resolve({
email: result,
context,
});
});
});
}));
}
loadTemplate('dailyReferralEmail', emailsList).then((results) => {
return Promise.all(results.map((result) => {
sendEmail({
to: result.context.email,
from: 'Your Name <your-email#test.com>',
'h:Reply-To': 'your-email#test.com',
subject: result.email.subject,
html: result.email.html,
text: result.email.text,
});
}));
}).then(() => {
var response = {
text: "Email sent"
}
JSON.stringify(response);
res.status(200).send(response);
});
});
module.exports = router;
As a template generator, I'm using HBS. So you must have a templates folder in the root folder of your project, with this tree:
You can use your variables inside your email with {{ }}.
Inside html.hbs:
<p>Hello {{name}}</p>
Inside subject.hbs
Subject of your email
Inside text.hbs
Preview text of your email
Hope this helps!
Related
I am an absolute novice at Node.js. So, as I'm learning, I ran into this problem.
I am adding codes from backend for CRUD (This index.js may seem incomplete, because I faced the problem halfway and then started seeking the solution.)
package.json
{
"name": "backend",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "nodemon index.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.18.2",
"mysql": "^2.18.1",
"nodemon": "^2.0.20"
}
}
index.js
import express from 'express';
import mysql from "mysql";
const app = express();
const db = mysql.createConnection({
host: "localhost",
user: "root",
password: "akdkfjdkfj;a",
database: "online_sustainability_db"
});
app.use(express.json());
app.get("/", (req, res) =>{
res.json("Hello. You are connected to backend.");
});
app.get("/data", (req, res) =>{
const query = "SELECT * FROM online_sustainability_db.idea_proposers";
db.query(query, (err, data)=>{
if(err)
return res.json(err);
else
return res.json(data);
})
});
app.post("/data", (req, res)=>{
const q = "INSERT INTO idea_proposers (`last_name`, `first_name`, `account_no`, `github_repository_link`, `submission_id`) VALUES (?, ?, ?, ?, ?)";
const last_name = req.body.last_name;
const first_name = req.body.first_name;
const account_no = req.body.account_no;
const github_link = req.body.github_repository_link;
const submission_id = req.body.submission_id;
db.query(q, [last_name, first_name, account_no, github_link, submission_id], (err, data)=>{
if(err)
return res.json(err);
else
return res.json("Provided data were recorded successfully.");
});
});
app.listen(8800, ()=>{
console.log("Connected to backend!");
});
The following image is from postman application. This is the error I am getting. Please, help me fixing it.
This is the description of the table I am trying to post the data in.
I tried doing some syntactical change and running the code several times. Well, it didn't work. I even looked for resources online, but I couldn't find any similar.
Kindly select the JSON from Postman whenever you want to send the JSON data. currently, you're sending data as a text.
I am following Twilio's API for sending outbound messages.
I've followed their short code implementation using Nodejs.
Dependencies
"dependencies": {
"express": "^4.17.1",
"read-excel-file": "^4.0.6",
"twilio": "^3.0.0"
}
Code
const accountSid = '[account sid]';
const authToken = '[account authtoken]';
var client = require('twilio')(accountSid, authToken);
client.messages.create({
body: 'Hello from Node',
from: '[usa number]',
to: '[singapore number]'
})
.then((message) => console.log(message.sid));
i run the code with node index.js
but nothing comes out. I've tried changing vars to const and const to vars but nothing works.
Console shows nothing at all.
It looks like your promise is being rejected, at a .catch, to see what the error is. You can check to see if SMS Geographic permissions are set appropriately.
Something like:
const accountSid = '[account sid]';
const authToken = '[account authtoken]';
var client = require('twilio')(accountSid, authToken);
client.messages.create({
body: 'Hello from Node',
from: '[usa number]',
to: '[singapore number]'
})
.then((message) => console.log(message.sid))
.catch(err => console.log(err));
I have setup a firebase-function with nodemailer to grab the input from my
firebase-database connected to my contact form and email it to my email.
I have successfully deployed the function and can see the function showing up in my firebase console, however i do not receive any errors in the console nor see any logs or information in the function section of the console. And it just simply doesn't work right now.
This is the first time i am doing this, and i have looked at almost all other similar questions on SO but none of them have given me any clues as to what i am doing wrong.
This is my functions package.json:
{
"name": "functions",
"description": "Cloud Functions for Firebase",
"scripts": {
"lint": "eslint .",
"serve": "firebase serve --only functions",
"shell": "firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "8"
},
"dependencies": {
"firebase-admin": "~7.0.0",
"firebase-functions": "^2.3.0",
"nodemailer": "^6.1.1"
},
"devDependencies": {
"eslint-plugin-promise": "^4.0.1",
"firebase-functions-test": "^0.1.6"
},
"private": true
}
and this is the index.js code inside the functions-folder:
const functions = require("firebase-functions");
const admin = require("firebase-admin");
const nodemailer = require("nodemailer");
const gmailEmail = "k****l#gmail.com";
const gmailPassword = functions.config().gmail.pass;
admin.initializeApp();
var goMail = function(message) {
const transporter = nodemailer.createTransport({
service: "gmail",
auth: {
user: gmailEmail,
pass: gmailPassword
}
});
const mailOptions = {
from: gmailEmail, // sender address
to: "****l#gmail.com", // list of receivers
subject: "!", // Subject line
text: "!" + message, // plain text body
html: "!" + message // html body
};
const getDeliveryStatus = function(error, info) {
if (error) {
return console.log(error);
}
console.log("Message sent: %s", info.messageId);
};
transporter.sendMail(mailOptions, getDeliveryStatus);
};
exports.onDataAdded = functions.database
.ref("/messages/{messageId}")
.onCreate(function(snap, context) {
const createdData = snap.val();
var name = createdData.name;
var email = createdData.email;
var number = createdData.number;
var message = createdData.message;
goMail(name, email, number, message);
});
I'm not sure if my setup is wrong or if I'm doing something wrong with the nodemailer code in index.js.
Thanks for the help in advance.
As explained in the comment, since your Cloud Function is triggered by a background event, you must return a promise to indicate that the asynchronous tasks are finished.
So in the goMail function you should return the promise returned by the sendMail() method with:
...
return transporter.sendMail(mailOptions); //Remove the callback
And you should return, in the Cloud Function itself, the promise returned by the goMail function with:
return goMail(...)
when i use Twilio to send SMS it return
TypeError: self._qs.unescape is not a function
packaje.json :
"dependencies": {
"twilio": "^2.11.1",
"typescript": "^2.8.3",
},
"devDependencies": {
"#types/lodash": "^4.14.108",
"#types/node": "^9.6.6",
"#types/twilio": "0.0.9"
}
And My Code :
var twilio = require('twilio');
var ACCOUNT_SID = "***";
var AUTH_TOKEN = "***";
TwilioClient.messages.create({
body: 'Welcome ',
to: '+*****'
from: '+****' // From a valid Twilio number
}).then((message) => console.log(message.sid));
and returned :
Exception in delivering result of invoking 'Register': TypeError: self._qs.unescape is not a function
you need to initiate the twilio client and then use it :
var client = new twilio(ACCOUNT_SID, AUTH_TOKEN);
client.messages.create({
body: 'Welcome ',
to: '+*****'
from: '+****' // From a valid Twilio number
}).then((message) => console.log(message.sid));
In Meteor, I should connect to the Twilio API from the server.
When I requested from the client, I got the error.
https://developers.google.com/actions/reference/nodejs/ApiAiApp
I'd like to obtain an access token on Dialogflow by referring to the above official website, but the execution result of DialogflowApp.getUser() will be null.
Account linking is set up and on the client side it is certified with a Google Account.
AssistantToAgentDebug.assistantToAgentJson.user on the DEBUG tab of DialogFlow Simulator contains a value.
Also, I can get an access token by referring req.body.originalRequest.data.user.accessToken variable on the request body.
I'd like to obtain user information with DialogflowApp.getUser(),
Is there a mistake in the definition below?
*Using the Fullfilment, the logic is described in index.js.
*index.js
'use strict';
const App = require('actions-on-google').DialogflowApp;
exports.testMethod = (req, res) => {
// result is null
const app = new App({req, res});
let user = app.getUser();
console.log('User is ' + user);
// Access token can be acquired
let accessToken = req.body.originalRequest.data.user.accessToken;
console.log('accessToken is ' + accessToken);
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify({ 'speech': 'success!', 'displayText': 'success!' }));
};
*package.json
{
"name": "testMethod",
"engines": {
"node": "~4.2"
},
"dependencies": {
"actions-on-google": "^1.0.0",
"firebase-admin": "^4.2.1",
"firebase-functions": "^0.5.7"
}
}
The problem is that the call to the constructor expect the parameters to be named request and response. So you should write the line as
const app = new App({request:req, response:res});
You need to use getUser().accesToken like this:
let accestoken = app.getUser().accessToken;