mirror of
https://github.com/zulip/zulip.git
synced 2025-11-03 13:33:24 +00:00
webhooks: Add Dialogflow integration.
With minor fixes by eeshangarg! Fixes #6990
This commit is contained in:
BIN
static/images/integrations/dialogflow/001.png
Normal file
BIN
static/images/integrations/dialogflow/001.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.2 KiB |
BIN
static/images/integrations/logos/dialogflow.png
Normal file
BIN
static/images/integrations/logos/dialogflow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.0 KiB |
@@ -284,6 +284,7 @@ WEBHOOK_INTEGRATIONS = [
|
||||
WebhookIntegration('circleci', ['continuous-integration'], display_name='CircleCI'),
|
||||
WebhookIntegration('codeship', ['continuous-integration', 'deployment']),
|
||||
WebhookIntegration('crashlytics', ['monitoring']),
|
||||
WebhookIntegration('dialogflow', ['customer-support'], display_name='Dialogflow'),
|
||||
WebhookIntegration('delighted', ['customer-support', 'marketing'], display_name='Delighted'),
|
||||
WebhookIntegration(
|
||||
'deskdotcom',
|
||||
|
||||
0
zerver/webhooks/dialogflow/__init__.py
Normal file
0
zerver/webhooks/dialogflow/__init__.py
Normal file
28
zerver/webhooks/dialogflow/doc.md
Normal file
28
zerver/webhooks/dialogflow/doc.md
Normal file
@@ -0,0 +1,28 @@
|
||||
Get personal message notifications in Zulip for the results of your Dialogflow queries!
|
||||
|
||||
1. {!create-stream.md!}
|
||||
|
||||
1. Next, on your {{ settings_html|safe }}, [create a bot](/help/add-a-bot-or-integration) for
|
||||
{{ integration_display_name }}. Make sure that you select
|
||||
**Incoming webhook** as the **Bot type**.
|
||||
|
||||
The API key for an incoming webhook bot cannot be used to read messages out
|
||||
of Zulip. Thus, using an incoming webhook bot lowers the security risk of
|
||||
exposing the bot's API key to a third-party service.
|
||||
|
||||
Construct the URL for the Dialogflow bot using the bot's API key and your Zulip email.
|
||||
The webhook URL should look like:
|
||||
|
||||
`{{api_url}}?api_key=BOT'S_API_KEY&email=foo@example.com`
|
||||
|
||||
Modify the parameters of the URL above where `api_key` is the API key of your Zulip bot
|
||||
and `email` is your Zulip email.
|
||||
|
||||
1. Go to the **Fulfillment** settings of your Dialogflow app and enable **Webhooks**.
|
||||
Set **URL** to the URL constructed above.
|
||||
Go to **Intents** and at the bottom, check the box **Use webhook**
|
||||
under **Fulfillment**.
|
||||
|
||||
{!congrats.md!}
|
||||
|
||||

|
||||
45
zerver/webhooks/dialogflow/fixtures/alternate_result.json
Normal file
45
zerver/webhooks/dialogflow/fixtures/alternate_result.json
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"id": "69316a96-cce1-4322-9bdc-d94e8298f0d2",
|
||||
"timestamp": "2018-01-12T12:22:31.283Z",
|
||||
"lang": "en",
|
||||
"result": {
|
||||
"source": "agent",
|
||||
"resolvedQuery": "what's the weather in New Delhi",
|
||||
"action": "yahooWeatherForecast",
|
||||
"actionIncomplete": false,
|
||||
"parameters": {
|
||||
"geo-city": "New Delhi"
|
||||
},
|
||||
"contexts": [],
|
||||
"metadata": {
|
||||
"intentId": "a61266c2-b6af-4dc8-a7b9-72dfb11b72d8",
|
||||
"webhookUsed": "true",
|
||||
"webhookForSlotFillingUsed": "false",
|
||||
"webhookResponseTime": 115,
|
||||
"intentName": "weather-intent"
|
||||
},
|
||||
"fulfillment": {
|
||||
"speech": "",
|
||||
"source": "apiai-weather-webhook-sample",
|
||||
"displayText": "",
|
||||
"messages": [
|
||||
{
|
||||
"type": 0,
|
||||
"speech": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
"score": 0.7099999785423279
|
||||
},
|
||||
"alternateResult": {
|
||||
"fulfillment": {
|
||||
"speech": "Weather in New Delhi is nice!"
|
||||
},
|
||||
},
|
||||
"status": {
|
||||
"code": 200,
|
||||
"errorType": "success",
|
||||
"webhookTimedOut": false
|
||||
},
|
||||
"sessionId": "2507496e-8028-4be5-ac52-1624f752b188"
|
||||
}
|
||||
37
zerver/webhooks/dialogflow/fixtures/default.json
Normal file
37
zerver/webhooks/dialogflow/fixtures/default.json
Normal file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"id": "1faaa328-dad8-4532-be7e-c4103dfdbf40",
|
||||
"timestamp": "2018-01-12T12:09:15.699Z",
|
||||
"lang": "en",
|
||||
"result": {
|
||||
"source": "agent",
|
||||
"resolvedQuery": "how is the weather in Sunnyvale",
|
||||
"action": "",
|
||||
"actionIncomplete": false,
|
||||
"parameters": {
|
||||
"geo-city": "Sunnyvale"
|
||||
},
|
||||
"contexts": [],
|
||||
"metadata": {
|
||||
"intentId": "a61266c2-b6af-4dc8-a7b9-72dfb11b72d8",
|
||||
"webhookUsed": "false",
|
||||
"webhookForSlotFillingUsed": "false",
|
||||
"intentName": "weather-intent"
|
||||
},
|
||||
"fulfillment": {
|
||||
"speech": "The weather sure looks great !",
|
||||
"messages": [
|
||||
{
|
||||
"type": 0,
|
||||
"speech": "The weather sure looks great !"
|
||||
}
|
||||
]
|
||||
},
|
||||
"score": 1
|
||||
},
|
||||
"status": {
|
||||
"code": 200,
|
||||
"errorType": "success",
|
||||
"webhookTimedOut": false
|
||||
},
|
||||
"sessionId": "2507496e-8028-4be5-ac52-1624f752b188"
|
||||
}
|
||||
14
zerver/webhooks/dialogflow/fixtures/error_status.json
Normal file
14
zerver/webhooks/dialogflow/fixtures/error_status.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"id": "69316a96-cce1-4322-9bdc-d94e8298f0d2",
|
||||
"timestamp": "2018-01-12T12:22:31.283Z",
|
||||
"lang": "en",
|
||||
"result": {
|
||||
"resolvedQuery": "what's the weather in New Delhi",
|
||||
},
|
||||
"status": {
|
||||
"code": 403,
|
||||
"errorType": "fail",
|
||||
"errorDetails": "Access Denied"
|
||||
},
|
||||
"sessionId": "2507496e-8028-4be5-ac52-1624f752b188"
|
||||
}
|
||||
45
zerver/webhooks/dialogflow/fixtures/exception.json
Normal file
45
zerver/webhooks/dialogflow/fixtures/exception.json
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"id": "69316a96-cce1-4322-9bdc-d94e8298f0d2",
|
||||
"timestamp": "2018-01-12T12:22:31.283Z",
|
||||
"lang": "en",
|
||||
"result": {
|
||||
"source": "agent",
|
||||
"resolvedQuery": "what's the weather in New Delhi",
|
||||
"action": "yahooWeatherForecast",
|
||||
"actionIncomplete": false,
|
||||
"parameters": {
|
||||
"geo-city": "New Delhi"
|
||||
},
|
||||
"contexts": [],
|
||||
"metadata": {
|
||||
"intentId": "a61266c2-b6af-4dc8-a7b9-72dfb11b72d8",
|
||||
"webhookUsed": "true",
|
||||
"webhookForSlotFillingUsed": "false",
|
||||
"webhookResponseTime": 115,
|
||||
"intentName": "weather-intent"
|
||||
},
|
||||
"fulfillment": {
|
||||
"speech": "",
|
||||
"source": "apiai-weather-webhook-sample",
|
||||
"displayText": "",
|
||||
"messages": [
|
||||
{
|
||||
"type": 0,
|
||||
"speech": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
"score": 0.7099999785423279
|
||||
},
|
||||
"alternateResult": {
|
||||
"fulfillment": {
|
||||
"speech": ""
|
||||
},
|
||||
},
|
||||
"status": {
|
||||
"code": 200,
|
||||
"errorType": "success",
|
||||
"webhookTimedOut": false
|
||||
},
|
||||
"sessionId": "2507496e-8028-4be5-ac52-1624f752b188"
|
||||
}
|
||||
40
zerver/webhooks/dialogflow/fixtures/weather_app.json
Normal file
40
zerver/webhooks/dialogflow/fixtures/weather_app.json
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"id": "69316a96-cce1-4322-9bdc-d94e8298f0d2",
|
||||
"timestamp": "2018-01-12T12:22:31.283Z",
|
||||
"lang": "en",
|
||||
"result": {
|
||||
"source": "agent",
|
||||
"resolvedQuery": "what's the weather in New Delhi",
|
||||
"action": "yahooWeatherForecast",
|
||||
"actionIncomplete": false,
|
||||
"parameters": {
|
||||
"geo-city": "New Delhi"
|
||||
},
|
||||
"contexts": [],
|
||||
"metadata": {
|
||||
"intentId": "a61266c2-b6af-4dc8-a7b9-72dfb11b72d8",
|
||||
"webhookUsed": "true",
|
||||
"webhookForSlotFillingUsed": "false",
|
||||
"webhookResponseTime": 115,
|
||||
"intentName": "weather-intent"
|
||||
},
|
||||
"fulfillment": {
|
||||
"speech": "Today the weather in Delhi: Sunny, And the temperature is 65 F",
|
||||
"source": "apiai-weather-webhook-sample",
|
||||
"displayText": "Today the weather in Delhi: Sunny, And the temperature is 65 F",
|
||||
"messages": [
|
||||
{
|
||||
"type": 0,
|
||||
"speech": "Today the weather in Delhi: Sunny, And the temperature is 65 F"
|
||||
}
|
||||
]
|
||||
},
|
||||
"score": 0.7099999785423279
|
||||
},
|
||||
"status": {
|
||||
"code": 200,
|
||||
"errorType": "success",
|
||||
"webhookTimedOut": false
|
||||
},
|
||||
"sessionId": "2507496e-8028-4be5-ac52-1624f752b188"
|
||||
}
|
||||
66
zerver/webhooks/dialogflow/tests.py
Normal file
66
zerver/webhooks/dialogflow/tests.py
Normal file
@@ -0,0 +1,66 @@
|
||||
# -*- coding: utf -*-
|
||||
from typing import Text
|
||||
from zerver.lib.test_classes import WebhookTestCase
|
||||
|
||||
class DialogflowHookTests(WebhookTestCase):
|
||||
URL_TEMPLATE = u"/api/v1/external/dialogflow?api_key={api_key}&email=AARON@zulip.com"
|
||||
|
||||
def test_dialogflow_default(self) -> None:
|
||||
self.url = self.build_webhook_url(
|
||||
email="AARON@zulip.com",
|
||||
username="aaron",
|
||||
user_ip="127.0.0.1"
|
||||
)
|
||||
expected_message = u"Today the weather in Delhi: Sunny, And the tempreture is 65F"
|
||||
self.send_and_test_private_message('default',
|
||||
expected_message,
|
||||
content_type="application/json")
|
||||
|
||||
def test_dialogflow_weather_app(self) -> None:
|
||||
self.url = self.build_webhook_url(
|
||||
email="AARON@zulip.com",
|
||||
username="aaron",
|
||||
user_ip="127.0.0.1"
|
||||
)
|
||||
expected_message = u"The weather sure looks great !"
|
||||
self.send_and_test_private_message('weather_app',
|
||||
expected_message,
|
||||
content_type="application/json")
|
||||
|
||||
def test_dialogflow_alternate_result(self) -> None:
|
||||
self.url = self.build_webhook_url(
|
||||
email="AARON@zulip.com",
|
||||
username="aaron",
|
||||
user_ip="127.0.0.1"
|
||||
)
|
||||
expected_message = u"Weather in New Delhi is nice!"
|
||||
self.send_and_test_private_message('alternate_result',
|
||||
expected_message,
|
||||
content_type="application/json")
|
||||
|
||||
def test_dialogflow_error_status(self) -> None:
|
||||
self.url = self.build_webhook_url(
|
||||
email="AARON@zulip.com",
|
||||
username="aaron",
|
||||
user_ip="127.0.0.1"
|
||||
)
|
||||
expected_message = u"403 - Access Denied"
|
||||
self.send_and_test_private_message('error_status',
|
||||
expected_message,
|
||||
content_type="application/json")
|
||||
|
||||
def test_dialogflow_exception(self) -> None:
|
||||
self.url = self.build_webhook_url(
|
||||
email="AARON@zulip.com",
|
||||
username="aaron",
|
||||
user_ip="127.0.0.1"
|
||||
)
|
||||
expected_message = u"DialogFlow couldn't process your query."
|
||||
self.send_and_test_private_message('exception',
|
||||
expected_message,
|
||||
content_type="application/json")
|
||||
|
||||
def get_body(self, fixture_name: Text) -> Text:
|
||||
return self.fixture_data("dialogflow",
|
||||
fixture_name,
|
||||
file_type="json")
|
||||
33
zerver/webhooks/dialogflow/view.py
Normal file
33
zerver/webhooks/dialogflow/view.py
Normal file
@@ -0,0 +1,33 @@
|
||||
# Webhooks for external integrations.
|
||||
from typing import Text, Any, Dict
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from zerver.decorator import api_key_only_webhook_view
|
||||
from zerver.lib.actions import check_send_private_message
|
||||
from zerver.lib.request import REQ, has_request_variables
|
||||
from zerver.lib.response import json_success
|
||||
from zerver.models import UserProfile, get_user_profile_by_email
|
||||
|
||||
@api_key_only_webhook_view("dialogflow")
|
||||
@has_request_variables
|
||||
def api_dialogflow_webhook(request: HttpRequest, user_profile: UserProfile,
|
||||
payload: Dict[str, Any]=REQ(argument_type='body'),
|
||||
email: str=REQ(default='foo')) -> HttpResponse:
|
||||
status = payload["status"]["code"]
|
||||
|
||||
if status == 200:
|
||||
result = payload["result"]["fulfillment"]["speech"]
|
||||
if not result:
|
||||
alternate_result = payload["alternateResult"]["fulfillment"]["speech"]
|
||||
if not alternate_result:
|
||||
body = u"DialogFlow couldn't process your query."
|
||||
else:
|
||||
body = alternate_result
|
||||
else:
|
||||
body = result
|
||||
else:
|
||||
error_status = payload["status"]["errorDetails"]
|
||||
body = u"{} - {}".format(status, error_status)
|
||||
|
||||
profile = get_user_profile_by_email(email)
|
||||
check_send_private_message(user_profile, request.client, profile, body)
|
||||
return json_success()
|
||||
Reference in New Issue
Block a user