I have a problem.
I am developing an API with Node and the express framework to send transactional email using Mandril.
I download the powerdrill library to call the Mandrill API.
Everything is working fine, the emails are being sent ok, except for the problem that the request in the post is saving.
For example, if I call the API once I will send one email, and if I send a second one I will send 2 emails (the first one that I sent and the new one), and if I call the API once again I will send 3 email (the first 2 and the new one).
As you can see I sent 1 email using the request welcome. In the second one I called other request called submittedApplication but when I call the API using POSTMAN 2 emails were sent 1.-the new one and 2.- the first one again.
Does anyone know why the request is saving?
var express = require('express'),
router = express.Router(),
config = require('config'),
Message = require('powerdrill').Message;
var message = new Message();
router.get('/',function(req,res){
res.send('test ok Mandrillllll');
})
router.post('/welcomeGorn',function(req,res){
console.log(req.body);
message.apiKey(config.mandrillKey)
.subject(req.body.subject)
.template(req.body.template)
.from(config.mandrilEmail)
.to(req.body.to)
.tag('complex')
.globalMergeVar('VERIFY_EMAIL',req.body.linkVefifyEmail)
.send(function(err, resp) {
//console.log(resp);
res.send(resp).end();
});
});
router.post('/submittedApplication',function(req,res){
console.log(req.body);
message.apiKey(config.mandrillKey)
.subject(req.body.subject)
.template(req.body.template)
.from(config.mandrilEmail)
.to(req.body.to)
.tag('complex')
.globalMergeVar('RECRUITER_NAME',req.body.recruiterName)
.globalMergeVar('RECRUITER_EXTENSION',req.body.recruiterExtension)
.globalMergeVar('RECRUITER_EMAIL',req.body.recruiterEmail)
.send(function(err, resp) {
//console.log(resp);
res.send(resp);
});
});
module.exports = router;
The console is showing me this warning:
Powerdrill: Attempting to add the same email twice. Using data from first instance
You can find this warning here
I think the problem is message variable is saving all information and sending all together every time. Try to initialize it at the beginning of every method:
router.post('/welcomeGorn',function(req,res){
var message = new Message();
Related
I create router from mailgun to forward emails to my website endpoint www.example.com/messages
and I received emails successfully when it only text but when i attach file to this email, I don't receive any thing and the request body is empty
export const incomingEmails = async (req, res) => {
const from = req.body.from.split('<')[0].trim();
const sender = req.body.sender;
const recipient = req.body.recipient;
const subject = req.body.subject;
const html = req.body['stripped-html'];
try {
const incomingEmail = new Support({
from,
sender,
recipient,
subject,
html
})
await incomingEmail.save();
res.sendStatus(200)
} catch (error) {
res.status(500)
next(new Error('something went wrong'))
}}
i'm using url encoded middle ware
app.use(express.urlencoded())
note the stack I use is node and express at at backend
I ran into the same issue and I figured out why. I used the forward method to receive emails on my backend. The forward method only works when there is no attachment. With attachments, Mailgun will return an empty body because Mailgun has to first store the attachments, which is asynchronous.
In order to solve this issue, you have to use the store method instead of the forward method:
store(notification endpoint)
Stores the message temporarily (for up to 3 days) on Mailgun’s servers
so that you can retrieve it later. This is helpful for large
attachments that may cause time-outs or if you just want to retrieve
them later to reduce the frequency of hits on your server.
You have to edit your route in the Mailgun web app: go under "Receiving" in the menu and then edit your existing route.
Instead of entering:
forward("http://example.com/callback")
You enter:
store(notify="http://example.com/callback")
I'm trying to build a real-time program where users can set a marker on a Google Map and others who are connected can get that same marker. Everything seems to work fine except that after a few minutes, the server side is submitting the data a second time.
To clarify: client sets a marker on the map, the marker is sent to the server, running Node JS with Express JS, in JSON format. The server returns the data to all connected clients. Minutes later, the server sends the same data it received once more, causing a "ERR_EMPTY_RESPONSE" client-side on the last line of example "Client code".
Client code:
var data = new Array();
data.push({lat: Gmap.markers[0].lat, lng: Gmap.markers[0].lng});
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "/marker", true);
xhttp.setRequestHeader('Content-type', 'application/json; charset=UTF-8');
xhttp.send(JSON.stringify(data));
Server-side:
var app = express():
app.post('/marker', function(req,res){
io.emit('marker', req.body);
})
Anyone have any idea of whats going on?
You need to send a response to the http request. If you don't, the browser will time it out and may attempt to retry.
var app = express():
app.post('/marker', function(req,res){
io.emit('marker', req.body);
res.send("ok"); // <== Send a response to the http request here
})
I am implementing OAuth Google Sign in using backend (written in node.js, express framework at Heroku). Front end is Android and it sends the token id to the server just fine. And server receives the token id correctly.
Here is the code (which is ripped off straight from Google Documents)
var auth = new GoogleAuth;
var client = new auth.OAuth2(CLIENT_ID, '', '');
client.verifyIdToken(
token,
CLIENT_ID,
// Or, if multiple clients access the backend:
//[CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3],
function(e, login) {
var payload = login.getPayload();
var userid = payload['sub'];
// If request specified a G Suite domain:
//var domain = payload['hd'];
});
But at times login in undefined. Its so strange that this problem occurs 1/10 rather than for every try so that I am not able to track the source of issue. For every other 9/10 it works just fine.
Any suggestions on how to solve this?
The problem in your code is that you are not checking if your callback get's any error.
The standard way in node.js to use a callback function is using two parameters - error is the first, the actual (success) returned data is the second, and the convention is that if an error exists - you should address it, and you're not gauranteed to get the data, and if everything went well- error will be null and you'll get your data.
So in your code, you are not checking that there's an error (and like you say, not always there's one).
Should be something like:
function(e, login) {
if (e) {
// handle error here
return; // don't continue, you don't have login
}
// if we got here, login is defined
var payload = login.getPayload();
var userid = payload['sub'];
// If request specified a G Suite domain:
//var domain = payload['hd'];
});
The first parameter to the callback function is an error that needs to handled.
function(error, login) {
if (error) return console.error(error)
var payload = login.getPayload();
var userid = payload['sub'];
// If request specified a G Suite domain:
//var domain = payload['hd'];
});
I'm trying to send a message to GCM server to forward to another phone. The request keeps saying 400. I've checked the code close to a hundred times, but I'll put it up just in case. I also have changed the registration token parameter to registration_id and various others, along with changing the data to arrays etc. Just to be clear that the API key and Registration ID work, I can get a push notification from this Web site:
http://demo.androidhive.info/gcm_chat/push_test.php
Here's the code:
var gcm = require('node-gcm');
var gcmSender = new gcm.Sender('A......1234568AAA'); //my api key
var GCMmessage = new gcm.Message();
GCMmessage.addData("message", message);
GCMmessage.addData("from", from);
GCMmessage.addNotification('title', 'Alert!!!');
GCMmessage.addNotification('body', 'Abnormal data access');
GCMmessage.addNotification('icon', 'ic_launcher');
var regtoken = response.GCM.RegID; //data returned from another function
//Gives the RegID for a specific user
gcmSender.send(GCMmessage, {"to" : regtoken}, function(err, gcmResponse) {
if(err){
console.log(err);
} else {
console.log(gcmResponse);
console.log("message sent");
}
});
Ok it seems that it is best to send your gcm message directly using an npm module like 'request' or something similar. When I sent a message using that I received a very detailed error message telling me that 'from' is a reserved word. I'm not sure if that was the whole issue, but having a detailed error message made the code modification pretty easy.
I have a server in node.js which handles registration from users.
When someone attempts to register I first check if the introduced email already exists in my database, and if not I send a response back saying that that email has already been used.
The problem is that when I send a response with response.write() when the browser receives the response it replaces all the webpage by the response text, and what I want is to use that response to display a message next to the form in the registration page.
I also want to get the response with a Dart event listener so that the client knows that the email is in use and can display the message. My code for making the HTTP request with Dart is the following:
signupSubmit.onClick.listen((e) {
var req = new HttpRequest();
req.onReadyStateChange.listen((e) {
if (req.readyState == HttpRequest.DONE) {
print('Data submitted!');
}
});
req.open('POST', signupForm.action);
req.send(JSON.encode(serializeForm(signupForm)));
});
serializeForm(FormElement form) {
var data = {};
form.querySelectorAll('input,select').forEach((Element el) {
if (el is InputElement)
data[el.name] = el.value;
});
return data;
}
So how can I send a response that I can process in the client?
And how can I get the server response with Dart?
The signupSubmit click seems to submit its <form>. You can block the default form submission with :
signupForm.onSubmit.listen((e) => e.preventDefault());