웹훅 구현

이 가이드에서는 웹훅 구현을 위한 다양한 샘플과 웹훅 문제 해결 권장사항을 제공합니다.

세션 매개변수 설정

다음 샘플은 세션 매개변수를 설정하는 방법을 보여줍니다.

Go

CTS에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

웹훅 빠른 시작을 참고하세요.

Java

CTS에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.


// TODO: Change class name to Example
// TODO: Uncomment the line below before running cloud function
// package com.example;

import com.google.cloud.functions.HttpFunction;
import com.google.cloud.functions.HttpRequest;
import com.google.cloud.functions.HttpResponse;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import java.io.BufferedWriter;

public class WebhookConfigureSessionParameters implements HttpFunction {
  @Override
  public void service(HttpRequest request, HttpResponse response) throws Exception {
    JsonObject orderParameter = new JsonObject();
    orderParameter.addProperty("order_number", "12345");

    JsonObject parameterObject = new JsonObject();
    parameterObject.add("parameters", orderParameter);

    // Creates webhook response object
    JsonObject webhookResponse = new JsonObject();
    webhookResponse.add("session_info", parameterObject);

    Gson gson = new GsonBuilder().setPrettyPrinting().create();
    String jsonResponseObject = gson.toJson(webhookResponse);

    /** { "session_info": { "parameters": { "order_number": "12345" } } } */
    BufferedWriter writer = response.getWriter();
    // Sends the webhookResponseObject
    writer.write(jsonResponseObject.toString());
  }
}

Node.js

CTS에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

const functions = require('@google-cloud/functions-framework');

functions.http('configureSessionParams', (request, response) => {
  // Session parameter configured by the webhook
  const orderNumber = 123;

  const jsonResponse = {
    sessionInfo: {
      parameters: {
        orderNumber: orderNumber,
      },
    },
  };

  response.send(jsonResponse);
});

Python

CTS에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

import functions_framework

# TODO (developer): change entry point to configure_session_params in Cloud Function


@functions_framework.http
def configure_session_params(request):
    """Webhook to validate or configure new session parameters."""

    order_number = 123

    json_response = {
        "sessionInfo": {
            "parameters": {
                "orderNumber": order_number,
            },
        },
    }

    return json_response

fulfillment 응답 반환

다음 샘플은 fulfillment 응답을 반환하는 방법을 보여줍니다.

Go

CTS에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

웹훅 빠른 시작을 참고하세요.

Java

CTS에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.


// TODO: Change class name to Example
// TODO: add GSON dependency to Pom file
// (https://mvnrepository.com/artifact/com.google.code.gson/gson/2.8.5)
// TODO: Uncomment the line bellow before running cloud function
// package com.example;

import com.google.cloud.functions.HttpFunction;
import com.google.cloud.functions.HttpRequest;
import com.google.cloud.functions.HttpResponse;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.io.BufferedWriter;

public class BasicWebhook implements HttpFunction {
  @Override
  public void service(HttpRequest request, HttpResponse response) throws Exception {
    Gson gson = new GsonBuilder().create();
    JsonObject parsedRequest = gson.fromJson(request.getReader(), JsonObject.class);

    // For more information on the structure of this object https://cloud.google.com/dialogflow/cx/docs/reference/rest/v3/Fulfillment
    String requestTag = parsedRequest.getAsJsonObject("fulfillmentInfo")
        .getAsJsonPrimitive("tag").toString();
    JsonObject responseObject = null;
    String defaultIntent = "\"Default Welcome Intent\"";
    String secondIntent = "\"get-agent-name\"";
    String responseText = "";

    // Compares the Intent Tag to provide the correct response 
    if (requestTag.equals(defaultIntent)) {
      responseText = "\"Hello from a Java GCF Webhook\"";
    } else if (requestTag.equals(secondIntent)) {
      responseText = "\"My name is Flowhook\"";
    } else {
      responseText = "\"Sorry I didn't get that\"";
    }

    // Constructing the response jsonObject 
    responseObject =
        JsonParser
            .parseString(
                "{ \"fulfillment_response\": { \"messages\": [ { \"text\": { \"text\": ["
                    + responseText
                    + "] } } ] } }")
            .getAsJsonObject();
    BufferedWriter writer = response.getWriter();

    //Sends the responseObject
    writer.write(responseObject.toString());
  }
}

Node.js

CTS에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

const functions = require('@google-cloud/functions-framework');

functions.http('handleWebhook', (request, response) => {
  const tag = request.body.fulfillmentInfo.tag;
  let text = '';

  if (tag === 'Default Welcome Intent') {
    text = 'Hello from a GCF Webhook';
  } else if (tag === 'get-name') {
    text = 'My name is Flowhook';
  } else {
    text = `There are no fulfillment responses defined for "${tag}"" tag`;
  }

  const jsonResponse = {
    fulfillment_response: {
      messages: [
        {
          text: {
            //fulfillment text response to be sent to the agent
            text: [text],
          },
        },
      ],
    },
  };

  response.send(jsonResponse);
});

Python

CTS에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

import functions_framework

# TODO(developer): change entry point to handle_webhook in cloud function


@functions_framework.http
def handle_webhook(request):
    req = request.get_json()

    tag = req["fulfillmentInfo"]["tag"]

    if tag == "Default Welcome Intent":
        text = "Hello from a GCF Webhook"
    elif tag == "get-name":
        text = "My name is Flowhook"
    else:
        text = f"There are no fulfillment responses defined for {tag} tag"

    # You can also use the google.cloud.dialogflowcx_v3.types.WebhookRequest protos instead of manually writing the json object
    # Please see https://googleapis.dev/python/dialogflow/latest/dialogflow_v2/types.html?highlight=webhookresponse#google.cloud.dialogflow_v2.types.WebhookResponse for an overview
    res = {"fulfillment_response": {"messages": [{"text": {"text": [text]}}]}}

    # Returns json
    return res

필요에 따라 양식 매개변수 설정

다음 샘플은 필요에 따라 매개변수를 플래그 지정하는 방법을 보여줍니다.

Java

CTS에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.


// TODO: Change class name to Example
// TODO: Uncomment the line below before running cloud function
// package com.example;

import com.google.cloud.functions.HttpFunction;
import com.google.cloud.functions.HttpRequest;
import com.google.cloud.functions.HttpResponse;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import java.io.BufferedWriter;

public class ConfigureWebhookToSetFormParametersAsOptionalOrRequired implements HttpFunction {
  @Override
  public void service(HttpRequest request, HttpResponse response) throws Exception {
    JsonObject parameterObject = new JsonObject();
    parameterObject.addProperty("display_name", "order_number");
    parameterObject.addProperty("required", "true");
    parameterObject.addProperty("state", "VALID");

    JsonArray parameterInfoList = new JsonArray();
    parameterInfoList.add(parameterObject);

    JsonObject parameterInfoObject = new JsonObject();
    parameterInfoObject.add("parameter_info", parameterInfoList);

    JsonObject formInfo = new JsonObject();
    formInfo.add("form_info", parameterInfoObject);

    // Constructs the webhook response object
    JsonObject webhookResponse = new JsonObject();
    webhookResponse.add("page_info", formInfo);

    Gson gson = new GsonBuilder().setPrettyPrinting().create();
    String jsonResponseObject = gson.toJson(webhookResponse);

    /* {
     *   "page_info": {
     *     "form_info": {
     *       "parameter_info": [
     *         {
     *           "display_name": "order_number",
     *           "required": "true",
     *           "state": "VALID"
     *         }
     *       ]
     *     }
     *   }
     * }
     */

    BufferedWriter writer = response.getWriter();

    // Sends the responseObject
    writer.write(jsonResponseObject.toString());
  }
}

Node.js

CTS에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

const functions = require('@google-cloud/functions-framework');

functions.http('configureOptionalFormParam', (request, response) => {
  // The value of the parameter that the webhook will set as optional or required.
  // Note that the webhook cannot add or remove any form parameter

  const jsonResponse = {
    pageInfo: {
      formInfo: {
        parameterInfo: [
          {
            displayName: 'order-number',
            // if required: false, the agent will not reprompt for this parameter, even if the state is 'INVALID'
            required: true,
            state: 'VALID',
          },
        ],
      },
    },
  };

  // Info about form parameter that is sent in the webhook response:
  console.log(
    'Parameter Info: \n',
    jsonResponse.pageInfo.formInfo.parameterInfo[0]
  );

  response.send(jsonResponse);
});

양식 매개변수 확인

다음 샘플은 양식 매개변수를 확인하는 방법을 보여줍니다.

Java

CTS에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.


// TODO: Change class name to Example
// TODO: Uncomment the line below before running cloud function
// package com.example;

import com.google.cloud.functions.HttpFunction;
import com.google.cloud.functions.HttpRequest;
import com.google.cloud.functions.HttpResponse;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import java.io.BufferedWriter;

public class WebhookValidateFormParameter implements HttpFunction {
  @Override
  public void service(HttpRequest request, HttpResponse response) throws Exception {
    JsonObject sessionInfo = new JsonObject();
    JsonObject sessionParameter = new JsonObject();

    sessionParameter.addProperty("order_number", "null");
    sessionInfo.add("parameters", sessionParameter);

    JsonObject parameterObject = new JsonObject();
    parameterObject.addProperty("display_name", "order_number");
    parameterObject.addProperty("required", "true");
    parameterObject.addProperty("state", "INVALID");
    parameterObject.addProperty("value", "123");

    JsonArray parameterInfoList = new JsonArray();
    parameterInfoList.add(parameterObject);

    JsonObject parameterInfoObject = new JsonObject();
    parameterInfoObject.add("parameter_info", parameterInfoList);

    JsonObject pageInfo = new JsonObject();
    pageInfo.add("form_info", parameterInfoObject);

    // Constructs the webhook response object
    JsonObject webhookResponse = new JsonObject();
    webhookResponse.add("page_info", pageInfo);
    webhookResponse.add("session_info", sessionInfo);

    Gson gson = new GsonBuilder().setPrettyPrinting().create();
    String jsonResponseObject = gson.toJson(webhookResponse);

    /**
     * { "page_info": { "form_info": { "parameter_info": [ { "display_name": "order_number",
     * "required": "true", "state": "INVALID", "value": "123" } ] } }, "session_info": {
     * "parameters": { "order_number": "null" } } }
     */
    BufferedWriter writer = response.getWriter();

    // Sends the responseObject
    writer.write(jsonResponseObject.toString());
  }
}

Node.js

CTS에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

const functions = require('@google-cloud/functions-framework');

functions.http('validateParameter', (request, response) => {
  // Webhook will validate or invalidate parameter based on logic configured by the user.
  // Access parameter values through the webhook request via `request.body.pageInfo.formInfo.parameterInfo[]`
  const jsonResponse = {
    page_info: {
      form_info: {
        parameter_info: [
          {
            displayName: 'orderNumber',
            required: true,
            state: 'INVALID',
            value: 123,
          },
        ],
      },
    },
    sessionInfo: {
      parameters: {
        // Set session parameter to null if the form parameter is 'INVALID' and your agent needs to reprompt the user
        orderNumber: null,
      },
    },
  };

  response.send(jsonResponse);
});

Python

CTS에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

import functions_framework


@functions_framework.http
def validate_parameter(request):
    """Webhook will validate or invalidate parameter based on logic configured by the user."""
    return {
        "page_info": {
            "form_info": {
                "parameter_info": [
                    {
                        "displayName": "orderNumber",
                        "required": True,
                        "state": "INVALID",
                        "value": 123,
                    },
                ],
            },
        },
        "sessionInfo": {
            "parameters": {
                # Set session parameter to None if the form parameter is 'INVALID' and your agent needs to reprompt the user
                "orderNumber": None,
            },
        },
    }

세션 ID 기록

다음 샘플은 웹훅 요청에서 session ID를 기록하는 방법을 보여줍니다.

Python

CTS에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.


import re

import functions_framework


@functions_framework.http
def log_session_id_for_troubleshooting(request):
    """Webhook will log session id corresponding to request."""

    req = request.get_json()
    # You can read more about SessionInfo at https://cloud.google.com/dialogflow/cx/docs/reference/rest/v3/SessionInfo
    # Use a regex pattern to get the session ID
    session_id_regex = r".+\/sessions\/(.+)"
    session = req["sessionInfo"]["session"]
    regex_match = re.search(session_id_regex, session)
    session_id = regex_match.group(1)

    # Instead of printing, use the logging tools available to you
    print(f"Debug Node: session ID = {session_id}")

    # Return a generic response
    res = {
        "fulfillment_response": {
            "messages": [{"text": {"text": [f"Request Session ID: {session_id}"]}}]
        }
    }

    # Returns json
    return res

문제 해결

웹훅 호출 수명

웹훅 호출은 항상 대화형 에이전트 (Dialogflow CX)에 의해 시작되며 HTTPS를 통해 웹 서버로 이동합니다. 일반 웹 서비스 웹훅 호출은 Google에 속한 인터넷 IP 주소에서 시작되며 공개 인터넷에서 사용할 수 있는 웹 서버 (웹훅 서버)에 연결할 수 있습니다. 반면 서비스 디렉터리 웹훅은 항상 내부Google Cloud 주소에서 시작되며 Google Cloud내의 비공개 네트워크에 있는 웹훅 서버에만 연결할 수 있습니다.

웹훅 디버깅에 유용한 로그

웹훅 문제를 디버깅하려면 일반적으로 Cloud Logging Dialogflow 로그와 웹훅 서버 로그를 수집해야 합니다. 웹훅 서버가 Cloud Run 함수를 사용하여 구현된 경우 로그는 Cloud Logging에 있습니다. 그렇지 않으면 로그는 일반적으로 웹훅 서버가 실행되는 위치에 있습니다.

표준 웹훅 로그에는 웹훅 서버에서 특정 호출을 추적하는 데 유용할 수 있는 UUID가 포함된 detectIntentResponseId 필드가 포함되어 있습니다. 이 로그는 Cloud Logging이 사용 설정된 경우 Dialogflow Cloud Logging 로그에 있습니다.

일반적인 웹훅 문제

웹훅 호출에 대한 Dialogflow 로그에서 발견할 수 있는 오류는 다음과 같습니다.

웹훅 서버 호스트 이름 확인 오류

Dialogflow가 일반 웹훅의 호스트 이름을 조회했지만 DNS에 호스트 이름이 없습니다. 호스트 이름이 공개 DNS에 등록되어 있는지 확인합니다. 호스트 이름이 새 이름인 경우 레코드가 전파되는 데 다소 시간이 걸릴 수 있습니다. Cloud Logging 메시지: State: URL_ERROR, Reason: ERROR_DNS

웹훅 서버가 클라이언트 측 오류를 반환함

ERROR_DNS을 제외하고 이 상태는 웹훅 서버의 4xx 응답을 나타냅니다. 승인되지 않은 상태 (401 - ERROR_AUTHENTICATION)이거나 URL을 웹훅 서버에서 찾을 수 없는 상태 (404 - ERROR_NOT_FOUND)일 수 있습니다. Cloud Logging 메시지: State: URL_ERROR

웹훅 서버가 응답을 반환하기 전에 Dialogflow 에이전트가 시간 초과됨

웹 서버가 완료되기 전에 Dialogflow가 웹훅 제한 시간에 도달했습니다. 여기서 가능한 두 가지 접근 방식은 웹훅 서버 처리 시간을 줄이거나 Dialogflow가 웹훅을 기다리는 시간을 늘리는 것입니다. 처리 시간을 줄이면 일반적으로 최상의 결과를 얻을 수 있지만, 많은 경우에 쉽지 않습니다. 웹훅에는 최대 시간 제한이 있으며 이 설정을 늘리기 전에 최종 호출자 또는 사용자가 상담사의 답변을 받기 위해 더 오래 기다려야 합니다. Cloud Logging 메시지: State: URL_TIMEOUT, Reason: TIMEOUT_WEB.

웹훅 서버가 응답을 반환하기 전에 gRPC가 시간 초과됨

웹훅 호출이 완료되기 전에 Dialogflow API 호출에서 gRPC에 의해 설정된 시간 제한에 도달했습니다. 이 한도는 일반적으로 통합 수준에서 설정되며 Dialogflow 매개변수 및 웹훅 제한 시간 한도와는 독립적입니다. gRPC 기한에 대한 자세한 내용은 https://grpc.io/docs/guides/deadlines/를 참고하세요. Cloud Logging 메시지: State: URL_REJECTED, Reason: REJECTED_DEADLINE_EXCEEDED.

Dialogflow가 웹훅 서버에 연결할 수 없음

네트워크 오류로 인해 웹훅 서버에 연결할 수 없거나 연결이 설정되었는데 웹훅 서버가 요청을 처리하는 중에 문제가 있음을 나타내는 HTTP 상태 5xx를 반환했습니다. Dialogflow가 네트워킹 수준에서 웹훅 서버 주소에 연결할 수 있는지 확인합니다. 요청이 웹훅 서버 로그에 표시되면 호출이 5xx 오류를 반환한 이유를 찾습니다. Cloud Logging 메시지: State: URL_UNREACHABLE

웹훅 호출 추적

표준 웹훅 호출은 세션 ID, detectIntentResponse ID, Cloud Run Functions의 추적 ID, 호출 타임스탬프를 사용하여 Dialogflow와 웹훅 서버 간에 상관관계를 지정할 수 있습니다. 유연한 웹훅 추적은 호출의 타임스탬프와 설계 시 웹훅 정의에 지정된 세션 매개변수 값을 사용하여 실행할 수 있습니다. 표준 및 유연한 웹훅 요청에 대한 자세한 내용은 웹훅을 참고하세요.

세션 ID는 WebhookRequestsessionInfo.session 필드에 표시됩니다. 이 세션 ID는 대화마다 고유해야 하며 동일한 세션 ID를 사용하는 요청에 대해 에이전트 로그와 웹훅 로그를 비교하는 데 도움이 될 수 있습니다. 이전 세션 ID 기록 섹션은 웹훅에서 세션 ID를 기록하는 방법을 보여줍니다.

또한 Cloud Run 함수 또는 유사한 Google Cloud 서버리스 옵션에 웹훅을 호스팅하는 경우 로그 항목trace 필드를 로그 필터로 사용할 수 있습니다. 함수를 한 번 실행하면 동일한 trace 값을 가진 여러 로그 항목이 생성됩니다.

다음 예시에서는 세션 ID와 추적 값을 모두 사용하여 특정 Dialogflow 에이전트 오류 로그를 해당 Cloud Run 함수 웹훅 로그 항목과 연결합니다. 이 예시에서는 Cloud Logging을 사용 설정한 에이전트에 Cloud Logging 필터를 사용합니다.

1. 특정 에이전트의 오류 로그에 대한 Dialogflow 로그 필터링

다음 Cloud Logging 필터를 사용하여 특정 에이전트의 오류 로그에 대한 Dialogflow 로그를 필터링합니다.

labels.location_id="global"
labels.agent_id="AGENT_ID"
severity=ERROR

웹훅 로그 오류 항목은 다음과 같습니다.

{
  "insertId": "-j4gkkre31e2o",
  "jsonPayload": {
    "code": 14,
    "message": "Error calling webhook 'https://us-central1-PROJECT_ID.cloudfunctions.net/function-webhook': State: URL_UNREACHABLE, Reason: UNREACHABLE_5xx, HTTP status code: 500"
  },
  "labels": {
    "agent_id": "e9e01392-1351-42dc-9b15-b583fb2d2881",
    "environment_id": "",
    "location_id": "global",
    "session_id": "07c899-a86-78b-a77-569625b37"
  },
  "logName": "projects/PROJECT_ID/logs/dialogflow-runtime.googleapis.com%2Frequests",
  "receiveTimestamp": "2024-10-28T21:49:04.288439054Z",
  "resource": {
    "labels": {
      "project_id": "PROJECT_ID"
    },
    "type": "global",
  },
  "severity": "ERROR",
  "timestamp": "2024-10-28T21:49:04.132548Z"
}

세션 ID가 포함된 labels.session_id 필드를 기록합니다. 다음 단계에서 세션 ID를 사용합니다.

2. 세션 ID별로 Cloud Run Functions 로그 필터링

다음 Cloud Logging 필터를 사용하여 세션 ID별로 Cloud Run 함수 로그를 필터링합니다.

resource.type = "cloud_run_revision"
resource.labels.service_name = "CLOUD_RUN_FUNCTION_NAME"
resource.labels.location = "CLOUD_RUN_FUNCTION_REGION"
textPayload="Debug Node: session ID = SESSION_ID"

결과 로그는 제공된 세션 중에 작성된 웹훅 로그에 해당합니다. 예를 들면 다음과 같습니다.

{
  "insertId": "671c42940007ebebdbb1d56e",
  "labels": {
    "execution_id": "pgy8jvvblovs",
    "goog-managed-by": "cloudfunctions",
    "instance_id": "004940b3b8e3d975a4b11a4ed7d1ded4ce3ed37467ffc5e2a8f13a1908db928f8200b01cc554a5eda66ffc9d23d76dd75cec1619a07cb5751fa2e8a93bc6cfc3df86dfa0650a"
  },
  "logName": "projects/PROJECT_ID/logs/run.googleapis.com%2Fstdout",
  "receiveTimestamp": "2024-10-26T01:15:00.523313187Z",
  "resource": {
    "labels": {
      "configuration_name": "function-webhook",
      "location": "us-central1",
      "project_id": "PROJECT_ID",
      "revision_name": "function-webhook-00001-jiv",
      "service_name": "function-webhook",
    },
    "type": "cloud_run_revision"
  },
  "spanId": "6938366936362981595",
  "trace": "d1b54fbc8945dd59bdcaed37d7d5e185",
  "textPayload": "Debug Node: session ID = 07c899-a86-78b-a77-569625b37",
  "timestamp": "2024-10-26T01:15:00.519147Z"
}

다음 단계에서 사용되는 trace 필드를 기록합니다.

3. 특정 trace에 대한 Cloud 함수 로그 필터링

다음 Cloud Logging 필터를 사용하여 특정 trace에 대한 Cloud 함수 로그를 필터링합니다.

resource.type = "cloud_run_revision"
resource.labels.service_name = "CLOUD_RUN_FUNCTION_NAME"
resource.labels.location = "CLOUD_RUN_FUNCTION_REGION"
trace="projects/PROJECT_ID/traces/TRACE_ID"

여기서 TRACE_ID는 trace의 마지막 세그먼트입니다. 예를 들어 projects/PROJECT_ID/traces/e41eefc1fac48665b442bfa400cc2f5eTRACE_IDe41eefc1fac48665b442bfa400cc2f5e입니다.

결과는 1단계의 세션 ID와 2단계의 트레이스와 연결된 웹훅 요청을 실행하는 동안 생성된 웹훅 서버 로그입니다. 로그는 다음과 같이 표시됩니다.

{
  "insertId": "671c42940008465e29f5faf0",
  "httpRequest": {
    "requestMethod": "POST",
    "requestUrl": "https://us-central1-TEST_PROJECT.cloudfunctions.net/function-webhook",
    "requestSize": "2410",
    "status": 200,
    "responseSize": "263",
    "userAgent": "Google-Dialogflow",
    "remoteIp": "8.34.210.1",
    "serverIp": "216.239.36.1",
    "latency": "0.166482342s",
    "protocol": "HTTP/1.1"
  },
  "resource": {
    "type": "cloud_run_revision",
    "labels": {
      "project_id": "PROJECT_ID",
      "service_name": "function-webhook",
      "location": "us-central1",
      "revision_name": "function-webhook-00001-jiv",
      "configuration_name": "function-webhook"
    }
  },
  "timestamp": "2024-10-26T01:15:00.352197Z",
  "severity": "INFO",
  "labels": {
    "instanceId": "004940b3b813af8a656c92aac1bd07ffad5165f1353e1e346b6161c14bcde225f68f4a88ceedc08aa9020f387b1b59471f73de45f2882a710ced37dea921f05ad962347690be",
    "goog-managed-by": "cloudfunctions"
  },
  "logName": "projects/test-project-12837/logs/run.googleapis.com%2Frequests",
  "trace": "projects/test-project-12837/traces/d1b54fbc8945dd59bdcaed37d7d5e185",
  "receiveTimestamp": "2024-10-26T01:15:00.548931586Z",
  "spanId": "604a07f7b33b18db",
  "traceSampled": true
}