Repository: opsdroid/opsdroid

Issue:
Default connector and default room
When writing a skill which originates from something other than a message (e.g cron #26) the response may need to know which room to post into. 

Most chat clients have a default room, like `#general` in Slack. This could be available as a property in the connector so that skills can easily access it. 

e.g

``` python
@non_message_decorator()
def myskill(opsdroid):
    for connector in opsdroid.connectors:
        message = Message("Message text", connector.default_room, None, connector)
        connector.respond(message)
```

It should also be possible to override the default room in the connector config.

``` yaml
connectors:
  slack:
    default-room: "#random"
```


Discussion:
coveralls: 
[![Coverage Status](https://coveralls.io/builds/8894977/badge)](https://coveralls.io/builds/8894977)

Coverage decreased (-2.07%) to 88.406% when pulling **2e9fbd4168e097d8122029b9d206fbb814f18b7b on jacobtomlinson:default-connectors** into **717138af2143ac10eb2232582987ca8fa9e04e00 on opsdroid:dev**.

coveralls: 
[![Coverage Status](https://coveralls.io/builds/9341671/badge)](https://coveralls.io/builds/9341671)

Coverage decreased (-1.9%) to 90.537% when pulling **0ee3aa909cca4b0b9c75c6a71c142a3b94f2ec14 on jacobtomlinson:default-connectors** into **bef3ccfae2b581b0e01fa001334a6beef7a7df57 on opsdroid:dev**.

coveralls: 
[![Coverage Status](https://coveralls.io/builds/9342108/badge)](https://coveralls.io/builds/9342108)

Coverage increased (+0.2%) to 92.602% when pulling **a285e010c0ce6ff857827b9b5ca28827da44b560 on jacobtomlinson:default-connectors** into **bef3ccfae2b581b0e01fa001334a6beef7a7df57 on opsdroid:dev**.


Patch:
diff --git a/docs/extending/connectors.md b/docs/extending/connectors.md
index 620723f..1d45b7d 100644
--- a/docs/extending/connectors.md
+++ b/docs/extending/connectors.md
@@ -1,6 +1,6 @@
 # Creating a connector
 
-Connectors are a class which extends the base opsdroid Connector. The class has three mandatory methods, `connect`, `listen` and `respond`.
+Connectors are a class which extends the base opsdroid Connector. The class has three mandatory methods, `connect`, `listen` and `respond`. There are also some default values you can override with the `__init__` function, just be sure you are setting everything that the default init sets.
 
 #### connect
 *connect* is a method which connects to a specific chat service
@@ -26,6 +26,12 @@ from opsdroid.message import Message
 
 class MyConnector(Connector):
 
+  def __init__(self, config):
+    # Init the config for the connector
+    self.name = "MyConnector" # The name of your connector
+    self.config = config # The config dictionary to be accessed later
+    self.default_room = "MyDefaultRoom" # The default room for messages to go
+
   async def connect(self, opsdroid):
     # Create connection object with chat library
     self.connection = await chatlibrary.connect()
diff --git a/opsdroid/connector.py b/opsdroid/connector.py
index c1f0381..e446c97 100644
--- a/opsdroid/connector.py
+++ b/opsdroid/connector.py
@@ -24,6 +24,7 @@ class Connector():
         """
         self.name = ""
         self.config = config
+        self.default_room = None
 
     async def connect(self, opsdroid):
         """Connect to chat service.
diff --git a/opsdroid/core.py b/opsdroid/core.py
index dc9bd4b..3141d57 100644
--- a/opsdroid/core.py
+++ b/opsdroid/core.py
@@ -46,6 +46,18 @@ class OpsDroid():
         """Remove self from existing instances."""
         self.__class__.instances = []
 
+    @property
+    def default_connector(self):
+        """Return the default connector."""
+        default_connector = None
+        for connector in self.connectors:
+            if "default" in connector.config and connector.config["default"]:
+                default_connector = connector
+                break
+        if default_connector is None:
+            default_connector = self.connectors[0]
+        return default_connector
+
     def exit(self):
         """Exit application."""
         logging.info("Exiting application with return code " +


Test patch:
diff --git a/tests/test_connector.py b/tests/test_connector.py
index 5e53ddd..ac6cd22 100644
--- a/tests/test_connector.py
+++ b/tests/test_connector.py
@@ -14,6 +14,7 @@ class TestConnectorBaseClass(unittest.TestCase):
     def test_init(self):
         config = {"example_item": "test"}
         connector = Connector(config)
+        self.assertEqual(None, connector.default_room)
         self.assertEqual("", connector.name)
         self.assertEqual("test", connector.config["example_item"])
 
diff --git a/tests/test_core.py b/tests/test_core.py
index 3199dce..daaa79d 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -104,6 +104,21 @@ class TestCore(unittest.TestCase):
             opsdroid.setup_skills(example_modules)
             self.assertEqual(len(example_modules[0]["module"].mock_calls), 1)
 
+    def test_default_connector(self):
+        with OpsDroid() as opsdroid:
+            mock_connector = Connector({})
+            opsdroid.connectors.append(mock_connector)
+            self.assertEqual(opsdroid.default_connector, mock_connector)
+
+            mock_default_connector = Connector({"default": True})
+            opsdroid.connectors.append(mock_default_connector)
+            self.assertEqual(opsdroid.default_connector,
+                             mock_default_connector)
+
+    def test_default_room(self):
+        mock_connector = Connector({})
+        self.assertEqual(None, mock_connector.default_room)
+
 
 class TestCoreAsync(asynctest.TestCase):
     """Test the async methods of the opsdroid core class."""