Repository: opsdroid/opsdroid

Issue:
API.AI is now Dialogflow, needs updating throughout
On the 10th of October Api.ai renamed their company to [Dialogflow](https://blog.dialogflow.com/post/apiai-new-name-dialogflow-new-features/).

Therefore I suggest the following changes:
 - Copy `match_apiai_action` and `match_apiai_intent` to `match_dialogflow_action` and `match_dialogflow_intent`
 - Modify `match_apiai_action` and `match_apiai_intent` to log a deprecation notice. These will be removed at some point in the future.
 - Rename `apiai` to `dialogflow` throughout the code and tests.
 - Rename 'Api.ai' to 'Dialogflow (Api.ai)' in [mkdocs.yaml](https://github.com/opsdroid/opsdroid/blob/master/mkdocs.yml).
- Rename [docs/matchers/api.ai.md](https://github.com/opsdroid/opsdroid/blob/master/docs/matchers/api.ai.md) to `dialogflow.md`.
- Update references to api.ai in the docs to Dialogflow. First mention should probably be `Dialogflow (previously Api.ai)`.


Discussion:
I can do this if you'd like Jacob
Go for it!
On Sat, 21 Oct 2017 at 19:41, Fábio Rosado <notifications@github.com> wrote:

> I can do this if you'd like Jacob
>
> —
> You are receiving this because you authored the thread.
> Reply to this email directly, view it on GitHub
> <https://github.com/opsdroid/opsdroid/issues/293#issuecomment-338423658>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/ABiUYtR60QcpTgBN_-Rcmr4Pab0OQxJfks5sujrSgaJpZM4QBqaS>
> .
>


Resolving patch:
diff --git a/opsdroid/core.py b/opsdroid/core.py
--- a/opsdroid/core.py
+++ b/opsdroid/core.py
@@ -13,7 +13,7 @@
 from opsdroid.loader import Loader
 from opsdroid.parsers.always import parse_always
 from opsdroid.parsers.regex import parse_regex
-from opsdroid.parsers.apiai import parse_apiai
+from opsdroid.parsers.dialogflow import parse_dialogflow
 from opsdroid.parsers.luisai import parse_luisai
 from opsdroid.parsers.witai import parse_witai
 from opsdroid.parsers.crontab import parse_crontab
@@ -195,15 +195,15 @@ async def parse(self, message):
                 _LOGGER.debug("Processing parsers")
                 parsers = self.config["parsers"]
 
-                apiai = [p for p in parsers if p["name"] == "apiai"]
-                _LOGGER.debug("Checking apiai")
-                if len(apiai) == 1 and \
-                        ("enabled" not in apiai[0] or
-                         apiai[0]["enabled"] is not False):
-                    _LOGGER.debug("Parsing with apiai")
+                dialogflow = [p for p in parsers if p["name"] == "dialogflow"]
+                _LOGGER.debug("Checking dialogflow")
+                if len(dialogflow) == 1 and \
+                        ("enabled" not in dialogflow[0] or
+                         dialogflow[0]["enabled"] is not False):
+                    _LOGGER.debug("Parsing with Dialogflow")
                     tasks.append(
                         self.eventloop.create_task(
-                            parse_apiai(self, message, apiai[0])))
+                            parse_dialogflow(self, message, dialogflow[0])))
 
                 luisai = [p for p in parsers if p["name"] == "luisai"]
                 _LOGGER.debug("Checking luisai")
diff --git a/opsdroid/matchers.py b/opsdroid/matchers.py
--- a/opsdroid/matchers.py
+++ b/opsdroid/matchers.py
@@ -24,23 +24,53 @@ def matcher(func):
 
 
 def match_apiai_action(action):
-    """Return apiai action match decorator."""
+    """Return Dialogflow action match decorator."""
     def matcher(func):
-        """Add decorated function to skills list for apiai matching."""
+        """Add decorated function to skills list for Dialogflow matching."""
         opsdroid = get_opsdroid()
-        opsdroid.skills.append({"apiai_action": action, "skill": func,
+        opsdroid.skills.append({"dialogflow_action": action, "skill": func,
                                 "config":
                                 opsdroid.loader.current_import_config})
         return func
+    _LOGGER.warning("Api.ai is now called Dialogflow, this matcher "
+                    "will stop working in the future. "
+                    "Use match_dialogflow_action instead.")
     return matcher
 
 
 def match_apiai_intent(intent):
-    """Return apiai intent match decorator."""
+    """Return Dialogflow intent match decorator."""
     def matcher(func):
-        """Add decorated function to skills list for apiai matching."""
+        """Add decorated function to skills list for Dialogflow matching."""
         opsdroid = get_opsdroid()
-        opsdroid.skills.append({"apiai_intent": intent, "skill": func,
+        opsdroid.skills.append({"dialogflow_intent": intent, "skill": func,
+                                "config":
+                                opsdroid.loader.current_import_config})
+        return func
+    _LOGGER.warning("Api.ai is now called Dialogflow, this matcher "
+                    "will stop working in the future. "
+                    "Use match_dialogflow_intent instead.")
+    return matcher
+
+
+def match_dialogflow_action(action):
+    """Return Dialogflowi action match decorator."""
+    def matcher(func):
+        """Add decorated function to skills list for Dialogflow matching."""
+        opsdroid = get_opsdroid()
+        opsdroid.skills.append({"dialogflow_action": action, "skill": func,
+                                "config":
+                                opsdroid.loader.current_import_config})
+        return func
+    return matcher
+
+
+def match_dialogflow_intent(intent):
+    """Return Dialogflow intent match decorator."""
+    def matcher(func):
+        """Add decorated function to skills list for Dialogflow matching."""
+        opsdroid = get_opsdroid()
+        opsdroid.skills.append({"dialogflow_intent": intent, "skill": func,
                                 "config":
                                 opsdroid.loader.current_import_config})
         return func
diff --git a/opsdroid/parsers/apiai.py b/opsdroid/parsers/dialogflow.py
similarity index 70%
rename from opsdroid/parsers/apiai.py
rename to opsdroid/parsers/dialogflow.py
--- a/opsdroid/parsers/apiai.py
+++ b/opsdroid/parsers/dialogflow.py
@@ -1,4 +1,4 @@
-"""A helper function for parsing and executing api.ai skills."""
+"""A helper function for parsing and executing Dialogflow skills."""
 
 import logging
 import json
@@ -9,8 +9,8 @@
 _LOGGER = logging.getLogger(__name__)
 
 
-async def call_apiai(message, config):
-    """Call the api.ai api and return the response."""
+async def call_dialogflow(message, config):
+    """Call the Dialogflow api and return the response."""
     async with aiohttp.ClientSession() as session:
         payload = {
             "v": "20150910",
@@ -22,50 +22,51 @@ async def call_apiai(message, config):
             "Authorization": "Bearer " + config['access-token'],
             "Content-Type": "application/json"
         }
-        resp = await session.post("https://api.api.ai/v1/query",
+        resp = await session.post("https://api.dialogflow.com/v1/query",
                                   data=json.dumps(payload),
                                   headers=headers)
         result = await resp.json()
-        _LOGGER.debug("api.ai response - " + json.dumps(result))
+        _LOGGER.debug("Dialogflow response - " + json.dumps(result))
 
         return result
 
 
-async def parse_apiai(opsdroid, message, config):
-    """Parse a message against all apiai skills."""
+async def parse_dialogflow(opsdroid, message, config):
+    """Parse a message against all Dialogflow skills."""
     # pylint: disable=broad-except
     # We want to catch all exceptions coming from a skill module and not
     # halt the application. If a skill throws an exception it just doesn't
     # give a response to the user, so an error response should be given.
     if 'access-token' in config:
         try:
-            result = await call_apiai(message, config)
+            result = await call_dialogflow(message, config)
         except aiohttp.ClientOSError:
-            _LOGGER.error("No response from api.ai, check your network.")
+            _LOGGER.error("No response from Dialogflow, check your network.")
             return
 
         if result["status"]["code"] >= 300:
-            _LOGGER.error("api.ai error - " +
+            _LOGGER.error("Dialogflow error - " +
                           str(result["status"]["code"]) + " " +
                           result["status"]["errorType"])
             return
 
         if "min-score" in config and \
                 result["result"]["score"] < config["min-score"]:
-            _LOGGER.debug("api.ai score lower than min-score")
+            _LOGGER.debug("Dialogflow score lower than min-score")
             return
 
         if result:
             for skill in opsdroid.skills:
 
-                if "apiai_action" in skill or "apiai_intent" in skill:
+                if "dialogflow_action" in skill or \
+                                "dialogflow_intent" in skill:
                     if ("action" in result["result"] and
-                            skill["apiai_action"] in
+                            skill["dialogflow_action"] in
                             result["result"]["action"]) \
                             or ("intentName" in result["result"] and
-                                skill["apiai_intent"] in
+                                skill["dialogflow_intent"] in
                                 result["result"]["intentName"]):
-                        message.apiai = result
+                        message.dialogflow = result
                         try:
                             await skill["skill"](opsdroid, skill["config"],
                                                  message)


Test patch:
diff --git a/tests/test_core.py b/tests/test_core.py
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -9,7 +9,7 @@
 from opsdroid.core import OpsDroid
 from opsdroid.message import Message
 from opsdroid.connector import Connector
-from opsdroid.matchers import (match_regex, match_apiai_action,
+from opsdroid.matchers import (match_regex, match_dialogflow_action,
                                match_luisai_intent, match_witai)
 
 
@@ -175,18 +175,18 @@ async def test_parse_regex_insensitive(self):
                 await task
             self.assertTrue(skill.called)
 
-    async def test_parse_apiai(self):
+    async def test_parse_dialogflow(self):
         with OpsDroid() as opsdroid:
-            opsdroid.config["parsers"] = [{"name": "apiai"}]
-            apiai_action = ""
+            opsdroid.config["parsers"] = [{"name": "dialogflow"}]
+            dialogflow_action = ""
             skill = amock.CoroutineMock()
             mock_connector = Connector({})
-            decorator = match_apiai_action(apiai_action)
+            decorator = match_dialogflow_action(dialogflow_action)
             decorator(skill)
             message = Message("Hello world", "user", "default", mock_connector)
-            with amock.patch('opsdroid.parsers.apiai.parse_apiai'):
+            with amock.patch('opsdroid.parsers.dialogflow.parse_dialogflow'):
                 tasks = await opsdroid.parse(message)
-                self.assertEqual(len(tasks), 3)  # apiai, regex and always
+                self.assertEqual(len(tasks), 3)  # dialogflow, regex and always
                 for task in tasks:
                     await task
 
diff --git a/tests/test_matchers.py b/tests/test_matchers.py
--- a/tests/test_matchers.py
+++ b/tests/test_matchers.py
@@ -29,13 +29,33 @@ async def test_match_apiai(self):
             decorator = matchers.match_apiai_action(action)
             decorator(mockedskill)
             self.assertEqual(len(opsdroid.skills), 1)
-            self.assertEqual(opsdroid.skills[0]["apiai_action"], action)
+            self.assertEqual(opsdroid.skills[0]["dialogflow_action"], action)
             self.assertIsInstance(opsdroid.skills[0]["skill"], mock.MagicMock)
             intent = "myIntent"
             decorator = matchers.match_apiai_intent(intent)
             decorator(mockedskill)
             self.assertEqual(len(opsdroid.skills), 2)
-            self.assertEqual(opsdroid.skills[1]["apiai_intent"], intent)
+            self.assertEqual(opsdroid.skills[1]["dialogflow_intent"], intent)
+            self.assertIsInstance(opsdroid.skills[1]["skill"], mock.MagicMock)
+            with mock.patch('opsdroid.matchers._LOGGER.warning') as logmock:
+                decorator = matchers.match_apiai_intent(intent)
+                decorator(mockedskill)
+                self.assertTrue(logmock.called)
+
+    async def test_match_dialogflow(self):
+        with OpsDroid() as opsdroid:
+            action = "myaction"
+            mockedskill = mock.MagicMock()
+            decorator = matchers.match_dialogflow_action(action)
+            decorator(mockedskill)
+            self.assertEqual(len(opsdroid.skills), 1)
+            self.assertEqual(opsdroid.skills[0]["dialogflow_action"], action)
+            self.assertIsInstance(opsdroid.skills[0]["skill"], mock.MagicMock)
+            intent = "myIntent"
+            decorator = matchers.match_dialogflow_intent(intent)
+            decorator(mockedskill)
+            self.assertEqual(len(opsdroid.skills), 2)
+            self.assertEqual(opsdroid.skills[1]["dialogflow_intent"], intent)
             self.assertIsInstance(opsdroid.skills[1]["skill"], mock.MagicMock)
 
     async def test_match_luisai(self):
diff --git a/tests/test_parser_apiai.py b/tests/test_parser_dialogflow.py
similarity index 58%
rename from tests/test_parser_apiai.py
rename to tests/test_parser_dialogflow.py
--- a/tests/test_parser_apiai.py
+++ b/tests/test_parser_dialogflow.py
@@ -5,19 +5,19 @@
 from aiohttp import helpers, ClientOSError
 
 from opsdroid.core import OpsDroid
-from opsdroid.matchers import match_apiai_action
+from opsdroid.matchers import match_dialogflow_action
 from opsdroid.message import Message
-from opsdroid.parsers import apiai
+from opsdroid.parsers import dialogflow
 from opsdroid.connector import Connector
 
 
-class TestParserApiai(asynctest.TestCase):
-    """Test the opsdroid api.ai parser."""
+class TestParserDialogflow(asynctest.TestCase):
+    """Test the opsdroid Dialogflow parser."""
 
-    async def test_call_apiai(self):
+    async def test_call_dialogflow(self):
         mock_connector = Connector({})
         message = Message("Hello world", "user", "default", mock_connector)
-        config = {'name': 'apiai', 'access-token': 'test'}
+        config = {'name': 'dialogflow', 'access-token': 'test'}
         result = amock.Mock()
         result.json = amock.CoroutineMock()
         result.json.return_value = {
@@ -33,22 +33,23 @@ async def test_call_apiai(self):
         with amock.patch('aiohttp.ClientSession.post') as patched_request:
             patched_request.return_value = helpers.create_future(self.loop)
             patched_request.return_value.set_result(result)
-            await apiai.call_apiai(message, config)
+            await dialogflow.call_dialogflow(message, config)
             self.assertTrue(patched_request.called)
 
-    async def test_parse_apiai(self):
+    async def test_parse_dialogflow(self):
         with OpsDroid() as opsdroid:
             opsdroid.config['parsers'] = [
-                    {'name': 'apiai', 'access-token': "test"}
+                    {'name': 'dialogflow', 'access-token': "test"}
                 ]
             mock_skill = amock.CoroutineMock()
-            match_apiai_action('myaction')(mock_skill)
+            match_dialogflow_action('myaction')(mock_skill)
 
             mock_connector = amock.CoroutineMock()
             message = Message("Hello world", "user", "default", mock_connector)
 
-            with amock.patch.object(apiai, 'call_apiai') as mocked_call_apiai:
-                mocked_call_apiai.return_value = {
+            with amock.patch.object(dialogflow, 'call_dialogflow') as \
+                    mocked_call_dialogflow:
+                mocked_call_dialogflow.return_value = {
                         "result": {
                             "action": "myaction",
                             "score": 0.7
@@ -58,25 +59,26 @@ async def test_parse_apiai(self):
                             "errorType": "success"
                         }
                     }
-                await apiai.parse_apiai(opsdroid, message,
-                                        opsdroid.config['parsers'][0])
+                await dialogflow.parse_dialogflow(
+                    opsdroid, message, opsdroid.config['parsers'][0])
 
             self.assertTrue(mock_skill.called)
 
-    async def test_parse_apiai_raises(self):
+    async def test_parse_dialogflow_raises(self):
         with OpsDroid() as opsdroid:
             opsdroid.config['parsers'] = [
-                    {'name': 'apiai', 'access-token': "test"}
+                    {'name': 'dialogflow', 'access-token': "test"}
                 ]
             mock_skill = amock.CoroutineMock()
             mock_skill.side_effect = Exception()
-            match_apiai_action('myaction')(mock_skill)
+            match_dialogflow_action('myaction')(mock_skill)
 
             mock_connector = amock.CoroutineMock()
             message = Message("Hello world", "user", "default", mock_connector)
 
-            with amock.patch.object(apiai, 'call_apiai') as mocked_call_apiai:
-                mocked_call_apiai.return_value = {
+            with amock.patch.object(dialogflow, 'call_dialogflow') as \
+                    mocked_call_dialogflow:
+                mocked_call_dialogflow.return_value = {
                         "result": {
                             "action": "myaction",
                             "score": 0.7
@@ -86,24 +88,25 @@ async def test_parse_apiai_raises(self):
                             "errorType": "success"
                         }
                     }
-                await apiai.parse_apiai(opsdroid, message,
-                                        opsdroid.config['parsers'][0])
+                await dialogflow.parse_dialogflow(
+                    opsdroid, message, opsdroid.config['parsers'][0])
 
             self.assertTrue(mock_skill.called)
 
-    async def test_parse_apiai_failure(self):
+    async def test_parse_dialogflow_failure(self):
         with OpsDroid() as opsdroid:
             opsdroid.config['parsers'] = [
-                    {'name': 'apiai', 'access-token': "test"}
+                    {'name': 'dialogflow', 'access-token': "test"}
                 ]
             mock_skill = amock.CoroutineMock()
-            match_apiai_action('myaction')(mock_skill)
+            match_dialogflow_action('myaction')(mock_skill)
 
             mock_connector = amock.CoroutineMock()
             message = Message("Hello world", "user", "default", mock_connector)
 
-            with amock.patch.object(apiai, 'call_apiai') as mocked_call_apiai:
-                mocked_call_apiai.return_value = {
+            with amock.patch.object(dialogflow, 'call_dialogflow') as \
+                    mocked_call_dialogflow:
+                mocked_call_dialogflow.return_value = {
                         "result": {
                             "action": "myaction",
                             "score": 0.7
@@ -113,24 +116,29 @@ async def test_parse_apiai_failure(self):
                             "errorType": "not found"
                         }
                     }
-                await apiai.parse_apiai(opsdroid, message,
-                                        opsdroid.config['parsers'][0])
+                await dialogflow.parse_dialogflow(
+                    opsdroid, message, opsdroid.config['parsers'][0])
 
             self.assertFalse(mock_skill.called)
 
-    async def test_parse_apiai_low_score(self):
+    async def test_parse_dialogflow_low_score(self):
         with OpsDroid() as opsdroid:
             opsdroid.config['parsers'] = [
-                    {'name': 'apiai', 'access-token': "test", "min-score": 0.8}
+                    {
+                        'name': 'dialogflow',
+                        'access-token': "test",
+                        "min-score": 0.8
+                    }
                 ]
             mock_skill = amock.CoroutineMock()
-            match_apiai_action('myaction')(mock_skill)
+            match_dialogflow_action('myaction')(mock_skill)
 
             mock_connector = amock.CoroutineMock()
             message = Message("Hello world", "user", "default", mock_connector)
 
-            with amock.patch.object(apiai, 'call_apiai') as mocked_call_apiai:
-                mocked_call_apiai.return_value = {
+            with amock.patch.object(dialogflow, 'call_dialogflow') as \
+                    mocked_call_dialogflow:
+                mocked_call_dialogflow.return_value = {
                         "result": {
                             "action": "myaction",
                             "score": 0.7
@@ -140,26 +148,30 @@ async def test_parse_apiai_low_score(self):
                             "errorType": "success"
                         }
                     }
-                await apiai.parse_apiai(opsdroid, message,
-                                        opsdroid.config['parsers'][0])
+                await dialogflow.parse_dialogflow(
+                    opsdroid, message, opsdroid.config['parsers'][0])
 
             self.assertFalse(mock_skill.called)
 
-    async def test_parse_apiai_raise_ClientOSError(self):
+    async def test_parse_dialogflow_raise_ClientOSError(self):
         with OpsDroid() as opsdroid:
             opsdroid.config['parsers'] = [
-                    {'name': 'apiai', 'access-token': "test", "min-score": 0.8}
+                    {
+                        'name': 'dialogflow',
+                        'access-token': "test",
+                        "min-score": 0.8}
                 ]
             mock_skill = amock.CoroutineMock()
-            match_apiai_action('myaction')(mock_skill)
+            match_dialogflow_action('myaction')(mock_skill)
 
             mock_connector = amock.CoroutineMock()
             message = Message("Hello world", "user", "default", mock_connector)
 
-            with amock.patch.object(apiai, 'call_apiai') as mocked_call:
+            with amock.patch.object(dialogflow, 'call_dialogflow') \
+                    as mocked_call:
                 mocked_call.side_effect = ClientOSError()
-                await apiai.parse_apiai(opsdroid, message,
-                                        opsdroid.config['parsers'][0])
+                await dialogflow.parse_dialogflow(
+                    opsdroid, message, opsdroid.config['parsers'][0])
 
             self.assertFalse(mock_skill.called)
             self.assertTrue(mocked_call.called)