From 5904ecde5a4e8efe11a84afe4d6965c7a4b49b64 Mon Sep 17 00:00:00 2001 From: Mihail Gribkov <61027276+Misha-133@users.noreply.github.com> Date: Mon, 11 Nov 2024 21:53:11 +0300 Subject: [PATCH] [Feature] Support sending voice messages (#3024) * yup * a --- .../Entities/Messages/FileAttachment.cs | 18 ++++++++++++++++-- .../Entities/Messages/IAttachment.cs | 5 +++++ .../API/Rest/UploadFileParams.cs | 10 +++++++++- .../API/Rest/UploadInteractionFileParams.cs | 8 +++++++- .../API/Rest/UploadWebhookFileParams.cs | 11 ++++++++++- .../Entities/Messages/Attachment.cs | 5 +++++ 6 files changed, 52 insertions(+), 5 deletions(-) diff --git a/src/Discord.Net.Core/Entities/Messages/FileAttachment.cs b/src/Discord.Net.Core/Entities/Messages/FileAttachment.cs index 7d7f6a46..57bb8ba2 100644 --- a/src/Discord.Net.Core/Entities/Messages/FileAttachment.cs +++ b/src/Discord.Net.Core/Entities/Messages/FileAttachment.cs @@ -27,6 +27,16 @@ namespace Discord /// public bool IsThumbnail { get; set; } + /// + /// Gets or sets the duration of a voice message. if the attachment is not a voice message. + /// + public double? DurationSeconds { get; set; } + + /// + /// Gets or sets bytearray representing a sampled waveform. if the attachment is not a voice message. + /// + public byte[] Waveform { get; set; } + #pragma warning disable IDISP008 /// /// Gets the stream containing the file content. @@ -44,7 +54,7 @@ namespace Discord /// The description of the attachment. /// Whether or not the attachment is a spoiler. /// Whether or not this attachment should be a thumbnail for a media channel post. - public FileAttachment(Stream stream, string fileName, string description = null, bool isSpoiler = false, bool isThumbnail = false) + public FileAttachment(Stream stream, string fileName, string description = null, bool isSpoiler = false, bool isThumbnail = false, double? durationSeconds = null, byte[] waveform = null) { _isDisposed = false; FileName = fileName; @@ -57,6 +67,8 @@ namespace Discord } catch { } IsSpoiler = isSpoiler; + DurationSeconds = durationSeconds; + Waveform = waveform; } /// @@ -91,7 +103,7 @@ namespace Discord /// The file specified in was not found. /// /// An I/O error occurred while opening the file. - public FileAttachment(string path, string fileName = null, string description = null, bool isSpoiler = false, bool isThumbnail = false) + public FileAttachment(string path, string fileName = null, string description = null, bool isSpoiler = false, bool isThumbnail = false, double? durationSeconds = null, byte[] waveform = null) { _isDisposed = false; Stream = File.OpenRead(path); @@ -99,6 +111,8 @@ namespace Discord Description = description; IsSpoiler = isSpoiler; IsThumbnail = isThumbnail; + DurationSeconds = durationSeconds; + Waveform = waveform; } public void Dispose() diff --git a/src/Discord.Net.Core/Entities/Messages/IAttachment.cs b/src/Discord.Net.Core/Entities/Messages/IAttachment.cs index 591c9586..65bf93e0 100644 --- a/src/Discord.Net.Core/Entities/Messages/IAttachment.cs +++ b/src/Discord.Net.Core/Entities/Messages/IAttachment.cs @@ -76,6 +76,11 @@ namespace Discord /// public string Waveform { get; } + /// + /// Gets the bytearray representing a sampled waveform. if the attachment is not a voice message. + /// + public byte[] WaveformBytes { get; } + /// /// Gets flags related to this to this attachment. /// diff --git a/src/Discord.Net.Rest/API/Rest/UploadFileParams.cs b/src/Discord.Net.Rest/API/Rest/UploadFileParams.cs index 49a8268d..c1e4309e 100644 --- a/src/Discord.Net.Rest/API/Rest/UploadFileParams.cs +++ b/src/Discord.Net.Rest/API/Rest/UploadFileParams.cs @@ -1,6 +1,7 @@ using Discord.Net.Converters; using Discord.Net.Rest; using Newtonsoft.Json; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -34,6 +35,9 @@ namespace Discord.API.Rest { var d = new Dictionary(); + if (Files.Any(x => x.Waveform is not null && x.DurationSeconds is not null)) + Flags = Flags.GetValueOrDefault(MessageFlags.None) | MessageFlags.VoiceMessage; + var payload = new Dictionary(); if (Content.IsSpecified) payload["content"] = Content.Value; @@ -71,7 +75,11 @@ namespace Discord.API.Rest { id = (ulong)n, filename = filename, - description = attachment.Description ?? Optional.Unspecified + description = attachment.Description ?? Optional.Unspecified, + duration_secs = attachment.DurationSeconds ?? Optional.Unspecified, + waveform = attachment.Waveform is null + ? Optional.Unspecified + : Convert.ToBase64String(attachment.Waveform) }); } diff --git a/src/Discord.Net.Rest/API/Rest/UploadInteractionFileParams.cs b/src/Discord.Net.Rest/API/Rest/UploadInteractionFileParams.cs index 9ba10016..dcdc7e65 100644 --- a/src/Discord.Net.Rest/API/Rest/UploadInteractionFileParams.cs +++ b/src/Discord.Net.Rest/API/Rest/UploadInteractionFileParams.cs @@ -44,6 +44,8 @@ namespace Discord.API.Rest { var d = new Dictionary(); + if (Files.Any(x => x.Waveform is not null && x.DurationSeconds is not null)) + Flags = Flags.GetValueOrDefault(MessageFlags.None) | MessageFlags.VoiceMessage; var payload = new Dictionary(); payload["type"] = Type; @@ -79,7 +81,11 @@ namespace Discord.API.Rest { id = (ulong)n, filename = filename, - description = attachment.Description ?? Optional.Unspecified + description = attachment.Description ?? Optional.Unspecified, + duration_secs = attachment.DurationSeconds ?? Optional.Unspecified, + waveform = attachment.Waveform is null + ? Optional.Unspecified + : Convert.ToBase64String(attachment.Waveform) }); } diff --git a/src/Discord.Net.Rest/API/Rest/UploadWebhookFileParams.cs b/src/Discord.Net.Rest/API/Rest/UploadWebhookFileParams.cs index c6242667..f33eecfb 100644 --- a/src/Discord.Net.Rest/API/Rest/UploadWebhookFileParams.cs +++ b/src/Discord.Net.Rest/API/Rest/UploadWebhookFileParams.cs @@ -1,8 +1,10 @@ using Discord.Net.Converters; using Discord.Net.Rest; using Newtonsoft.Json; +using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Text; namespace Discord.API.Rest @@ -35,6 +37,9 @@ namespace Discord.API.Rest { var d = new Dictionary(); + if (Files.Any(x => x.Waveform is not null && x.DurationSeconds is not null)) + Flags = Flags.GetValueOrDefault(MessageFlags.None) | MessageFlags.VoiceMessage; + var payload = new Dictionary(); if (Content.IsSpecified) payload["content"] = Content.Value; @@ -76,7 +81,11 @@ namespace Discord.API.Rest { id = (ulong)n, filename = filename, - description = attachment.Description ?? Optional.Unspecified + description = attachment.Description ?? Optional.Unspecified, + duration_secs = attachment.DurationSeconds ?? Optional.Unspecified, + waveform = attachment.Waveform is null + ? Optional.Unspecified + : Convert.ToBase64String(attachment.Waveform) }); } diff --git a/src/Discord.Net.Rest/Entities/Messages/Attachment.cs b/src/Discord.Net.Rest/Entities/Messages/Attachment.cs index 592b2a5f..73906efe 100644 --- a/src/Discord.Net.Rest/Entities/Messages/Attachment.cs +++ b/src/Discord.Net.Rest/Entities/Messages/Attachment.cs @@ -1,5 +1,6 @@ using Discord.Rest; using System; +using System.Buffers.Text; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; @@ -35,6 +36,8 @@ namespace Discord /// public string Waveform { get; } /// + public byte[] WaveformBytes { get; } + /// public double? Duration { get; } /// @@ -69,6 +72,8 @@ namespace Discord Title = title; ClipParticipants = clipParticipants; ClipCreatedAt = clipCreatedAt; + if (waveform is not null) + WaveformBytes = Convert.FromBase64String(waveform); } internal static Attachment Create(Model model, BaseDiscordClient discord)