{"id":15619285,"url":"https://github.com/xavidop/dialogflow-cx-webhook-go","last_synced_at":"2025-07-04T09:32:46.888Z","repository":{"id":135063284,"uuid":"528838565","full_name":"xavidop/dialogflow-cx-webhook-go","owner":"xavidop","description":"Webhook for Dialogflow using proto buf types and local debugging","archived":false,"fork":false,"pushed_at":"2025-04-16T21:50:00.000Z","size":2216,"stargazers_count":4,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-28T13:14:18.926Z","etag":null,"topics":["dialogflow","dialogflow-cx","go","golang","google-cloud-platform","serverless"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xavidop.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2022-08-25T12:21:52.000Z","updated_at":"2023-10-16T10:13:54.000Z","dependencies_parsed_at":"2024-03-13T23:51:49.357Z","dependency_job_id":null,"html_url":"https://github.com/xavidop/dialogflow-cx-webhook-go","commit_stats":null,"previous_names":[],"tags_count":0,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xavidop%2Fdialogflow-cx-webhook-go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xavidop%2Fdialogflow-cx-webhook-go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xavidop%2Fdialogflow-cx-webhook-go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xavidop%2Fdialogflow-cx-webhook-go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xavidop","download_url":"https://codeload.github.com/xavidop/dialogflow-cx-webhook-go/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251319593,"owners_count":21570428,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dialogflow","dialogflow-cx","go","golang","google-cloud-platform","serverless"],"created_at":"2024-10-03T08:04:30.160Z","updated_at":"2025-04-28T13:14:23.711Z","avatar_url":"https://github.com/xavidop.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!-- TOC --\u003e\n\n- [Dialogflow CX Webhooks with Golang](#dialogflow-cx-webhooks-with-golang)\n  - [Prerequisites](#prerequisites)\n  - [Creating the Dialogflow CX Agent with the Console](#creating-the-dialogflow-cx-agent-with-the-console)\n  - [Project Files](#project-files)\n  - [Google Cloud function in golang](#google-cloud-function-in-golang)\n  - [Deploying your Dialogflow CX Webhook](#deploying-your-dialogflow-cx-webhook)\n  - [Dialogflow CX Console](#dialogflow-cx-console)\n    - [Testing your Dialogflow CX Agent](#testing-your-dialogflow-cx-agent)\n  - [Local](#local)\n    - [Building the Dialoglfow CX Webhook](#building-the-dialoglfow-cx-webhook)\n    - [Running the Dialogflow CX Webhook](#running-the-dialogflow-cx-webhook)\n    - [Testing requests locally](#testing-requests-locally)\n    - [Debugging the Dialogflow CX webhook](#debugging-the-dialogflow-cx-webhook)\n  - [Hybrid](#hybrid)\n    - [Port-forwarding requests directly from Dialogflow CX Console to your laptop](#port-forwarding-requests-directly-from-dialogflow-cx-console-to-your-laptop)\n  - [Resources](#resources)\n  - [Conclusion](#conclusion)\n\n\u003c!-- /TOC --\u003e\n\n\n# Dialogflow CX Webhooks with Golang\n\nDialogflow CX Webhooks can be developed using Google Cloud functions or a REST API endpoint.\nGoogle Cloud Function function is Googles's implementation of serverless functions available in GCP. \nGoogle recommends using Google Cloud Function functions for Dialogflow CX development.\n \nIn this post, we will implement a Dialogflow CX Agent by using Golang, protobuf and Google Cloud Functions. This project is basically a Hello World example. \n\nThis post contains materials from different resources that can be seen in the Resources section.\n\n## Prerequisites\n\nHere you have the technologies used in this project\n1. Google Cloud Account - [Sign up here for free](https://cloud.google.com/)\n2. Dialogflow API enabled - [How to enable it](https://cloud.google.com/dialogflow/cx/docs/reference)\n3. gcloud CLI - [Install and configure gcloud CLI](https://cloud.google.com/sdk/docs/install)\n4. Dialogflow CX CLI - [Install and configure Dialogflow CX CLI](https://cxcli.xavidop.me/)\n5. Golang v1.19 or higher\n6. Visual Studio Code\n7. Dialogflow CX for Golang (Version \u003e=1.23.0)\n8. ngrok\n\nThe Google Cloud Command Line Interface (`gcloud` CLI) is a tool for you to manage your Google Cloud serverless functions and related resources.\n`cxcli` CLI allows you to manage Dialogflow CX Agents programmatically from the command line.\nWe will use these powerful tools to create, build, deploy and manage our Hello World Dialogflow CX agent. Let's start!\n\n## Creating the Dialogflow CX Agent with the Console\n\nFor creating the Dialogflow CX Agent, you will need to go to the Dialogflow CX Console and create an agent. Once you have your agent created, you will see the design view:\n\n![image](img/agent.png)\n\nAnd that's it, with these steps you have created your first Dialogflow CX agent. You only have to deploy your local changes. We are going to explain it in the next steps.\n\n## Project Files \n\nThese are the main files of the project:\n\n```bash\n├── cmd\n│   └── main.go\n├── function.go\n├── go.mod\n└── go.sum\n```\n\n* `cmd`: The folder that contains all we need to spin up a local server for debugging.\n  * `main.go`: file that contains a `main()` method and runs a local server listening in port `8080`.\n* `function.go`: the Google Cloud Function main entry point.\n* `go.mod`: this file is core to the Golang ecosystem and is a basic part of understanding and working with golang.\n* `go.sum`: this file lists down the checksum of direct and indirect dependency required along with the version\n## Google Cloud function in golang\n\nThe Dialogflow CX SDK for Golang makes it easier for you to build highly engaging dialogflow CX conversations by allowing you to spend more time implementing features and less time writing boilerplate code.\n\nYou can find documentation, samples and helpful links in their official [GitHub repository](https://github.com/googleapis/google-cloud-go/tree/main/dialogflow/cx/apiv3)\n\nThe main Golang file in our Google Cloud Function project is `function.go` located in the root folder. This file contains all handlers.\n\nThe `HandleWebhookRequest` function is executed every time Dialogflow CX calls the webhook. \n\n```go\n\n// HandleWebhookRequest handles WebhookRequest and sends the WebhookResponse.\nfunc HandleWebhookRequest(w http.ResponseWriter, r *http.Request) {\n\tvar request cx.WebhookRequest\n\tvar response cx.WebhookResponse\n\tvar err error\n\n\t// Read input JSON\n\tbody, err := ioutil.ReadAll(r.Body)\n\tif err != nil {\n\t\thandleError(w, err)\n\t\treturn\n\t}\n\n\tunmarshal := protojson.UnmarshalOptions{\n\t\tAllowPartial:   true,\n\t\tDiscardUnknown: true,\n\t}\n\n\t// Unmarshal from the protobuf struct\n\tif err = unmarshal.Unmarshal(body, \u0026request); err != nil {\n\t\thandleError(w, err)\n\t\treturn\n\t}\n\n\tlog.Printf(\"Request: %+v\", request)\n\n\t// Execute the response\n\tresponse, err = webhookResponse(request)\n\n\tif err != nil {\n\t\thandleError(w, err)\n\t\treturn\n\t}\n\tlog.Printf(\"Response: %+v\", response)\n\n\tmarshal := protojson.MarshalOptions{\n\t\tAllowPartial: true,\n\t}\n\n\t// Marshal from the protobuf struct\n\tbytes, err := marshal.Marshal(\u0026response)\n\tif err != nil {\n\t\thandleError(w, err)\n\t\treturn\n\t}\n\n\t// Send response\n\tif _, err = w.Write(bytes); err != nil {\n\t\thandleError(w, err)\n\t\treturn\n\t}\n\n}\n\n```\nIt is important to notice here that to have a better development experience, we are using `protobuf` structs from the Dialogflow CX SDK. This is why we are marshalling and unmarshalling using the `protojson` library.\n\n## Deploying your Dialogflow CX Webhook\n\nWith the code ready to go, we need to deploy it on Google Cloud so it can be connected to the agent.\n\nBefore we continue, make sure that you have enabled the Cloud functions API enabled:\n\n```bash\n    gcloud services enable cloudfunctions.googleapis.com\n```\n\nNow we can deploy our webhook with gcloud CLI on the root folder:\n\n```bash\n    gcloud functions deploy my-agent-function --runtime go119 --trigger-http --entry-point HandleWebhookRequest\n```\n\nThe public endpoint of this function is going to have this format:\n```bash\n    https://\u003cregion\u003e-\u003cproject-id\u003e.cloudfunctions.net/\u003cfunction-name\u003e\n```\n\nSo imagine that we have deployed this function in `us-central1` and the project `test-cx-346408`, the URL will look like this:\n```bash\n    https://us-central1-test-cx-346408.cloudfunctions.net/my-agent-function\n```\n\nNow the code is ready to be tested on the Console!\n\n## Dialogflow CX Console\n\n### Testing your Dialogflow CX Agent\n\nOnce you have deployed your changes, you can go to your Dialogflow CX Agent on the console and create a Webhook:\n\n![image](img/webhook.png)\n\nOnce you have added your webhook in your agent, you can go to any flow and set it wherever you need. Then you just need to test it in the simulator!\n\n![image](img/testing.png)\n\n## Local\n\n### Building the Dialoglfow CX Webhook\n\nInside `go.mod`, we will almost always find metadata specific to the project. \nThis metadata helps identify the project and acts as a baseline for users and contributors to get information about the project.\n\nHere is how this file looks like:\n\n```go\n\nmodule dialogflow.cx/cloudfunction\n\ngo 1.16\n\nrequire (\n\tcloud.google.com/go/dialogflow v1.26.0\n\tgoogle.golang.org/protobuf v1.28.1\n)\n\n```\n\nFor downloading our Webhook dependencies, we can run the following command:\n\n```bash\n\n  go mod tidy\n\n```\n\nThis command installs a package, and any packages that it depends on. \nIf the package has a go.sum file, the installation of dependencies will be driven by that.\n\nTo build the webhook just run:\n```bash\n\n    go build -o webhook .\n\n```\n\n### Running the Dialogflow CX Webhook\n\nThe `launch.json` file in `.vscode` folder has the configuration for Visual Studio Code which allow us to run our lambda locally:\n\n```json\n\n{\n    \"version\": \"0.2.0\",\n    \"configurations\": [\n        {\n            \"name\": \"Run function\",\n            \"type\": \"go\",\n            \"request\": \"launch\",\n            \"mode\": \"debug\",\n            \"program\": \"${workspaceFolder}/cmd/main.go\",\n            \"env\": {\n                \"ENV\": \"development\"\n            }\n        }\n    ]\n}\n\n```\nThis configuration file will execute the following command:\n\n```bash\n\ndlv dap --listen=127.0.0.1:52462 --log-dest=3 from /Users/xavierportillaedo/Documents/personal/repos/dialogflow-cx-webhook-go/cmd\n\n```\n\nFor a new incoming request a new server is running listening in port `8080`.\nFrom the data received on the server the request body is extracted, parsed into JSON and passed to the webhook invoker's serverless function handler.\nThe response from the lambda serverless function is parsed as Dialogflow CX protobuf format as specified [here](https://pkg.go.dev/cloud.google.com/go/dialogflow@v1.23.0/cx/apiv3beta1/cxpb)\nThe response is written onto the server and returned.\n\nAfter configuring our launch.json file and understanding how the local debugger works, it is time to click on the play button:\n\n![image](img/run.png)\n\nAfter executing it, you can send Dialogflow CX POST requests to http://localhost:8080.\n\n### Testing requests locally\n\nI'm sure you already know the famous tool called [Postman](https://www.postman.com/). REST APIs have become the new standard in providing a public and secure interface for your service. Though REST has become ubiquitous, it's not always easy to test. Postman, makes it easier to test and manage HTTP REST APIs. Postman gives us multiple features to import, test and share APIs, which will help you and your team be more productive in the long run.\n\nAfter running your application you will have an endpoint available at http://localhost:8080. With Postman you can emulate any Dialogflow CX Request. \n\nFor example, you can test this Request:\n\n```json\n\n{\n   \"detectIntentResponseId\":\"dsfsdaf-c5c9-46ce-bf2c-935396c08926\",\n   \"intentInfo\":{\n      \"lastMatchedIntent\":\"projects/my-project-123/locations/us-central1/agents/sddadsa-576c-4bbb-bc27-34c276bfecd5/intents/00000000-0000-0000-0000-000000000000\",\n      \"displayName\":\"Default Welcome Intent\",\n      \"confidence\":0.6684057\n   },\n   \"pageInfo\":{\n      \"currentPage\":\"projects/my-project-123/locations/us-central1/agents/sadasd-d5fc-4eb7-88fc-c25169027aee/flows/68f7790d-5c1f-4546-bb53-8d641f8288b4/pages/21939010-3336-450d-ae8b-0c9926aec791\",\n      \"formInfo\":{\n         \"parameterInfo\":[\n            {\n               \"displayName\":\"pokemon\",\n               \"required\":true,\n               \"state\":\"FILLED\",\n               \"value\":\"pikachu\"\n            }\n         ]\n      }\n   },\n   \"sessionInfo\":{\n      \"session\":\"projects/my-project-123/locations/us-central1/agents/sadasd-d5fc-4eb7-88fc-c25169027aee/sessions/7fab78-aac-10e-989-d99313ca4\",\n      \"parameters\":{\n         \"pokemon\":\"pikachu\"\n      }\n   },\n   \"fulfillmentInfo\":{\n      \"tag\":\"test\"\n   },\n   \"text\":\"Hi!\",\n   \"languageCode\":\"en\"\n}\n\n```\n\nThe response from this example webhook is gonna be this one:\n```json\n{\n  \"fulfillmentResponse\": {\n    \"messages\": [\n      {\n        \"text\": {\n          \"text\": [\n            \"hi from the webhook!\"\n          ]\n        }\n      }\n    ],\n    \"mergeBehavior\": \"REPLACE\"\n  },\n  \"sessionInfo\": {\n    \"parameters\": {\n      \"key\": \"value\"\n    }\n  }\n}\n```\n\n### Debugging the Dialogflow CX webhook\n\nFollowing the steps before, now you can set up breakpoints wherever you want inside all Golang files in order to debug your webhook:\n\n![image](img/debug.png)\n\n## Hybrid\n### Port-forwarding requests directly from Dialogflow CX Console to your laptop\n\nngrok is a very cool, lightweight tool that creates a secure tunnel on your local machine along with a public URL you can use for browsing your local site or APIs.\n\nWhen ngrok is running, it listens on the same port that you’re local web server is running on and proxies external requests to your local machine\n\nFrom there, it’s a simple step to get it to listen to your web server. Say you’re running your local web server on port 8080. In a terminal, you’d type in: `ngrok http 8080`. This starts ngrok listening on port 8080 and creates the secure tunnel:\n\n![image](img/tunnel.png)\n\nSo now you have to go to [Dialogflow CX console](https://dialogflow.cloud.google.com/cx/), go to your Agent \u003e webhooks and add the https url generated above. Eg: https://1179-46-25-42-125.eu.ngrok.io.\n\nGo to the Simulator tab in the Dialogflow CX Console and launch your agent.\n\nThe Dialogflow CX Console will send an HTTPS request to the ngrok endpoint (https://1179-46-25-42-125.eu.ngrok.io) which will route it to your webhook running on Web API server at http://localhost:8080.\n\n## Resources\n* [Official Dialogflow CX Golang SDK](https://github.com/googleapis/google-cloud-go/tree/main/dialogflow/cx/apiv3) - Official Dialogflow CX Golang SDK\n* [Official Dialogflow CX Documentation](https://cloud.google.com/dialogflow/cx/docs) - Official Dialogflow CX Documentation\n\n## Conclusion \n\nThis was a basic tutorial to learn Dialogflow CX webhooks using Golang.\nAs you have seen in this example, the Dialoglfow CX SDK for Golang and the Dialogflow CX Tools like gcloud and `cxcli` CLIs can help us a lot and also they give us the possibility to create Agents and conversations easily. \nI hope this example project is useful to you.\n\nThat's all folks!\n\nHappy coding!","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxavidop%2Fdialogflow-cx-webhook-go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxavidop%2Fdialogflow-cx-webhook-go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxavidop%2Fdialogflow-cx-webhook-go/lists"}