Repository: opsdroid/opsdroid

Issue:
Update regex pattern for the envvar construtor
You can use envvars on your configuration, but they need to follow this pattern `$ENVVARNAME` the regex pattern should be updated to allow users to use either `$ENVVARNAME` or `${ENVVARNAME}`. 

While we are at it we should allow users to use other characters as well like `_` or `-`. 

This change needs to be done on [opsdroid.loader.load_config_file](https://github.com/opsdroid/opsdroid/blob/674013037eab826640174407a73f8fed1a29b290/opsdroid/loader.py#L347)


Discussion:
I'm also having issues when using quotes.

#### Works

```yaml
connectors:
  - name: slack
    api-token: $OPSDROID_SLACK_TOKEN
```

#### Doesn't work

```yaml
connectors:
  - name: slack
    api-token: "$OPSDROID_SLACK_TOKEN"
```
Hey @FabioRosado, 

I am new to opsdroid and just starting to dip my toes into open source. Something like this might satisfy your requirements:
`re.compile(r"^\"?\${?([A-Z-_]*)}?\"?$")`  

Here are some examples:
![Screen Shot 2019-11-25 at 7 25 49 AM](https://user-images.githubusercontent.com/28970163/69548661-f88ed080-0f54-11ea-9b47-46648657d20c.png)

Is this issue available to work on? I would also be happy to add tests for the regex pattern if necessary.

Thanks for commenting @benjpalmer, that looks great ~(I think `$something` is a valid env var, just not a best practice style)~. Please feel free to pick this up. 

Shout if you need any help, we are usually around in Matrix chat [over here](https://riot.im/app/#/room/#opsdroid-developers:matrix.org).

**Edit: actually thinking about it let's go with convention and not allow lowercase**

Resolving patch:
diff --git a/opsdroid/configuration/__init__.py b/opsdroid/configuration/__init__.py
--- a/opsdroid/configuration/__init__.py
+++ b/opsdroid/configuration/__init__.py
@@ -7,7 +7,7 @@
 import logging
 import yaml
 
-from opsdroid.const import DEFAULT_CONFIG_PATH, EXAMPLE_CONFIG_FILE
+from opsdroid.const import DEFAULT_CONFIG_PATH, ENV_VAR_REGEX, EXAMPLE_CONFIG_FILE
 from opsdroid.configuration.validation import validate_configuration, BASE_SCHEMA
 from opsdroid.helper import update_pre_0_17_config_format
 
@@ -71,7 +71,7 @@ def get_config_path(config_paths):
     return config_path
 
 
-env_var_pattern = re.compile(r"^\$([A-Z_]*)$")
+env_var_pattern = re.compile(ENV_VAR_REGEX)
 
 
 def envvar_constructor(loader, node):
diff --git a/opsdroid/const.py b/opsdroid/const.py
--- a/opsdroid/const.py
+++ b/opsdroid/const.py
@@ -41,3 +41,4 @@
 
 WATSON_API_ENDPOINT = "https://{gateway}.watsonplatform.net/assistant/api"
 WATSON_API_VERSION = "2019-02-28"
+ENV_VAR_REGEX = r"^\"?\${?(?=\_?[A-Z])([A-Z-_]+)}?\"?$"


Test patch:
diff --git a/tests/test_loader.py b/tests/test_loader.py
--- a/tests/test_loader.py
+++ b/tests/test_loader.py
@@ -10,6 +10,7 @@
 import pkg_resources
 from opsdroid.cli.start import configure_lang
 from opsdroid.configuration import load_config_file
+from opsdroid.const import ENV_VAR_REGEX
 from opsdroid import loader as ld
 from opsdroid.helper import del_rw
 
@@ -685,3 +686,34 @@ def test_setup_module_bad_config(self):
             loader.load_modules_from_config(config)
             self.assertTrue(mock_sysexit.called)
             self.assertLogs("_LOGGER", "critical")
+
+    def test_env_var_regex(self):
+        test_data = [
+            {"env_var": "$OPS_DROID", "match": True},
+            {"env_var": "$OPS-DROID", "match": True},
+            {"env_var": "${OPS_DROID}", "match": True},
+            {"env_var": '"$OPSDROID_SLACK_TOKEN"', "match": True},
+            {"env_var": "$_OPS_DROID", "match": True},
+            {"env_var": "${_OPS_DROID}", "match": True},
+            {"env_var": "$INVALID!_CHARACTERS@", "match": False},
+            {"env_var": "OPS_DROID", "match": False},
+            {"env_var": "$OPS_DROID23", "match": False},
+            {"env_var": "$UPPER-AND-lower", "match": False},
+            {"env_var": '"MISSING_PREFIX"', "match": False},
+            {"env_var": "$all_lowercase", "match": False},
+            {"env_var": "a simple sentence.", "match": False},
+            {"env_var": "$", "match": False},
+            {"env_var": "${}", "match": False},
+            {"env_var": "", "match": False},
+            {"env_var": "556373", "match": False},
+            {"env_var": "${@!!}", "match": False},
+            {"env_var": "${_-_-}", "match": False},
+            {"env_var": "$ALONGSTRINGTHAT$CONTAINS$", "match": False},
+            {"env_var": "NOPREFIXALONGSTRINGTHAT$CONTAINS$", "match": False},
+        ]
+        for d in test_data:
+            # Tests opsdroid constant ENV_VAR_REGEX for both valid and invalid environment variables.
+            if d["match"]:
+                self.assertRegex(d["env_var"], ENV_VAR_REGEX)
+            else:
+                self.assertNotRegex(d["env_var"], ENV_VAR_REGEX)