Idea
Discussion

Hi all,

I tried to implement a web service with the configuration section in Creatio for SAP business one Service Layer and the default port for service layer is 50000. URL is the Https://myserver.com:50000/ Configuring the webservice Creatio omitted last 0 and the computed Uri was 0/b1s/... instead of /b1s/ and the connection try was resulting unable to connect because it was attacking on port 5000. I had to change the settings of SAP Service Layer for 5000 then connection succeeded. As we are on prem with SAP no issue to patch but clients on cloud would have issues.

 

is it possible to fix this issue in Creatio accepting 5 digits for port number?

 

Thanks in advance,

Franck

3 comments

Hi,

There are no restrictions on port length in Creatio.



Try to create the web service again and check how it works.

Perhaps the service settings are cached.

Hi Nikita,

You can reproduce like this:

Create a new web service with the port 50000:

https://127.0.0.1:50000/mywebservice

 

Then click ok, you will see that the URI is truncated and a 0 has been put to the method. You may try to change the values but the system would not save it properly. Running on 7.18.3 same behavior on 8.0.3 on demo instance.

Thanks,

Franck

Thanks, I reproduced the described behavior.

 

You can change the service URL and method settings manually.

I changed it manually, and everything saved correctly for me.

Show all comments

Hi Community!!!

I used built in web service configuration to configure an integration with third party app.

The JSON that third party app receives looks like this:

{

  "url": "https://test",

  "events": ["a","b"]

}



The configuration for the events parameter into web service is as shown in the image below:

My issue is when I try to call this Web Service/Method from a Business Process. I cannot send the correct values for the events parameter. I tried several options for example: read a lookup values, create list or collection in a script task, etc. but I couldn't achive the goal.

The image below shows how the parameter is requested on the business process:

 

Below I show the trace with an example of the values I try to pass to the paramter:



"Parameter": "Events",

            "Value": {

                "Before execution": [

                    {

                        "Name": "invitee.created"

                    },

                    {

                        "Name": "invitee.canceled"

                    }

                ],

 

Any recomendation?

Regards.

 

 

 

 

Like 0

Like

3 comments

Hello,

You can send  your values using a collection.

The values of collection parameters of a [ Call web service ] process element can be mapped to the nested parameters of another collection of a [ Read data ] or [ Call web service ] process element .Additionally, each item of the collection can be mapped to an individual subprocess instance in the [ Subprocess ] element.



 

You can find more detailed information on the academy website:

https://academy.creatio.com/docs/user/bpm_tools/process_elements_refere…

Cherednichenko Nikita,

Thank you! I tried it but the result is something like this:

 

[

                    {

                        "Name": "invitee.created"

                    },

                    {

                        "Name": "invitee.canceled"

                    }

                ],

The expected value is 

[invitee.created","invitee.canceled"]

 

How can I achive this?

Regards.

Hello,

The code

[

                    {

                        "Name": "invitee.created"

                    },

                    {

                        "Name": "invitee.canceled"

                    }

],

Is seen like : [{"Name": "invitee.created"}, {"Name": "invitee.canceled"}].

But, in your case, I believe you can use the parameter value "Collection of values"

 

Show all comments

Hello,



I want to make a cascading dropdown. For example; user selects City, then County, then District, then Street... I want to fill the dropdowns from external web service whenever user selected previous dropdown.



How should i go about it?



Like 3

Like

3 comments

Hello Ensar,

Loos like you just need to add a filter to the column based on the other column value.

You can do it by adding attribute on the needed column.

For example:

"Transport": {
                "dataValueType": Terrasoft.DataValueType.LOOKUP,
                "lookupListConfig": {
                    "filters": [
                        function() {
                            var filterGroup = Ext.create("Terrasoft.FilterGroup");
                            filterGroup.add("WhatWeight",
                                Terrasoft.createColumnFilterWithParameter(
                                    Terrasoft.ComparisonType.GREATER,
                                    "[StTransport:Id].StMaxWeight",
                                    this.get("Weight")));
                            return filterGroup;
                        }
                    ]
                }

In this example we have column "Transport" and we wont to display values where their column "StMaxWeight" is greater that out column "Weight".

Thanks for your reply Dmytro Vovchenko,

 

Filtering is ok. At the same time, i need to get data from external web service not database. Is there a way binding lookups to external web service dynamically?

Not quite understand what are you trying to do but I think you can store the value from your web service in the schemas attribute and then work with it. To make it work you just need to somehow get the needed value from the web server in the schema code. 

Show all comments

Good day community,

 

I'm having trouble with adding the correct JSON path for my request body.

 

I have to send a POST request with the following JSON below:

{
  "members": [
    {
      "@odata.type": "--TYPE HERE--",
      "user@odata.bind": "--USER 1 HERE--"
    },
    {
      "@odata.type": "--TYPE HERE--",
      "user@odata.bind": "--USER 2 HERE--"
    }
  ]
}

This is how my parameter structure looks:

Generated JSON here:

{
	"chatType": "oneOnOne",
	"members": [
		{
			"@odata": {
				"type": "--TYPE HERE--"
			},
			"user@odata": {
				"bind": "--USER 1 HERE--"
			}
		}
	]
}

The problem with this structure is that it generates a nested key for type under @odata, and for bind as well. I don't wan't this to happen if possible.

 

Is there any way to get this to work using parameters in web service? Or would my only resort be to generate the request body via script?

Like 0

Like

2 comments

Hello,

 

The body of the webservice seems to be generated properly since "members" is the array of objects "@odata" and "user@odata". The request was properly parsed and that's why you saw the result as on the screenshot. If this structure won't work in your business case then a separate script task should be created to sent the request.

 

Best regards,

Oscar 

Hi Oscar,

 

Thank you for you response.

 

In forming the json path, I would have made it as $.[members]["@odata.dataType"] or $.[members]["user@odata.bind"], but I'm guessing that this is not possible using the built-in function (nesting parameters) in Creatio?

 

I think I'll instead be resorting to creating a script task for this.

 

Thank you!

 

Lyle

Show all comments

Hi Community,

 

I want to make use of and set up OAuth 2.0 Authentication in web service authentication. For that I found below the academy article :

 

https://academy.creatio.com/docs/user/no_code_customization/web_service…

 

While setting up as per the article, there is one required field in the OAuth Setting fields which is "Auth code request URL".

 

But the API endpoints for which, I have to make use of Web Service OAuth Authentication, is not having settings for Auth code request URL required parameter.

 

 

Please guide and help me on this point that how I can set up OAuth Authentication in web service without Auth code request URL.

Like 0

Like

1 comments

Hello Pratic,



Unfortunately, the is no way to set up OAuth Authentication in web service without Auth code request URL.



This parameter is necessary to identify users.



Best regards,

Bogdan



 

Show all comments

Hello Creatio community !

I would like to call the Creatio Webservice ..../0/rest/FinAppSpecService/InheritSpecificationsForFinApp  which automatically populates the Product Terms in Application, inside a Business Process. I can not call it in a c# class because the the constructor of FinAppSpecService class does not accept UserConnection as e parameter. Which is the proper way to solve this problem ?

Like 1

Like

11 comments
Best reply

Hello Petrika,

 

It's possible if you create a webservice record where the POST method complete address will be {siteURL}/0/rest/FinAppSpecService/InheritSpecificationsForFinApp and in the request parameters specify the following header parameters:

 

BPMCSRF

ForceUseSession (default value set to true)

Connection (default value set to true)

 

and the following cookies parameters:

 

BPMSESSIONID

UserName

BPMLOADER

BPMCSRF

.ASPXAUTH

 

in the webservice settings (since the FinAppSpecService service is not anonymous). The most difficult part here is setting cookies parameters. I could only recommend the following scenario here:

 

1) Create a separate authentication service webservice request (to {siteURL}/ServiceModel/AuthService.svc/Login)

2) Specify UserName and UserPassword request body parameters:

3) Add the Set-Cookie response header parameter:

4) Validate the response by performing a test call. It should return the Set-Cookie header that will be then used in the process:

5) Create a separate business process and configure it to run once per hour or once per half a day (depending on the value of the "UserSessionTimeout" system setting). The set-Cookie response header should be parsed to extract values for the

 

BPMSESSIONID

UserName

BPMLOADER

BPMCSRF

.ASPXAUTH

 

headers. It can be done by means of the script-task. Extracted values should be set as values for the system settings created separately (one per each header).

 

6) In your process where you need to call the FinAppSpecService in the "Call webservice" element set the values for the cookie parameters as values from the system settings from step 5. And also specify the value for the BPMCSRF header parameter.

 

7) Add all other request body parameters and call the service.

 

This approach should work since we simulate the Postman call of the same service, but set cookie parameters and header parameters via the separate business process and system settings.

 

Best regards,

Oscar

Hello Petrika,

 

It's possible if you create a webservice record where the POST method complete address will be {siteURL}/0/rest/FinAppSpecService/InheritSpecificationsForFinApp and in the request parameters specify the following header parameters:

 

BPMCSRF

ForceUseSession (default value set to true)

Connection (default value set to true)

 

and the following cookies parameters:

 

BPMSESSIONID

UserName

BPMLOADER

BPMCSRF

.ASPXAUTH

 

in the webservice settings (since the FinAppSpecService service is not anonymous). The most difficult part here is setting cookies parameters. I could only recommend the following scenario here:

 

1) Create a separate authentication service webservice request (to {siteURL}/ServiceModel/AuthService.svc/Login)

2) Specify UserName and UserPassword request body parameters:

3) Add the Set-Cookie response header parameter:

4) Validate the response by performing a test call. It should return the Set-Cookie header that will be then used in the process:

5) Create a separate business process and configure it to run once per hour or once per half a day (depending on the value of the "UserSessionTimeout" system setting). The set-Cookie response header should be parsed to extract values for the

 

BPMSESSIONID

UserName

BPMLOADER

BPMCSRF

.ASPXAUTH

 

headers. It can be done by means of the script-task. Extracted values should be set as values for the system settings created separately (one per each header).

 

6) In your process where you need to call the FinAppSpecService in the "Call webservice" element set the values for the cookie parameters as values from the system settings from step 5. And also specify the value for the BPMCSRF header parameter.

 

7) Add all other request body parameters and call the service.

 

This approach should work since we simulate the Postman call of the same service, but set cookie parameters and header parameters via the separate business process and system settings.

 

Best regards,

Oscar

Thank you very much for you response Oscar. It was very helpful.

Is there any article or example in the academy regarding point 5, parsing set-Cookie response header to extract values (inside a script task) ?

Petrika,

 

This is the task that should be covered by the C# code, using substring method for example. It's something as if you had a task to substring the "test" word from the "Hello test wordl!" string. Please find the way using the topics as the following:

 

https://stackoverflow.com/questions/9505400/extract-part-of-a-string-be…

 

Please also notice that the cookies values length is always constant and all of them start with the cookie name and the "=" character and end with the ";" symbol. This shouldn't be a difficult task.

 

Once string parts are extracted you can set them as parameter values (here is the Academy article that may be useful) and use these parameters in formulas to set parameter values to correspondent system settings.

 

Best regards,

Oscar

Oscar Dylan,

BPMSESSIONID is generated in the set-Cookie response header, because it seems that it's not found there ? I managed to extract everything else as required

Petrika,

 

Sorry, made a little mistake. BPMSESSIONID cookie is not returned as a response to the /AuthService.svc/Login call, but as a result of the first call to any other working endpoint like /0/odata/Account after authentication. Just try it in Postman and check the response headers in the next request that goes after AuthService request.

 

Best regards,

Oscar

Oscar ,

When i make a request from postman to another web-service the BPMSessionId is generated, I tested it.

Are you suggesting that i put the BPMSESSIONID as a reponse parameter to the InheritSpecificationsForFinApp, not as a request parameter ?

If i understand correctly.

 

Petrika,

If you're calling a configuration service, there's no need to actually use it as a service. It's simply a C# class that you can use directly.

For example, something like this: 

var svc = new Terrasoft.Configuration.FinAppSpecService();
svc.InheritSpecificationsForFinApp()

Depending on how the configuration service is implemented, you might need to also pass a UserConnection to it, which means you'd need to modify the service to allow this to be passed in.

You had mentioned: "I can not call it in a c# class because the the constructor of FinAppSpecService class does not accept UserConnection as e parameter. Which is the proper way to solve this problem?"

Why not just add two constructors to the class? One that is the default constructor and one that accepts a UserConnection? In the class you could add a method that either returns your private UserConnection variable (passed in by code consuming the class directly) or the one from the session (or BaseService) if being used as a service. I do it this way often and it is far more easy to consume the class directly than to call as a service when it's not needed to be used as a service (not to mention the extra overhead of using it as a service rather than consuming it directly)

Ryan

Ryan Farley,

 

FinAppSpecService() class constructor doesnt allow UserConnection as an argument. I can not modify the FinAppSpecService class because its part of the configuration. 

 

Ryan Farley,

Are you suggesting that i copy the 

FinAppSpecService  class to my package and make proper modifications to it ?

Petrika,

I was assuming this was your class, that you could modify, not a configuration one that was uneditable by you. 

I assume that FinAppSpecService inherits BaseService? If so, it has a UserConnection property that is protected (that does have a setter) as well as a protected constructor that accepts a UserConnection. Since they are protected you should be able to access them if your class is derived from it. 

it might work to just make a new class that inherits from the FinAppSpecService that allows a UserConnection to be passed? I've not tried that but it might work - just to throw out some ideas.

Something like this: 

public class UsrFinAppSpecServiceWrapper : FinAppSpecService
{
    public void SetUserConnection(UserConnection)
    {
        this.UserConnection = UserConnection;
    }
}

Then to use it:

var svc = new Terrasoft.Configuration.UsrFinAppSpecServiceWrapper();
svc.SetUserConnection(UserConnection);
svc.InheritSpecificationsForFinApp();

Again, I've not tested/tried that before, but I would assume something like this could work? If it does, still far easier route than calling it as a service IMO.

Ryan

Ryan Farley,

Ryan the response i get from the back-end 

is the same as the reponse i get from the front-end 

Still When i call this web-service from the back-end my goal isnt achieved. As you can see the detail of product terms isnt automaticalluy generated

Dont know if am missing something here

Thank you Petrika

Show all comments

Hi,

Q:   IS Creatio custom web service DDOS safe ?



In other words:   If I create a custom web service (Anonymous) for integration with external systems (of course with basic security logic to identify the source which is accessing my endpoint), Is creatio DDoS Safe? Or in this case i should use application firewall (like cloudflare) infront of creatio ?

Like 2

Like

0 comments
Show all comments

Hello Everyone.

I want to log in a separate file every communication with a Web-Service (request , response time etc).Is there any built-in , or tools from Marketplace to realize this task. Or I should customize the source -code.  

Like 0

Like

4 comments
Best reply

Petrika,

 

Perfect, then additionally you can use the same approach with EntitySchemaQuery, but create record is some section and then use the standard "Export to excel" functionality to get the file with request calls. So each time something is calling the GetErSumSq method you can create a record in some separate section (for example called "Integration call" and add information like DateTime.Now (to get the date and time when the method was called and which value was returned (sum))). Also you can try looking into the HttpContext, HttpContextAccessor and AppConnection to see which information is available there that can be used to additionally log the method call.

 

Best regards,

Oscar

Hi Petrika,

 

This should be done directly in the code of the 3rd party endpoint to which the call is performed (in case we are discussing the 3rd party webservice call from the business process). Logs of the integration call on the Creatio side are accessible only via standard IIS logs. Or you can enable the process tracing to see the status of the call.

 

In case the webservice is stored in the Creatio configuration (standard anonymous or regular webservice) then you can either add a part of inserting a record to some specific table in Creatio (via InsertQuery class for example) and retrieve data from there.

 

Best regards,

Oscar

Thank you very much for your immediate response Oscar. I have got an idea now.  This is what i am trying to do. I have created a button in the Front-End (Get Sum Ws) which calls in the Back-End a basic web service that caculates the sum of the AmountHC in Details Rows.

This is the code in the back-end

namespace test1323.Files.cs
{
    [EntityEventListener(SchemaName = "PetrikaExpenseReport")]
    [ServiceContract]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
    class DemoService : BaseService
    {
 
        [OperationContract]
        [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped,
ResponseFormat = WebMessageFormat.Json)]
 
        public decimal GetErSumSq(string name) 
        {
 
            EntitySchemaQuery entity = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "PetrikaExpenseReport"); 
 
            entity.AddColumn("Id");
            entity.AddColumn("PetrikaTotalAmount");
            entity.AddColumn("PetrikaName");
            entity.PrimaryQueryColumn.IsVisible = true;                                                                   
 
            IEntitySchemaQueryFilterItem parentfilter =
            entity.CreateFilterWithParameters(FilterComparisonType.Equal,"PetrikaName",name);
            entity.Filters.Add(parentfilter);                                                                            
            EntityCollection records = entity.GetEntityCollection(UserConnection);                                      
            Guid parentId = records[0].GetTypedColumnValue<Guid>("Id");
 
           EntitySchemaQuery rows = new EntitySchemaQuery(UserConnection.EntitySchemaManager, 
           "PetrikaExpenseReportLines");
 
            rows.AddColumn("PetrikaAmountHC");
            rows.AddColumn("PetrikaAmountFC");
            rows.AddColumn("Id");
 
            IEntitySchemaQueryFilterItem childfilter =
            rows.CreateFilterWithParameters(FilterComparisonType.Equal, "PetrikaExpenseReport", parentId);
            rows.Filters.Add(childfilter);                                                                            
            EntityCollection lines = rows.GetEntityCollection(UserConnection);
 
            decimal sum = decimal.Zero;
 
            foreach (var r in lines) 
            {
                sum = sum + r.GetTypedColumnValue<decimal>("PetrikaAmountHC");
            }
            records[0].SetColumnValue("PetrikaTotalAmount", sum);                                             
            records[0].Save();
            return sum;
        }
}
}

I want to log in a separate file every communication (request , response time etc) with GetErSumSq.

Petrika,

 

Perfect, then additionally you can use the same approach with EntitySchemaQuery, but create record is some section and then use the standard "Export to excel" functionality to get the file with request calls. So each time something is calling the GetErSumSq method you can create a record in some separate section (for example called "Integration call" and add information like DateTime.Now (to get the date and time when the method was called and which value was returned (sum))). Also you can try looking into the HttpContext, HttpContextAccessor and AppConnection to see which information is available there that can be used to additionally log the method call.

 

Best regards,

Oscar

Oleg Drobina,

Hi , I can't find the whole solution for logging a web service , it seems some comments have been missed or deleted , any ways , how can i log a web service in creatio ? 

Show all comments

Hi Community,

I am trying to make a request from Creatio to the HTTP REST API Endpoints. |Where File should be added to the API request. 

Is there any way to work with the File type request Parameter in Rest API from Creatio? If yes, please suggest to me how I can achieve this.

 

An example of an API call from Postman is something like as per below :

 

Like 0

Like

3 comments

Hi Patrik,

 

To successfully upload an image you need to make sure that "WebDav publishing" feature is disabled in Windows features of the IIS server (can be found at "World wide web services" -> "Common HTTP Features" -> "WebDAVPublishing"):

Once done you need to perform the following steps:

 

1) Create a POST request to https://app_root_URL/0/odata/SysImage with the JSON raw body with the following content:

{
    "Name": "scr_NewContactPhoto.png",
    "Id": "330006E1-CA4E-4502-A9EC-E54D922D2C01",
    "MimeType": "image/png"
}

330006E1-CA4E-4502-A9EC-E54D922D2C01 should be a random unique identifier. This request will create a record in the SysImage table and the response should be similar to the below:

{
    "@odata.context": "https://app_root_URL/0/odata/$metadata#SysImage/$entity",
    "Id": "330006e1-ca4e-4502-a9ec-e54d922d2c01",
    "CreatedOn": "2021-09-30T10:24:26.830457Z",
    "CreatedById": "410006e1-ca4e-4502-a9ec-e54d922d2c00",
    "ModifiedOn": "2021-09-30T10:24:26.830457Z",
    "ModifiedById": "410006e1-ca4e-4502-a9ec-e54d922d2c00",
    "ProcessListeners": 0,
    "UploadedOn": "0001-01-01T00:00:00Z",
    "Name": "scr_NewContactPhoto.png",
    "Data@odata.mediaEditLink": "SysImage(330006e1-ca4e-4502-a9ec-e54d922d2c01)/Data",
    "Data@odata.mediaReadLink": "SysImage(330006e1-ca4e-4502-a9ec-e54d922d2c01)/Data",
    "Data@odata.mediaContentType": "application/octet-stream",
    "MimeType": "image/png",
    "HasRef": false,
    "PreviewData@odata.mediaEditLink": "SysImage(330006e1-ca4e-4502-a9ec-e54d922d2c01)/PreviewData",
    "PreviewData@odata.mediaReadLink": "SysImage(330006e1-ca4e-4502-a9ec-e54d922d2c01)/PreviewData",
    "PreviewData@odata.mediaContentType": "application/octet-stream"
}

2) Create a PUT request to https://app_root_URL/0/odata/SysImage(330006e1-ca4e-4502-a9ec-e54d922d2c01)/Data with the binary body and select an image there:

Once executed the response will be 200OK.

 

And after that we can perform a GET request to check the result:

Please also note that BPMCSRF cookie should be always in headers:

Best regards,

Oscar

Hi Oscar,

Thanks for the Guidance, But I want to make an API call from Creatio itself ( Using Web-Service / Script Task ), not from Postman

 

Could you guide me on that? 

Hi Pratik,

 

Please see examples here https://academy.creatio.com/docs/developer/integrations_and_api/data_se…

 

Best regards,

Oscar

Show all comments

Hello

how i can set x-www-form-urlencoded parameters in request ?I have only these types in webservice 

Like 1

Like

5 comments

Hello,

 

Unfortunately webservices in Creatio can process JSON body only, and we have a task for our core R&D team to make it possible to set the request body in X-WWW-FORM-URLENCODED type. Currently the request body should be formed separately via a script task and then passed to the webservice request body:

string Request = "From=" + System.Web.HttpUtility.UrlEncode(Get<string>("FromNumber")) + "&" + "Body=" + System.Web.HttpUtility.UrlEncode(Get<string>("Message")) + "&" +"To=" + System.Web.HttpUtility.UrlEncode(Get<string>("ToNumber"));
Set<string>("twilioRequest", Request);
return true;

twilioRequest is the process parameter of the text datatype that should be then used in the webservice body.

Oscar Dylan,

which Parameter type must I use in the request as body 

Moheman,

 

Since twilioRequest is a string then parameter type should be also string.

Oscar Dylan,

How's it going with the x-www-form support? When can we expect it?

Hi Oscar,

 

The solution you gave did  not work for us. May be we are missing something. Can you please share the request body from Test Request feature in webservice so that we can compare and check from our side?

Show all comments