The gcp:diagflow/cxWebhook:CxWebhook resource, part of the Pulumi GCP provider, defines webhooks that connect Dialogflow CX agents to external services for dynamic response generation, data validation, and backend actions. This guide focuses on three capabilities: OAuth and service account authentication, flexible request transformation, and Service Directory integration for private endpoints.
Webhooks belong to Dialogflow CX agents and reference Secret Manager secrets, Service Directory services, or service accounts. The examples are intentionally small. Combine them with your own agent configuration and backend services.
Call external APIs with OAuth authentication
Conversational agents often need to call external APIs to validate data or trigger backend actions. Standard webhooks provide OAuth-based authentication with support for custom headers and credentials.
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
When Dialogflow invokes the webhook, it first obtains an OAuth token from the tokenEndpoint using the clientId and secret stored in Secret Manager. The oauthConfig block defines the OAuth 2.0 client credentials flow. The secretVersionForClientSecret points to a Secret Manager version containing your client secret, and scopes define the requested OAuth permissions.
Transform requests with custom HTTP methods and body mapping
Some backend services require specific HTTP methods or custom request bodies that differ from Dialogflow’s default format. Flexible webhooks let you control the exact HTTP request structure.
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
The webhookType of “FLEXIBLE” enables custom request transformation. The httpMethod property sets the HTTP verb, requestBody defines a JSON template for the request payload, and parameterMapping extracts Dialogflow parameters into specific paths in your backend’s expected format. This gives you full control over how conversation data is sent to your service.
Authenticate to Google APIs with service accounts
When calling Google Cloud APIs or services that support Google authentication, service account authentication provides a simpler alternative to OAuth flows.
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 webhookUseServiceAccount = new gcp.diagflow.CxWebhook("webhook_use_service_account", {
parent: agent.id,
displayName: "MyWebhook",
genericWebService: {
uri: "https://example.googleapis.com",
webhookType: "STANDARD",
serviceAccountAuthConfig: {
serviceAccount: "my@service-account.com",
},
},
});
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,
})
webhook_use_service_account = gcp.diagflow.CxWebhook("webhook_use_service_account",
parent=agent.id,
display_name="MyWebhook",
generic_web_service={
"uri": "https://example.googleapis.com",
"webhook_type": "STANDARD",
"service_account_auth_config": {
"service_account": "my@service-account.com",
},
})
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, "webhook_use_service_account", &diagflow.CxWebhookArgs{
Parent: agent.ID(),
DisplayName: pulumi.String("MyWebhook"),
GenericWebService: &diagflow.CxWebhookGenericWebServiceArgs{
Uri: pulumi.String("https://example.googleapis.com"),
WebhookType: pulumi.String("STANDARD"),
ServiceAccountAuthConfig: &diagflow.CxWebhookGenericWebServiceServiceAccountAuthConfigArgs{
ServiceAccount: pulumi.String("my@service-account.com"),
},
},
})
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 webhookUseServiceAccount = new Gcp.Diagflow.CxWebhook("webhook_use_service_account", new()
{
Parent = agent.Id,
DisplayName = "MyWebhook",
GenericWebService = new Gcp.Diagflow.Inputs.CxWebhookGenericWebServiceArgs
{
Uri = "https://example.googleapis.com",
WebhookType = "STANDARD",
ServiceAccountAuthConfig = new Gcp.Diagflow.Inputs.CxWebhookGenericWebServiceServiceAccountAuthConfigArgs
{
ServiceAccount = "my@service-account.com",
},
},
});
});
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.CxWebhookGenericWebServiceServiceAccountAuthConfigArgs;
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 webhookUseServiceAccount = new CxWebhook("webhookUseServiceAccount", CxWebhookArgs.builder()
.parent(agent.id())
.displayName("MyWebhook")
.genericWebService(CxWebhookGenericWebServiceArgs.builder()
.uri("https://example.googleapis.com")
.webhookType("STANDARD")
.serviceAccountAuthConfig(CxWebhookGenericWebServiceServiceAccountAuthConfigArgs.builder()
.serviceAccount("my@service-account.com")
.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
webhookUseServiceAccount:
type: gcp:diagflow:CxWebhook
name: webhook_use_service_account
properties:
parent: ${agent.id}
displayName: MyWebhook
genericWebService:
uri: https://example.googleapis.com
webhookType: STANDARD
serviceAccountAuthConfig:
serviceAccount: my@service-account.com
The serviceAccountAuthConfig block replaces OAuth configuration when calling Google APIs. Dialogflow uses the specified service account to generate short-lived tokens automatically. The service account must have appropriate IAM permissions for the target API.
Route through Service Directory for private endpoints
Applications running in private networks need Service Directory integration to resolve internal service endpoints without exposing them publicly.
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 block wraps the genericWebService configuration and adds a service property that points to a Service Directory service path. Dialogflow resolves the service endpoint through Service Directory, enabling connections to private VPC services. The agent location must match the Service Directory region.
Beyond these examples
These snippets focus on specific webhook features: OAuth and service account authentication, flexible request transformation, and Service Directory integration. They’re intentionally minimal rather than full conversational flows.
The examples reference pre-existing infrastructure such as Dialogflow CX agents, Secret Manager secrets for credentials, Service Directory namespaces and services, and service accounts with appropriate permissions. 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)
- Multiple authentication methods in one webhook
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
httpMethod), custom request bodies (requestBody), and parameter mapping (parameterMapping) for more control over webhook requests.genericWebService for direct URI-based webhooks where you specify the endpoint URL directly. Use serviceDirectory when integrating with Google Cloud Service Directory for service discovery, which nests the genericWebService configuration within the Service Directory service reference.Authentication & Security
You have three authentication options:
- OAuth - Use
oauthConfigwith client ID, token endpoint, and secret references - Service Account - Use
serviceAccountAuthConfigwith a service account email (simpler option) - None - Set
serviceAgentAuthto “NONE” for unauthenticated requests
secretVersionForClientSecret for OAuth secrets and secretVersionsForRequestHeaders for header secrets (references to Secret Manager versions). For FLEXIBLE webhooks, use clientSecret directly with the secret version path.Agent Integration & Properties
parent property is immutable after creation. You must recreate the webhook if you need to associate it with a different agent.parent property requires the format: projects/<Project ID>/locations/<Location ID>/agents/<Agent ID>. This identifies the Dialogflow CX agent that will use the webhook.disabled property to true to disable the webhook while keeping its configuration intact.Deprecated Features
enableSpellCorrection (spell correction setting), enableStackdriverLogging (logging setting), securitySettings (security reference), and startFlow (start flow reference). These properties are maintained for backward compatibility but should not be used in new configurations.Using a different cloud?
Explore integration guides for other cloud providers: