internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: opsdroid/opsdroid

Issue:
Remove function skill deprecation warning
A while back we added class based skills and added a deprecation warning to function based skills.

In hindsight we probably don't want to deprecate function based skills as they can still be useful and easier for a beginner to get on with.

So let's remove [this deprecation warning](https://github.com/opsdroid/opsdroid/blob/96477f218d4b900746bc868956caa53d1b862c76/opsdroid/core.py#L259).


Discussion:
I can certainly do that to get used to the code, as I'm a beginner to the project (as well as to count towards my PR's for Hacktoberfest).

If possible, will contribute with another PR as well, for some other issue.
Hi Jacob, 

I did the changes and trying to push but getting 403 access denied message, do i have to add myself in contributor list or something?

Thanks,
Vijay

Resolving patch:
diff --git a/opsdroid/core.py b/opsdroid/core.py
--- a/opsdroid/core.py
+++ b/opsdroid/core.py
@@ -254,27 +254,12 @@ def setup_skills(self, skills):
                     continue
 
                 if hasattr(func, "skill"):
-                    _LOGGER.warning(
-                        _(
-                            "Function based skills are deprecated "
-                            "and will be removed in a future "
-                            "release. Please use class-based skills "
-                            "instead."
-                        )
-                    )
                     func.config = skill["config"]
                     self.skills.append(func)
 
         with contextlib.suppress(AttributeError):
             for skill in skills:
                 skill["module"].setup(self, self.config)
-                _LOGGER.warning(
-                    _(
-                        "<skill module>.setup() is deprecated and "
-                        "will be removed in a future release. "
-                        "Please use class-based skills instead."
-                    )
-                )
 
     async def train_parsers(self, skills):
         """Train the parsers."""


Test patch:
Repository: opsdroid/opsdroid

Issue:
Direct messages to Slack Users is sent via Slack Bot instead of the configured Bot User
<!-- 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
Sending messages directly to Slack Users is sent by the default Slack Bot instead of the configured Bot User.


## Steps to Reproduce
1. Configure Slack Connector in Opsdroid.
2. Send a message to a user instead of a channel by setting the `message.target` value (e.g. @someuser)


## Expected Functionality
The message should be sent to the user via the bot user whose API token we have configured.


## Experienced Functionality
The message is sent to the user via the default Slack Bot.

## Versions
- **Opsdroid version:** master branch in git
- **Python version:** 3.6.8
- **OS/Docker version:** Ubuntu 18.04 LTS

## Configuration File
Please include your version of the configuration file below.

```yaml
# Your code goes here.
welcome-message: true

connectors:
  - name: slack
    api-token: "<Bot OAuth Token>"

skills:
  - name: myskill
    path: /path/to/myskill

```

## Additional Details
Any other details you wish to include such as screenshots, console messages, etc.


<!-- Love opsdroid? Please consider supporting our collective:
 +👉  https://opencollective.com/opsdroid/donate -->



Discussion:

Resolving patch:
diff --git a/opsdroid/connector/slack/__init__.py b/opsdroid/connector/slack/__init__.py
--- a/opsdroid/connector/slack/__init__.py
+++ b/opsdroid/connector/slack/__init__.py
@@ -27,6 +27,7 @@ def __init__(self, config, opsdroid=None):
         self.icon_emoji = config.get("icon-emoji", ":robot_face:")
         self.token = config["api-token"]
         self.timeout = config.get("connect-timeout", 10)
+        self.chat_as_user = config.get("chat-as-user", False)
         self.ssl_context = ssl.create_default_context(cafile=certifi.where())
         self.slack = slack.WebClient(
             token=self.token, run_async=True, ssl=self.ssl_context
@@ -141,7 +142,7 @@ async def send_message(self, message):
             data={
                 "channel": message.target,
                 "text": message.text,
-                "as_user": False,
+                "as_user": self.chat_as_user,
                 "username": self.bot_name,
                 "icon_emoji": self.icon_emoji,
             },
@@ -157,6 +158,7 @@ async def send_blocks(self, blocks):
             "chat.postMessage",
             data={
                 "channel": blocks.target,
+                "as_user": self.chat_as_user,
                 "username": self.bot_name,
                 "blocks": blocks.blocks,
                 "icon_emoji": self.icon_emoji,


Test patch:
Repository: opsdroid/opsdroid

Issue:
Duplicated shell prompt 
# Description
When I run the hello skill from the shell, I found duplicated shell prompt output. I think there's some issue with the shell connector. 


## Steps to Reproduce
```
qidong@ubuntu:~/Documents/opsdroid$ opsdroid start
mybot> hello
Hello qidong
mybot> mybot>
```


## Expected Functionality
There should be only one prompt printed after the skill response. 

## Experienced Functionality
One extra prompt is printed. 


## Configuration File

```yaml
logging:
  console: false

connectors:
  websocket:
    bot-name: "mybot"
    max-connections: 10
    connection-timeout: 10
  
  shell:
    bot-name: "mybot"

skills:
  ## Hello (https://github.com/opsdroid/skill-hello)
  hello: {}
```






Discussion:

Resolving patch:
diff --git a/opsdroid/connector/shell/__init__.py b/opsdroid/connector/shell/__init__.py
--- a/opsdroid/connector/shell/__init__.py
+++ b/opsdroid/connector/shell/__init__.py
@@ -125,7 +125,6 @@ async def respond(self, message):
         _LOGGER.debug(_("Responding with: %s."), message.text)
         self.clear_prompt()
         print(message.text)
-        self.draw_prompt()
 
     async def disconnect(self):
         """Disconnects the connector."""


Test patch:
diff --git a/tests/test_connector_shell.py b/tests/test_connector_shell.py
--- a/tests/test_connector_shell.py
+++ b/tests/test_connector_shell.py
@@ -161,7 +161,7 @@ async def test_respond(self):
         with contextlib.redirect_stdout(f):
             await self.connector.respond(message)
             prompt = f.getvalue()
-            self.assertEqual(prompt.strip(), "Hi\nopsdroid>")
+            self.assertEqual(prompt.strip(), "Hi")
 
     async def test_disconnect(self):
         connector = ConnectorShell({}, opsdroid=OpsDroid())
Repository: opsdroid/opsdroid

Issue:
Add 3.8 support to setup.py
We've been running CI against 3.8 for a while now, we should update the metadata in `setup.py` to explicitly state we support 3.8.

We should also update the [support table](https://github.com/opsdroid/opsdroid/blob/master/docs/maintaining/supported-python-versions.md) to say we support 3.8.


Discussion:
and also pull 3.6 now 0.19 is out as well.
Can I work on this issue?
Hello @elijose55  please go ahead and submit a PR, let us know if you need any help

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -74,6 +74,7 @@ def run(self):
         "Programming Language :: Python :: 3 :: Only",
         "Programming Language :: Python :: 3.6",
         "Programming Language :: Python :: 3.7",
+        "Programming Language :: Python :: 3.8",
         "Topic :: Communications :: Chat",
         "Topic :: Scientific/Engineering :: Artificial Intelligence",
         "Topic :: Software Development :: Libraries :: Python Modules",


Test patch:
Repository: opsdroid/opsdroid

Issue:
Drop Python 3.6
We should now drop Python 3.6 as 0.19 is out.

_Originally posted by @Cadair in https://github.com/opsdroid/opsdroid/issues/1534#issuecomment-644825884_


Discussion:
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.


Resolving patch:
diff --git a/opsdroid/cli/utils.py b/opsdroid/cli/utils.py
--- a/opsdroid/cli/utils.py
+++ b/opsdroid/cli/utils.py
@@ -112,11 +112,11 @@ def check_dependencies():
 
     Returns:
         int: the exit code. Returns 1 if the Python version installed is
-        below 3.6.
+        below 3.7.
 
     """
-    if sys.version_info.major < 3 or sys.version_info.minor < 6:
-        logging.critical(_("Whoops! opsdroid requires python 3.6 or above."))
+    if sys.version_info.major < 3 or sys.version_info.minor < 7:
+        logging.critical(_("Whoops! opsdroid requires python 3.7 or above."))
         sys.exit(1)
 
 
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -72,7 +72,6 @@ def run(self):
         "Programming Language :: Python",
         "Programming Language :: Python :: 3",
         "Programming Language :: Python :: 3 :: Only",
-        "Programming Language :: Python :: 3.6",
         "Programming Language :: Python :: 3.7",
         "Programming Language :: Python :: 3.8",
         "Topic :: Communications :: Chat",


Test patch:
diff --git a/tests/test_cli.py b/tests/test_cli.py
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -103,12 +103,10 @@ def test_check_version_36(self):
         with mock.patch.object(sys, "version_info") as version_info:
             version_info.major = 3
             version_info.minor = 6
-            try:
+            with self.assertRaises(SystemExit):
                 from opsdroid.cli.utils import check_dependencies
 
                 check_dependencies()
-            except SystemExit:
-                self.fail("check_dependencies() exited unexpectedly!")
 
     def test_check_version_37(self):
         with mock.patch.object(sys, "version_info") as version_info:
Repository: opsdroid/opsdroid

Issue:
Configuration validator warning could be more useful + accurate
<!-- 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
The Opsdroid warning "Opsdroid has a new configuration format since version 0.17.0, we will change your configuration now. Please read on how to migrate in the documentation." indicates that the daemon itself will re-write your configuration file, but this is not the case.  

It could also include a link to how one might be able to migrate their config-file, saving frantic seconds of Googling :-) 

## Steps to Reproduce
Just use an otherwise-working config-file that doesn't conform to the new standard 

## Expected Functionality
Warning message should reflect reality (shouldn't say "We will change your config now") and hint to the user where they can directly read up on the new format (such as via including a link)


## Experienced Functionality
Explain what happened instead(Please include the debug log).

## Versions
- **Opsdroid version:** 0.19.0
- **Python version:** 3.8.4
- **OS/Docker version:**

## Configuration File
Please include your version of the configuration file below.

```yaml
# Your code goes here.

```

## Additional Details
Any other details you wish to include such as screenshots, console messages, etc.


<!-- Love opsdroid? Please consider supporting our collective:
 +👉  https://opencollective.com/opsdroid/donate -->



Discussion:

Resolving patch:
diff --git a/opsdroid/helper.py b/opsdroid/helper.py
--- a/opsdroid/helper.py
+++ b/opsdroid/helper.py
@@ -63,7 +63,7 @@ def convert_dictionary(modules):
 
     if isinstance(modules, list):
         _LOGGER.warning(
-            "Opsdroid has a new configuration format since version 0.17.0, we will change your configuration now. Please read on how to migrate in the documentation."
+            "Opsdroid has a new configuration format since version 0.17.0. Please read on how to migrate in the documentation at https://docs.opsdroid.dev/en/stable/configuration.html#migrate-to-new-configuration-layout."
         )
         for module in modules:
             module_copy = module.copy()


Test patch:
Repository: opsdroid/opsdroid

Issue:
Twitch connector can't connect to webhook
When I was working on the Twitter connector, I realised that I had changed the configuration for the webhook URL to use the `base-url` although I forgot to make the changes to the `connect_webhook` method.

This means that the Twitch connector isn't able to connect to webhooks because we are passing a None url.

I am going to raise a PR to fix this issue in a moment.


Discussion:

Resolving patch:
diff --git a/opsdroid/connector/twitch/__init__.py b/opsdroid/connector/twitch/__init__.py
--- a/opsdroid/connector/twitch/__init__.py
+++ b/opsdroid/connector/twitch/__init__.py
@@ -61,10 +61,13 @@ def __init__(self, config, opsdroid=None):
         # TODO: Allow usage of SSL connection
         self.server = "ws://irc-ws.chat.twitch.tv"
         self.port = "80"
-        self.base_url = config.get("base-url")
         self.loop = asyncio.get_event_loop()
         self.reconnections = 0
         self.auth_file = TWITCH_JSON
+        try:
+            self.base_url = opsdroid.config["web"]["base-url"]
+        except KeyError:
+            self.base_url = config.get("forward-url")
 
     async def validate_request(self, request, secret):
         """Compute sha256 hash of request and secret.


Test patch:
diff --git a/opsdroid/connector/twitch/tests/test_connector_twitch.py b/opsdroid/connector/twitch/tests/test_connector_twitch.py
--- a/opsdroid/connector/twitch/tests/test_connector_twitch.py
+++ b/opsdroid/connector/twitch/tests/test_connector_twitch.py
@@ -33,6 +33,35 @@ def test_init(opsdroid):
     assert connector.reconnections == 0
 
 
+def test_base_url_twitch_config(opsdroid):
+    config = {
+        "code": "yourcode",
+        "channel": "test",
+        "client-id": "client-id",
+        "client-secret": "client-secret",
+        "forward-url": "http://my-awesome-url",
+    }
+
+    connector = ConnectorTwitch(config, opsdroid=opsdroid)
+
+    assert connector.base_url == "http://my-awesome-url"
+
+
+def test_base_url_web_config(opsdroid):
+    config = {
+        "code": "yourcode",
+        "channel": "test",
+        "client-id": "client-id",
+        "client-secret": "client-secret",
+    }
+
+    opsdroid.config["web"] = {"base-url": "http://my-awesome-url"}
+
+    connector = ConnectorTwitch(config, opsdroid=opsdroid)
+
+    assert connector.base_url == "http://my-awesome-url"
+
+
 @pytest.mark.asyncio
 async def test_validate_request(opsdroid):
     connector = ConnectorTwitch(connector_config, opsdroid=opsdroid)
Repository: opsdroid/opsdroid

Issue:
Add a config option to disable registering a route for /
In the web server by default a route is registered for the base / path. This should be configurable in case a user wants to register their own.


Discussion:
Hey there,I would like to work on this issue since this is beginner one.Can you guide me as to what has to be done inorder to resolve this issue?

[this](https://github.com/opsdroid/opsdroid/blob/master/opsdroid/web.py#L28) line needs to be configurable. If the added config option is false then it shouldn't be run.
@Cadair  is this what you are asking for?
`
if (self.web_index_handler){
    self.web_app.router.add_get("/", self.web_index_handler)
}
`

Resolving patch:
diff --git a/opsdroid/web.py b/opsdroid/web.py
--- a/opsdroid/web.py
+++ b/opsdroid/web.py
@@ -34,8 +34,10 @@ def __init__(self, opsdroid):
         self.web_app = web.Application()
         self.runner = web.AppRunner(self.web_app)
         self.site = None
-        self.web_app.router.add_get("/", self.web_index_handler)
-        self.web_app.router.add_get("", self.web_index_handler)
+        if not self.config.get("disable_web_index_handler_in_root", False):
+            self.web_app.router.add_get("/", self.web_index_handler)
+            self.web_app.router.add_get("", self.web_index_handler)
+
         self.web_app.router.add_get("/stats", self.web_stats_handler)
         self.web_app.router.add_get("/stats/", self.web_stats_handler)
 


Test patch:
diff --git a/opsdroid/tests/test_web.py b/opsdroid/tests/test_web.py
--- a/opsdroid/tests/test_web.py
+++ b/opsdroid/tests/test_web.py
@@ -38,6 +38,24 @@ async def test_web_get_host(opsdroid):
     assert app.get_host == "127.0.0.1"
 
 
+async def test_web_disable_web_index_handler_in_root(opsdroid):
+    """Check disabling of web index handler in root."""
+    opsdroid.config["web"] = {"disable_web_index_handler_in_root": True}
+    app = web.Web(opsdroid)
+    canonicals = [resource.canonical for resource in app.web_app._router.resources()]
+    assert "/" not in canonicals
+
+    opsdroid.config["web"] = {"disable_web_index_handler_in_root": False}
+    app = web.Web(opsdroid)
+    canonicals = [resource.canonical for resource in app.web_app._router.resources()]
+    assert "/" in canonicals
+
+    opsdroid.config["web"] = {}
+    app = web.Web(opsdroid)
+    canonicals = [resource.canonical for resource in app.web_app._router.resources()]
+    assert "/" in canonicals
+
+
 async def test_web_get_ssl(opsdroid):
     """Check the host getter."""
     opsdroid.config["web"] = {}
Repository: opsdroid/opsdroid

Issue:
Infinite self-responses in Mattermost connector
After fixing the Mattermost connector with PR #1774 it turns out it suffers from the same infinite self-response problem  (#1691) as was fixed for the Gitter connector in #1692.


Discussion:

Resolving patch:
diff --git a/opsdroid/connector/mattermost/__init__.py b/opsdroid/connector/mattermost/__init__.py
--- a/opsdroid/connector/mattermost/__init__.py
+++ b/opsdroid/connector/mattermost/__init__.py
@@ -39,6 +39,7 @@ def __init__(self, config, opsdroid=None):
         self.mfa_token = None
         self.debug = False
         self.listening = True
+        self.bot_id = None
 
         self.mm_driver = Driver(
             {
@@ -66,8 +67,7 @@ async def connect(self):
             self.bot_id = login_response["id"]
         if "username" in login_response:
             self.bot_name = login_response["username"]
-
-        _LOGGER.info(_("Connected as %s"), self.bot_name)
+            _LOGGER.info(_("Connected as %s"), self.bot_name)
 
         self.mm_driver.websocket = Websocket(
             self.mm_driver.options, self.mm_driver.client.token
@@ -93,15 +93,18 @@ async def process_message(self, raw_message):
         if "event" in message and message["event"] == "posted":
             data = message["data"]
             post = json.loads(data["post"])
-            await self.opsdroid.parse(
-                Message(
-                    text=post["message"],
-                    user=data["sender_name"],
-                    target=data["channel_name"],
-                    connector=self,
-                    raw_event=message,
+            # don't parse our own messages (https://github.com/opsdroid/opsdroid/issues/1775)
+            # (but also parse if somehow our bot_id is unknown, like in the unit tests)
+            if self.bot_id is None or self.bot_id != post["user_id"]:
+                await self.opsdroid.parse(
+                    Message(
+                        text=post["message"],
+                        user=data["sender_name"],
+                        target=data["channel_name"],
+                        connector=self,
+                        raw_event=message,
+                    )
                 )
-            )
 
     @register_event(Message)
     async def send_message(self, message):


Test patch:
Repository: opsdroid/opsdroid

Issue:
User configurable connection for mongo-based databases
So the pymongo client has a multitude of ways for connecting to different mongo services

So for MongoDB Atlas users the connection string is given as such 
for python connections to the mongo db atlas 

`mongodb+srv://<username>:<password>@<cluster-name>.mongodb.net/myFirstDatabase`

In making the mongo connection to be user configurable we can specify different types of mongo services versus
just asking for the basic connection arguments like port, user name,  pass, and also we can give users an easier way to connect versus making assumptions about the type of mongodb the kinds of credentials they might have. 

As long as the pymongo client accepts the connection and connects the user to the database and the collection they want I think this would be great!

Thanks again guys!



Discussion:

Resolving patch:
diff --git a/opsdroid/database/mongo/__init__.py b/opsdroid/database/mongo/__init__.py
--- a/opsdroid/database/mongo/__init__.py
+++ b/opsdroid/database/mongo/__init__.py
@@ -44,17 +44,18 @@ def __init__(self, config, opsdroid=None):
     async def connect(self):
         """Connect to the database."""
         host = self.config.get("host", "localhost")
+        protocol = self.config.get("protocol", "mongodb").replace("://", "")
         port = self.config.get("port", "27017")
+        if port != "27017":
+            host = f"{host}:{port}"
         database = self.config.get("database", "opsdroid")
         user = self.config.get("user")
         pwd = self.config.get("password")
         if user and pwd:
-            path = "mongodb://{user}:{pwd}@{host}:{port}".format(
-                user=user, pwd=pwd, host=host, port=port
-            )
+            self.db_url = f"{protocol}://{user}:{pwd}@{host}"
         else:
-            path = "mongodb://{host}:{port}".format(host=host, port=port)
-        self.client = AsyncIOMotorClient(path)
+            self.db_url = f"{protocol}://{host}"
+        self.client = AsyncIOMotorClient(self.db_url)
         self.database = self.client[database]
         _LOGGER.info("Connected to MongoDB.")
 


Test patch:
diff --git a/opsdroid/database/mongo/tests/test_mongo.py b/opsdroid/database/mongo/tests/test_mongo.py
--- a/opsdroid/database/mongo/tests/test_mongo.py
+++ b/opsdroid/database/mongo/tests/test_mongo.py
@@ -44,6 +44,8 @@ def test_init(database):
         {
             "database": "test_db",
             "collection": "test_collection",
+            "protocol": "mongodb://",
+            "port": "1234",
             "user": "root",
             "password": "mongo",
         },
@@ -53,6 +55,7 @@ async def test_connect(database):
     """Test that the mongo database has implemented connect function properly"""
     try:
         await database.connect()
+        assert "mongodb://" in database.db_url
     except NotImplementedError:
         raise Exception
     else: