To use fulfillment in a production system, you should implement and deploy a webhook service. To handle fulfillment, your webhook service needs to accept JSON requests and return JSON responses as specified in this guide. The detailed processing flow for fulfillment and webhooks is described in the fulfillment overview document.
Webhook service requirements
The following requirements must be met by your webhook service:
- It must handle HTTPS requests. HTTP is not supported. If you host your webhook service on Google Cloud Platform using a Compute or Serverless Computing solution, see the product documentation for serving with HTTPS. For other hosting options, see Get an SSL certificate for your domain.
- Its URL for requests must be publicly accessible.
- It must handle POST requests with a JSON
WebhookRequest
body. - It must respond to
WebhookRequest
requests with a JSONWebhookResponse
body.
Authentication
It's important to secure your webhook service, so that only you or your Dialogflow agent are authorized to make requests. Dialogflow supports the following mechanisms for authentication:
- Basic authentication with login and password. This is configured when enabling fulfillment.
- Authentication with authentication headers. This is configured when enabling fulfillment.
- Mutual TLS authentication.
Webhook request
When an intent configured for fulfillment is matched, Dialogflow sends an HTTPS POST webhook request to your webhook service. The body of this request is a JSON object with information about the matched intent.
See the
WebhookRequest
reference documentation for details.
Here is a sample request:
{ "responseId": "response-id", "session": "projects/project-id/agent/sessions/session-id", "queryResult": { "queryText": "End-user expression", "parameters": { "param-name": "param-value" }, "allRequiredParamsPresent": true, "fulfillmentText": "Response configured for matched intent", "fulfillmentMessages": [ { "text": { "text": [ "Response configured for matched intent" ] } } ], "outputContexts": [ { "name": "projects/project-id/agent/sessions/session-id/contexts/context-name", "lifespanCount": 5, "parameters": { "param-name": "param-value" } } ], "intent": { "name": "projects/project-id/agent/intents/intent-id", "displayName": "matched-intent-name" }, "intentDetectionConfidence": 1, "diagnosticInfo": {}, "languageCode": "en" }, "originalDetectIntentRequest": {} }
Webhook response
Once your webhook receives a webhook request, it needs to send a webhook response. The body of this response is a JSON object with the following information:
- The response that Dialogflow returns to the end-user.
- Updates to contexts active for the conversation.
- A follow-up event to trigger an intent match.
- A custom payload to be sent to the integration or detect intent client
The following limitations apply to your response:
- The response must occur within 10 seconds for Google Assistant applications or 5 seconds for all other applications, otherwise the request will time out.
- The response must be less than or equal to 64 KiB in size.
See the
WebhookResponse
reference documentation for details.
Text response
Example for a text response:
{ "fulfillmentMessages": [ { "text": { "text": [ "Text response from webhook" ] } } ] }
Card response
Example for a card response:
{ "fulfillmentMessages": [ { "card": { "title": "card title", "subtitle": "card text", "imageUri": "https://example.com/images/example.png", "buttons": [ { "text": "button text", "postback": "https://example.com/path/for/end-user/to/follow" } ] } } ] }
Google Assistant response
Example for a Google Assistant response:
{ "payload": { "google": { "expectUserResponse": true, "richResponse": { "items": [ { "simpleResponse": { "textToSpeech": "this is a Google Assistant response" } } ] } } } }
Context
Example that sets output context:
{ "fulfillmentMessages": [ { "text": { "text": [ "Text response from webhook" ] } } ], "outputContexts": [ { "name": "projects/project-id/agent/sessions/session-id/contexts/context-name", "lifespanCount": 5, "parameters": { "param-name": "param-value" } } ] }
Event
Example that invokes a custom event:
{ "followupEventInput": { "name": "event-name", "languageCode": "en-US", "parameters": { "param-name": "param-value" } } }
Session entity
Example that sets a session entity:
{ "fulfillmentMessages": [ { "text": { "text": [ "Choose apple or orange" ] } } ], "sessionEntityTypes":[ { "name":"projects/project-id/agent/sessions/session-id/entityTypes/fruit", "entities":[ { "value":"APPLE_KEY", "synonyms":[ "apple", "green apple", "crabapple" ] }, { "value":"ORANGE_KEY", "synonyms":[ "orange" ] } ], "entityOverrideMode":"ENTITY_OVERRIDE_MODE_OVERRIDE" } ] }
Enable and manage fulfillment
To enable and manage fulfillment for your agent with the console:
- Go to the Dialogflow ES Console.
- Select an agent.
- Select Fulfillment in the left sidebar menu.
- Toggle the Webhook field to Enabled.
- Provide the details for your webhook service in the form. If your webhook doesn't require authentication, leave the authentication fields blank.
- Click Save at the bottom of the page.
To enable and manage fulfillment for your agent with the API,
see the
agent reference.
The getFulfillment
and updateFulfillment
methods can
be used to manage fulfillment settings.
To enable fulfillment for an intent with the console:
- Select Intents in the left sidebar menu.
- Select an intent.
- Scroll down to the Fulfillment section.
- Toggle Enable webhook call for this intent to on.
- Click Save.
To enable fulfillment for an intent with the API,
see the
intents reference.
Set the webhookState
field to WEBHOOK_STATE_ENABLED
.
Webhook errors
If your webhook service encounters an error, it should return one of the following HTTP status codes:
400
Bad Request401
Unauthorized403
Forbidden404
Not found500
Server fault503
Service Unavailable
In any of the following error situations, Dialogflow responds to the end-user with the built-in response configured for the intent currently matched:
- Response timeout exceeded.
- Error status code received.
- Response is invalid.
- Webhook service is unavailable.
In addition, if the intent match was triggered by a
detect intent API call,
the status
field in the detect intent response contains the webhook error information. For example:
"status": {
"code": 206,
"errorType": "webhook call failed with %error Code% error"
}
Samples
The following sample shows how to receive a WebhookRequest and send a WebhookResponse. This sample references intents created in the quickstart.
Go
import ( "encoding/json" "fmt" "log" "net/http" ) type intent struct { DisplayName string `json:"displayName"` } type queryResult struct { Intent intent `json:"intent"` } type text struct { Text []string `json:"text"` } type message struct { Text text `json:"text"` } // webhookRequest is used to unmarshal a WebhookRequest JSON object. Note that // not all members need to be defined--just those that you need to process. // As an alternative, you could use the types provided by // the Dialogflow protocol buffers: // https://godoc.org/google.golang.org/genproto/googleapis/cloud/dialogflow/v2#WebhookRequest type webhookRequest struct { Session string `json:"session"` ResponseID string `json:"responseId"` QueryResult queryResult `json:"queryResult"` } // webhookResponse is used to marshal a WebhookResponse JSON object. Note that // not all members need to be defined--just those that you need to process. // As an alternative, you could use the types provided by // the Dialogflow protocol buffers: // https://godoc.org/google.golang.org/genproto/googleapis/cloud/dialogflow/v2#WebhookResponse type webhookResponse struct { FulfillmentMessages []message `json:"fulfillmentMessages"` } // welcome creates a response for the welcome intent. func welcome(request webhookRequest) (webhookResponse, error) { response := webhookResponse{ FulfillmentMessages: []message{ { Text: text{ Text: []string{"Welcome from Dialogflow Go Webhook"}, }, }, }, } return response, nil } // getAgentName creates a response for the get-agent-name intent. func getAgentName(request webhookRequest) (webhookResponse, error) { response := webhookResponse{ FulfillmentMessages: []message{ { Text: text{ Text: []string{"My name is Dialogflow Go Webhook"}, }, }, }, } return response, nil } // handleError handles internal errors. func handleError(w http.ResponseWriter, err error) { w.WriteHeader(http.StatusInternalServerError) fmt.Fprintf(w, "ERROR: %v", err) } // HandleWebhookRequest handles WebhookRequest and sends the WebhookResponse. func HandleWebhookRequest(w http.ResponseWriter, r *http.Request) { var request webhookRequest var response webhookResponse var err error // Read input JSON if err = json.NewDecoder(r.Body).Decode(&request); err != nil { handleError(w, err) return } log.Printf("Request: %+v", request) // Call intent handler switch intent := request.QueryResult.Intent.DisplayName; intent { case "Default Welcome Intent": response, err = welcome(request) case "get-agent-name": response, err = getAgentName(request) default: err = fmt.Errorf("Unknown intent: %s", intent) } if err != nil { handleError(w, err) return } log.Printf("Response: %+v", response) // Send response if err = json.NewEncoder(w).Encode(&response); err != nil { handleError(w, err) return } }