The gcp:diagflow/cxWebhook:CxWebhook resource, part of the Pulumi GCP provider, defines webhooks that connect Dialogflow CX agents to external APIs for dynamic responses, validation, and backend actions. This guide focuses on three capabilities: standard webhook format with OAuth, flexible webhook format with custom requests, and Service Directory routing for private services.
Webhooks belong to Dialogflow CX agents and reference Secret Manager secrets for authentication. The examples are intentionally small. Combine them with your own agents, secrets, and backend services.
Connect to external APIs with standard webhook format
Dialogflow CX agents call external APIs to validate input, fetch data, or trigger backend actions. Standard webhooks provide structured request/response format with built-in authentication.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const agent = new gcp.diagflow.CxAgent("agent", {
displayName: "dialogflowcx-agent",
location: "global",
defaultLanguageCode: "en",
supportedLanguageCodes: [
"it",
"de",
"es",
],
timeZone: "America/New_York",
description: "Example description.",
avatarUri: "https://cloud.google.com/_static/images/cloud/icons/favicons/onecloud/super_cloud.png",
enableStackdriverLogging: true,
enableSpellCorrection: true,
speechToTextSettings: {
enableSpeechAdaptation: true,
},
});
const standardWebhook = new gcp.diagflow.CxWebhook("standard_webhook", {
parent: agent.id,
displayName: "MyFlow",
genericWebService: {
allowedCaCerts: ["BQA="],
uri: "https://example.com",
requestHeaders: {
"example-key": "example-value",
},
webhookType: "STANDARD",
oauthConfig: {
clientId: "example-client-id",
secretVersionForClientSecret: "projects/example-proj/secrets/example-secret/versions/example-version",
tokenEndpoint: "https://example.com",
scopes: ["example-scope"],
},
serviceAgentAuth: "NONE",
secretVersionForUsernamePassword: "projects/example-proj/secrets/example-secret/versions/example-version",
secretVersionsForRequestHeaders: [
{
key: "example-key-1",
secretVersion: "projects/example-proj/secrets/example-secret/versions/example-version",
},
{
key: "example-key-2",
secretVersion: "projects/example-proj/secrets/example-secret/versions/example-version-2",
},
],
},
});
import pulumi
import pulumi_gcp as gcp
agent = gcp.diagflow.CxAgent("agent",
display_name="dialogflowcx-agent",
location="global",
default_language_code="en",
supported_language_codes=[
"it",
"de",
"es",
],
time_zone="America/New_York",
description="Example description.",
avatar_uri="https://cloud.google.com/_static/images/cloud/icons/favicons/onecloud/super_cloud.png",
enable_stackdriver_logging=True,
enable_spell_correction=True,
speech_to_text_settings={
"enable_speech_adaptation": True,
})
standard_webhook = gcp.diagflow.CxWebhook("standard_webhook",
parent=agent.id,
display_name="MyFlow",
generic_web_service={
"allowed_ca_certs": ["BQA="],
"uri": "https://example.com",
"request_headers": {
"example-key": "example-value",
},
"webhook_type": "STANDARD",
"oauth_config": {
"client_id": "example-client-id",
"secret_version_for_client_secret": "projects/example-proj/secrets/example-secret/versions/example-version",
"token_endpoint": "https://example.com",
"scopes": ["example-scope"],
},
"service_agent_auth": "NONE",
"secret_version_for_username_password": "projects/example-proj/secrets/example-secret/versions/example-version",
"secret_versions_for_request_headers": [
{
"key": "example-key-1",
"secret_version": "projects/example-proj/secrets/example-secret/versions/example-version",
},
{
"key": "example-key-2",
"secret_version": "projects/example-proj/secrets/example-secret/versions/example-version-2",
},
],
})
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/diagflow"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
agent, err := diagflow.NewCxAgent(ctx, "agent", &diagflow.CxAgentArgs{
DisplayName: pulumi.String("dialogflowcx-agent"),
Location: pulumi.String("global"),
DefaultLanguageCode: pulumi.String("en"),
SupportedLanguageCodes: pulumi.StringArray{
pulumi.String("it"),
pulumi.String("de"),
pulumi.String("es"),
},
TimeZone: pulumi.String("America/New_York"),
Description: pulumi.String("Example description."),
AvatarUri: pulumi.String("https://cloud.google.com/_static/images/cloud/icons/favicons/onecloud/super_cloud.png"),
EnableStackdriverLogging: pulumi.Bool(true),
EnableSpellCorrection: pulumi.Bool(true),
SpeechToTextSettings: &diagflow.CxAgentSpeechToTextSettingsArgs{
EnableSpeechAdaptation: pulumi.Bool(true),
},
})
if err != nil {
return err
}
_, err = diagflow.NewCxWebhook(ctx, "standard_webhook", &diagflow.CxWebhookArgs{
Parent: agent.ID(),
DisplayName: pulumi.String("MyFlow"),
GenericWebService: &diagflow.CxWebhookGenericWebServiceArgs{
AllowedCaCerts: pulumi.StringArray{
pulumi.String("BQA="),
},
Uri: pulumi.String("https://example.com"),
RequestHeaders: pulumi.StringMap{
"example-key": pulumi.String("example-value"),
},
WebhookType: pulumi.String("STANDARD"),
OauthConfig: &diagflow.CxWebhookGenericWebServiceOauthConfigArgs{
ClientId: pulumi.String("example-client-id"),
SecretVersionForClientSecret: pulumi.String("projects/example-proj/secrets/example-secret/versions/example-version"),
TokenEndpoint: pulumi.String("https://example.com"),
Scopes: pulumi.StringArray{
pulumi.String("example-scope"),
},
},
ServiceAgentAuth: pulumi.String("NONE"),
SecretVersionForUsernamePassword: pulumi.String("projects/example-proj/secrets/example-secret/versions/example-version"),
SecretVersionsForRequestHeaders: diagflow.CxWebhookGenericWebServiceSecretVersionsForRequestHeaderArray{
&diagflow.CxWebhookGenericWebServiceSecretVersionsForRequestHeaderArgs{
Key: pulumi.String("example-key-1"),
SecretVersion: pulumi.String("projects/example-proj/secrets/example-secret/versions/example-version"),
},
&diagflow.CxWebhookGenericWebServiceSecretVersionsForRequestHeaderArgs{
Key: pulumi.String("example-key-2"),
SecretVersion: pulumi.String("projects/example-proj/secrets/example-secret/versions/example-version-2"),
},
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var agent = new Gcp.Diagflow.CxAgent("agent", new()
{
DisplayName = "dialogflowcx-agent",
Location = "global",
DefaultLanguageCode = "en",
SupportedLanguageCodes = new[]
{
"it",
"de",
"es",
},
TimeZone = "America/New_York",
Description = "Example description.",
AvatarUri = "https://cloud.google.com/_static/images/cloud/icons/favicons/onecloud/super_cloud.png",
EnableStackdriverLogging = true,
EnableSpellCorrection = true,
SpeechToTextSettings = new Gcp.Diagflow.Inputs.CxAgentSpeechToTextSettingsArgs
{
EnableSpeechAdaptation = true,
},
});
var standardWebhook = new Gcp.Diagflow.CxWebhook("standard_webhook", new()
{
Parent = agent.Id,
DisplayName = "MyFlow",
GenericWebService = new Gcp.Diagflow.Inputs.CxWebhookGenericWebServiceArgs
{
AllowedCaCerts = new[]
{
"BQA=",
},
Uri = "https://example.com",
RequestHeaders =
{
{ "example-key", "example-value" },
},
WebhookType = "STANDARD",
OauthConfig = new Gcp.Diagflow.Inputs.CxWebhookGenericWebServiceOauthConfigArgs
{
ClientId = "example-client-id",
SecretVersionForClientSecret = "projects/example-proj/secrets/example-secret/versions/example-version",
TokenEndpoint = "https://example.com",
Scopes = new[]
{
"example-scope",
},
},
ServiceAgentAuth = "NONE",
SecretVersionForUsernamePassword = "projects/example-proj/secrets/example-secret/versions/example-version",
SecretVersionsForRequestHeaders = new[]
{
new Gcp.Diagflow.Inputs.CxWebhookGenericWebServiceSecretVersionsForRequestHeaderArgs
{
Key = "example-key-1",
SecretVersion = "projects/example-proj/secrets/example-secret/versions/example-version",
},
new Gcp.Diagflow.Inputs.CxWebhookGenericWebServiceSecretVersionsForRequestHeaderArgs
{
Key = "example-key-2",
SecretVersion = "projects/example-proj/secrets/example-secret/versions/example-version-2",
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.diagflow.CxAgent;
import com.pulumi.gcp.diagflow.CxAgentArgs;
import com.pulumi.gcp.diagflow.inputs.CxAgentSpeechToTextSettingsArgs;
import com.pulumi.gcp.diagflow.CxWebhook;
import com.pulumi.gcp.diagflow.CxWebhookArgs;
import com.pulumi.gcp.diagflow.inputs.CxWebhookGenericWebServiceArgs;
import com.pulumi.gcp.diagflow.inputs.CxWebhookGenericWebServiceOauthConfigArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var agent = new CxAgent("agent", CxAgentArgs.builder()
.displayName("dialogflowcx-agent")
.location("global")
.defaultLanguageCode("en")
.supportedLanguageCodes(
"it",
"de",
"es")
.timeZone("America/New_York")
.description("Example description.")
.avatarUri("https://cloud.google.com/_static/images/cloud/icons/favicons/onecloud/super_cloud.png")
.enableStackdriverLogging(true)
.enableSpellCorrection(true)
.speechToTextSettings(CxAgentSpeechToTextSettingsArgs.builder()
.enableSpeechAdaptation(true)
.build())
.build());
var standardWebhook = new CxWebhook("standardWebhook", CxWebhookArgs.builder()
.parent(agent.id())
.displayName("MyFlow")
.genericWebService(CxWebhookGenericWebServiceArgs.builder()
.allowedCaCerts("BQA=")
.uri("https://example.com")
.requestHeaders(Map.of("example-key", "example-value"))
.webhookType("STANDARD")
.oauthConfig(CxWebhookGenericWebServiceOauthConfigArgs.builder()
.clientId("example-client-id")
.secretVersionForClientSecret("projects/example-proj/secrets/example-secret/versions/example-version")
.tokenEndpoint("https://example.com")
.scopes("example-scope")
.build())
.serviceAgentAuth("NONE")
.secretVersionForUsernamePassword("projects/example-proj/secrets/example-secret/versions/example-version")
.secretVersionsForRequestHeaders(
CxWebhookGenericWebServiceSecretVersionsForRequestHeaderArgs.builder()
.key("example-key-1")
.secretVersion("projects/example-proj/secrets/example-secret/versions/example-version")
.build(),
CxWebhookGenericWebServiceSecretVersionsForRequestHeaderArgs.builder()
.key("example-key-2")
.secretVersion("projects/example-proj/secrets/example-secret/versions/example-version-2")
.build())
.build())
.build());
}
}
resources:
agent:
type: gcp:diagflow:CxAgent
properties:
displayName: dialogflowcx-agent
location: global
defaultLanguageCode: en
supportedLanguageCodes:
- it
- de
- es
timeZone: America/New_York
description: Example description.
avatarUri: https://cloud.google.com/_static/images/cloud/icons/favicons/onecloud/super_cloud.png
enableStackdriverLogging: true
enableSpellCorrection: true
speechToTextSettings:
enableSpeechAdaptation: true
standardWebhook:
type: gcp:diagflow:CxWebhook
name: standard_webhook
properties:
parent: ${agent.id}
displayName: MyFlow
genericWebService:
allowedCaCerts:
- BQA=
uri: https://example.com
requestHeaders:
example-key: example-value
webhookType: STANDARD
oauthConfig:
clientId: example-client-id
secretVersionForClientSecret: projects/example-proj/secrets/example-secret/versions/example-version
tokenEndpoint: https://example.com
scopes:
- example-scope
serviceAgentAuth: NONE
secretVersionForUsernamePassword: projects/example-proj/secrets/example-secret/versions/example-version
secretVersionsForRequestHeaders:
- key: example-key-1
secretVersion: projects/example-proj/secrets/example-secret/versions/example-version
- key: example-key-2
secretVersion: projects/example-proj/secrets/example-secret/versions/example-version-2
The genericWebService property defines the webhook endpoint. The uri points to your API, while webhookType set to “STANDARD” uses Dialogflow’s structured request format. The oauthConfig block handles OAuth authentication: clientId identifies your application, secretVersionForClientSecret references a Secret Manager secret containing your client secret, and tokenEndpoint specifies where to obtain access tokens. Custom requestHeaders pass additional metadata to your API.
Customize request format with flexible webhooks
Some backend services require custom request formats that don’t match Dialogflow’s standard structure. Flexible webhooks let you control HTTP method, body, and parameter mapping.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const agent = new gcp.diagflow.CxAgent("agent", {
displayName: "dialogflowcx-agent",
location: "global",
defaultLanguageCode: "en",
supportedLanguageCodes: [
"it",
"de",
"es",
],
timeZone: "America/New_York",
description: "Example description.",
avatarUri: "https://cloud.google.com/_static/images/cloud/icons/favicons/onecloud/super_cloud.png",
enableStackdriverLogging: true,
enableSpellCorrection: true,
speechToTextSettings: {
enableSpeechAdaptation: true,
},
});
const flexibleWebhook = new gcp.diagflow.CxWebhook("flexible_webhook", {
parent: agent.id,
displayName: "MyFlow",
genericWebService: {
uri: "https://example.com",
requestHeaders: {
"example-key": "example-value",
},
webhookType: "FLEXIBLE",
oauthConfig: {
clientId: "example-client-id",
clientSecret: "projects/example-proj/secrets/example-secret/versions/example-version",
tokenEndpoint: "https://example.com",
},
serviceAgentAuth: "NONE",
httpMethod: "POST",
requestBody: "{\"example-key\": \"example-value\"}",
parameterMapping: {
"example-parameter": "examplePath",
},
},
});
import pulumi
import pulumi_gcp as gcp
agent = gcp.diagflow.CxAgent("agent",
display_name="dialogflowcx-agent",
location="global",
default_language_code="en",
supported_language_codes=[
"it",
"de",
"es",
],
time_zone="America/New_York",
description="Example description.",
avatar_uri="https://cloud.google.com/_static/images/cloud/icons/favicons/onecloud/super_cloud.png",
enable_stackdriver_logging=True,
enable_spell_correction=True,
speech_to_text_settings={
"enable_speech_adaptation": True,
})
flexible_webhook = gcp.diagflow.CxWebhook("flexible_webhook",
parent=agent.id,
display_name="MyFlow",
generic_web_service={
"uri": "https://example.com",
"request_headers": {
"example-key": "example-value",
},
"webhook_type": "FLEXIBLE",
"oauth_config": {
"client_id": "example-client-id",
"client_secret": "projects/example-proj/secrets/example-secret/versions/example-version",
"token_endpoint": "https://example.com",
},
"service_agent_auth": "NONE",
"http_method": "POST",
"request_body": "{\"example-key\": \"example-value\"}",
"parameter_mapping": {
"example-parameter": "examplePath",
},
})
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/diagflow"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
agent, err := diagflow.NewCxAgent(ctx, "agent", &diagflow.CxAgentArgs{
DisplayName: pulumi.String("dialogflowcx-agent"),
Location: pulumi.String("global"),
DefaultLanguageCode: pulumi.String("en"),
SupportedLanguageCodes: pulumi.StringArray{
pulumi.String("it"),
pulumi.String("de"),
pulumi.String("es"),
},
TimeZone: pulumi.String("America/New_York"),
Description: pulumi.String("Example description."),
AvatarUri: pulumi.String("https://cloud.google.com/_static/images/cloud/icons/favicons/onecloud/super_cloud.png"),
EnableStackdriverLogging: pulumi.Bool(true),
EnableSpellCorrection: pulumi.Bool(true),
SpeechToTextSettings: &diagflow.CxAgentSpeechToTextSettingsArgs{
EnableSpeechAdaptation: pulumi.Bool(true),
},
})
if err != nil {
return err
}
_, err = diagflow.NewCxWebhook(ctx, "flexible_webhook", &diagflow.CxWebhookArgs{
Parent: agent.ID(),
DisplayName: pulumi.String("MyFlow"),
GenericWebService: &diagflow.CxWebhookGenericWebServiceArgs{
Uri: pulumi.String("https://example.com"),
RequestHeaders: pulumi.StringMap{
"example-key": pulumi.String("example-value"),
},
WebhookType: pulumi.String("FLEXIBLE"),
OauthConfig: &diagflow.CxWebhookGenericWebServiceOauthConfigArgs{
ClientId: pulumi.String("example-client-id"),
ClientSecret: pulumi.String("projects/example-proj/secrets/example-secret/versions/example-version"),
TokenEndpoint: pulumi.String("https://example.com"),
},
ServiceAgentAuth: pulumi.String("NONE"),
HttpMethod: pulumi.String("POST"),
RequestBody: pulumi.String("{\"example-key\": \"example-value\"}"),
ParameterMapping: pulumi.StringMap{
"example-parameter": pulumi.String("examplePath"),
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var agent = new Gcp.Diagflow.CxAgent("agent", new()
{
DisplayName = "dialogflowcx-agent",
Location = "global",
DefaultLanguageCode = "en",
SupportedLanguageCodes = new[]
{
"it",
"de",
"es",
},
TimeZone = "America/New_York",
Description = "Example description.",
AvatarUri = "https://cloud.google.com/_static/images/cloud/icons/favicons/onecloud/super_cloud.png",
EnableStackdriverLogging = true,
EnableSpellCorrection = true,
SpeechToTextSettings = new Gcp.Diagflow.Inputs.CxAgentSpeechToTextSettingsArgs
{
EnableSpeechAdaptation = true,
},
});
var flexibleWebhook = new Gcp.Diagflow.CxWebhook("flexible_webhook", new()
{
Parent = agent.Id,
DisplayName = "MyFlow",
GenericWebService = new Gcp.Diagflow.Inputs.CxWebhookGenericWebServiceArgs
{
Uri = "https://example.com",
RequestHeaders =
{
{ "example-key", "example-value" },
},
WebhookType = "FLEXIBLE",
OauthConfig = new Gcp.Diagflow.Inputs.CxWebhookGenericWebServiceOauthConfigArgs
{
ClientId = "example-client-id",
ClientSecret = "projects/example-proj/secrets/example-secret/versions/example-version",
TokenEndpoint = "https://example.com",
},
ServiceAgentAuth = "NONE",
HttpMethod = "POST",
RequestBody = "{\"example-key\": \"example-value\"}",
ParameterMapping =
{
{ "example-parameter", "examplePath" },
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.diagflow.CxAgent;
import com.pulumi.gcp.diagflow.CxAgentArgs;
import com.pulumi.gcp.diagflow.inputs.CxAgentSpeechToTextSettingsArgs;
import com.pulumi.gcp.diagflow.CxWebhook;
import com.pulumi.gcp.diagflow.CxWebhookArgs;
import com.pulumi.gcp.diagflow.inputs.CxWebhookGenericWebServiceArgs;
import com.pulumi.gcp.diagflow.inputs.CxWebhookGenericWebServiceOauthConfigArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var agent = new CxAgent("agent", CxAgentArgs.builder()
.displayName("dialogflowcx-agent")
.location("global")
.defaultLanguageCode("en")
.supportedLanguageCodes(
"it",
"de",
"es")
.timeZone("America/New_York")
.description("Example description.")
.avatarUri("https://cloud.google.com/_static/images/cloud/icons/favicons/onecloud/super_cloud.png")
.enableStackdriverLogging(true)
.enableSpellCorrection(true)
.speechToTextSettings(CxAgentSpeechToTextSettingsArgs.builder()
.enableSpeechAdaptation(true)
.build())
.build());
var flexibleWebhook = new CxWebhook("flexibleWebhook", CxWebhookArgs.builder()
.parent(agent.id())
.displayName("MyFlow")
.genericWebService(CxWebhookGenericWebServiceArgs.builder()
.uri("https://example.com")
.requestHeaders(Map.of("example-key", "example-value"))
.webhookType("FLEXIBLE")
.oauthConfig(CxWebhookGenericWebServiceOauthConfigArgs.builder()
.clientId("example-client-id")
.clientSecret("projects/example-proj/secrets/example-secret/versions/example-version")
.tokenEndpoint("https://example.com")
.build())
.serviceAgentAuth("NONE")
.httpMethod("POST")
.requestBody("{\"example-key\": \"example-value\"}")
.parameterMapping(Map.of("example-parameter", "examplePath"))
.build())
.build());
}
}
resources:
agent:
type: gcp:diagflow:CxAgent
properties:
displayName: dialogflowcx-agent
location: global
defaultLanguageCode: en
supportedLanguageCodes:
- it
- de
- es
timeZone: America/New_York
description: Example description.
avatarUri: https://cloud.google.com/_static/images/cloud/icons/favicons/onecloud/super_cloud.png
enableStackdriverLogging: true
enableSpellCorrection: true
speechToTextSettings:
enableSpeechAdaptation: true
flexibleWebhook:
type: gcp:diagflow:CxWebhook
name: flexible_webhook
properties:
parent: ${agent.id}
displayName: MyFlow
genericWebService:
uri: https://example.com
requestHeaders:
example-key: example-value
webhookType: FLEXIBLE
oauthConfig:
clientId: example-client-id
clientSecret: projects/example-proj/secrets/example-secret/versions/example-version
tokenEndpoint: https://example.com
serviceAgentAuth: NONE
httpMethod: POST
requestBody: '{"example-key": "example-value"}'
parameterMapping:
example-parameter: examplePath
Setting webhookType to “FLEXIBLE” enables custom formatting. The httpMethod property specifies the HTTP verb (POST, GET, etc.), while requestBody defines the exact JSON payload sent to your API. The parameterMapping object extracts values from Dialogflow’s session parameters and maps them to your API’s expected structure. This gives you full control over request format when integrating with APIs that have specific requirements.
Route through Service Directory for private services
Backend services in private networks need Service Directory integration to avoid public exposure. Service Directory provides service discovery and routing for internal services.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const agent = new gcp.diagflow.CxAgent("agent", {
displayName: "dialogflowcx-agent",
location: "us-central1",
defaultLanguageCode: "en",
supportedLanguageCodes: [
"it",
"de",
"es",
],
timeZone: "America/New_York",
description: "Example description.",
avatarUri: "https://cloud.google.com/_static/images/cloud/icons/favicons/onecloud/super_cloud.png",
enableStackdriverLogging: true,
enableSpellCorrection: true,
speechToTextSettings: {
enableSpeechAdaptation: true,
},
});
const standardWebhook = new gcp.diagflow.CxWebhook("standard_webhook", {
parent: agent.id,
displayName: "MyFlow",
serviceDirectory: {
service: "projects/example-proj/locations/us-central1/namespaces/example-namespace/services/example-service",
genericWebService: {
allowedCaCerts: ["BQA="],
uri: "https://example.com",
requestHeaders: {
"example-key": "example-value",
},
webhookType: "STANDARD",
oauthConfig: {
clientId: "example-client-id",
secretVersionForClientSecret: "projects/example-proj/secrets/example-secret/versions/example-version",
tokenEndpoint: "https://example.com",
scopes: ["example-scope"],
},
serviceAgentAuth: "NONE",
secretVersionForUsernamePassword: "projects/example-proj/secrets/example-secret/versions/example-version",
secretVersionsForRequestHeaders: [
{
key: "example-key-1",
secretVersion: "projects/example-proj/secrets/example-secret/versions/example-version",
},
{
key: "example-key-2",
secretVersion: "projects/example-proj/secrets/example-secret/versions/example-version-2",
},
],
},
},
});
import pulumi
import pulumi_gcp as gcp
agent = gcp.diagflow.CxAgent("agent",
display_name="dialogflowcx-agent",
location="us-central1",
default_language_code="en",
supported_language_codes=[
"it",
"de",
"es",
],
time_zone="America/New_York",
description="Example description.",
avatar_uri="https://cloud.google.com/_static/images/cloud/icons/favicons/onecloud/super_cloud.png",
enable_stackdriver_logging=True,
enable_spell_correction=True,
speech_to_text_settings={
"enable_speech_adaptation": True,
})
standard_webhook = gcp.diagflow.CxWebhook("standard_webhook",
parent=agent.id,
display_name="MyFlow",
service_directory={
"service": "projects/example-proj/locations/us-central1/namespaces/example-namespace/services/example-service",
"generic_web_service": {
"allowed_ca_certs": ["BQA="],
"uri": "https://example.com",
"request_headers": {
"example-key": "example-value",
},
"webhook_type": "STANDARD",
"oauth_config": {
"client_id": "example-client-id",
"secret_version_for_client_secret": "projects/example-proj/secrets/example-secret/versions/example-version",
"token_endpoint": "https://example.com",
"scopes": ["example-scope"],
},
"service_agent_auth": "NONE",
"secret_version_for_username_password": "projects/example-proj/secrets/example-secret/versions/example-version",
"secret_versions_for_request_headers": [
{
"key": "example-key-1",
"secret_version": "projects/example-proj/secrets/example-secret/versions/example-version",
},
{
"key": "example-key-2",
"secret_version": "projects/example-proj/secrets/example-secret/versions/example-version-2",
},
],
},
})
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/diagflow"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
agent, err := diagflow.NewCxAgent(ctx, "agent", &diagflow.CxAgentArgs{
DisplayName: pulumi.String("dialogflowcx-agent"),
Location: pulumi.String("us-central1"),
DefaultLanguageCode: pulumi.String("en"),
SupportedLanguageCodes: pulumi.StringArray{
pulumi.String("it"),
pulumi.String("de"),
pulumi.String("es"),
},
TimeZone: pulumi.String("America/New_York"),
Description: pulumi.String("Example description."),
AvatarUri: pulumi.String("https://cloud.google.com/_static/images/cloud/icons/favicons/onecloud/super_cloud.png"),
EnableStackdriverLogging: pulumi.Bool(true),
EnableSpellCorrection: pulumi.Bool(true),
SpeechToTextSettings: &diagflow.CxAgentSpeechToTextSettingsArgs{
EnableSpeechAdaptation: pulumi.Bool(true),
},
})
if err != nil {
return err
}
_, err = diagflow.NewCxWebhook(ctx, "standard_webhook", &diagflow.CxWebhookArgs{
Parent: agent.ID(),
DisplayName: pulumi.String("MyFlow"),
ServiceDirectory: &diagflow.CxWebhookServiceDirectoryArgs{
Service: pulumi.String("projects/example-proj/locations/us-central1/namespaces/example-namespace/services/example-service"),
GenericWebService: &diagflow.CxWebhookServiceDirectoryGenericWebServiceArgs{
AllowedCaCerts: pulumi.StringArray{
pulumi.String("BQA="),
},
Uri: pulumi.String("https://example.com"),
RequestHeaders: pulumi.StringMap{
"example-key": pulumi.String("example-value"),
},
WebhookType: pulumi.String("STANDARD"),
OauthConfig: &diagflow.CxWebhookServiceDirectoryGenericWebServiceOauthConfigArgs{
ClientId: pulumi.String("example-client-id"),
SecretVersionForClientSecret: pulumi.String("projects/example-proj/secrets/example-secret/versions/example-version"),
TokenEndpoint: pulumi.String("https://example.com"),
Scopes: pulumi.StringArray{
pulumi.String("example-scope"),
},
},
ServiceAgentAuth: pulumi.String("NONE"),
SecretVersionForUsernamePassword: pulumi.String("projects/example-proj/secrets/example-secret/versions/example-version"),
SecretVersionsForRequestHeaders: diagflow.CxWebhookServiceDirectoryGenericWebServiceSecretVersionsForRequestHeaderArray{
&diagflow.CxWebhookServiceDirectoryGenericWebServiceSecretVersionsForRequestHeaderArgs{
Key: pulumi.String("example-key-1"),
SecretVersion: pulumi.String("projects/example-proj/secrets/example-secret/versions/example-version"),
},
&diagflow.CxWebhookServiceDirectoryGenericWebServiceSecretVersionsForRequestHeaderArgs{
Key: pulumi.String("example-key-2"),
SecretVersion: pulumi.String("projects/example-proj/secrets/example-secret/versions/example-version-2"),
},
},
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var agent = new Gcp.Diagflow.CxAgent("agent", new()
{
DisplayName = "dialogflowcx-agent",
Location = "us-central1",
DefaultLanguageCode = "en",
SupportedLanguageCodes = new[]
{
"it",
"de",
"es",
},
TimeZone = "America/New_York",
Description = "Example description.",
AvatarUri = "https://cloud.google.com/_static/images/cloud/icons/favicons/onecloud/super_cloud.png",
EnableStackdriverLogging = true,
EnableSpellCorrection = true,
SpeechToTextSettings = new Gcp.Diagflow.Inputs.CxAgentSpeechToTextSettingsArgs
{
EnableSpeechAdaptation = true,
},
});
var standardWebhook = new Gcp.Diagflow.CxWebhook("standard_webhook", new()
{
Parent = agent.Id,
DisplayName = "MyFlow",
ServiceDirectory = new Gcp.Diagflow.Inputs.CxWebhookServiceDirectoryArgs
{
Service = "projects/example-proj/locations/us-central1/namespaces/example-namespace/services/example-service",
GenericWebService = new Gcp.Diagflow.Inputs.CxWebhookServiceDirectoryGenericWebServiceArgs
{
AllowedCaCerts = new[]
{
"BQA=",
},
Uri = "https://example.com",
RequestHeaders =
{
{ "example-key", "example-value" },
},
WebhookType = "STANDARD",
OauthConfig = new Gcp.Diagflow.Inputs.CxWebhookServiceDirectoryGenericWebServiceOauthConfigArgs
{
ClientId = "example-client-id",
SecretVersionForClientSecret = "projects/example-proj/secrets/example-secret/versions/example-version",
TokenEndpoint = "https://example.com",
Scopes = new[]
{
"example-scope",
},
},
ServiceAgentAuth = "NONE",
SecretVersionForUsernamePassword = "projects/example-proj/secrets/example-secret/versions/example-version",
SecretVersionsForRequestHeaders = new[]
{
new Gcp.Diagflow.Inputs.CxWebhookServiceDirectoryGenericWebServiceSecretVersionsForRequestHeaderArgs
{
Key = "example-key-1",
SecretVersion = "projects/example-proj/secrets/example-secret/versions/example-version",
},
new Gcp.Diagflow.Inputs.CxWebhookServiceDirectoryGenericWebServiceSecretVersionsForRequestHeaderArgs
{
Key = "example-key-2",
SecretVersion = "projects/example-proj/secrets/example-secret/versions/example-version-2",
},
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.diagflow.CxAgent;
import com.pulumi.gcp.diagflow.CxAgentArgs;
import com.pulumi.gcp.diagflow.inputs.CxAgentSpeechToTextSettingsArgs;
import com.pulumi.gcp.diagflow.CxWebhook;
import com.pulumi.gcp.diagflow.CxWebhookArgs;
import com.pulumi.gcp.diagflow.inputs.CxWebhookServiceDirectoryArgs;
import com.pulumi.gcp.diagflow.inputs.CxWebhookServiceDirectoryGenericWebServiceArgs;
import com.pulumi.gcp.diagflow.inputs.CxWebhookServiceDirectoryGenericWebServiceOauthConfigArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var agent = new CxAgent("agent", CxAgentArgs.builder()
.displayName("dialogflowcx-agent")
.location("us-central1")
.defaultLanguageCode("en")
.supportedLanguageCodes(
"it",
"de",
"es")
.timeZone("America/New_York")
.description("Example description.")
.avatarUri("https://cloud.google.com/_static/images/cloud/icons/favicons/onecloud/super_cloud.png")
.enableStackdriverLogging(true)
.enableSpellCorrection(true)
.speechToTextSettings(CxAgentSpeechToTextSettingsArgs.builder()
.enableSpeechAdaptation(true)
.build())
.build());
var standardWebhook = new CxWebhook("standardWebhook", CxWebhookArgs.builder()
.parent(agent.id())
.displayName("MyFlow")
.serviceDirectory(CxWebhookServiceDirectoryArgs.builder()
.service("projects/example-proj/locations/us-central1/namespaces/example-namespace/services/example-service")
.genericWebService(CxWebhookServiceDirectoryGenericWebServiceArgs.builder()
.allowedCaCerts("BQA=")
.uri("https://example.com")
.requestHeaders(Map.of("example-key", "example-value"))
.webhookType("STANDARD")
.oauthConfig(CxWebhookServiceDirectoryGenericWebServiceOauthConfigArgs.builder()
.clientId("example-client-id")
.secretVersionForClientSecret("projects/example-proj/secrets/example-secret/versions/example-version")
.tokenEndpoint("https://example.com")
.scopes("example-scope")
.build())
.serviceAgentAuth("NONE")
.secretVersionForUsernamePassword("projects/example-proj/secrets/example-secret/versions/example-version")
.secretVersionsForRequestHeaders(
CxWebhookServiceDirectoryGenericWebServiceSecretVersionsForRequestHeaderArgs.builder()
.key("example-key-1")
.secretVersion("projects/example-proj/secrets/example-secret/versions/example-version")
.build(),
CxWebhookServiceDirectoryGenericWebServiceSecretVersionsForRequestHeaderArgs.builder()
.key("example-key-2")
.secretVersion("projects/example-proj/secrets/example-secret/versions/example-version-2")
.build())
.build())
.build())
.build());
}
}
resources:
agent:
type: gcp:diagflow:CxAgent
properties:
displayName: dialogflowcx-agent
location: us-central1
defaultLanguageCode: en
supportedLanguageCodes:
- it
- de
- es
timeZone: America/New_York
description: Example description.
avatarUri: https://cloud.google.com/_static/images/cloud/icons/favicons/onecloud/super_cloud.png
enableStackdriverLogging: true
enableSpellCorrection: true
speechToTextSettings:
enableSpeechAdaptation: true
standardWebhook:
type: gcp:diagflow:CxWebhook
name: standard_webhook
properties:
parent: ${agent.id}
displayName: MyFlow
serviceDirectory:
service: projects/example-proj/locations/us-central1/namespaces/example-namespace/services/example-service
genericWebService:
allowedCaCerts:
- BQA=
uri: https://example.com
requestHeaders:
example-key: example-value
webhookType: STANDARD
oauthConfig:
clientId: example-client-id
secretVersionForClientSecret: projects/example-proj/secrets/example-secret/versions/example-version
tokenEndpoint: https://example.com
scopes:
- example-scope
serviceAgentAuth: NONE
secretVersionForUsernamePassword: projects/example-proj/secrets/example-secret/versions/example-version
secretVersionsForRequestHeaders:
- key: example-key-1
secretVersion: projects/example-proj/secrets/example-secret/versions/example-version
- key: example-key-2
secretVersion: projects/example-proj/secrets/example-secret/versions/example-version-2
The serviceDirectory property wraps the genericWebService configuration and adds a service reference pointing to your Service Directory service. This routes webhook calls through Service Directory’s internal networking rather than the public internet. Note that the agent must be in a regional location (like us-central1) rather than global for Service Directory integration to work. This extends the standard webhook pattern from earlier with private network routing.
Beyond these examples
These snippets focus on specific webhook features: standard and flexible webhook formats, OAuth and basic authentication, and Service Directory integration for private services. They’re intentionally minimal rather than full conversational AI applications.
The examples reference pre-existing infrastructure such as Dialogflow CX agents, Secret Manager secrets for credentials, and Service Directory services for private routing. They focus on webhook configuration rather than provisioning the surrounding infrastructure.
To keep things focused, common webhook patterns are omitted, including:
- Webhook timeout configuration (timeout)
- Webhook disabling (disabled)
- CA certificate validation (allowedCaCerts)
- Service agent authentication (serviceAgentAuth options)
These omissions are intentional: the goal is to illustrate how each webhook feature is wired, not provide drop-in integration modules. See the Dialogflow CX Webhook resource reference for all available configuration options.
Let's configure GCP Dialogflow CX Webhooks
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Webhook Types & Configuration
secretVersionForClientSecret, while FLEXIBLE webhooks support direct secrets (clientSecret), custom HTTP methods (httpMethod), request bodies (requestBody), and parameter mapping (parameterMapping).oauthConfig within genericWebService. For STANDARD webhooks, use secretVersionForClientSecret with clientId, tokenEndpoint, and scopes. For FLEXIBLE webhooks, use clientSecret directly with clientId and tokenEndpoint.secretVersionForClientSecret and secretVersionsForRequestHeaders (pointing to Secret Manager versions). FLEXIBLE webhooks can use clientSecret directly as a string value.Deployment Options
genericWebService with a direct uri for simple deployments. Use serviceDirectory with a service reference when integrating with Service Directory for service discovery and management.serviceDirectory property with a service reference (format: projects/<Project ID>/locations/<Location ID>/namespaces/<namespace>/services/<service>), then nest your genericWebService configuration inside it.Resource Management
parent property is immutable. You must recreate the webhook if you need to change its parent agent.enableSpellCorrection, enableStackdriverLogging, securitySettings, and startFlow. These properties are deprecated and should not be used in new configurations.Using a different cloud?
Explore integration guides for other cloud providers: