Repository: opsdroid/opsdroid

Issue:
Making skill-hello case insensitive exposed a bug: infinite self-responses.
<!-- 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

Thanks for this great project!

While trying out a case-insensitive variation of skill-hello that I just [submitted as a PR against skill-hello](https://github.com/opsdroid/skill-hello/pull/4) I encountered an infinite loop of the bot responding to itself.

## Expected behavior

I expected to say "Hi" and get one "Hi" / "Hello" / "Hey" back.

## Experienced behavior

Instead, the bot responded to me and then to _itself_. It happens to respond with a capitalized first letter (e.g. "Hi", "Hey", "Hello"). This is why my case-insensitive variation happens to expose this self-response bug: it was previously ignoring "Hi" because of the capital "H". On my branch, it now matches its own responses.

In the detail box below I have pasted the relevant DEBUG logs, where you can see my initial message, its response (good so far...), and then a string of its responses to its own responses. The infinite loop eventually stopped after 20 messages or so; I suspect the bot was throttled by gitter at that point.

(In this example my username is `danielballan` and the bot is `twinkling-tree`. Forgive the silly bot name; my application is a hobby project controlling Christmas tree lights.)

<details>

```
DEBUG opsdroid.connector.gitter: {'id': '5ff1dc10aa6bb528c38a9d47', 'text': 'hi', 'html': 'hi', 'sent': '2021-01-03T15:00:32.273Z', 'readBy': 0, 'urls': [], 'mentions': [], 'issues': [], 'meta': [], 'v': 1, 'fromUser': {'id': '54ac2a22db8155e6700e6990', 'username': 'danielballan', 'displayName': 'Dan Allan', 'url': '/danielballan', 'avatarUrl': 'https://avatars-05.gitter.im/gh/uv/4/danielballan', 'avatarUrlSmall': 'https://avatars2.githubusercontent.com/u/2279598?v=4&s=60', 'avatarUrlMedium': 'https://avatars2.githubusercontent.com/u/2279598?v=4&s=128', 'v': 35, 'gv': '4'}}
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=hi)>.
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
INFO opsdroid.connector.gitter: Successfully responded.
DEBUG opsdroid.connector.gitter: {'id': '5ff1dc1163fe034496359a84', 'text': 'Hi danielballan', 'html': 'Hi danielballan', 'sent': '2021-01-03T15:00:33.815Z', 'readBy': 0, 'urls': [], 'mentions': [], 'issues': [], 'meta': [], 'v': 1, 'fromUser': {'id': '5ff0c884d73408ce4ff7d787', 'username': 'twinkling-tree', 'displayName': 'twinkling-tree', 'url': '/twinkling-tree', 'avatarUrl': 'https://avatars-01.gitter.im/gh/uv/4/twinkling-tree', 'avatarUrlSmall': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=60', 'avatarUrlMedium': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=128', 'v': 3, 'gv': '4'}}
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=Hi danielballan)>.
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
INFO opsdroid.connector.gitter: Successfully responded.
DEBUG opsdroid.connector.gitter: {'id': '5ff1dc1197312f4b6b07832c', 'text': 'Hey twinkling-tree', 'html': 'Hey twinkling-tree', 'sent': '2021-01-03T15:00:33.910Z', 'readBy': 0, 'urls': [], 'mentions': [], 'issues': [], 'meta': [], 'v': 1, 'fromUser': {'id': '5ff0c884d73408ce4ff7d787', 'username': 'twinkling-tree', 'displayName': 'twinkling-tree', 'url': '/twinkling-tree', 'avatarUrl': 'https://avatars-01.gitter.im/gh/uv/4/twinkling-tree', 'avatarUrlSmall': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=60', 'avatarUrlMedium': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=128', 'v': 3, 'gv': '4'}}
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=Hey twinkling-tree)>.
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
INFO opsdroid.connector.gitter: Successfully responded.
DEBUG opsdroid.connector.gitter: {'id': '5ff1dc12acd1e516f8ce8723', 'text': 'Hello twinkling-tree', 'html': 'Hello twinkling-tree', 'sent': '2021-01-03T15:00:34.012Z', 'readBy': 0, 'urls': [], 'mentions': [], 'issues': [], 'meta': [], 'v': 1, 'fromUser': {'id': '5ff0c884d73408ce4ff7d787', 'username': 'twinkling-tree', 'displayName': 'twinkling-tree', 'url': '/twinkling-tree', 'avatarUrl': 'https://avatars-01.gitter.im/gh/uv/4/twinkling-tree', 'avatarUrlSmall': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=60', 'avatarUrlMedium': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=128', 'v': 3, 'gv': '4'}}
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=Hello twinkling-tree)>.
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
INFO opsdroid.connector.gitter: Successfully responded.
DEBUG opsdroid.connector.gitter: {'id': '5ff1dc12dbb17f28c5b79b25', 'text': 'Hey twinkling-tree', 'html': 'Hey twinkling-tree', 'sent': '2021-01-03T15:00:34.093Z', 'readBy': 0, 'urls': [], 'mentions': [], 'issues': [], 'meta': [], 'v': 1, 'fromUser': {'id': '5ff0c884d73408ce4ff7d787', 'username': 'twinkling-tree', 'displayName': 'twinkling-tree', 'url': '/twinkling-tree', 'avatarUrl': 'https://avatars-01.gitter.im/gh/uv/4/twinkling-tree', 'avatarUrlSmall': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=60', 'avatarUrlMedium': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=128', 'v': 3, 'gv': '4'}}
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=Hey twinkling-tree)>.
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
INFO opsdroid.connector.gitter: Successfully responded.
DEBUG opsdroid.connector.gitter: {'id': '5ff1dc12de608143155d1990', 'text': 'Hi twinkling-tree', 'html': 'Hi twinkling-tree', 'sent': '2021-01-03T15:00:34.195Z', 'readBy': 0, 'urls': [], 'mentions': [], 'issues': [], 'meta': [], 'v': 1, 'fromUser': {'id': '5ff0c884d73408ce4ff7d787', 'username': 'twinkling-tree', 'displayName': 'twinkling-tree', 'url': '/twinkling-tree', 'avatarUrl': 'https://avatars-01.gitter.im/gh/uv/4/twinkling-tree', 'avatarUrlSmall': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=60', 'avatarUrlMedium': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=128', 'v': 3, 'gv': '4'}}
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=Hi twinkling-tree)>.
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
INFO opsdroid.connector.gitter: Successfully responded.
DEBUG opsdroid.connector.gitter: {'id': '5ff1dc1269ee7f0422dd640f', 'text': 'Hey twinkling-tree', 'html': 'Hey twinkling-tree', 'sent': '2021-01-03T15:00:34.312Z', 'readBy': 0, 'urls': [], 'mentions': [], 'issues': [], 'meta': [], 'v': 1, 'fromUser': {'id': '5ff0c884d73408ce4ff7d787', 'username': 'twinkling-tree', 'displayName': 'twinkling-tree', 'url': '/twinkling-tree', 'avatarUrl': 'https://avatars-01.gitter.im/gh/uv/4/twinkling-tree', 'avatarUrlSmall': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=60', 'avatarUrlMedium': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=128', 'v': 3, 'gv': '4'}}
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=Hey twinkling-tree)>.
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
INFO opsdroid.connector.gitter: Successfully responded.
DEBUG opsdroid.connector.gitter: {'id': '5ff1dc12acd1e516f8ce8726', 'text': 'Hey twinkling-tree', 'html': 'Hey twinkling-tree', 'sent': '2021-01-03T15:00:34.406Z', 'readBy': 0, 'urls': [], 'mentions': [], 'issues': [], 'meta': [], 'v': 1, 'fromUser': {'id': '5ff0c884d73408ce4ff7d787', 'username': 'twinkling-tree', 'displayName': 'twinkling-tree', 'url': '/twinkling-tree', 'avatarUrl': 'https://avatars-01.gitter.im/gh/uv/4/twinkling-tree', 'avatarUrlSmall': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=60', 'avatarUrlMedium': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=128', 'v': 3, 'gv': '4'}}
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=Hey twinkling-tree)>.
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
INFO opsdroid.connector.gitter: Successfully responded.
DEBUG opsdroid.connector.gitter: {'id': '5ff1dc12c746c6431cf1d1cc', 'text': 'Hello twinkling-tree', 'html': 'Hello twinkling-tree', 'sent': '2021-01-03T15:00:34.509Z', 'readBy': 0, 'urls': [], 'mentions': [], 'issues': [], 'meta': [], 'v': 1, 'fromUser': {'id': '5ff0c884d73408ce4ff7d787', 'username': 'twinkling-tree', 'displayName': 'twinkling-tree', 'url': '/twinkling-tree', 'avatarUrl': 'https://avatars-01.gitter.im/gh/uv/4/twinkling-tree', 'avatarUrlSmall': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=60', 'avatarUrlMedium': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=128', 'v': 3, 'gv': '4'}}
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=Hello twinkling-tree)>.
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
INFO opsdroid.connector.gitter: Successfully responded.
DEBUG opsdroid.connector.gitter: {'id': '5ff1dc12dbb17f28c5b79b28', 'text': 'Hi twinkling-tree', 'html': 'Hi twinkling-tree', 'sent': '2021-01-03T15:00:34.599Z', 'readBy': 0, 'urls': [], 'mentions': [], 'issues': [], 'meta': [], 'v': 1, 'fromUser': {'id': '5ff0c884d73408ce4ff7d787', 'username': 'twinkling-tree', 'displayName': 'twinkling-tree', 'url': '/twinkling-tree', 'avatarUrl': 'https://avatars-01.gitter.im/gh/uv/4/twinkling-tree', 'avatarUrlSmall': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=60', 'avatarUrlMedium': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=128', 'v': 3, 'gv': '4'}}
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=Hi twinkling-tree)>.
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
INFO opsdroid.connector.gitter: Successfully responded.
DEBUG opsdroid.connector.gitter: {'id': '5ff1dc1222f12e449b2af62b', 'text': 'Hi twinkling-tree', 'html': 'Hi twinkling-tree', 'sent': '2021-01-03T15:00:34.709Z', 'readBy': 0, 'urls': [], 'mentions': [], 'issues': [], 'meta': [], 'v': 1, 'fromUser': {'id': '5ff0c884d73408ce4ff7d787', 'username': 'twinkling-tree', 'displayName': 'twinkling-tree', 'url': '/twinkling-tree', 'avatarUrl': 'https://avatars-01.gitter.im/gh/uv/4/twinkling-tree', 'avatarUrlSmall': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=60', 'avatarUrlMedium': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=128', 'v': 3, 'gv': '4'}}
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=Hi twinkling-tree)>.
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
INFO opsdroid.connector.gitter: Successfully responded.
DEBUG opsdroid.connector.gitter: {'id': '5ff1dc12acd1e516f8ce872a', 'text': 'Hello twinkling-tree', 'html': 'Hello twinkling-tree', 'sent': '2021-01-03T15:00:34.797Z', 'readBy': 0, 'urls': [], 'mentions': [], 'issues': [], 'meta': [], 'v': 1, 'fromUser': {'id': '5ff0c884d73408ce4ff7d787', 'username': 'twinkling-tree', 'displayName': 'twinkling-tree', 'url': '/twinkling-tree', 'avatarUrl': 'https://avatars-01.gitter.im/gh/uv/4/twinkling-tree', 'avatarUrlSmall': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=60', 'avatarUrlMedium': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=128', 'v': 3, 'gv': '4'}}
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=Hello twinkling-tree)>.
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
INFO opsdroid.connector.gitter: Successfully responded.
DEBUG opsdroid.connector.gitter: {'id': '5ff1dc12c746c6431cf1d1d3', 'text': 'Hi twinkling-tree', 'html': 'Hi twinkling-tree', 'sent': '2021-01-03T15:00:34.915Z', 'readBy': 0, 'urls': [], 'mentions': [], 'issues': [], 'meta': [], 'v': 1, 'fromUser': {'id': '5ff0c884d73408ce4ff7d787', 'username': 'twinkling-tree', 'displayName': 'twinkling-tree', 'url': '/twinkling-tree', 'avatarUrl': 'https://avatars-01.gitter.im/gh/uv/4/twinkling-tree', 'avatarUrlSmall': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=60', 'avatarUrlMedium': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=128', 'v': 3, 'gv': '4'}}
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=Hi twinkling-tree)>.
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
INFO opsdroid.connector.gitter: Successfully responded.
DEBUG opsdroid.connector.gitter: {'id': '5ff1dc1397312f4b6b078330', 'text': 'Hi twinkling-tree', 'html': 'Hi twinkling-tree', 'sent': '2021-01-03T15:00:34.999Z', 'readBy': 0, 'urls': [], 'mentions': [], 'issues': [], 'meta': [], 'v': 1, 'fromUser': {'id': '5ff0c884d73408ce4ff7d787', 'username': 'twinkling-tree', 'displayName': 'twinkling-tree', 'url': '/twinkling-tree', 'avatarUrl': 'https://avatars-01.gitter.im/gh/uv/4/twinkling-tree', 'avatarUrlSmall': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=60', 'avatarUrlMedium': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=128', 'v': 3, 'gv': '4'}}
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=Hi twinkling-tree)>.
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
INFO opsdroid.connector.gitter: Successfully responded.
DEBUG opsdroid.connector.gitter: {'id': '5ff1dc13e7f693041f4a73e3', 'text': 'Hi twinkling-tree', 'html': 'Hi twinkling-tree', 'sent': '2021-01-03T15:00:35.098Z', 'readBy': 0, 'urls': [], 'mentions': [], 'issues': [], 'meta': [], 'v': 1, 'fromUser': {'id': '5ff0c884d73408ce4ff7d787', 'username': 'twinkling-tree', 'displayName': 'twinkling-tree', 'url': '/twinkling-tree', 'avatarUrl': 'https://avatars-01.gitter.im/gh/uv/4/twinkling-tree', 'avatarUrlSmall': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=60', 'avatarUrlMedium': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=128', 'v': 3, 'gv': '4'}}
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=Hi twinkling-tree)>.
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
INFO opsdroid.connector.gitter: Successfully responded.
DEBUG opsdroid.connector.gitter: {'id': '5ff1dc13acd1e516f8ce872e', 'text': 'Hi twinkling-tree', 'html': 'Hi twinkling-tree', 'sent': '2021-01-03T15:00:35.194Z', 'readBy': 0, 'urls': [], 'mentions': [], 'issues': [], 'meta': [], 'v': 1, 'fromUser': {'id': '5ff0c884d73408ce4ff7d787', 'username': 'twinkling-tree', 'displayName': 'twinkling-tree', 'url': '/twinkling-tree', 'avatarUrl': 'https://avatars-01.gitter.im/gh/uv/4/twinkling-tree', 'avatarUrlSmall': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=60', 'avatarUrlMedium': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=128', 'v': 3, 'gv': '4'}}
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=Hi twinkling-tree)>.
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
INFO opsdroid.connector.gitter: Successfully responded.
DEBUG opsdroid.connector.gitter: {'id': '5ff1dc13dbb17f28c5b79b2c', 'text': 'Hi twinkling-tree', 'html': 'Hi twinkling-tree', 'sent': '2021-01-03T15:00:35.273Z', 'readBy': 0, 'urls': [], 'mentions': [], 'issues': [], 'meta': [], 'v': 1, 'fromUser': {'id': '5ff0c884d73408ce4ff7d787', 'username': 'twinkling-tree', 'displayName': 'twinkling-tree', 'url': '/twinkling-tree', 'avatarUrl': 'https://avatars-01.gitter.im/gh/uv/4/twinkling-tree', 'avatarUrlSmall': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=60', 'avatarUrlMedium': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=128', 'v': 3, 'gv': '4'}}
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=Hi twinkling-tree)>.
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
INFO opsdroid.connector.gitter: Successfully responded.
DEBUG opsdroid.connector.gitter: {'id': '5ff1dc1369ee7f0422dd6413', 'text': 'Hey twinkling-tree', 'html': 'Hey twinkling-tree', 'sent': '2021-01-03T15:00:35.360Z', 'readBy': 0, 'urls': [], 'mentions': [], 'issues': [], 'meta': [], 'v': 1, 'fromUser': {'id': '5ff0c884d73408ce4ff7d787', 'username': 'twinkling-tree', 'displayName': 'twinkling-tree', 'url': '/twinkling-tree', 'avatarUrl': 'https://avatars-01.gitter.im/gh/uv/4/twinkling-tree', 'avatarUrlSmall': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=60', 'avatarUrlMedium': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=128', 'v': 3, 'gv': '4'}}
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=Hey twinkling-tree)>.
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
INFO opsdroid.connector.gitter: Successfully responded.
DEBUG opsdroid.connector.gitter: {'id': '5ff1dc13dbb17f28c5b79b30', 'text': 'Hello twinkling-tree', 'html': 'Hello twinkling-tree', 'sent': '2021-01-03T15:00:35.443Z', 'readBy': 0, 'urls': [], 'mentions': [], 'issues': [], 'meta': [], 'v': 1, 'fromUser': {'id': '5ff0c884d73408ce4ff7d787', 'username': 'twinkling-tree', 'displayName': 'twinkling-tree', 'url': '/twinkling-tree', 'avatarUrl': 'https://avatars-01.gitter.im/gh/uv/4/twinkling-tree', 'avatarUrlSmall': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=60', 'avatarUrlMedium': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=128', 'v': 3, 'gv': '4'}}
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=Hello twinkling-tree)>.
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
INFO opsdroid.connector.gitter: Successfully responded.
DEBUG opsdroid.connector.gitter: {'id': '5ff1dc1322f12e449b2af62f', 'text': 'Hello twinkling-tree', 'html': 'Hello twinkling-tree', 'sent': '2021-01-03T15:00:35.524Z', 'readBy': 0, 'urls': [], 'mentions': [], 'issues': [], 'meta': [], 'v': 1, 'fromUser': {'id': '5ff0c884d73408ce4ff7d787', 'username': 'twinkling-tree', 'displayName': 'twinkling-tree', 'url': '/twinkling-tree', 'avatarUrl': 'https://avatars-01.gitter.im/gh/uv/4/twinkling-tree', 'avatarUrlSmall': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=60', 'avatarUrlMedium': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=128', 'v': 3, 'gv': '4'}}
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=Hello twinkling-tree)>.
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
INFO opsdroid.connector.gitter: Successfully responded.
DEBUG opsdroid.connector.gitter: {'id': '5ff1dc13c746c6431cf1d1d8', 'text': 'Hey twinkling-tree', 'html': 'Hey twinkling-tree', 'sent': '2021-01-03T15:00:35.612Z', 'readBy': 0, 'urls': [], 'mentions': [], 'issues': [], 'meta': [], 'v': 1, 'fromUser': {'id': '5ff0c884d73408ce4ff7d787', 'username': 'twinkling-tree', 'displayName': 'twinkling-tree', 'url': '/twinkling-tree', 'avatarUrl': 'https://avatars-01.gitter.im/gh/uv/4/twinkling-tree', 'avatarUrlSmall': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=60', 'avatarUrlMedium': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=128', 'v': 3, 'gv': '4'}}
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=Hey twinkling-tree)>.
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
INFO opsdroid.connector.gitter: Successfully responded.
DEBUG opsdroid.connector.gitter: {'id': '5ff1dc138bb73474696f4e51', 'text': 'Hello twinkling-tree', 'html': 'Hello twinkling-tree', 'sent': '2021-01-03T15:00:35.699Z', 'readBy': 0, 'urls': [], 'mentions': [], 'issues': [], 'meta': [], 'v': 1, 'fromUser': {'id': '5ff0c884d73408ce4ff7d787', 'username': 'twinkling-tree', 'displayName': 'twinkling-tree', 'url': '/twinkling-tree', 'avatarUrl': 'https://avatars-01.gitter.im/gh/uv/4/twinkling-tree', 'avatarUrlSmall': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=60', 'avatarUrlMedium': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=128', 'v': 3, 'gv': '4'}}
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=Hello twinkling-tree)>.
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
INFO opsdroid.connector.gitter: Successfully responded.
DEBUG opsdroid.connector.gitter: {'id': '5ff1dc1369ee7f0422dd6417', 'text': 'Hi twinkling-tree', 'html': 'Hi twinkling-tree', 'sent': '2021-01-03T15:00:35.790Z', 'readBy': 0, 'urls': [], 'mentions': [], 'issues': [], 'meta': [], 'v': 1, 'fromUser': {'id': '5ff0c884d73408ce4ff7d787', 'username': 'twinkling-tree', 'displayName': 'twinkling-tree', 'url': '/twinkling-tree', 'avatarUrl': 'https://avatars-01.gitter.im/gh/uv/4/twinkling-tree', 'avatarUrlSmall': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=60', 'avatarUrlMedium': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=128', 'v': 3, 'gv': '4'}}
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=Hi twinkling-tree)>.
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
INFO opsdroid.connector.gitter: Successfully responded.
DEBUG opsdroid.connector.gitter: {'id': '5ff1dc13de608143155d1996', 'text': 'Hello twinkling-tree', 'html': 'Hello twinkling-tree', 'sent': '2021-01-03T15:00:35.883Z', 'readBy': 0, 'urls': [], 'mentions': [], 'issues': [], 'meta': [], 'v': 1, 'fromUser': {'id': '5ff0c884d73408ce4ff7d787', 'username': 'twinkling-tree', 'displayName': 'twinkling-tree', 'url': '/twinkling-tree', 'avatarUrl': 'https://avatars-01.gitter.im/gh/uv/4/twinkling-tree', 'avatarUrlSmall': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=60', 'avatarUrlMedium': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=128', 'v': 3, 'gv': '4'}}
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=Hello twinkling-tree)>.
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
INFO opsdroid.connector.gitter: Successfully responded.
DEBUG opsdroid.connector.gitter: {'id': '5ff1dc1393af5216fc7c683f', 'text': 'Hey twinkling-tree', 'html': 'Hey twinkling-tree', 'sent': '2021-01-03T15:00:35.971Z', 'readBy': 0, 'urls': [], 'mentions': [], 'issues': [], 'meta': [], 'v': 1, 'fromUser': {'id': '5ff0c884d73408ce4ff7d787', 'username': 'twinkling-tree', 'displayName': 'twinkling-tree', 'url': '/twinkling-tree', 'avatarUrl': 'https://avatars-01.gitter.im/gh/uv/4/twinkling-tree', 'avatarUrlSmall': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=60', 'avatarUrlMedium': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=128', 'v': 3, 'gv': '4'}}
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=Hey twinkling-tree)>.
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
INFO opsdroid.connector.gitter: Successfully responded.
DEBUG opsdroid.connector.gitter: {'id': '5ff1dc1497312f4b6b078334', 'text': 'Hey twinkling-tree', 'html': 'Hey twinkling-tree', 'sent': '2021-01-03T15:00:36.054Z', 'readBy': 0, 'urls': [], 'mentions': [], 'issues': [], 'meta': [], 'v': 1, 'fromUser': {'id': '5ff0c884d73408ce4ff7d787', 'username': 'twinkling-tree', 'displayName': 'twinkling-tree', 'url': '/twinkling-tree', 'avatarUrl': 'https://avatars-01.gitter.im/gh/uv/4/twinkling-tree', 'avatarUrlSmall': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=60', 'avatarUrlMedium': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=128', 'v': 3, 'gv': '4'}}
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=Hey twinkling-tree)>.
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
INFO opsdroid.connector.gitter: Successfully responded.
DEBUG opsdroid.connector.gitter: {'id': '5ff1dc14ce40bd3cdb1b8692', 'text': 'Hi twinkling-tree', 'html': 'Hi twinkling-tree', 'sent': '2021-01-03T15:00:36.139Z', 'readBy': 0, 'urls': [], 'mentions': [], 'issues': [], 'meta': [], 'v': 1, 'fromUser': {'id': '5ff0c884d73408ce4ff7d787', 'username': 'twinkling-tree', 'displayName': 'twinkling-tree', 'url': '/twinkling-tree', 'avatarUrl': 'https://avatars-01.gitter.im/gh/uv/4/twinkling-tree', 'avatarUrlSmall': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=60', 'avatarUrlMedium': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=128', 'v': 3, 'gv': '4'}}
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=Hi twinkling-tree)>.
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
INFO opsdroid.connector.gitter: Successfully responded.
DEBUG opsdroid.connector.gitter: {'id': '5ff1dc14ac9d8e7463ea02b2', 'text': 'Hey twinkling-tree', 'html': 'Hey twinkling-tree', 'sent': '2021-01-03T15:00:36.228Z', 'readBy': 0, 'urls': [], 'mentions': [], 'issues': [], 'meta': [], 'v': 1, 'fromUser': {'id': '5ff0c884d73408ce4ff7d787', 'username': 'twinkling-tree', 'displayName': 'twinkling-tree', 'url': '/twinkling-tree', 'avatarUrl': 'https://avatars-01.gitter.im/gh/uv/4/twinkling-tree', 'avatarUrlSmall': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=60', 'avatarUrlMedium': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=128', 'v': 3, 'gv': '4'}}
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=Hey twinkling-tree)>.
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
INFO opsdroid.connector.gitter: Successfully responded.
DEBUG opsdroid.connector.gitter: {'id': '5ff1dc1422f12e449b2af633', 'text': 'Hello twinkling-tree', 'html': 'Hello twinkling-tree', 'sent': '2021-01-03T15:00:36.323Z', 'readBy': 0, 'urls': [], 'mentions': [], 'issues': [], 'meta': [], 'v': 1, 'fromUser': {'id': '5ff0c884d73408ce4ff7d787', 'username': 'twinkling-tree', 'displayName': 'twinkling-tree', 'url': '/twinkling-tree', 'avatarUrl': 'https://avatars-01.gitter.im/gh/uv/4/twinkling-tree', 'avatarUrlSmall': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=60', 'avatarUrlMedium': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=128', 'v': 3, 'gv': '4'}}
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=Hello twinkling-tree)>.
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
INFO opsdroid.connector.gitter: Successfully responded.
DEBUG opsdroid.connector.gitter: {'id': '5ff1dc14aa6bb528c38a9d64', 'text': 'Hello twinkling-tree', 'html': 'Hello twinkling-tree', 'sent': '2021-01-03T15:00:36.408Z', 'readBy': 0, 'urls': [], 'mentions': [], 'issues': [], 'meta': [], 'v': 1, 'fromUser': {'id': '5ff0c884d73408ce4ff7d787', 'username': 'twinkling-tree', 'displayName': 'twinkling-tree', 'url': '/twinkling-tree', 'avatarUrl': 'https://avatars-01.gitter.im/gh/uv/4/twinkling-tree', 'avatarUrlSmall': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=60', 'avatarUrlMedium': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=128', 'v': 3, 'gv': '4'}}
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=Hello twinkling-tree)>.
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
INFO opsdroid.connector.gitter: Successfully responded.
DEBUG opsdroid.connector.gitter: {'id': '5ff1dc1469ee7f0422dd641c', 'text': 'Hello twinkling-tree', 'html': 'Hello twinkling-tree', 'sent': '2021-01-03T15:00:36.499Z', 'readBy': 0, 'urls': [], 'mentions': [], 'issues': [], 'meta': [], 'v': 1, 'fromUser': {'id': '5ff0c884d73408ce4ff7d787', 'username': 'twinkling-tree', 'displayName': 'twinkling-tree', 'url': '/twinkling-tree', 'avatarUrl': 'https://avatars-01.gitter.im/gh/uv/4/twinkling-tree', 'avatarUrlSmall': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=60', 'avatarUrlMedium': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=128', 'v': 3, 'gv': '4'}}
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=Hello twinkling-tree)>.
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
INFO opsdroid.connector.gitter: Successfully responded.
DEBUG opsdroid.connector.gitter: {'id': '5ff1dc148bb73474696f4e55', 'text': 'Hi twinkling-tree', 'html': 'Hi twinkling-tree', 'sent': '2021-01-03T15:00:36.584Z', 'readBy': 0, 'urls': [], 'mentions': [], 'issues': [], 'meta': [], 'v': 1, 'fromUser': {'id': '5ff0c884d73408ce4ff7d787', 'username': 'twinkling-tree', 'displayName': 'twinkling-tree', 'url': '/twinkling-tree', 'avatarUrl': 'https://avatars-01.gitter.im/gh/uv/4/twinkling-tree', 'avatarUrlSmall': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=60', 'avatarUrlMedium': 'https://avatars2.githubusercontent.com/u/76883179?v=4&s=128', 'v': 3, 'gv': '4'}}
DEBUG opsdroid.core: Parsing input: <opsdroid.events.Message(text=Hi twinkling-tree)>.
DEBUG opsdroid.memory: Getting seen from memory.
DEBUG opsdroid.memory: Putting seen to memory.
INFO opsdroid.connector.gitter: Successfully responded.
```

</details>

## Steps to Reproduce

Run against the branch linked in the description and say "Hi" or any variation recognized by skill-hello.

## Versions
- **Opsdroid version:** 0.19.0
- **Python version:** 3.7.3
- **OS/Docker version:** Raspbian GNU/Linux 10

## Configuration File

```yaml
connectors:
  gitter:
    bot-name: "twinkling-tree"
    room-id: "<room is>"  # danielballan/twinkling-tree
    token: "<token>"

skills:
  custom_hello:
    repo: "https://github.com/danielballan/skill-hello.git"
    branch: "case_insensitive"
  seen: {}

logging:
  level: debug
  path: ~/.opsdroid/output.log
  console: true
```

The fix seems simple enough: the bot knows its `bot-name` from the configuration and should use that to avoid responding to itself. My question is, **Where is to right place to filter self-responses?** My first thought was to add this to `skill-hello`, but I don't think it has access to the bot name, only the sender. And this seems like something that should happen in a more general place, not a skill-specific one. Does this code belong in the gitter connector? I notice that `bot_name` is set that but not referred to anywhere in the class.

https://github.com/opsdroid/opsdroid/blob/03afd709682bd60deaeeb9c872e45a3aa153f4d8/opsdroid/connector/gitter/__init__.py#L28

It is used by another layer? Is that where this fix belongs? I'm happy to submit a patch if you can give me nudge in the right direction. Thanks!

---

Edit reasons: hide the token and room id. 

<!-- Love opsdroid? Please consider supporting our collective:
 +👉  https://opencollective.com/opsdroid/donate -->



Discussion:
Hello and thank you for raising this issue. I'm thinking that the reason why opsdroid doesn't reply to itself in the case sensitive is mostly because it will reply with a lower case string 🤔

Your assumption is right, this seems a bug from the gitter connector itself, I'm thinking that if we change line 75 (that if statement) to handle the case where Message is coming from the bot. 

The Message event contains a user parameter, we should check if we are creating the event right first when parsing the message - that should prevent opsdroid from replying to itself 🤔

Here's the [Message event docs](https://docs.opsdroid.dev/en/stable/skills/events.html#message) for reference

It would be awesome if you could tackle this issue, if you don't have the time I'll try to get a fix as soon as possible 😄

Btw make sure to refresh your gitter token 😄
Great, thanks. It makes sense this would have be handled in the connector. I think I can submit a patch in the next day or two for the gitter one.

Ha. Thanks for the heads up about the token—yikes.
No worries, I tend to leak my tokens while live stream all the time haha

Resolving patch:
diff --git a/opsdroid/connector/gitter/__init__.py b/opsdroid/connector/gitter/__init__.py
--- a/opsdroid/connector/gitter/__init__.py
+++ b/opsdroid/connector/gitter/__init__.py
@@ -12,6 +12,7 @@
 _LOGGER = logging.getLogger(__name__)
 GITTER_STREAM_API = "https://stream.gitter.im/v1/rooms"
 GITTER_MESSAGE_BASE_API = "https://api.gitter.im/v1/rooms"
+CURRENT_USER_API = "https://api.gitter.im/v1/user/me"
 CONFIG_SCHEMA = {Required("token"): str, Required("room-id"): str, "bot-name": str}
 
 
@@ -23,9 +24,9 @@ def __init__(self, config, opsdroid=None):
         super().__init__(config, opsdroid=opsdroid)
         _LOGGER.debug(_("Starting Gitter Connector."))
         self.name = "gitter"
+        self.bot_name = None  # set at connection time
         self.session = None
         self.response = None
-        self.bot_name = self.config.get("bot-name", "opsdroid")
         self.room_id = self.config.get("room-id")
         self.access_token = self.config.get("token")
         self.update_interval = 1
@@ -40,13 +41,31 @@ async def connect(self):
         _LOGGER.debug(_("Connecting with Gitter stream."))
         self.session = aiohttp.ClientSession()
 
-        gitter_url = self.build_url(
+        # Gitter figures out who we are based on just our access token, but we
+        # need to additionally know our own user ID in order to know which
+        # messages comes from us.
+        current_user_url = self.build_url(
+            CURRENT_USER_API,
+            access_token=self.access_token,
+        )
+        response = await self.session.get(current_user_url, timeout=None)
+        # We cannot continue without a user ID, so raise if this failed.
+        response.raise_for_status()
+        response_json = await response.json()
+        self.bot_gitter_id = response_json["id"]
+        self.bot_name = response_json["username"]
+        _LOGGER.debug(
+            _("Successfully obtained bot's gitter id, %s."), self.bot_gitter_id
+        )
+
+        message_stream_url = self.build_url(
             GITTER_STREAM_API,
             self.room_id,
             "chatMessages",
             access_token=self.access_token,
         )
-        self.response = await self.session.get(gitter_url, timeout=None)
+        self.response = await self.session.get(message_stream_url, timeout=None)
+        self.response.raise_for_status()
 
     def build_url(self, base_url, *res, **params):
         """Build the url. args ex:(base_url,p1,p2=1,p2=2)."""
@@ -72,7 +91,8 @@ async def _get_messages(self):
         await asyncio.sleep(self.update_interval)
         async for data in self.response.content.iter_chunked(1024):
             message = await self.parse_message(data)
-            if message is not None:
+            # Do not parse messages that we ourselves sent.
+            if message is not None and message.user_id != self.bot_gitter_id:
                 await self.opsdroid.parse(message)
 
     async def parse_message(self, message):
@@ -85,12 +105,12 @@ async def parse_message(self, message):
                 return Message(
                     text=message["text"],
                     user=message["fromUser"]["username"],
+                    user_id=message["fromUser"]["id"],
                     target=self.room_id,
                     connector=self,
                 )
             except KeyError as err:
-                _LOGGER.error(_("Unable to parse message %s."), err)
-                _LOGGER.error(err)
+                _LOGGER.error(_("Unable to parse message %r."), err)
 
     @register_event(Message)
     async def send_message(self, message):


Test patch:
diff --git a/tests/test_connector_gitter.py b/tests/test_connector_gitter.py
--- a/tests/test_connector_gitter.py
+++ b/tests/test_connector_gitter.py
@@ -1,6 +1,7 @@
 """Tests for the RocketChat class."""
 
 import asyncio
+import json
 import unittest
 import asynctest
 import asynctest.mock as amock
@@ -40,13 +41,21 @@ def setUp(self):
             self.connector.session = mocked_session
 
     async def test_connect(self):
+        BOT_GITTER_ID = "12345"
         with amock.patch("aiohttp.ClientSession.get") as patched_request:
             mockresponse = amock.CoroutineMock()
             mockresponse.status = 200
-            mockresponse.json = amock.CoroutineMock(return_value={"login": "opsdroid"})
+            mockresponse.json = amock.CoroutineMock(
+                return_value={
+                    "login": "opsdroid",
+                    "id": BOT_GITTER_ID,
+                    "username": "bot",
+                }
+            )
             patched_request.return_value = asyncio.Future()
             patched_request.return_value.set_result(mockresponse)
             await self.connector.connect()
+        assert self.connector.bot_gitter_id == BOT_GITTER_ID
 
     def test_build_url(self):
         self.assertEqual(
@@ -91,10 +100,23 @@ async def test_listen_break_loop(self):
     async def test_get_message(self):
         """Test that listening consumes from the socket."""
 
+        BOT_GITTER_ID = "12345"
+        OTHER_GITTER_ID = "67890"
+
         async def iter_chuncked1(n=None):
-            response = [{"message": "hi"}, {"message": "hi"}]
+            response = [
+                {
+                    "text": "hi",
+                    "fromUser": {"username": "not a bot", "id": OTHER_GITTER_ID},
+                },
+                {"text": "hi", "fromUser": {"username": "bot", "id": BOT_GITTER_ID}},
+                {
+                    "text": "hi",
+                    "fromUser": {"username": "not a bot", "id": OTHER_GITTER_ID},
+                },
+            ]
             for doc in response:
-                yield doc
+                yield json.dumps(doc).encode()
 
         response1 = amock.CoroutineMock()
         response1.content.iter_chunked = iter_chuncked1
@@ -103,12 +125,26 @@ async def iter_chuncked1(n=None):
             {"bot-name": "github", "room-id": "test-id", "token": "test-token"},
             opsdroid=OpsDroid(),
         )
-        connector.parse_message = amock.CoroutineMock()
+        # Connect first, in order to set bot_gitter_id.
+        with amock.patch("aiohttp.ClientSession.get") as patched_request:
+            mockresponse = amock.CoroutineMock()
+            mockresponse.status = 200
+            mockresponse.json = amock.CoroutineMock(
+                return_value={
+                    "login": "opsdroid",
+                    "id": BOT_GITTER_ID,
+                    "username": "bot",
+                }
+            )
+            patched_request.return_value = asyncio.Future()
+            patched_request.return_value.set_result(mockresponse)
+            await connector.connect()
+
         connector.opsdroid.parse = amock.CoroutineMock()
         connector.response = response1
         assert await connector._get_messages() is None
-        self.assertTrue(connector.parse_message.called)
-        self.assertTrue(connector.opsdroid.parse.called)
+        # Should be called *twice* given these three messages (skipping own message)
+        assert connector.opsdroid.parse.call_count == 2
 
     async def test_send_message_success(self):
         post_response = amock.Mock()