Search code examples
javascriptpythoncurlflaskservicenow

Adding a curl request into a serviceNow business rule (javascript)


IN SHORT: How do I write a javascript code that can send an API PUT message to my flask server?

CONTEXT

I have a simple flask applications like as described here: http://flask-restful.readthedocs.io/en/0.3.5/quickstart.html

But I have added CORS capability by adding this to the top:

from flask import Flask
from flask_restful import reqparse, abort, Api, Resource
from flask_cors import CORS


app = Flask(__name__)
CORS(app)
api = Api(app)

It is on a server at [server_ip]

There is a ticketing service applications called serviceNOW and they allow one to run simple javascript commands in their business rules.

They supply the context:

(function executeRule(current, previous /*null when async*/) {



})(current, previous);

And I want to add the functionality: curl http://[server_ip]:5000/todos/todo3 -d "task=something different" -X PUT -v

MAIN IDEA: I want to send API calls from the serviceNOW server to my flask server when a business rule is called

Using the chrome console while on the serviceNOW server page I have run the following code:

var xhttp = new XMLHttpRequest();
xhttp.open("GET", "http://[my_server]:5000/todos/todo3", false);
xhttp.send();

And i get the error:

Mixed Content: The page at 'https://[serviceNOW instance]' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://[server_ip]:5000/todos/todo3'. This request has been blocked; the content must be served over HTTPS.
(anonymous) @ VM1629:1
VM1629:1 Uncaught DOMException: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'http://[server_ip]:5000/todos/todo3'.
    at <anonymous>:1:7

EDIT 1

I changed:

xhttp.open("GET", "http://[my_server]:5000/todos/todo3", false);
xhttp.send();

to

xhttp.open("PUT", "https://[my_server]:5000/todos/todo3", false);`
xhttp.send(JSON.stringify({ "task": "new task2"}));

and i get:

VM1698:1 OPTIONS https://[server_ip]:5000/todos/todo5 
(anonymous) @ VM1698:1
VM1698:1 Uncaught DOMException: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'https://[server_ip]:5000/todos/todo5'.
    at <anonymous>:1:7

My server says:

code 400, message Bad HTTP/0.9 request type ('\x16\x03\x...more hex..')
?m?~)]?n??K...more stuf..?,?0̨̩????/5" 400 -

EDIT 2

This is my current code:

var xhttp = new XMLHttpRequest();    
xhttp.open("PUT", "https://[my_server]:5000/todos/todo3", false);`
xhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhttp.send(JSON.stringify({ "task": "new task2"}));

This is my current console side error:

DOMException: Failed to execute 'send' on 'XMLHttpRequest': Failed to load

This is my current server side error:

code 400, message Bad HTTP/0.9 request type

This curl works:

curl http://[server_ip]:5000/todos/todo5 -d "task=something differentyea" -X PUT -v

EDIT 3

This is my current code:

var xhttp = new XMLHttpRequest();    
xhttp.open("PUT", "https://[my_server]:5000/todos/todo3", true);`
xhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhttp.send(JSON.stringify({ "task": "new task2"}));

This is my current error:

OPTIONS https://[server_ip:5000/todos/todo6 net::ERR_SSL_PROTOCOL_ERROR

EDIT 4

This code works (note the http and not https):

var xhttp = new XMLHttpRequest();    
xhttp.open("PUT", "http://[my_server]:5000/todos/todo3", true);`
xhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhttp.send(JSON.stringify({ "task": "new task2"}));

But I have to run it from a none https site.


Solution

  • Business Rules in ServiceNow execute server side. Prototyping your code in the browser console will not be helpful. Most importantly, XMLHttpRequest does not exist server-side.

    To make HTTP calls from a Business Rule you must use the ServiceNow RESTMessageV2 API. See API Docs - RESTMessageV2 for usage information and example code.

    Your code might look something like this:

    var rm = new sn_ws.RESTMessageV2(); 
    rm.setEndpoint('http://[my_server]:5000/todos/todo3'); 
    rm.setHttpMethod('PUT'); 
    rm.setRequestHeader('Content-Type', 'application/json;charset=UTF-8'); 
    rm.setRequestBody(JSON.stringify({ "task": "new task2"})); 
    
    var response = rm.execute();
    var responseBody = response.getBody(); 
    
    // Process the response here...
    

    response is a RESTResponseV2 object. See the docs for more information on interacting with the response.