Restez organisé à l'aide des collections
Enregistrez et classez les contenus selon vos préférences.
L'agent prédéfini que vous avez créé à l'étape précédente ne peut pas fournir de données dynamiques telles que les soldes de compte, car tout est codé en dur dans l'agent.
À cette étape du tutoriel, vous allez créer un webhook pouvant fournir des données dynamiques à l'agent.
Les fonctions Cloud Run sont utilisées pour héberger le webhook dans ce tutoriel en raison de leur simplicité, mais il existe de nombreuses autres façons d'héberger un service de webhook.
L'exemple utilise également le langage de programmation Go, mais vous pouvez utiliser n'importe quel langage compatible avec les fonctions Cloud Run.
Il est important que votre agent Dialogflow et la fonction se trouvent dans le même projet.
Il s'agit du moyen le plus simple pour Dialogflow d'accéder de manière sécurisée à votre fonction.
Avant de créer la fonction, sélectionnez votre projet dans la console Google Cloud .
Cliquez sur Créer une fonction, puis définissez les champs suivants:
Environnement: 1re génération
Nom de la fonction: tutorial-banking-webhook
Région: si vous avez spécifié une région pour votre agent, utilisez la même région.
Type de déclencheur HTTP: HTTP
URL: cliquez sur le bouton de copie et enregistrez la valeur.
Vous en aurez besoin pour configurer le webhook.
Authentification: exigez l'authentification.
Nécessite le protocole HTTPS: cochez cette case.
Cliquez sur Enregistrer.
Cliquez sur Suivant (vous n'avez pas besoin de paramètres d'exécution, de compilation, de connexion ni de sécurité spéciaux).
Attribuez aux champs suivants les valeurs correspondantes :
Environnement d'exécution: sélectionnez le dernier environnement d'exécution Go.
Code source: Éditeur intégré
Point d'entrée: HandleWebhookRequest
Remplacez le code par le code suivant:
packageestwhimport("context""encoding/json""fmt""log""net/http""os""strings""cloud.google.com/go/spanner""google.golang.org/grpc/codes")//clientisaSpannerclient,createdonlyoncetoavoidcreation//foreveryrequest.//See:https://cloud.google.com/functions/docs/concepts/go-runtime#one-time_initializationvarclient*spanner.Clientfuncinit(){//Ifusingadatabase,theseenvironmentvariableswillbeset.pid:=os.Getenv("PROJECT_ID")iid:=os.Getenv("SPANNER_INSTANCE_ID")did:=os.Getenv("SPANNER_DATABASE_ID")ifpid!="" && iid!="" && did!=""{db:=fmt.Sprintf("projects/%s/instances/%s/databases/%s",pid,iid,did)log.Printf("Creating Spanner client for %s",db)varerrerror//Usethebackgroundcontextwhencreatingtheclient,//butusetherequestcontextforcallstotheclient.//See:https://cloud.google.com/functions/docs/concepts/go-runtime#contextcontextclient,err=spanner.NewClient(context.Background(),db)iferr!=nil{log.Fatalf("spanner.NewClient: %v",err)}}}typequeryResultstruct{Actionstring`json:"action"`Parametersmap[string]interface{}`json:"parameters"`}typetextstruct{Text[]string`json:"text"`}typemessagestruct{Texttext`json:"text"`}//webhookRequestisusedtounmarshalaWebhookRequestJSONobject.Notethat//notallmembersneedtobedefined--justthosethatyouneedtoprocess.//Asanalternative,youcouldusethetypesprovidedby//theDialogflowprotocolbuffers://https://godoc.org/google.golang.org/genproto/googleapis/cloud/dialogflow/v2#WebhookRequesttypewebhookRequeststruct{Sessionstring`json:"session"`ResponseIDstring`json:"responseId"`QueryResultqueryResult`json:"queryResult"`}//webhookResponseisusedtomarshalaWebhookResponseJSONobject.Notethat//notallmembersneedtobedefined--justthosethatyouneedtoprocess.//Asanalternative,youcouldusethetypesprovidedby//theDialogflowprotocolbuffers://https://godoc.org/google.golang.org/genproto/googleapis/cloud/dialogflow/v2#WebhookResponsetypewebhookResponsestruct{FulfillmentMessages[]message`json:"fulfillmentMessages"`}//accountBalanceCheckhandlesthesimilarnamedactionfuncaccountBalanceCheck(ctxcontext.Context,requestwebhookRequest)(webhookResponse,error){account:=request.QueryResult.Parameters["account"].(string)account=strings.ToLower(account)vartablestringifaccount=="savings account"{table="Savings"}else{table="Checking"}s:="Your balance is $0"ifclient!=nil{//ASpannerclientexists,soaccessthedatabase.//See:https://pkg.go.dev/cloud.google.com/go/spanner#ReadOnlyTransaction.ReadRowrow,err:=client.Single().ReadRow(ctx,table,spanner.Key{1},//TheaccountID[]string{"Balance"})iferr!=nil{ifspanner.ErrCode(err)==codes.NotFound{log.Printf("Account %d not found",1)}else{returnwebhookResponse{},err}}else{//Arowwasreturned,socheckthevaluevarbalanceint64err:=row.Column(0, &balance)iferr!=nil{returnwebhookResponse{},err}s=fmt.Sprintf("Your balance is $%.2f",float64(balance)/100.0)}}response:=webhookResponse{FulfillmentMessages:[]message{{Text:text{Text:[]string{s},},},},}returnresponse,nil}//Defineatypeforhandlerfunctions.typehandlerFnfunc(ctxcontext.Context,requestwebhookRequest)(webhookResponse,error)//Createamapfromactiontohandlerfunction.varhandlersmap[string]handlerFn=map[string]handlerFn{"account.balance.check":accountBalanceCheck,}//handleErrorhandlesinternalerrors.funchandleError(whttp.ResponseWriter,errerror){log.Printf("ERROR: %v",err)http.Error(w,fmt.Sprintf("ERROR: %v",err),http.StatusInternalServerError)}//HandleWebhookRequesthandlesWebhookRequestandsendstheWebhookResponse.funcHandleWebhookRequest(whttp.ResponseWriter,r*http.Request){varrequestwebhookRequestvarresponsewebhookResponsevarerrerror//ReadinputJSONiferr=json.NewDecoder(r.Body).Decode(&request);err!=nil{handleError(w,err)return}log.Printf("Request: %+v",request)//Gettheactionfromtherequest,andcallthecorresponding//functionthathandlesthataction.action:=request.QueryResult.Actioniffn,ok:=handlers[action];ok{response,err=fn(r.Context(),request)}else{err=fmt.Errorf("Unknown action: %s",action)}iferr!=nil{handleError(w,err)return}log.Printf("Response: %+v",response)//Sendresponseiferr=json.NewEncoder(w).Encode(&response);err!=nil{handleError(w,err)return}}
Cliquez sur Déployer.
Attendez que l'indicateur d'état indique que la fonction a bien été déployée.
Pendant que vous attendez, examinez le code que vous venez de déployer.
Configurer le webhook de votre agent
Maintenant que le webhook existe en tant que service, vous devez l'associer à votre agent.
Cela se fait via l'exécution.
Pour activer et gérer le fulfillment pour votre agent:
Sélectionnez l'agent prédéfini que vous venez de créer.
Dans le menu de la barre latérale de gauche, sélectionnez Fulfillment.
Définissez le champ Webhook sur Enabled (Activé).
Indiquez l'URL que vous avez copiée ci-dessus.
Laissez tous les autres champs vides.
Cliquez sur Enregistrer au bas de la page.
Maintenant que le fulfillment est activé pour l'agent, vous devez activer le fulfillment pour un intent:
Cliquez sur Intents dans le menu de la barre latérale gauche.
Sélectionnez l'intent account.balance.check.
Faites défiler la page jusqu'à la section Fulfillment.
Activez l'option Activer l'appel webhook pour cet intent.
Cliquez sur Enregistrer.
Essayer l'agent
Votre agent est maintenant prêt à être testé.
Cliquez sur le bouton Tester l'agent pour ouvrir le simulateur.
Essayez de tenir la conversation suivante avec l'agent:
Tour de parole
Vous
Agent
1
Bonjour,
Bonjour, merci d'avoir choisi la banque ACME.
2
Je souhaite connaître le solde de mon compte
Pour quel compte souhaitez-vous connaître le solde: compte d'épargne ou compte courant ?
3
Vérification…
Voici votre dernier solde: 0,00 $
Lors du troisième tour de conversation, vous avez indiqué "compte courant" comme type de compte.
L'intent account.balance.check comporte un paramètre appelé account.
Ce paramètre est défini sur "checking" (vérification) dans cette conversation.
L'intent a également une valeur d'action de "account.balance.check".
Le service de webhook est appelé et les valeurs du paramètre et de l'action lui sont transmises.
Si vous examinez le code du webhook ci-dessus, vous constaterez que cette action déclenche l'appel d'une fonction portant un nom similaire.
La fonction détermine le solde du compte.
La fonction vérifie si des variables d'environnement spécifiques sont définies avec des informations permettant de se connecter à la base de données.
Si ces variables d'environnement ne sont pas définies, la fonction utilise un solde de compte codé en dur.
Dans les étapes suivantes, vous allez modifier l'environnement de la fonction pour qu'elle récupère des données à partir d'une base de données.
Dépannage
Le code du webhook inclut des instructions de journalisation.
Si vous rencontrez des problèmes, essayez d'afficher les journaux de votre fonction.
En savoir plus
Pour en savoir plus sur les étapes ci-dessus, consultez les ressources suivantes:
Sauf indication contraire, le contenu de cette page est régi par une licence Creative Commons Attribution 4.0, et les échantillons de code sont régis par une licence Apache 2.0. Pour en savoir plus, consultez les Règles du site Google Developers. Java est une marque déposée d'Oracle et/ou de ses sociétés affiliées.
Dernière mise à jour le 2025/09/04 (UTC).
[[["Facile à comprendre","easyToUnderstand","thumb-up"],["J'ai pu résoudre mon problème","solvedMyProblem","thumb-up"],["Autre","otherUp","thumb-up"]],[["Difficile à comprendre","hardToUnderstand","thumb-down"],["Informations ou exemple de code incorrects","incorrectInformationOrSampleCode","thumb-down"],["Il n'y a pas l'information/les exemples dont j'ai besoin","missingTheInformationSamplesINeed","thumb-down"],["Problème de traduction","translationIssue","thumb-down"],["Autre","otherDown","thumb-down"]],["Dernière mise à jour le 2025/09/04 (UTC)."],[[["\u003cp\u003eThis tutorial guides you through creating a webhook using Cloud Run functions to provide dynamic data, such as account balances, to a Dialogflow agent, enhancing its capabilities beyond hardcoded responses.\u003c/p\u003e\n"],["\u003cp\u003eThe webhook, hosted via Cloud Run functions, interacts with the Dialogflow agent through fulfillment, and this interaction is triggered by specific intents, in this example, the 'account.balance.check' intent.\u003c/p\u003e\n"],["\u003cp\u003eThe example uses the Go programming language to develop the webhook code, which can be viewed and edited inline within the Google Cloud console, and handles requests and responses between Dialogflow and a potential database.\u003c/p\u003e\n"],["\u003cp\u003eTo set up the webhook, you must first create a Cloud Run function within the same Google Cloud project as your Dialogflow agent, ensuring secure access, then configure fulfillment within Dialogflow, associating it with the created function's URL.\u003c/p\u003e\n"],["\u003cp\u003eAfter enabling the webhook for specific intents and configuring fulfillment, you can test the enhanced Dialogflow agent using the simulator, where the agent can now retrieve and display dynamic account balance information.\u003c/p\u003e\n"]]],[],null,["# Create a webhook service\n\nThe prebuilt agent you created in the last step\ncannot provide dynamic data like account balances,\nbecause everything is hardcoded into the agent.\nIn this step of the tutorial,\nyou will create a\n[webhook](/dialogflow/es/docs/fulfillment-overview)\nthat can provide dynamic data to the agent.\n[Cloud Run functions](/functions/docs)\nare used to host the webhook in this tutorial due to their simplicity,\nbut there are many other ways that you could host a webhook service.\nThe example also uses the Go programming language,\nbut you can use any\n[language supported by Cloud Run functions](/functions/docs/concepts/exec).\n\nCreate the Function\n-------------------\n\nCloud Run functions can be created with the Google Cloud console ([visit documentation](https://support.google.com/cloud/answer/3465889?ref_topic=3340599), [open console](https://console.cloud.google.com/)).\nTo create a function for this tutorial:\n\n1. It is important that your Dialogflow agent and the function\n are both in the same project.\n This is the easiest way for Dialogflow to have\n [secure access to your function](/dialogflow/es/docs/fulfillment-webhook#gcf).\n Before creating the function,\n select your project from the Google Cloud console.\n\n [Go to project selector](https://console.cloud.google.com/projectselector2/home/dashboard)\n2. Open the Cloud Run functions overview page.\n\n [Go to Cloud Run functions overview](https://console.cloud.google.com/functions/list)\n3. Click **Create Function**, and set the following fields:\n\n - **Environment**: 1st gen\n - **Function name**: tutorial-banking-webhook\n - **Region**: If you specified a region for your agent, use the same region.\n - **HTTP Trigger type**: HTTP\n - **URL**: Click the copy button here and save the value. You will need this URL when configuring the webhook.\n - **Authentication**: Require authentication\n - **Require HTTPS**: checked\n4. Click **Save**.\n\n5. Click **Next** (You do not need special runtime, build,\n connections, or security settings).\n\n6. Set the following fields:\n\n - **Runtime**: Select the latest Go runtime.\n - **Source code**: Inline Editor\n - **Entry point**: HandleWebhookRequest\n7. Replace the code with the following:\n\n ```python\n package estwh\n\n import (\n \t\"context\"\n \t\"encoding/json\"\n \t\"fmt\"\n \t\"log\"\n \t\"net/http\"\n \t\"os\"\n \t\"strings\"\n\n \t\"cloud.google.com/go/spanner\"\n \"google.golang.org/grpc/codes\"\n )\n\n // client is a Spanner client, created only once to avoid creation\n // for every request.\n // See: https://cloud.google.com/functions/docs/concepts/go-runtime#one-time_initialization\n var client *spanner.Client\n\n func init() {\n \t// If using a database, these environment variables will be set.\n \tpid := os.Getenv(\"PROJECT_ID\")\n \tiid := os.Getenv(\"SPANNER_INSTANCE_ID\")\n \tdid := os.Getenv(\"SPANNER_DATABASE_ID\")\n \tif pid != \"\" && iid != \"\" && did != \"\" {\n \t\tdb := fmt.Sprintf(\"projects/%s/instances/%s/databases/%s\",\n \t\t\tpid, iid, did)\n \t\tlog.Printf(\"Creating Spanner client for %s\", db)\n \t\tvar err error\n \t\t// Use the background context when creating the client,\n \t\t// but use the request context for calls to the client.\n \t\t// See: https://cloud.google.com/functions/docs/concepts/go-runtime#contextcontext\n \t\tclient, err = spanner.NewClient(context.Background(), db)\n \t\tif err != nil {\n \t\t\tlog.Fatalf(\"spanner.NewClient: %v\", err)\n \t\t}\n \t}\n }\n\n type queryResult struct {\n \tAction string `json:\"action\"`\n \tParameters map[string]interface{} `json:\"parameters\"`\n }\n\n type text struct {\n \tText []string `json:\"text\"`\n }\n\n type message struct {\n \tText text `json:\"text\"`\n }\n\n // webhookRequest is used to unmarshal a WebhookRequest JSON object. Note that\n // not all members need to be defined--just those that you need to process.\n // As an alternative, you could use the types provided by\n // the Dialogflow protocol buffers:\n // https://godoc.org/google.golang.org/genproto/googleapis/cloud/dialogflow/v2#WebhookRequest\n type webhookRequest struct {\n \tSession string `json:\"session\"`\n \tResponseID string `json:\"responseId\"`\n \tQueryResult queryResult `json:\"queryResult\"`\n }\n\n // webhookResponse is used to marshal a WebhookResponse JSON object. Note that\n // not all members need to be defined--just those that you need to process.\n // As an alternative, you could use the types provided by\n // the Dialogflow protocol buffers:\n // https://godoc.org/google.golang.org/genproto/googleapis/cloud/dialogflow/v2#WebhookResponse\n type webhookResponse struct {\n \tFulfillmentMessages []message `json:\"fulfillmentMessages\"`\n }\n\n // accountBalanceCheck handles the similar named action\n func accountBalanceCheck(ctx context.Context, request webhookRequest) (\n \twebhookResponse, error) {\n \taccount := request.QueryResult.Parameters[\"account\"].(string)\n \taccount = strings.ToLower(account)\n \tvar table string\n \tif account == \"savings account\" {\n \t\ttable = \"Savings\"\n \t} else {\n \t\ttable = \"Checking\"\n \t}\n \ts := \"Your balance is $0\"\n \tif client != nil {\n \t\t// A Spanner client exists, so access the database.\n \t\t// See: https://pkg.go.dev/cloud.google.com/go/spanner#ReadOnlyTransaction.ReadRow\n \t\trow, err := client.Single().ReadRow(ctx,\n \t\t\ttable,\n \t\t\tspanner.Key{1}, // The account ID\n \t\t\t[]string{\"Balance\"})\n \t\tif err != nil {\n \t\t\tif spanner.ErrCode(err) == codes.NotFound {\n \t\t\t\tlog.Printf(\"Account %d not found\", 1)\n \t\t\t} else {\n \t\t\t\treturn webhookResponse{}, err\n \t\t\t}\n \t\t} else {\n \t\t\t// A row was returned, so check the value\n \t\t\tvar balance int64\n \t\t\terr := row.Column(0, &balance)\n \t\t\tif err != nil {\n \t\t\t\treturn webhookResponse{}, err\n \t\t\t}\n \t\t\ts = fmt.Sprintf(\"Your balance is $%.2f\", float64(balance)/100.0)\n \t\t}\n \t}\n \tresponse := webhookResponse{\n \t\tFulfillmentMessages: []message{\n \t\t\t{\n \t\t\t\tText: text{\n \t\t\t\t\tText: []string{s},\n \t\t\t\t},\n \t\t\t},\n \t\t},\n \t}\n \treturn response, nil\n }\n\n // Define a type for handler functions.\n type handlerFn func(ctx context.Context, request webhookRequest) (\n \twebhookResponse, error)\n\n // Create a map from action to handler function.\n var handlers map[string]handlerFn = map[string]handlerFn{\n \t\"account.balance.check\": accountBalanceCheck,\n }\n\n // handleError handles internal errors.\n func handleError(w http.ResponseWriter, err error) {\n \tlog.Printf(\"ERROR: %v\", err)\n \thttp.Error(w,\n \t\tfmt.Sprintf(\"ERROR: %v\", err),\n \t\thttp.StatusInternalServerError)\n }\n\n // HandleWebhookRequest handles WebhookRequest and sends the WebhookResponse.\n func HandleWebhookRequest(w http.ResponseWriter, r *http.Request) {\n \tvar request webhookRequest\n \tvar response webhookResponse\n \tvar err error\n\n \t// Read input JSON\n \tif err = json.NewDecoder(r.Body).Decode(&request); err != nil {\n \t\thandleError(w, err)\n \t\treturn\n \t}\n \tlog.Printf(\"Request: %+v\", request)\n\n \t// Get the action from the request, and call the corresponding\n \t// function that handles that action.\n \taction := request.QueryResult.Action\n \tif fn, ok := handlers[action]; ok {\n \t\tresponse, err = fn(r.Context(), request)\n \t} else {\n \t\terr = fmt.Errorf(\"Unknown action: %s\", action)\n \t}\n \tif err != nil {\n \t\thandleError(w, err)\n \t\treturn\n \t}\n \tlog.Printf(\"Response: %+v\", response)\n\n \t// Send response\n \tif err = json.NewEncoder(w).Encode(&response); err != nil {\n \t\thandleError(w, err)\n \t\treturn\n \t}\n }\n ```\n\n \u003cbr /\u003e\n\n8. Click **Deploy**.\n\n9. Wait until the status indicator shows that the function\n has successfully deployed.\n While waiting, examine the code you just deployed.\n\nConfigure the webhook for your agent\n------------------------------------\n\nNow that the webhook exists as a service,\nyou need to associate this webhook with your agent.\nThis is done via fulfillment.\nTo enable and manage fulfillment for your agent:\n\n1. Go to the [Dialogflow ES console](https://dialogflow.cloud.google.com).\n2. Select the pre-built agent you just created.\n3. Select **Fulfillment** in the left sidebar menu.\n4. Toggle the **Webhook** field to **Enabled**.\n5. Provide the URL that you copied from above. Leave all other fields blank.\n6. Click **Save** at the bottom of the page.\n\nNow that fulfillment is enabled for the agent,\nyou need to enable fulfillment for an intent:\n\n1. Select **Intents** in the left sidebar menu.\n2. Select the **account.balance.check** intent.\n3. Scroll down to the **Fulfillment** section.\n4. Toggle **Enable webhook call for this intent** to on.\n5. Click **Save**.\n\nTry the agent\n-------------\n\nYour agent is now ready to try.\nClick the **Test Agent** button to open the simulator.\nAttempt to have the following conversation with the agent:\n\nAt conversational turn #3,\nyou supplied \"checking\" as the account type.\nThe **account.balance.check** intent has a parameter called **account**.\nThis parameter is set to \"checking\" in this conversation.\nThe intent also has an action value of \"account.balance.check\".\nThe webhook service is called,\nand it is passed the parameter and action values.\n\nIf you examine the webhook code above,\nyou see that this action triggers a similar named function to be called.\nThe function determines the account balance.\nThe function checks whether specific environment variables are set\nwith information for connecting to the database.\nIf these environment variables are not set,\nthe function uses a hardcoded account balance.\nIn upcoming steps,\nyou will alter the environment for the function\nso that it retrieves data from a database.\n\nTroubleshooting\n---------------\n\nThe webhook code includes logging statements.\nIf you are having issues, try viewing the logs for your function.\n\nMore information\n----------------\n\nFor more information about the steps above, see:\n\n- [Cloud Run functions Go quickstart](/functions/docs/console-quickstart-1st-gen)"]]