How to start an UiPath Process from Salesforce interface - rest

How I can Start an UiPath Process on UiPath Robot from the Salesforce interface?
I know that Salesforce can send REST API commands to other software.

I tried to do exactly the same thing, like you in your movie on YouTube.
Please, can you look on my/Your apex code bellow, and maybe help me. Thanks!!
{
//#future(callout=true)
public static void startProcess(String param1,String param2)
{
Http http = new Http();
HttpRequest rm = new HttpRequest();
rm.setEndpoint('https://account.uipath.com/oauth/token');
rm.setMethod('POST');
rm.setHeader('Content-Type', 'application/json');
rm.setHeader('X-UIPATH-TenantName', 'ioDefault');
//rm.setTimeout(60000);
JSONGenerator gen = JSON.createGenerator(true);
gen.writeStartObject();
gen.writeStringField('grant_type','refresh_token');
gen.writeStringField('client_id','8DEv1AMNXczW3y4U15LL3jYf62jK93n5');
gen.writeStringField('refresh_token','2I7ZERqOZHFmzVzyPUE_sdf-l-dGa4086xN8fyrW-xF8-');
gen.writeEndObject();
rm.setBody(gen.getAsString());
HttpResponse rs = http.send(rm);
System.debug(rs.getBody());
Map<String,Object> res = (Map<String,Object>)JSON.deserializeUntyped(rs.getBody());
System.debug(String.valueOf(res.get('access_token')));
HttpRequest rm2 = new HttpRequest();
rm2.setMethod('POST');
rm2.setEndpoint('https://platform.uipath.com/zuhtkqf/ioDefault/odata/Jobs/UiPath.Server.Configuration.OData.StartJobs');
rm2.setHeader('Content-Type', 'application/json');
rm2.setHeader('X-UIPATH-TenantName', 'ioDefault');
rm2.setHeader('Authorization', 'Bearer '+String.valueOf(res.get('access_token')));
//rm2.setTimeout(60000);
JSONGenerator gen2 = JSON.createGenerator(true);
/// start a simple process without parameters
gen2.writeStartObject();
gen2.writeFieldName('startInfo');
gen2.writeStartObject();
gen2.writeStringField('ReleaseKey','6aa09f52-ef47-47aa-ab2e-8e487e7841e5');
gen2.writeStringField('Strategy','All');
gen2.writeEndObject();
gen2.writeEndObject();
/// start a simple process with parameters
/* gen2.writeStartObject();
gen2.writeFieldName('startInfo');
gen2.writeStartObject();
gen2.writeStringField('ReleaseKey','YOUR release KEY for process see the YouTube movie below');
gen2.writeStringField('Strategy','All');
gen2.writeStringField('InputArguments','{\"param1\":\"'+param1+'\",\"param2\":\"'+param2+'\"}');
gen2.writeEndObject();
gen2.writeEndObject();
*/
rm2.setBody(gen2.getAsString());
HttpResponse rs2 = http.send(rm2);
System.debug(rs2.getBody());
}
}

Related

Calling External WCF Service (using generated client) from CRM sandboxed plugin OnPremise is failing

How to call HTTPS WCF web service in Plugin, plugin assembly is registered in sandbox mode. I am getting System.Security.SecurityException exception, Can somebody please provide the way to all https web service. My code is below :
BasicHttpBinding myBinding = new BasicHttpBinding();
myBinding.MaxReceivedMessageSize = Int32.MaxValue;
myBinding.Name = “basicHttpBinding”;
if (EndPoint.ToLower().Contains(“https://”))
{
//Throwing exception here – System.Security.SecurityException exception,
ServicePointManager.ServerCertificateValidationCallback += (sendr, cert, chain, sslPolicyErrors) => true;
ServicePointManager.SecurityProtocol = (SecurityProtocolType)768 | (SecurityProtocolType)3072 | (SecurityProtocolType)192;
myBinding.Security.Mode = BasicHttpSecurityMode.Transport;
}
else
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
myBinding.Security.Mode = BasicHttpSecurityMode.None;
}
myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
myBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
myBinding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
EndpointAddress endPointAddress = new EndpointAddress(EndPoint);
WebIALClient myClient = new WebIALClient(myBinding, endPointAddress)
Since you are in on-premise version, you can register the plugin assembly in non-sandbox mode. ie Isolation mode = none to overcome such errors.
In case you wanted to use sandbox mode, try using WebClient class for invoking WCF service call. Read more
using (WebClient client = new WebClient())
{
byte[] responseBytes = client.DownloadData(webAddress);
string response = Encoding.UTF8.GetString(responseBytes);
tracingService.Trace(response);
// For demonstration purposes, throw an exception so that the response
// is shown in the trace dialog of the Microsoft Dynamics CRM user interface.
throw new InvalidPluginExecutionException("WebClientPlugin completed successfully.");
}
Can you try and also include: using System.Web.Http.Cors;
[EnableCors(origins: "*", headers: "*", methods: "*")]
[Route("api/ConvertUpload/{env}/{id}")]
public string Get(string env, string id)
{
return "hi";
}
You may have to use WebClient as #Arun has mentioned.

Test a Symfony REST API using Behat / Mink : prb with POST request

My challenge here is to find the best way to test a Symfony (3.4) API application using Behat/Mink for functionnal test, in my CICD platform.
Because my testing processes must be called in a shell script, all the tests must be very linear. I have no way to start a standalone webserver like Apache or the PHP/Symfony webserver. Also, Docker is not an option.
For the moment, I can successfully test the GET verbs of the API using the Mink syntax :
-- file test.feature
#function1
Scenario Outline: Test my api
When I go to "/api/v1/hello"
Then the response is JSON
The "I go to" instruction is implemented by Mink (http://docs.behat.org/en/v2.5/cookbook/behat_and_mink.html) and it emulates a GET request only. When this instruction is called by BeHat, the app Symfony kernel is "spawned" and the "api/v1/hello" method is called internally : there is no network trafic, no TCP connection, there is no need for a dedicated webserver (apache, or the symfony standalone server). It looks like Behat is emulating a webserver and start by itself the Symfony app it its own user space.
Now I want to test the POST verbs of my API, with a json payload, but unfortunally Mink do not have other verbs than GET.
I have read some articles over the web (keyword : behat test post api) but all I have seen is based on a Guzzl/Curl client. So a real client-to-server connection is made to http://localhost and a real webserver have to respond to the request.
I want the Symfony API to be called internally without using an other webserver.
Is there a way to do that ? How to test a Symfony REST API and specially the POST verb without needing a standalone server to reply ?
Thank you.
Here is how I do a functional test of a POST API, with BeHat, without a local running webserver :
test.feature :
#function1
Scenario Outline: Test my api
Given I have the payload
"""
{ "data":"object"}
"""
When I request "POST /api/v1/post"
Then the response is JSON
The featureContext file implement two functions :
"I Have The Payload" : See here https://github.com/philsturgeon/build-apis-you-wont-hate/blob/master/chapter8/app/tests/behat/features/bootstrap/FeatureContext.php
"I request" : based on code provided by philsturgeon just above, I modify it to have something like that :
/**
* #When /^I request "(GET|PUT|POST|DELETE|PATCH) ([^"]*)"$/
*/
public function iRequest($httpMethod, $resource)
{
$this->lastResponse = $this->lastRequest = null;
$this->iAmOnHomepage();
$method = strtoupper($httpMethod);
$components = parse_url($this->getSession()->getCurrentUrl());
$baseUrl = $components['scheme'].'://'.$components['host'];
$this->requestUrl = $baseUrl.$resource;
$formParams = json_decode($this->requestPayload, true);
$formParamsList = [];
foreach($formParams as $param => $value) {
$formParamsList[$param] = json_encode($value);
}
// Construct request
$headers = [
'Accept'=>'application/json',
'Content-Type'=>'application/x-www-form-urlencoded'
];
try {
// Magic is here : allow to simulate any HTTP verb
$client = $this->getSession()->getDriver()->getClient();
$client->request(
$method,
$this->requestUrl,
$formParamsList,
[],
$headers,
null);
} catch (BadResponseException $e) {
$response = $e->getResponse();
// Sometimes the request will fail, at which point we have
// no response at all. Let Guzzle give an error here, it's
// pretty self-explanatory.
if (null === $response) {
throw $e;
}
$this->lastResponse = $e->getResponse();
throw new \Exception('Bad response.');
}
}
If you use Mink then it is quite easy
class FeatureContext extends RawMinkContext
{
/**
* #When make POST request to some Uri
*/
public function makePostRequestToSomeUri(): void
{
$uri = '/some-end-point';
/** #var \Symfony\Component\BrowserKit\Client $client */
$client = $this->getSession()->getDriver()->getClient();
$postParams = [];
$files = [];
$serverParams = [];
$rawContent = '';
$client->request(
\Symfony\Component\HttpFoundation\Request::METHOD_POST,
$uri,
$postParams,
$files,
$serverParams,
$rawContent
);
/** #var \Symfony\Component\HttpFoundation\Response $response */
$response = $client->getResponse();
//...
}
}

Groovy script for Jenkins: execute HTTP request without 3rd party libraries

I need to create a Groovy post build script in Jenkins and I need to make a request without using any 3rd party libraries as those can't be referenced from Jenkins.
I tried something like this:
def connection = new URL( "https://query.yahooapis.com/v1/public/yql?q=" +
URLEncoder.encode(
"select wind from weather.forecast where woeid in " + "(select woeid from geo.places(1) where text='chicago, il')",
'UTF-8' ) )
.openConnection() as HttpURLConnection
// set some headers
connection.setRequestProperty( 'User-Agent', 'groovy-2.4.4' )
connection.setRequestProperty( 'Accept', 'application/json' )
// get the response code - automatically sends the request
println connection.responseCode + ": " + connection.inputStream.text
but I also need to pass a JSON in the POST request and I'm not sure how I can do that. Any suggestion appreciated.
Executing POST request is pretty similar to a GET one, for example:
import groovy.json.JsonSlurper
// POST example
try {
def body = '{"id": 120}'
def http = new URL("http://localhost:8080/your/target/url").openConnection() as HttpURLConnection
http.setRequestMethod('POST')
http.setDoOutput(true)
http.setRequestProperty("Accept", 'application/json')
http.setRequestProperty("Content-Type", 'application/json')
http.outputStream.write(body.getBytes("UTF-8"))
http.connect()
def response = [:]
if (http.responseCode == 200) {
response = new JsonSlurper().parseText(http.inputStream.getText('UTF-8'))
} else {
response = new JsonSlurper().parseText(http.errorStream.getText('UTF-8'))
}
println "response: ${response}"
} catch (Exception e) {
// handle exception, e.g. Host unreachable, timeout etc.
}
There are two main differences comparing to GET request example:
You have to set HTTP method to POST
http.setRequestMethod('POST')
You write your POST body to outputStream:
http.outputStream.write(body.getBytes("UTF-8"))
where body might be a JSON represented as string:
def body = '{"id": 120}'
Eventually it's good practice to check what HTTP status code returned: in case of e.g. HTTP 200 OK you will get your response from inputStream while in case of any error like 404, 500 etc. you will get your error response body from errorStream.

How to call CQ author URL from a standalone code

I am trying to hit URL in cq Author instance from my standalone code. The URL looks like — http://<somehost>:<someport>//libs/dam/gui/content/reports/export.json
Below is the code:
URL url = new URL(newPath);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setReadTimeout(15 * 10000);
connection.connect();
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
But I got a 401 error, which is expected, as I'm not passing any authentication information — hence Sling says:
getAnonymousResolver: Anonymous access not allowed by configuration - requesting credentials.
How can I get resolve this?
You may use Basic HTTP authentication. Adding it to the HttpURLConnection is little awkward:
Authenticator.setDefault(new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("admin", "admin".toCharArray());
}
});
Consider using Apache HttpClient:
UsernamePasswordCredentials creds = new UsernamePasswordCredentials("admin", "admin");
DefaultHttpClient authorizedClient = new DefaultHttpClient();
HttpUriRequest request = new HttpGet(url);
request.addHeader(new BasicScheme().authenticate(creds, request));
HttpResponse response = authorizedClient.execute(request);
InputStream stream = response.getEntity().getContent();

Logging in to facebook using apache HTTP client

I am trying to write automated tests for a REST API using apache HTTP client, we are using Facebook as an affiliate to log in.
I have used this question as a starting point:
apache HttpClient to access facebook
But it is using lots of deprecated methods.
I have switched all of these out but I am finding that it is not working.
to validate I have written a method to print out the body response and I am viewing that by making it into a HTML document. When I load that page it has the facebook error message of:
Cookies Required
Cookies are not enabled on your browser. Please enable cookies in your browser preferences to continue.
My code:
CookieStore cs = new BasicCookieStore();
HttpClientContext context = HttpClientContext.create();
HttpGet httpget = new HttpGet("http://www.facebook.com/login.php");
HttpResponse response= HttpClientBuilder.create().setDefaultCookieStore(cs).build().execute(httpget);
System.out.println("Login form get: " + response.getStatusLine());
HttpPost httpost = new HttpPost("https://www.facebook.com/login.php");
context.setCookieStore(cs);
List <NameValuePair> nvps = new ArrayList <NameValuePair>();
nvps.add(new BasicNameValuePair("email", "******"));
nvps.add(new BasicNameValuePair("pass", "*****"));
nvps.add(new BasicNameValuePair("lsd", "AVptst2v"));
httpost.setHeader("User-Agent", "Mozilla/5.0");
httpost.setHeader("Host", "www.facebook.com");
httpost.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
httpost.setHeader("Accept-Language", "en-US,en;q=0.5");
httpost.setHeader("Cookie", cs.toString());
httpost.setHeader("Connection", "keep-alive");
httpost.setHeader("Referer", "https://www.facebook.com/login");
httpost.setHeader("Content-Type", "application/x-www-form-urlencoded");
httpost.setEntity(new UrlEncodedFormEntity(nvps));
response = HttpClientBuilder.create().setDefaultCookieStore(cs).build().execute(httpost,context);
System.out.println("Login form post: " + response.getStatusLine());
System.out.println(printBodyOfResponse(response));
To answer my own question, I found that creating a context and passing that through with each request carried the session, I see lots of answers saying that cookie management is automatic, but for me the only solution was to pass the context throughout
BasicHttpContext context = new BasicHttpContext();
HttpGet get = new HttpGet("http://www.facebook.com/login.php");
HttpResponse response= HttpClientBuilder.create().build().execute(get,context);
System.out.println("Login form get: " + response.getStatusLine());
HttpPost httpost = new HttpPost("https://www.facebook.com/login.php?login_attempt=1");
List <NameValuePair> nvps = new ArrayList <NameValuePair>();
nvps.add(new BasicNameValuePair("email",PropertiesUtil.loadSiteProperty("FB_email")));
nvps.add(new BasicNameValuePair("pass", PropertiesUtil.loadSiteProperty("FB_password")));
httpost.setHeader("User-Agent", "Mozilla/5.0");
httpost.setHeader("Host", "www.facebook.com");
httpost.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
httpost.setHeader("Accept-Language", "en-US,en;q=0.5");
httpost.setHeader("Connection", "keep-alive");
httpost.setHeader("Referer", "https://www.facebook.com/login");
httpost.setHeader("Content-Type", "application/x-www-form-urlencoded");
httpost.setEntity(new UrlEncodedFormEntity(nvps));
response = HttpClientBuilder.create().build().execute(httpost,context);