3

is there a way to send an email via Mailgun with html page as its content that is longer than ~2000 characters? I have this code, that works perfectly for short html as I believe it is sent in URL address:

var obj = $.request.body.asString();    
var req = new $.web.WebRequest($.net.http.POST, "/messages");
        req.headers.set('Content-Type', encodeURIComponent("application/x-www-form-urlencoded"));

        req.parameters.set("domain", "mailgundomain.com");
        req.parameters.set("from", "me@mailgundomain.com");
        req.parameters.set("to", 'to@email.com');
        req.parameters.set("subject", "subject");
        req.parameters.set("html", obj); //email content

In the code above I receive the file and save it to 'org' variable and then send it to mail. What I need is to probably get my "too large" .html file to the body and then show it as a content of the email. As you probably can see, I'm quite new in .xsjs so the more detailed answer the better. If you need any more info, feel free to ask. Thank you.

Edit1: I should add that when I try to send a larger file, the response I get is "414 Request-URI Too Large".

Tomalak
  • 332,285
  • 67
  • 532
  • 628

1 Answers1

2

EDIT

This seems to be the right approach, jointly figured out by the OP and myself:

var obj = $.request.body.asString();    
var req = new $.web.WebRequest($.net.http.POST, "/messages");

// request headers
req.headers.set('Content-Type', "application/x-www-form-urlencoded");

// request URL parameters
req.parameters.set("domain", "mailgundomain.com");
req.parameters.set("from", "me@mailgundomain.com");
req.parameters.set("to", 'to@email.com');
req.parameters.set("subject", "subject");

// request body
req.setBody(encodeURIComponent(message));

The $.web.WebRequest class sends everything you set in the .parameters collection as an URL parameter, even if the request method is POST. This is perfectly all-right, POST requests may have URL parameters. However, URLs are length-limited, as you have noticed.

The body of a POST request is not length-limited, but you have to do the proper content encoding on your own. The body of a application/x-www-form-urlencoded type request follows the same rules as the URL - key=value pairs separated by & characters.

var obj = $.request.body.asString();    
var req = new $.web.WebRequest($.net.http.POST, "/messages");

req.headers.set('Content-Type', "application/x-www-form-urlencoded");

var message = {
    domain: "mailgundomain.com",
    from: "me@mailgundomain.com",
    to: "to@email.com",
    subject: "subject",
    html: obj
};

req.setBody(urlEncode(message));

where urlEncodedFormat() is a little helper function:

function urlEncode(obj) {
    return Object.keys(obj).map(function (key) {
        return encodeURIComponent(key) + "=" + encodeURIComponent(obj[key]);
    }).join("&");
}

Turning objects into an URL-encoded string is a pretty common operation. It's likely that one of the libraries you use already contains a function that does that.

While the above function is is probably correct (there might be edge cases with undefined or null values), it's preferable not to use a hand-rolled variant. Spend some time looking for the right function in your libraries.

Maybe WebRequest already does the right thing on its own, I have no way to test it, though. Try setting the message object as the body directly:

req.setBody(message);
Tomalak
  • 332,285
  • 67
  • 532
  • 628
  • Now I get " 'from' parameter is missing". But the rest looks ok so far, thanks for the reply! – Martin Mareš Jan 14 '16 at 14:18
  • I don't know enough about mailgun to put my finger on it, my answer was based on my knowledge how web servers and HTTP requests work in general. My expectation was that an API end point that accepts POST requests is able to deal with a request body. The [official docs](https://documentation.mailgun.com/api-sending.html#sending) aren't helping either, unfortunately. – Tomalak Jan 14 '16 at 14:28
  • the whole message I get is { "message": "'from' parameter is missing" } – Martin Mareš Jan 14 '16 at 14:29
  • Yes, apparently the server expects that parameter to be transferred in the URL and not the body. You can try to debug this incrementally by putting back any parameter you get this error message for, one at a time until the error message disappears (or until the system forces you to send the message text as an URL parameter, at which point I would be out of ideas.) – Tomalak Jan 14 '16 at 14:49
  • I did exactly that and at some point I got " 'from' parameter is not a valid address. please check documentation". But then when I added more parameters back to the url, I got the previous message again. – Martin Mareš Jan 14 '16 at 15:16
  • But maybe it was only my mistake that I corrected without knowing. – Martin Mareš Jan 14 '16 at 15:18
  • For kicks, try another Ajax library. Just include jQuery in your page and do `$.post(url, message)` with the message object as defined above. Maybe it's a peculiarity of `$.web.WebRequest`. – Tomalak Jan 14 '16 at 15:25
  • 1
    Finally I got it working! I used the solution from your answer only with `req.setBody(urlEncode(message));` instead of `req.setBody(body, urlEncode(message));`. Thank you very much for your help! :) – Martin Mareš Jan 15 '16 at 09:22
  • @Martin m) That's what I meant to write all along. Glad you figured it out, I totally did not see this mistake. – Tomalak Jan 15 '16 at 09:49