Google Functions authentication issue

Hi Greg,
I used the link from Jason. From this page you could download zipped Test Function. And in this zipped JSON I see again the old URL. Also in zipped JSON you have this template in configuration:

"requestTemplate": "{ "data": "$esc.jsonString(${input.rawRequest})" }"

And in the text in the page you don`t have it.
I have to make more tests for detailed feedback, but I am really confused. All our Google Functions worked properly with TEST URL. When we switched to TRIGGER URL we started getting error messages, when we tested the functions. Initially I thought this was due to authorization, but now I see we actually fire the functions via the TRIGGER URL, but we recieve error messages in Genesys, that the response is not in proper format. And we changed nothing in the Google Function. How it happens, that with TEST URL the format is proper and with TRIGGER URL not?

Best regards,
Borislav

Best regards,
Borislav

Thanks for the details Barislav. I will get a story in for us updating the zip file. You are correct that is is out of date. The example text is current though, and the text Jason pasted
When using the trigger, the config I gave you is the correct example.
For calling triggers there are two changes needed different than using the CALL endpoint.

  1. No need for the requestTemplate manipulation we needed to use for the CALL format.
  2. The URL needs to be the trigger URL defined for your function in the Google config.

If you have both of those change and are still getting the error, please run as a /test and post the full output for review along with the correlation id returned and the region you are using.

I would also like the exact URL you are using in your config, just to be sure the endpoint you are hitting is correct.

Hi Greg,
Thank you very much for reply!
My original configuration with Test Url is:
request

{
"requestUrlTemplate": "https://cloudfunctions.googleapis.com/v1/projects/cf-genesys-dev-t7/locations/europe-west3/functions/gc_query_dedicated_skill:call",
"requestType": "POST",
"headers": {},
"requestTemplate": "{ "data": "$esc.jsonString(${input.rawRequest})" }"
}

response
{
"translationMap": {},
"translationMapDefaults": {},
"successTemplate": "${rawResult}"
}

When I test the function with this configuration everything is OK and I get result like this:
{
"skill": "FSD"
}

Then I made the corrections for Trigger Url:
request

{
"requestUrlTemplate": "https://europe-west3-cf-genesys-dev-t7.cloudfunctions.net/gc_query_dedicated_skill",
"requestType": "POST",
"headers": {},
"requestTemplate": "${input.rawRequest}"
}
(I cannot fully remove requestTemplate. I tried to remove, but aftrer saving I get it automatically back. That is why I left "${input.rawRequest}")

response is the same.

When test the function in this way, I get following error message:
{
"message": "The request could not be understood by the server due to malformed syntax.",
"code": "bad.request",
"status": 400,
"messageParams": {},
"contextId": "495868eb-bf0e-4340-91ef-ce1d006377d4",
"details": [
{
"errorCode": "ACTION.REMOTE_ENDPOINT"
}
],
"errors": [
{
"message": "REST call for action execute failed. Message: We were unable to process the response from the remote endpoint because it had a 'content-type' header of 'text/html; charset=utf-8' instead of the required value of 'application/json'. [495868eb-bf0e-4340-91ef-ce1d006377d4]",
"code": "BAD_REQUEST",
"status": 400,
"messageParams": {},
"details": [],
"errors": []
}
]
}

In the same time I see in Google Cloud, that the Function is executed correctly:
Default

2022-07-11T17:50:13.405372Z

gc_query_dedicated_skilldtf8twopmnde FSD

FSD

Debug

2022-07-11T17:50:13.407843979Z

gc_query_dedicated_skilldtf8twopmnde Function execution took 42 ms. Finished with status code: 200

Function execution took 42 ms. Finished with status code: 200

Still some issue in format, I believe.
Best regards,
Borislav

Hi Borislav,

I checked our logs and the content we are getting back is text/html. The call to authenticate, and to the europe-west3-cf-genesys-dev-t7.cloudfunctions.net endpoint all looked good.
The only suggestion I have is to change the permissions temporarily on your cloud function to allow unauthenticated access, and see what happens when you access the trigger from PostMan or curl to see what the text response we are getting looks like.

Hi Greg,
I had the same idea, but it is a little bit tricky to do this. I don`t have sufficient rights in Google Cloud to set unauthenticated access. I have to create a ticket about the topic and explain a lot the responsible colleagues. And even afterwards I am not sure I will get this temporary unauthenticated access. Of course, I could try, but it will take time also. Do you have any other idea how we could test and troubleshoot? Could we change the format of the response in any way?

Best regards,
Borislav

You might be able to use ngrok to capture the request response. Ngrok lets you setup a proxy that you would configure to point to the Google endpoint, and would change your Action to call the ngrok assigned proxy. You run the proxy locally. We often use this when doing internal testing of new endpoints to see the request/response flow.

Hi Greg,
I will try it tomorrow and write you about the result. At the moment here it is almost 23:00 and cannot go on working.

Best regards,
Borislav

Hi again Greg,
The colleagues granted only for very short time Public Access to the Function and I was able to test from Postman.
My cURL was:

curl --location --request POST 'https://europe-west3-cf-genesys-dev-t7.cloudfunctions.net/gc_query_dedicated_skill'
--header 'Content-Type: application/json'
--data-raw ' {
"integrationId": "be7e7424-e9dc-41b9-9471-abf71ddb184b",
"rawRequest": "{"contact":"359899884321","area_code":"DE_DUS_CCC"}",
"orgId": "720bb830-ca9b-47d1-bc1d-879e04bddc27",
"contact": "359899884321",
"area_code": "DE_DUS_CCC"
}'

and as a Response I recieved:

{"skill": "FSD"}

Best regards,
Borislav

Hi Borislav,

Can you look at the headers of the response, specifically the "Content-Type" header. We expect that header to include "application/json". If it is returning something like text/plain then that function needs to be updated to set the content-type to application/json.

--Jason

What was the content type header returned?

Hi Jason,
Great! We will try to meet your expectations.
Just a small question. Where in the documentation are they described? This about the response header, I mean. Obviously we have missed it.

Best regards,
Borislav

It would have been details from the curl. -v for verbose.

Just a small question. Where in the documentation are they described? This about the response header, I mean. Obviously we have missed it.

I don't see the content-type header requirement spelled out. On this page:

on the "Web services" tab it shows a requirement of "JSON-based web service calls." which I would expect to have a content-type that includes application/json for any response that includes a body. We can see about adding that as a documented requirement.

--Jason

Yes, if this requrement is valid for Google also, it will be nice, when it is written, I think. In Web Service I havent check at all, since I dont use this Integration. And one hint more. In your Example Function you have:

function createResponse(req) {

var response = {};
response.sumOfNumber1AndNumber2 = req.body.inputNumber1 + req.body.inputNumber2;
return response;

}

There is nothing about formating the response (its header).

Maybe, if you provide this in example, it will be easier for everyone.

Best regards,
Borislav

Content-type is a standard response header. I am just trying to find out what was returned when Borislav ran his test with curl to see if it was text/html like we were getting from the Action in production.

Hi Greg,
Hi Jason,
You are right. Our Function sends in the Response Content-Type text/html. I checked it again. And this is the reason we get this error. I made another function

https://europe-west3-cf-genesys-dev-t7.cloudfunctions.net/gc_query_dedicated_skill-test

It is identical with

https://europe-west3-cf-genesys-dev-t7.cloudfunctions.net/gc_query_dedicated_skill

I only added {'Content-Type': 'application/json'} in RETURN command in the code. And I think this new Function works fine.
We will test a little bit more and I will write here about the results.
Thank you very much for your support!

Best regards,
Borislav

Glad we could help. We will update the our documentation to warn about needing to set the Content-Type. We have not run into that in our tests.

Hi Jason,
I believe we solved our issue. Thank you very much again! Just finally I would like to get confirmation I have correctly understood something. You mentioned every Cloud Function requires separate Integration. But this doesn`t mean separate Service Account in the Google, as far as I understand. Am I right?

Best regards,
Borislav

You are correct, the same service account may be used. The separate integrations are needed because that is the level that authentication caching happens, and each google function ends up having a token unique to it when we authenticate. It is very specific to google function API and how the authentication for it has to be done.

Thank you for this explanation, Greg!
I wish you and Jason all the best!

Best regards,
Borislav