We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Cisco WebEx Teams connector doesn't start
# Error

```
INFO opsdroid.logging: ========================================
INFO opsdroid.logging: Started opsdroid 0+unknown.
WARNING opsdroid: 'welcome-message: true/false' is missing in configuration.yaml
WARNING opsdroid.loader: No databases in configuration. This will cause skills which store things in memory to lose data when opsdroid is restarted.
INFO opsdroid.loader: Cloning hello from remote repository.
Traceback (most recent call last):
  File "/usr/local/bin/opsdroid", line 8, in <module>
    sys.exit(cli())
  File "/usr/local/lib/python3.7/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.7/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.7/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.7/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/opsdroid/cli/start.py", line 42, in start
    opsdroid.run()
  File "/usr/local/lib/python3.7/site-packages/opsdroid/core.py", line 158, in run
    self.sync_load()
  File "/usr/local/lib/python3.7/site-packages/opsdroid/core.py", line 177, in sync_load
    self.eventloop.run_until_complete(self.load())
  File "/usr/local/lib/python3.7/asyncio/base_events.py", line 587, in run_until_complete
    return future.result()
  File "/usr/local/lib/python3.7/site-packages/opsdroid/core.py", line 185, in load
    await self.start_connectors(self.modules["connectors"])
  File "/usr/local/lib/python3.7/site-packages/opsdroid/core.py", line 319, in start_connectors
    await self.eventloop.create_task(connector.connect())
  File "/usr/local/lib/python3.7/site-packages/opsdroid/connector/webexteams/__init__.py", line 53, in connect
    await self.subscribe_to_rooms()
  File "/usr/local/lib/python3.7/site-packages/opsdroid/connector/webexteams/__init__.py", line 99, in subscribe_to_rooms
    secret=self.secret,
  File "/usr/local/lib/python3.7/site-packages/webexteamssdk/api/webhooks.py", line 159, in create
    json_data = self._session.post(API_ENDPOINT, json=post_data)
  File "/usr/local/lib/python3.7/site-packages/webexteamssdk/restsession.py", line 401, in post
    **kwargs)
  File "/usr/local/lib/python3.7/site-packages/webexteamssdk/restsession.py", line 258, in request
    check_response_code(response, erc)
  File "/usr/local/lib/python3.7/site-packages/webexteamssdk/utils.py", line 220, in check_response_code
    raise ApiError(response)
webexteamssdk.exceptions.ApiError: [400] Bad Request - POST failed: HTTP/1.1 400 Bad Request (url = https://webhook-engine-a.wbx2.com/webhook-engine/api/v1/webhooks, request/response TrackingId = ROUTER_5ECD21B0-63B3-01BB-00D6-B2CAA80F00D6, error = 'Invalid targetUrl: Illegal character in path at index 0: <function Url at 0x7fd36ce31f80>/connector/webexteams')
```
# How to reproduce

* Create `configuration.yaml` with the following content:

```
connectors:
  webexteams:
    token: MYBOTACCESSTOKEN
    webhook-url: https://my-webhook-url.com
    # Seem that webhook-url is not relevant for the error message
skills:
  hello:
```

* Create `debug.sh` with the following content:

```
docker run --rm -ti -p 8080:8080 \
	-v `pwd`/configuration.yaml:/root/.config/opsdroid/configuration.yaml:ro \
	opsdroid/opsdroid:v0.18.0 sh
```

* `chmod +x debug.sh`
* `./debug.sh`
* (in the container) `opsdroid start`



--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `opsdroid/connector/webexteams/__init__.py`
Content:
```
1 """A connector for Webex Teams."""
2 import json
3 import logging
4 import uuid
5 import os
6 
7 import aiohttp
8 
9 from webexteamssdk import WebexTeamsAPI
10 from voluptuous import Required, Url
11 
12 from opsdroid.connector import Connector, register_event
13 from opsdroid.events import Message
14 
15 
16 _LOGGER = logging.getLogger(__name__)
17 CONFIG_SCHEMA = {Required("webhook-url"): Url, Required("token"): str}
18 
19 
20 class ConnectorWebexTeams(Connector):
21     """A connector for Webex Teams."""
22 
23     def __init__(self, config, opsdroid=None):
24         """Create a connector."""
25         _LOGGER.debug(_("Loaded WebEx Teams Connector."))
26         super().__init__(config, opsdroid=opsdroid)
27         self.name = "webexteams"
28         self.config = config
29         self.opsdroid = opsdroid
30         self.default_target = None
31         self.bot_name = config.get("bot-name", "opsdroid")
32         self.bot_webex_id = None
33         self.secret = uuid.uuid4().hex
34         self.people = {}
35 
36     async def connect(self):
37         """Connect to the chat service."""
38         try:
39             self.api = WebexTeamsAPI(
40                 access_token=self.config["token"],
41                 proxies={
42                     "http": os.environ.get("HTTP_PROXY"),
43                     "https": os.environ.get("HTTPS_PROXY"),
44                 },
45             )
46         except KeyError:
47 
48             _LOGGER.error(_("Must set access-token for WebEx Teams Connector."))
49 
50             return
51 
52         await self.clean_up_webhooks()
53         await self.subscribe_to_rooms()
54         await self.set_own_id()
55 
56     async def webexteams_message_handler(self, request):
57         """Handle webhooks from the Webex Teams api."""
58         _LOGGER.debug(_("Handling message from WebEx Teams."))
59         req_data = await request.json()
60 
61         _LOGGER.debug(req_data)
62 
63         msg = self.api.messages.get(req_data["data"]["id"])
64 
65         if req_data["data"]["personId"] != self.bot_webex_id:
66             person = await self.get_person(req_data["data"]["personId"])
67 
68             try:
69                 message = Message(
70                     text=msg.text,
71                     user=person.displayName,
72                     target={"id": msg.roomId, "type": msg.roomType},
73                     connector=self,
74                 )
75                 await self.opsdroid.parse(message)
76             except KeyError as error:
77                 _LOGGER.error(error)
78 
79         return aiohttp.web.Response(text=json.dumps("Received"), status=201)
80 
81     async def clean_up_webhooks(self):
82         """Remove all existing webhooks."""
83         for webhook in self.api.webhooks.list():
84             self.api.webhooks.delete(webhook.id)
85 
86     async def subscribe_to_rooms(self):
87         """Create webhooks for all rooms."""
88         _LOGGER.debug(_("Creating Webex Teams webhook."))
89         webhook_endpoint = "/connector/webexteams"
90         self.opsdroid.web_server.web_app.router.add_post(
91             webhook_endpoint, self.webexteams_message_handler
92         )
93 
94         self.api.webhooks.create(
95             name="opsdroid",
96             targetUrl="{}{}".format(self.config.get("webhook-url"), webhook_endpoint),
97             resource="messages",
98             event="created",
99             secret=self.secret,
100         )
101 
102     async def get_person(self, personId):
103         """Get a person's info from the api or cache."""
104         if personId not in self.people:
105             self.people[personId] = self.api.people.get(personId)
106         return self.people[personId]
107 
108     async def set_own_id(self):
109         """Get the bot id and set it in the class."""
110         self.bot_webex_id = self.api.people.me().id
111 
112     async def listen(self):
113         """Listen for and parse new messages."""
114         pass  # Listening is handled by the aiohttp web server
115 
116     @register_event(Message)
117     async def send_message(self, message):
118         """Respond with a message."""
119         self.api.messages.create(message.target["id"], text=message.text)
120
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/opsdroid/connector/webexteams/__init__.py b/opsdroid/connector/webexteams/__init__.py
--- a/opsdroid/connector/webexteams/__init__.py
+++ b/opsdroid/connector/webexteams/__init__.py
@@ -14,7 +14,7 @@
 
 
 _LOGGER = logging.getLogger(__name__)
-CONFIG_SCHEMA = {Required("webhook-url"): Url, Required("token"): str}
+CONFIG_SCHEMA = {Required("webhook-url"): Url(), Required("token"): str}
 
 
 class ConnectorWebexTeams(Connector):

{"golden_diff": "diff --git a/opsdroid/connector/webexteams/__init__.py b/opsdroid/connector/webexteams/__init__.py\n--- a/opsdroid/connector/webexteams/__init__.py\n+++ b/opsdroid/connector/webexteams/__init__.py\n@@ -14,7 +14,7 @@\n \n \n _LOGGER = logging.getLogger(__name__)\n-CONFIG_SCHEMA = {Required(\"webhook-url\"): Url, Required(\"token\"): str}\n+CONFIG_SCHEMA = {Required(\"webhook-url\"): Url(), Required(\"token\"): str}\n \n \n class ConnectorWebexTeams(Connector):\n", "issue": "Cisco WebEx Teams connector doesn't start\n# Error\r\n\r\n```\r\nINFO opsdroid.logging: ========================================\r\nINFO opsdroid.logging: Started opsdroid 0+unknown.\r\nWARNING opsdroid: 'welcome-message: true/false' is missing in configuration.yaml\r\nWARNING opsdroid.loader: No databases in configuration. This will cause skills which store things in memory to lose data when opsdroid is restarted.\r\nINFO opsdroid.loader: Cloning hello from remote repository.\r\nTraceback (most recent call last):\r\n  File \"/usr/local/bin/opsdroid\", line 8, in <module>\r\n    sys.exit(cli())\r\n  File \"/usr/local/lib/python3.7/site-packages/click/core.py\", line 829, in __call__\r\n    return self.main(*args, **kwargs)\r\n  File \"/usr/local/lib/python3.7/site-packages/click/core.py\", line 782, in main\r\n    rv = self.invoke(ctx)\r\n  File \"/usr/local/lib/python3.7/site-packages/click/core.py\", line 1259, in invoke\r\n    return _process_result(sub_ctx.command.invoke(sub_ctx))\r\n  File \"/usr/local/lib/python3.7/site-packages/click/core.py\", line 1066, in invoke\r\n    return ctx.invoke(self.callback, **ctx.params)\r\n  File \"/usr/local/lib/python3.7/site-packages/click/core.py\", line 610, in invoke\r\n    return callback(*args, **kwargs)\r\n  File \"/usr/local/lib/python3.7/site-packages/opsdroid/cli/start.py\", line 42, in start\r\n    opsdroid.run()\r\n  File \"/usr/local/lib/python3.7/site-packages/opsdroid/core.py\", line 158, in run\r\n    self.sync_load()\r\n  File \"/usr/local/lib/python3.7/site-packages/opsdroid/core.py\", line 177, in sync_load\r\n    self.eventloop.run_until_complete(self.load())\r\n  File \"/usr/local/lib/python3.7/asyncio/base_events.py\", line 587, in run_until_complete\r\n    return future.result()\r\n  File \"/usr/local/lib/python3.7/site-packages/opsdroid/core.py\", line 185, in load\r\n    await self.start_connectors(self.modules[\"connectors\"])\r\n  File \"/usr/local/lib/python3.7/site-packages/opsdroid/core.py\", line 319, in start_connectors\r\n    await self.eventloop.create_task(connector.connect())\r\n  File \"/usr/local/lib/python3.7/site-packages/opsdroid/connector/webexteams/__init__.py\", line 53, in connect\r\n    await self.subscribe_to_rooms()\r\n  File \"/usr/local/lib/python3.7/site-packages/opsdroid/connector/webexteams/__init__.py\", line 99, in subscribe_to_rooms\r\n    secret=self.secret,\r\n  File \"/usr/local/lib/python3.7/site-packages/webexteamssdk/api/webhooks.py\", line 159, in create\r\n    json_data = self._session.post(API_ENDPOINT, json=post_data)\r\n  File \"/usr/local/lib/python3.7/site-packages/webexteamssdk/restsession.py\", line 401, in post\r\n    **kwargs)\r\n  File \"/usr/local/lib/python3.7/site-packages/webexteamssdk/restsession.py\", line 258, in request\r\n    check_response_code(response, erc)\r\n  File \"/usr/local/lib/python3.7/site-packages/webexteamssdk/utils.py\", line 220, in check_response_code\r\n    raise ApiError(response)\r\nwebexteamssdk.exceptions.ApiError: [400] Bad Request - POST failed: HTTP/1.1 400 Bad Request (url = https://webhook-engine-a.wbx2.com/webhook-engine/api/v1/webhooks, request/response TrackingId = ROUTER_5ECD21B0-63B3-01BB-00D6-B2CAA80F00D6, error = 'Invalid targetUrl: Illegal character in path at index 0: <function Url at 0x7fd36ce31f80>/connector/webexteams')\r\n```\r\n# How to reproduce\r\n\r\n* Create `configuration.yaml` with the following content:\r\n\r\n```\r\nconnectors:\r\n  webexteams:\r\n    token: MYBOTACCESSTOKEN\r\n    webhook-url: https://my-webhook-url.com\r\n    # Seem that webhook-url is not relevant for the error message\r\nskills:\r\n  hello:\r\n```\r\n\r\n* Create `debug.sh` with the following content:\r\n\r\n```\r\ndocker run --rm -ti -p 8080:8080 \\\r\n\t-v `pwd`/configuration.yaml:/root/.config/opsdroid/configuration.yaml:ro \\\r\n\topsdroid/opsdroid:v0.18.0 sh\r\n```\r\n\r\n* `chmod +x debug.sh`\r\n* `./debug.sh`\r\n* (in the container) `opsdroid start`\r\n\r\n\n", "before_files": [{"content": "\"\"\"A connector for Webex Teams.\"\"\"\nimport json\nimport logging\nimport uuid\nimport os\n\nimport aiohttp\n\nfrom webexteamssdk import WebexTeamsAPI\nfrom voluptuous import Required, Url\n\nfrom opsdroid.connector import Connector, register_event\nfrom opsdroid.events import Message\n\n\n_LOGGER = logging.getLogger(__name__)\nCONFIG_SCHEMA = {Required(\"webhook-url\"): Url, Required(\"token\"): str}\n\n\nclass ConnectorWebexTeams(Connector):\n    \"\"\"A connector for Webex Teams.\"\"\"\n\n    def __init__(self, config, opsdroid=None):\n        \"\"\"Create a connector.\"\"\"\n        _LOGGER.debug(_(\"Loaded WebEx Teams Connector.\"))\n        super().__init__(config, opsdroid=opsdroid)\n        self.name = \"webexteams\"\n        self.config = config\n        self.opsdroid = opsdroid\n        self.default_target = None\n        self.bot_name = config.get(\"bot-name\", \"opsdroid\")\n        self.bot_webex_id = None\n        self.secret = uuid.uuid4().hex\n        self.people = {}\n\n    async def connect(self):\n        \"\"\"Connect to the chat service.\"\"\"\n        try:\n            self.api = WebexTeamsAPI(\n                access_token=self.config[\"token\"],\n                proxies={\n                    \"http\": os.environ.get(\"HTTP_PROXY\"),\n                    \"https\": os.environ.get(\"HTTPS_PROXY\"),\n                },\n            )\n        except KeyError:\n\n            _LOGGER.error(_(\"Must set access-token for WebEx Teams Connector.\"))\n\n            return\n\n        await self.clean_up_webhooks()\n        await self.subscribe_to_rooms()\n        await self.set_own_id()\n\n    async def webexteams_message_handler(self, request):\n        \"\"\"Handle webhooks from the Webex Teams api.\"\"\"\n        _LOGGER.debug(_(\"Handling message from WebEx Teams.\"))\n        req_data = await request.json()\n\n        _LOGGER.debug(req_data)\n\n        msg = self.api.messages.get(req_data[\"data\"][\"id\"])\n\n        if req_data[\"data\"][\"personId\"] != self.bot_webex_id:\n            person = await self.get_person(req_data[\"data\"][\"personId\"])\n\n            try:\n                message = Message(\n                    text=msg.text,\n                    user=person.displayName,\n                    target={\"id\": msg.roomId, \"type\": msg.roomType},\n                    connector=self,\n                )\n                await self.opsdroid.parse(message)\n            except KeyError as error:\n                _LOGGER.error(error)\n\n        return aiohttp.web.Response(text=json.dumps(\"Received\"), status=201)\n\n    async def clean_up_webhooks(self):\n        \"\"\"Remove all existing webhooks.\"\"\"\n        for webhook in self.api.webhooks.list():\n            self.api.webhooks.delete(webhook.id)\n\n    async def subscribe_to_rooms(self):\n        \"\"\"Create webhooks for all rooms.\"\"\"\n        _LOGGER.debug(_(\"Creating Webex Teams webhook.\"))\n        webhook_endpoint = \"/connector/webexteams\"\n        self.opsdroid.web_server.web_app.router.add_post(\n            webhook_endpoint, self.webexteams_message_handler\n        )\n\n        self.api.webhooks.create(\n            name=\"opsdroid\",\n            targetUrl=\"{}{}\".format(self.config.get(\"webhook-url\"), webhook_endpoint),\n            resource=\"messages\",\n            event=\"created\",\n            secret=self.secret,\n        )\n\n    async def get_person(self, personId):\n        \"\"\"Get a person's info from the api or cache.\"\"\"\n        if personId not in self.people:\n            self.people[personId] = self.api.people.get(personId)\n        return self.people[personId]\n\n    async def set_own_id(self):\n        \"\"\"Get the bot id and set it in the class.\"\"\"\n        self.bot_webex_id = self.api.people.me().id\n\n    async def listen(self):\n        \"\"\"Listen for and parse new messages.\"\"\"\n        pass  # Listening is handled by the aiohttp web server\n\n    @register_event(Message)\n    async def send_message(self, message):\n        \"\"\"Respond with a message.\"\"\"\n        self.api.messages.create(message.target[\"id\"], text=message.text)\n", "path": "opsdroid/connector/webexteams/__init__.py"}], "after_files": [{"content": "\"\"\"A connector for Webex Teams.\"\"\"\nimport json\nimport logging\nimport uuid\nimport os\n\nimport aiohttp\n\nfrom webexteamssdk import WebexTeamsAPI\nfrom voluptuous import Required, Url\n\nfrom opsdroid.connector import Connector, register_event\nfrom opsdroid.events import Message\n\n\n_LOGGER = logging.getLogger(__name__)\nCONFIG_SCHEMA = {Required(\"webhook-url\"): Url(), Required(\"token\"): str}\n\n\nclass ConnectorWebexTeams(Connector):\n    \"\"\"A connector for Webex Teams.\"\"\"\n\n    def __init__(self, config, opsdroid=None):\n        \"\"\"Create a connector.\"\"\"\n        _LOGGER.debug(_(\"Loaded WebEx Teams Connector.\"))\n        super().__init__(config, opsdroid=opsdroid)\n        self.name = \"webexteams\"\n        self.config = config\n        self.opsdroid = opsdroid\n        self.default_target = None\n        self.bot_name = config.get(\"bot-name\", \"opsdroid\")\n        self.bot_webex_id = None\n        self.secret = uuid.uuid4().hex\n        self.people = {}\n\n    async def connect(self):\n        \"\"\"Connect to the chat service.\"\"\"\n        try:\n            self.api = WebexTeamsAPI(\n                access_token=self.config[\"token\"],\n                proxies={\n                    \"http\": os.environ.get(\"HTTP_PROXY\"),\n                    \"https\": os.environ.get(\"HTTPS_PROXY\"),\n                },\n            )\n        except KeyError:\n\n            _LOGGER.error(_(\"Must set access-token for WebEx Teams Connector.\"))\n\n            return\n\n        await self.clean_up_webhooks()\n        await self.subscribe_to_rooms()\n        await self.set_own_id()\n\n    async def webexteams_message_handler(self, request):\n        \"\"\"Handle webhooks from the Webex Teams api.\"\"\"\n        _LOGGER.debug(_(\"Handling message from WebEx Teams.\"))\n        req_data = await request.json()\n\n        _LOGGER.debug(req_data)\n\n        msg = self.api.messages.get(req_data[\"data\"][\"id\"])\n\n        if req_data[\"data\"][\"personId\"] != self.bot_webex_id:\n            person = await self.get_person(req_data[\"data\"][\"personId\"])\n\n            try:\n                message = Message(\n                    text=msg.text,\n                    user=person.displayName,\n                    target={\"id\": msg.roomId, \"type\": msg.roomType},\n                    connector=self,\n                )\n                await self.opsdroid.parse(message)\n            except KeyError as error:\n                _LOGGER.error(error)\n\n        return aiohttp.web.Response(text=json.dumps(\"Received\"), status=201)\n\n    async def clean_up_webhooks(self):\n        \"\"\"Remove all existing webhooks.\"\"\"\n        for webhook in self.api.webhooks.list():\n            self.api.webhooks.delete(webhook.id)\n\n    async def subscribe_to_rooms(self):\n        \"\"\"Create webhooks for all rooms.\"\"\"\n        _LOGGER.debug(_(\"Creating Webex Teams webhook.\"))\n        webhook_endpoint = \"/connector/webexteams\"\n        self.opsdroid.web_server.web_app.router.add_post(\n            webhook_endpoint, self.webexteams_message_handler\n        )\n\n        self.api.webhooks.create(\n            name=\"opsdroid\",\n            targetUrl=\"{}{}\".format(self.config.get(\"webhook-url\"), webhook_endpoint),\n            resource=\"messages\",\n            event=\"created\",\n            secret=self.secret,\n        )\n\n    async def get_person(self, personId):\n        \"\"\"Get a person's info from the api or cache.\"\"\"\n        if personId not in self.people:\n            self.people[personId] = self.api.people.get(personId)\n        return self.people[personId]\n\n    async def set_own_id(self):\n        \"\"\"Get the bot id and set it in the class.\"\"\"\n        self.bot_webex_id = self.api.people.me().id\n\n    async def listen(self):\n        \"\"\"Listen for and parse new messages.\"\"\"\n        pass  # Listening is handled by the aiohttp web server\n\n    @register_event(Message)\n    async def send_message(self, message):\n        \"\"\"Respond with a message.\"\"\"\n        self.api.messages.create(message.target[\"id\"], text=message.text)\n", "path": "opsdroid/connector/webexteams/__init__.py"}]}