Repository: opsdroid/opsdroid

Issue:
Constraints don't apply to non-Message events
<!-- Before you post an issue or if you are unsure about something join our matrix channel https://riot.im/app/#/room/#opsdroid-general:matrix.org and ask away! We are more than happy to help you. -->
# Description
It seems that constrains don't apply to non-Message events.

## Steps to Reproduce
```python
class ExampleSkill(Skill):

    @match_event(JoinRoom)
    @constrain_rooms(['room1'])
    async def user_join(self, event):
        print('User joined {}'.format(event.target))
```

## Expected Functionality
The `user_join()` skill method would only run if a user joined `room1`


## Experienced Functionality
The `user_join()` skill method is run when a user joins any room the connector is configured to join.

## Versions
- **Opsdroid version:** 7282a5da06
- **Python version:** 3.7.6
- **OS/Docker version:** Linux/Debian (testing)

## Configuration File
```yaml
connector:
  - name: matrix
    mxid: '@user:matrix.org'
    password: xxx
    nick: 'User'
    rooms:
      'room1': <room id>
      'room2': <room id>
```


Discussion:
Yep: https://github.com/opsdroid/opsdroid/blob/master/opsdroid/core.py#L494L497 should be an easy fix, and there is no good reason for it either.

Resolving patch:
diff --git a/opsdroid/connector/matrix/connector.py b/opsdroid/connector/matrix/connector.py
--- a/opsdroid/connector/matrix/connector.py
+++ b/opsdroid/connector/matrix/connector.py
@@ -210,6 +210,11 @@ async def listen(self):  # pragma: no cover
             except Exception:  # pylint: disable=W0703
                 _LOGGER.exception(_("Matrix sync error."))
 
+    def lookup_target(self, room):
+        """Convert name or alias of a room to the corresponding room ID."""
+        room = self.get_roomname(room)
+        return self.room_ids.get(room, room)
+
     async def get_nick(self, roomid, mxid):
         """
         Get nickname from user ID.
diff --git a/opsdroid/constraints.py b/opsdroid/constraints.py
--- a/opsdroid/constraints.py
+++ b/opsdroid/constraints.py
@@ -31,6 +31,9 @@ def constraint_decorator(func):
 
         def constraint_callback(message, rooms=rooms):
             """Check if the room is correct."""
+            if hasattr(message.connector, "lookup_target"):
+                rooms = list(map(message.connector.lookup_target, rooms))
+
             return message.target in rooms
 
         func = add_skill_attributes(func)
diff --git a/opsdroid/parsers/event_type.py b/opsdroid/parsers/event_type.py
--- a/opsdroid/parsers/event_type.py
+++ b/opsdroid/parsers/event_type.py
@@ -51,6 +51,9 @@ async def match_event(event, event_opts):
 async def parse_event_type(opsdroid, event):
     """Parse an event if it's of a certain type."""
     for skill in opsdroid.skills:
+        for constraint in skill.constraints:
+            if not constraint(event):
+                return
         for matcher in skill.matchers:
             event_opts = matcher.get("event_type", {})
             result = await match_event(event, event_opts)


Test patch:
diff --git a/tests/test_connector_matrix.py b/tests/test_connector_matrix.py
--- a/tests/test_connector_matrix.py
+++ b/tests/test_connector_matrix.py
@@ -414,6 +414,15 @@ def test_get_roomname(self):
         assert self.connector.get_roomname("!aroomid:localhost") == "main"
         assert self.connector.get_roomname("someroom") == "someroom"
 
+    def test_lookup_target(self):
+        self.connector.room_ids = {"main": "!aroomid:localhost"}
+
+        assert self.connector.lookup_target("main") == "!aroomid:localhost"
+        assert self.connector.lookup_target("#test:localhost") == "!aroomid:localhost"
+        assert (
+            self.connector.lookup_target("!aroomid:localhost") == "!aroomid:localhost"
+        )
+
     async def test_respond_image(self):
         gif_bytes = (
             b"GIF89a\x01\x00\x01\x00\x00\xff\x00,"
diff --git a/tests/test_parser_event_type.py b/tests/test_parser_event_type.py
--- a/tests/test_parser_event_type.py
+++ b/tests/test_parser_event_type.py
@@ -6,6 +6,7 @@
 from opsdroid.matchers import match_event
 from opsdroid import events
 from opsdroid.parsers.event_type import parse_event_type
+from opsdroid.constraints import constrain_rooms
 
 
 class TestParserEvent(asynctest.TestCase):
@@ -56,6 +57,23 @@ async def test_parse_event_with_args(self):
             await opsdroid.parse(message2)
             self.assertFalse(opsdroid.run_skill.called)
 
+    async def test_parse_event_with_constraint(self):
+        with OpsDroid() as opsdroid:
+            opsdroid.run_skill = amock.CoroutineMock()
+            mock_skill = await self.getMockSkill()
+            mock_skill = match_event(events.JoinRoom)(mock_skill)
+            mock_skill = constrain_rooms(["#general"])(mock_skill)
+            opsdroid.skills.append(mock_skill)
+
+            mock_connector = amock.CoroutineMock()
+            mock_connector.lookup_target = amock.Mock(return_value="some_room_id")
+            message = events.JoinRoom(
+                user="user", target="some_room_id", connector=mock_connector
+            )
+
+            await opsdroid.parse(message)
+            self.assertTrue(opsdroid.run_skill.called)
+
     async def test_parse_str_event(self):
         with OpsDroid() as opsdroid:
             opsdroid.run_skill = amock.CoroutineMock()