Mailgun in .xsjs - javascript

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".

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);

Related

Asana API - upload files using Ajax

I have a project that requires file uploads into Asana. I would like to be able to do this through Asana's API if possible. I have been able to successfully create tasks in Asana using Ajax Post requests. Is there anyway to use an Ajax Post request to upload a file to an Asana task? I would like to be able to upload files straight from an HTML FileUplaod Object. Does anyone know if this is possible?
I have tried Posting an JSON object like this to the attachments API, but this did not work.
https://app.asana.com/api/1.0/tasks/{taskID}/attachments
{
"parent": 1337,
"download_url": "https://www.dropbox.com/s/1234567890abcdef/Screenshot.png?dl=1",
}
I also don't want to post using a url, I want to post directly from the FileUpload object, if possible.
The short answer is to check out this other stack overflow question, which has a pretty good description of how to pull this off. sending a file as multipart through xmlHttpRequest
The long answer is this:
Uploading files has a different "feel" than most of the rest of our API, because the attachments endpoint expects to take content of Content-Type: multipart/form-data. There are several main things you have to get just right for this to work:
You have to set that Content-Type request header to multipart/form-data and to also in that header set the key boundary to be a unique, preferably long boundary to delimit the file, let's use 1z2x3c4v5b for this example.
You start the upload's body with 2 dashes and the boundary, i.e. --1z2x3c4v5b, followed by a newline
Still in the upload body, after the delimiter you have to provide some "headers" specifying Content-Disposition and Content-Type correctly for the file (i.e. what type of image it is, what its name is, that sort of thing)
2 newlines
The raw bytes of the file
2 newlines
2 dashes, the delimiter, and 2 final dashes, i.e. --1z2x3c4v5b--
Please note how all these features come together in the example in our Attachments documentation. This song-and-dance, which has to be done just right is what the author of that other SO post meant with "XHR will take care about proper headers and request body encoding". You can attempt to pull this off yourself, but I would recommend the approach they outline because it's by far the easiest.
I was able to solve this using the following code.
function addAttachment(taskID)
{
var data = new FormData();
data.append("file", document.getElementById("fileUploader").files[0]);
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});
xhr.open("POST", "https://app.asana.com/api/1.0/tasks/"+taskID+"/attachments");
xhr.setRequestHeader("authorization", "Bearer <access-token>");
xhr.send(data);
}

Accessing a Javascript variable inside an HTML file

I'm doing a little bit of reverse engineering on the Rapportive API in Gmail.
I make this request
import requests
url ='https://api.linkedin.com/uas/js/xdrpc.html'
r = requests.get(url)
print r.text
The response is an empty HTML file that has a lot of Javascript in it. On line 3661, it sets the RequestHeader for the subsequent call to Rapportive:
ak.setRequestHeader("oauth_token", ae);
Is there a way I can request that page and then return ae?
I think you can try:
Get the page as you already does;
Remove all non-javascript elements from the response page;
Prepend a javascript (described below) in the page's javascript to override some code;
Execute it with eval('<code>');
Check if the token has been set correctly;
I'm proposing the following code to override the XMLHttpRequest.setRequestHeader functionality to be able to get the token:
// this will keep the token
var headerToken;
// create a backup method
XMLHttpRequest.prototype.setRequestHeaderBkp =
XMLHttpRequest.prototype.setRequestHeader;
// override the "setRequestHeader" method
XMLHttpRequest.prototype.setRequestHeader = function(key, val)
{
if ('oauth_token' === key)
headerToken = val;
this.setRequestHeaderBkp(key, val);
}
If you are just interested in retrieving the token can't you just do a regex match:
var str = '<script>var a = 1;...ak.setRequestHeader("oauth_token", ae);...</script>';
var token = str.match(/setRequestHeader\("oauth_token",\s*([^)]+)/)[1];
Although this assumes ae is the actual string value. If it's a variable this approach wouldn't work as easily.
Edit: If it's a variable you could do something like:
str.replace(/\w+\.setRequestHeader\([^,]+,\s*([^)]+)\s*\);/, 'oauthToken = \1';
Before running the JavaScript returned from the page, then the global oauthToken (notice the missing 'var') will contain the value of the token, assuming the the evaluation of the code is run in the same scope as the caller.

Why won't this POST request send a JSON string to the server?

I'm using Sinatra. I've got a button that sends a JSON-formatted string to the server by making a POST request. Only problem is, the JSON string isn't getting to the server.
Here's index.erb:
<input id="post-button" type="button" value="Send POST request">
Here's script.js:
window.onload = function(){
var btn = document.getElementById('post-button');
btn.onclick = function(){
var req = new XMLHttpRequest();
var reqObj = {
name: 'Joe',
age: '100'
};
var reqJSON = JSON.stringify(reqObj);
req.open('POST','/post_target',true);
req.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
req.send(reqJSON);
}
}
And finally, main.rb:
get '/' do
erb :index
end
post '/post_target' do
p params
end
When I click the button and check Firebug, I see that the browser sent a POST request. But when I check the Ruby console, it prints {} for params. If it worked right, I guess params would show a JSON object in string form, along with whatever else it would show.
I'm running Sinatra on my machine, at address http://localhost:4567.
What am I doing wrong? If I need to do the request with jQuery, I can do that, but can it be done with "vanilla" JavaScript?
"params" is most likely looking for URL encoded query string values. You want the Body content of the post, not the params.
See How to parse JSON request body in Sinatra just once and expose it to all routes?
You need to parse the JSON body:
parsed_params = JSON.parse( request.body.read, symbolize_names:true )
Alex Hill is right. And the the post he mentioned show one way to solve it.
An other way is to use rack/contrib:
require it:
require 'rack'
require 'rack/contrib'
add the middleware
use Rack::PostBodyContentTypeParser
source: http://jaywiggins.com/2010/03/using-rack-middleware-to-parse-json/

I need some assistance with PHP and updating the URL after a "?"

Hi so I have a project for class that is a mix of PHP, HTML, and javascript/Ajax.
One of the requirements is "Execute program.php on server passing it the N/V pairs following the "?" symbol." How do I do this?
First off.. I don't know what NV pairs are and the reading links we were given say nothing about them.. I Googled "Php nv pairs" and literally nothing relative comes up.
I did an in-class activity that upon clicking a button, the url would update and add stuff after the "?" but of course that same code isn't doing it anymore. My professor is terrible at explaining anything and leaves us to follow his typo instructions that aren't even complete..
Here's the code we were given with his comments trying to explain what to do:
// startgame function
// sart button pressed check fields, if OK send to PHP via get request
function startgame(){
//Create the XMLHttpRequest Object
var xmlhttp;
// error handling
if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
try {
xmlhttp = new XMLHttpRequest();
} catch (e) {
xmlhttp = false;
}
}
http = xmlhttp;
// The PHP server script, called with N/V pair with GET request
// Using get request the NV pairs follow "?"
// execute program.php on server passing it the n/v pairs
// that follow the "?"
var url = "program.php?player1name=";
// for this example, only pass to PHP games played
// "&" separates n/v pairs
// player1name is name of algorithm player 1 is using
player1name = document.JForm.p1name.value;
player2name = document.JForm.p2name.value;
gamesplayed = document.JForm.gamesplayed.value;
sdata = url+player1name+"&gamesplayed="+gamesplayed;
// for a "real" solution, pass more data to PHP about state of game
// send get request to server with n/v pairs of screen data
http.open("GET",sdata, true);
// register with server what function to return data
http.onreadystatechange = handleHttpResponse;
// send request to server
http.send(null);
}
Anything will help, thanks!
NV apis means "Name/Value pairs". Basically, in the terms you will be using them in, it is a key connected to its value with an equal sign. For example: username=johnconde. username is the key and johnconde is the value. An example more closely related to your code would be gamesplayed=20. gamesplayed is the key and 20 is the value.
Name/value pairs are commonly found in query strings and it looks like that's what you need to do with your code. You need to build a query string comprised of name/value pairs containing the values you need for your PHP script to do whatever it is it needs to do. It looks like the code already does this and you just need to build the form necessary for this JavaScript to work.

Passing "#" hash symbol in request parameter of url not working in Firefox

I am hitting a struts action using AJAX, everything is fine but there is problem with Firefox , when i am passing the parameter in URL as a request parameter and if that parameter, contains hash(#) symbol in the end, then firefox strips everything after that symbol and send that parameter to action without it.
For example, if im passing test123#abcd in Firefox, then i am getting only test123 in action class as opposed to test123#abcd which is undesirable for my requirement.For IE it is working perfectly.Is there any way by which i can extract the full parameter including the # symbol in Firefox.
please let me know if i need to post the java action code also,thanks.
JS snippet
var valuePassword=test123#abcd;
var url = "/test/ChangePwdAjax.do?newPass="+valuePassword;
var xmlHTTP = getXMLHTTPRequest();
Use
var url = "/test/ChangePwdAjax.do?newPass="+ encodeURIComponent(valuePassword);
This will encode your valuePassword to a valid URL component which can be passed as a query string in URLs
And on the other side you should use decodeURIComponent to get the value from encoded string
var value = decodeURIComponent(valuePasswordPassed);
To know more about this Go here
When you change data you have to do a http POST request. Not a GET request. This will automatically solve your problem without having to encode your password.
xmlhttp.open("POST", "/test/ChangePwdAjax.do", true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send("newPass=" + valuePassword);
Surely worth mentioning that passing a password as a URL parameter is a terrible idea. A passer-by can see your new password in your browser's address bar. And anyone in the future can find the password in your browsing history.
-mobailey

Categories

Resources