Repository: opsdroid/opsdroid

Issue:
Rasa intents multilanguage support
<!-- Before you post an issue or if you are unsure about something join our matrix channel https://app.element.io/#/room/#opsdroid-general:matrix.org and ask away! We are more than happy to help you. -->
# Description

When using non-alphanumeric characters (non English language) in `intents.yml` with `rasanlu` parser Opsdroid exits with the following error:

```
DEBUG opsdroid.parsers.rasanlu Checking Rasa NLU version.
DEBUG opsdroid.parsers.rasanlu Rasa NLU response - {"version": "3.3.3", "minimum_compatible_version": "3.0.0"}.
DEBUG opsdroid.parsers.rasanlu Rasa NLU version 3.3.3.
INFO opsdroid.parsers.rasanlu Starting Rasa NLU training.
DEBUG asyncio Using selector: KqueueSelector
Traceback (most recent call last):
  File "/usr/local/Cellar/python@3.9/3.9.9/Frameworks/Python.framework/Versions/3.9/lib/python3.9/runpy.py", line 197, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/local/Cellar/python@3.9/3.9.9/Frameworks/Python.framework/Versions/3.9/lib/python3.9/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/Users/olegfiksel/opsdroid/opsdroid/__main__.py", line 12, in <module>
    init()
  File "/Users/olegfiksel/opsdroid/opsdroid/__main__.py", line 9, in init
    opsdroid.cli.cli()
  File "/Users/olegfiksel/opsdroid/venv/lib/python3.9/site-packages/click/core.py", line 1130, in __call__
    return self.main(*args, **kwargs)
  File "/Users/olegfiksel/opsdroid/venv/lib/python3.9/site-packages/click/core.py", line 1055, in main
    rv = self.invoke(ctx)
  File "/Users/olegfiksel/opsdroid/venv/lib/python3.9/site-packages/click/core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/Users/olegfiksel/opsdroid/venv/lib/python3.9/site-packages/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/Users/olegfiksel/opsdroid/venv/lib/python3.9/site-packages/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
  File "/Users/olegfiksel/opsdroid/opsdroid/cli/start.py", line 41, in start
    opsdroid.run()
  File "/Users/olegfiksel/opsdroid/opsdroid/core.py", line 170, in run
    self.sync_load()
  File "/Users/olegfiksel/opsdroid/opsdroid/core.py", line 219, in sync_load
    self.eventloop.run_until_complete(self.load())
  File "/usr/local/Cellar/python@3.9/3.9.9/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete
    return future.result()
  File "/Users/olegfiksel/opsdroid/opsdroid/core.py", line 232, in load
    await self.train_parsers(self.modules["skills"])
  File "/Users/olegfiksel/opsdroid/opsdroid/core.py", line 365, in train_parsers
    await train_rasanlu(rasanlu, skills)
  File "/Users/olegfiksel/opsdroid/opsdroid/parsers/rasanlu.py", line 174, in train_rasanlu
    intents = await _get_all_intents(skills)
  File "/Users/olegfiksel/opsdroid/opsdroid/parsers/rasanlu.py", line 35, in _get_all_intents
    return unicodedata.normalize("NFKD", intents).encode("ascii")
UnicodeEncodeError: 'ascii' codec can't encode character '\xdf' in position 118: ordinal not in range(128)

```


## Steps to Reproduce

* Create `intents.yml` and run Opsdroid agains a Rasa instance with this configuration


## Expected Functionality

* Opsdroid would send the content of `intents.yml` to Rasa to train a model

## Experienced Functionality

* Opsdroid exits with an error before sending the content of `intents.yml` to Rasa

## Versions
- **Opsdroid version: master (d6d23f32fadf289f692f7d6a24d9a62478e921a2)**
- **Python version: 3.9.9**
- **OS/Docker version: MacOS 12.6 for Opsdroid & Docker 20.10.6 for Rasa (3.3.3)**

## Configuration File

`configuration.yml`
```yaml
welcome-message: false
logging:
  level: debug
connectors:
  websocket:
parsers:
  rasanlu:
    url: http://rasa-host:5005
    token: very-secure-rasa-auth-token
skills:
  rasa-test:
    path: /Users/olegfiksel/opsdroid/rasa_test_skill
```

`intents.yml`

```yaml
version: "3.1"

language: "de"

intents:
  - hi
  - bye

nlu:
  - intent: hi
    examples: |
      - Hallo
      - Gruß
      - Grüße
  - intent: bye
    examples: |
      - tschüß
      - Aufwiedersehen
      - ciao
      - bis später
      - bis demnächst
```

`__init__.py`

```python
from opsdroid.skill import Skill
from opsdroid.matchers import match_rasanlu

class MySkill(Skill):
    @match_rasanlu("hi")
    async def hello(self, message):
        await message.respond("Hallo!")

    @match_rasanlu("bye")
    async def bye(self, message):
        await message.respond("Tschüß!")
```



Discussion:

Resolving patch:
diff --git a/opsdroid/parsers/rasanlu.py b/opsdroid/parsers/rasanlu.py
--- a/opsdroid/parsers/rasanlu.py
+++ b/opsdroid/parsers/rasanlu.py
@@ -31,7 +31,7 @@ async def _get_all_intents(skills):
     if not intents:
         return None
     intents = "\n\n".join(intents)
-    return unicodedata.normalize("NFKD", intents).encode("ascii")
+    return unicodedata.normalize("NFKD", intents)
 
 
 async def _get_intents_fingerprint(intents):


Test patch:
diff --git a/tests/test_parser_rasanlu.py b/tests/test_parser_rasanlu.py
--- a/tests/test_parser_rasanlu.py
+++ b/tests/test_parser_rasanlu.py
@@ -411,8 +411,8 @@ async def test__get_all_intents(self):
         skills[1] = {"intents": None}
         skills[2] = {"intents": "World"}
         intents = await rasanlu._get_all_intents(skills)
-        self.assertEqual(type(intents), type(b""))
-        self.assertEqual(intents, b"Hello\n\nWorld")
+        self.assertEqual(type(intents), type(""))
+        self.assertEqual(intents, "Hello\n\nWorld")
 
     async def test__get_all_intents_fails(self):
         skills = []