Repository: opsdroid/opsdroid

Issue:
Telegram connector can not handle the File event type
<!-- 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
Telegram connector does not handle File events.

## Steps to Reproduce
```
@match_regex(r'Please, send me a pdf file')
    async def sendDocument(self, message):
        path= '/file.pdf' 

        with open(path, 'rb') as file:
            fileEvent = File(file_bytes= file, mimetype= 'application/pdf', target= {'id': message.target})
            await message.respond( fileEvent )

```

## Expected Functionality
The connector should handle the File event type.


## Experienced Functionality
You get the following error

> `TypeError: Connector <class 'opsdroid.connector.telegram.ConnectorTelegram'> can not handle the 'File' event type.`

## Versions
- **Opsdroid version:** v0.17.1
- **Python version:** 3.7
- **OS/Docker version:** Fedora 31

## Configuration File
Not relevant, I think

## Additional Details
The solution should be quite similar to [Adds Image support for Telegram #929](https://github.com/opsdroid/opsdroid/pull/929)


<!-- Love opsdroid? Please consider supporting our collective:
 +👉  https://opencollective.com/opsdroid/donate -->



Discussion:

Resolving patch:
diff --git a/opsdroid/connector/telegram/__init__.py b/opsdroid/connector/telegram/__init__.py
--- a/opsdroid/connector/telegram/__init__.py
+++ b/opsdroid/connector/telegram/__init__.py
@@ -5,7 +5,7 @@
 from voluptuous import Required
 
 from opsdroid.connector import Connector, register_event
-from opsdroid.events import Message, Image
+from opsdroid.events import Message, Image, File
 
 
 _LOGGER = logging.getLogger(__name__)
@@ -318,6 +318,30 @@ async def send_image(self, file_event):
         else:
             _LOGGER.debug(_("Unable to send image - Status Code %s."), resp.status)
 
+    @register_event(File)
+    async def send_file(self, file_event):
+        """Send File to Telegram.
+
+        Gets the chat id from the channel and then
+        sends the bytes of the file as multipart/form-data.
+
+        """
+        data = aiohttp.FormData()
+        data.add_field(
+            "chat_id", str(file_event.target["id"]), content_type="multipart/form-data"
+        )
+        data.add_field(
+            "document",
+            await file_event.get_file_bytes(),
+            content_type="multipart/form-data",
+        )
+
+        resp = await self.session.post(self.build_url("sendDocument"), data=data)
+        if resp.status == 200:
+            _LOGGER.debug(_("Sent %s file successfully."), file_event.name)
+        else:
+            _LOGGER.debug(_("Unable to send file - Status Code %s."), resp.status)
+
     async def disconnect(self):
         """Disconnect from Telegram.
 


Test patch:
diff --git a/tests/test_connector_telegram.py b/tests/test_connector_telegram.py
--- a/tests/test_connector_telegram.py
+++ b/tests/test_connector_telegram.py
@@ -7,7 +7,7 @@
 
 from opsdroid.core import OpsDroid
 from opsdroid.connector.telegram import ConnectorTelegram
-from opsdroid.events import Message, Image
+from opsdroid.events import Message, Image, File
 from opsdroid.cli.start import configure_lang
 
 
@@ -510,6 +510,38 @@ async def test_respond_image_failure(self):
             await self.connector.send_image(image)
             self.assertLogs("_LOOGER", "debug")
 
+    async def test_respond_file(self):
+        post_response = amock.Mock()
+        post_response.status = 200
+
+        file_bytes = b"plain text file example"
+
+        file = File(file_bytes=file_bytes, target={"id": "123"})
+
+        with amock.patch.object(self.connector.session, "post") as patched_request:
+
+            patched_request.return_value = asyncio.Future()
+            patched_request.return_value.set_result(post_response)
+
+            await self.connector.send_file(file)
+            self.assertTrue(patched_request.called)
+
+    async def test_respond_file_failure(self):
+        post_response = amock.Mock()
+        post_response.status = 400
+
+        file_bytes = b"plain text file example"
+
+        file = File(file_bytes=file_bytes, target={"id": "123"})
+
+        with amock.patch.object(self.connector.session, "post") as patched_request:
+
+            patched_request.return_value = asyncio.Future()
+            patched_request.return_value.set_result(post_response)
+
+            await self.connector.send_file(file)
+            self.assertLogs("_LOOGER", "debug")
+
     async def test_listen(self):
         with amock.patch.object(
             self.connector.loop, "create_task"