Skip to content
This repository has been archived by the owner on Aug 22, 2019. It is now read-only.

Commit

Permalink
fixed tests & added to changelog
Browse files Browse the repository at this point in the history
  • Loading branch information
tmbo committed Aug 29, 2018
1 parent 7721445 commit 7aebdab
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 71 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rst
Expand Up @@ -18,6 +18,7 @@ This project adheres to `Semantic Versioning`_ starting with version 0.2.0.

Added
-----
- added microsoft botframework input and output channels
- script parameter ``--quiet`` to set the log level to ``WARNING``
- information about the python version a model has been trained with to the
model metadata
Expand Down
46 changes: 26 additions & 20 deletions docs/connectors.rst
Expand Up @@ -383,6 +383,24 @@ is ``/webhooks/twilio/webhook``.
Microsoft Bot Framework Setup
--------------

Using run script
^^^^^^^^^^^^^^^^
If you want to connect to the botframework input channel using the
run script, e.g. using:

.. code-block:: bash
python -m rasa_core.run -d models/dialogue -u models/nlu/current \
--port 5002 --credentials credentials.yml
you need to supply a ``credentials.yml`` with the following content:

.. code-block:: yaml
botframework:
app_id: "MICROSOFT_APP_ID"
app_password: "MICROSOFT_APP_PASSWORD"
Directly using python
^^^^^^^^^^^^^^^^^^^^^

Expand All @@ -392,27 +410,15 @@ from your webserver creation logic.

Code to create a Microsoft Bot Framework-compatible webserver looks like this:

.. code-block:: python
:linenos:
from rasa_core.channels import HttpInputChannel
from rasa_core.channels.botframework import BotFrameworkInput
from rasa_core.agent import Agent
from rasa_core.interpreter import RegexInterpreter
# load your trained agent
agent = Agent.load("dialogue", interpreter=RegexInterpreter())
input_channel = BotFrameworkInput(
bf_id="YOUR_BOT_FRAMEWORK_ID", # you get this from your Bot Framework account
bf_secret="YOUR_BOT_FRAMEWORK_SECRET" # also from your Bot Framework account
)
agent.handle_channel(HttpInputChannel(5004, "/app", input_channel))
.. literalinclude:: ../tests/test_channels.py
:pyobject: test_botframework_channel
:lines: 2-
:end-before: END DOC INCLUDE

The arguments for the ``HttpInputChannel`` are the port, the url prefix, and the input channel.
The default endpoint for receiving messages is ``/api/messages``, so the example above above would
listen for messages on ``/app/api/messages``.
The arguments for the ``handle_channels`` are the input channels and
the port. The endpoint for receiving botframework channel messages
is ``/webhooks/botframework/webhook``. This is the url you should
add in your microsoft bot service configuration.

.. _ngrok:

Expand Down
30 changes: 15 additions & 15 deletions rasa_core/channels/botframework.py
Expand Up @@ -32,11 +32,11 @@ class BotFramework(OutputChannel):
def name(cls):
return "botframework"

def __init__(self, bf_id, bf_secret, conversation, bot_id, service_url):
def __init__(self, app_id, app_password, conversation, bot_id, service_url):
# type: (Text, Text, Dict[Text], Text, Text) -> None

self.bf_id = bf_id
self.bf_secret = bf_secret
self.app_id = app_id
self.app_password = app_password
self.conversation = conversation
self.global_uri = "{}v3/".format(service_url)
self.bot_id = bot_id
Expand All @@ -46,8 +46,8 @@ def _get_headers(self):
uri = "{}/{}".format(MICROSOFT_OAUTH2_URL, MICROSOFT_OAUTH2_PATH)
grant_type = 'client_credentials'
scope = 'https://api.botframework.com/.default'
payload = {'client_id': self.bf_id,
'client_secret': self.bf_secret,
payload = {'client_id': self.app_id,
'client_secret': self.app_password,
'grant_type': grant_type,
'scope': scope}

Expand Down Expand Up @@ -138,32 +138,32 @@ class BotFrameworkInput(InputChannel):
def name(cls):
return "botframework"

def __init__(self, bf_id, bf_secret):
def __init__(self, app_id, app_password):
# type: (Text, Text) -> None
"""Create a Bot Framework input channel.
:param bf_id: Bot Framework's API id
:param bf_secret: Bot Framework application secret
:param app_id: Bot Framework's API id
:param app_password: Bot Framework application secret
"""

self.bf_id = bf_id
self.bf_secret = bf_secret
self.app_id = app_id
self.app_password = app_password

def blueprint(self, on_new_message):

bf_webhook = Blueprint('bf_webhook', __name__)
botframework_webhook = Blueprint('botframework_webhook', __name__)

@bf_webhook.route("/", methods=['GET'])
@botframework_webhook.route("/", methods=['GET'])
def health():
return jsonify({"status": "ok"})

@bf_webhook.route("/webhook", methods=['POST'])
@botframework_webhook.route("/webhook", methods=['POST'])
def webhook():
postdata = request.get_json(force=True)

try:
if postdata["type"] == "message":
out_channel = BotFramework(self.bf_id, self.bf_secret,
out_channel = BotFramework(self.app_id, self.app_password,
postdata["conversation"],
postdata["recipient"],
postdata["serviceUrl"])
Expand All @@ -181,4 +181,4 @@ def webhook():

return "success"

return bf_webhook
return botframework_webhook
114 changes: 78 additions & 36 deletions tests/test_channels.py
Expand Up @@ -63,13 +63,15 @@ def test_facebook_channel():
# END DOC INCLUDE
# the above marker marks the end of the code snipped included
# in the docs
assert s.started
routes_list = utils.list_routes(s.application)
assert routes_list.get("/webhooks/facebook/").startswith(
'fb_webhook.health')
assert routes_list.get("/webhooks/facebook/webhook").startswith(
'fb_webhook.webhook')
s.stop()
try:
assert s.started
routes_list = utils.list_routes(s.application)
assert routes_list.get("/webhooks/facebook/").startswith(
'fb_webhook.health')
assert routes_list.get("/webhooks/facebook/webhook").startswith(
'fb_webhook.webhook')
finally:
s.stop()


# USED FOR DOCS - don't rename without changing in the docs
Expand All @@ -93,13 +95,15 @@ def test_slack_channel():
# END DOC INCLUDE
# the above marker marks the end of the code snipped included
# in the docs
assert s.started
routes_list = utils.list_routes(s.application)
assert routes_list.get("/webhooks/slack/").startswith(
'slack_webhook.health')
assert routes_list.get("/webhooks/slack/webhook").startswith(
'slack_webhook.webhook')
s.stop()
try:
assert s.started
routes_list = utils.list_routes(s.application)
assert routes_list.get("/webhooks/slack/").startswith(
'slack_webhook.health')
assert routes_list.get("/webhooks/slack/webhook").startswith(
'slack_webhook.webhook')
finally:
s.stop()


# USED FOR DOCS - don't rename without changing in the docs
Expand Down Expand Up @@ -128,13 +132,47 @@ def test_mattermost_channel():
# END DOC INCLUDE
# the above marker marks the end of the code snipped included
# in the docs
assert s.started
routes_list = utils.list_routes(s.application)
assert routes_list.get("/webhooks/mattermost/").startswith(
'mattermost_webhook.health')
assert routes_list.get("/webhooks/mattermost/webhook").startswith(
'mattermost_webhook.webhook')
s.stop()
try:
assert s.started
routes_list = utils.list_routes(s.application)
assert routes_list.get("/webhooks/mattermost/").startswith(
'mattermost_webhook.health')
assert routes_list.get("/webhooks/mattermost/webhook").startswith(
'mattermost_webhook.webhook')
finally:
s.stop()


# USED FOR DOCS - don't rename without changing in the docs
def test_botframework_channel():
from rasa_core.channels.botframework import BotFrameworkInput
from rasa_core.agent import Agent
from rasa_core.interpreter import RegexInterpreter

# load your trained agent
agent = Agent.load(MODEL_PATH, interpreter=RegexInterpreter())

input_channel = BotFrameworkInput(
# you get this from your Bot Framework account
app_id="MICROSOFT_APP_ID",
# also from your Bot Framework account
app_password="MICROSOFT_APP_PASSWORD"
)

# set serve_forever=False if you want to keep the server running
s = agent.handle_channels([input_channel], 5004, serve_forever=False)
# END DOC INCLUDE
# the above marker marks the end of the code snipped included
# in the docs
try:
assert s.started
routes_list = utils.list_routes(s.application)
assert routes_list.get("/webhooks/botframework/").startswith(
'botframework_webhook.health')
assert routes_list.get("/webhooks/botframework/webhook").startswith(
'botframework_webhook.webhook')
finally:
s.stop()


# USED FOR DOCS - don't rename without changing in the docs
Expand Down Expand Up @@ -169,14 +207,16 @@ def test_telegram_channel():
# END DOC INCLUDE
# the above marker marks the end of the code snipped included
# in the docs
assert s.started
routes_list = utils.list_routes(s.application)
assert routes_list.get("/webhooks/telegram/").startswith(
'telegram_webhook.health')
assert routes_list.get("/webhooks/telegram/webhook").startswith(
'telegram_webhook.message')
s.stop()
httpretty.disable()
try:
assert s.started
routes_list = utils.list_routes(s.application)
assert routes_list.get("/webhooks/telegram/").startswith(
'telegram_webhook.health')
assert routes_list.get("/webhooks/telegram/webhook").startswith(
'telegram_webhook.message')
finally:
s.stop()
httpretty.disable()


# USED FOR DOCS - don't rename without changing in the docs
Expand All @@ -202,13 +242,15 @@ def test_twilio_channel():
# END DOC INCLUDE
# the above marker marks the end of the code snipped included
# in the docs
assert s.started
routes_list = utils.list_routes(s.application)
assert routes_list.get("/webhooks/twilio/").startswith(
'twilio_webhook.health')
assert routes_list.get("/webhooks/twilio/webhook").startswith(
'twilio_webhook.message')
s.stop()
try:
assert s.started
routes_list = utils.list_routes(s.application)
assert routes_list.get("/webhooks/twilio/").startswith(
'twilio_webhook.health')
assert routes_list.get("/webhooks/twilio/webhook").startswith(
'twilio_webhook.message')
finally:
s.stop()


def test_slack_init_one_parameter():
Expand Down

0 comments on commit 7aebdab

Please sign in to comment.