/// <summary>
        /// Sends a file to the room
        /// </summary>
        /// <param name="fileMessage">MatrixFileMessage object that contains information for sending</param>
        /// <returns>Bool based on success or failure</returns>
        public async Task <bool> SendMessage(MatrixFileMessage fileMessage)
        {
            JObject jsonContent = JObject.FromObject(fileMessage);

            if (fileMessage.Type != "m.file")
            {
                jsonContent.Property("filename").Remove();
            }

            return(await SendMessageRequest(jsonContent));
        }
Example #2
0
        /// <summary>
        /// Upload a file to Matrix
        /// </summary>
        /// <param name="filePath">Path to the file you want to upload</param>
        /// <param name="contentType">Optionally specify content type, otherwise it will be automatically detected</param>
        /// <returns>MatrixFileMessage with MxcUrl and Type, may return null if post fails</returns>
        /// <exception cref="FileNotFoundException"></exception>
        public async Task <MatrixFileMessage> Upload(string filePath, string contentType = null)
        {
            if (!File.Exists(filePath))
            {
                throw new FileNotFoundException("File not found", Path.GetFileName(filePath));
            }

            if (contentType == null)
            {
                contentType = MimeTypeMap.GetMimeType(Path.GetExtension(filePath));                      //credit to samuelneff for mime types https://github.com/samuelneff/MimeTypeMap
            }
            string filename  = Path.GetFileName(filePath);
            var    fileBytes = File.ReadAllBytes(filePath);

            HttpResponseMessage uploadResponse =
                await _backendHttpClient.Post($"/_matrix/media/r0/upload?filename={HttpUtility.UrlEncode(filename)}", true, fileBytes,
                                              new Dictionary <string, string>() { { "Content-Type", contentType } });

            string content = string.Empty;

            try
            {
                content = await uploadResponse.Content.ReadAsStringAsync();

                uploadResponse.EnsureSuccessStatusCode();
            }
            catch (HttpRequestException)
            {
                JObject error = JObject.Parse(content);

                switch (uploadResponse.StatusCode)
                {
                case HttpStatusCode.TooManyRequests:
                    var rateLimit = (int)error["retry_after_ms"];

                    Console.WriteLine($"You're being rate-limited, waiting {rateLimit}ms");
                    await Task.Delay(rateLimit);

                    return(await Upload(filePath, contentType));

                default:
                    throw new MatrixRequestException(
                              $"{error["errcode"] ?? ""} - {error["error"] ?? ""}. Unknown error occured with code {uploadResponse.StatusCode.ToString()}");
                }
            }
            catch (NullReferenceException)
            {
                return(null);
            }

            string uploadResponseContent = await uploadResponse.Content.ReadAsStringAsync();

            JObject uploadResponseJObject = JObject.Parse(uploadResponseContent);

            var matrixFileMessage = new MatrixFileMessage
            {
                MxcUrl      = (string)uploadResponseJObject["content_uri"],
                Filename    = filename,
                Description = filename
            };

            string contentTypeSplit = contentType.Split("/")[0];

            switch (contentTypeSplit)
            {
            case "image":
            case "video":
            case "audio":
                matrixFileMessage.Type = $"m.{contentTypeSplit}";
                break;

            default:
                matrixFileMessage.Type = "m.file";
                break;
            }

            return(matrixFileMessage);
        }