diff --git a/src/Discord.Net.Core/Entities/Messages/FileAttachment.cs b/src/Discord.Net.Core/Entities/Messages/FileAttachment.cs
index 7d7f6a4630..57bb8ba262 100644
--- a/src/Discord.Net.Core/Entities/Messages/FileAttachment.cs
+++ b/src/Discord.Net.Core/Entities/Messages/FileAttachment.cs
@@ -27,6 +27,16 @@ public struct FileAttachment : IDisposable
///
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 @@ public struct FileAttachment : IDisposable
/// 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 @@ public FileAttachment(Stream stream, string fileName, string description = null,
}
catch { }
IsSpoiler = isSpoiler;
+ DurationSeconds = durationSeconds;
+ Waveform = waveform;
}
///
@@ -91,7 +103,7 @@ public FileAttachment(Stream stream, string fileName, string description = null,
/// 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 @@ public FileAttachment(string path, string fileName = null, string description =
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 591c9586bf..65bf93e087 100644
--- a/src/Discord.Net.Core/Entities/Messages/IAttachment.cs
+++ b/src/Discord.Net.Core/Entities/Messages/IAttachment.cs
@@ -76,6 +76,11 @@ public interface IAttachment : ISnowflakeEntity
///
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 49a8268d7b..c1e4309eed 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 @@ public IReadOnlyDictionary ToDictionary()
{
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 @@ public IReadOnlyDictionary ToDictionary()
{
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 9ba1001644..dcdc7e65a8 100644
--- a/src/Discord.Net.Rest/API/Rest/UploadInteractionFileParams.cs
+++ b/src/Discord.Net.Rest/API/Rest/UploadInteractionFileParams.cs
@@ -44,6 +44,8 @@ public IReadOnlyDictionary ToDictionary()
{
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 @@ public IReadOnlyDictionary ToDictionary()
{
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 c62426670c..f33eecfb9d 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 @@ public IReadOnlyDictionary ToDictionary()
{
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 @@ public IReadOnlyDictionary ToDictionary()
{
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 592b2a5f55..73906efe5e 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 @@ public class Attachment : IAttachment
///
public string Waveform { get; }
///
+ public byte[] WaveformBytes { get; }
+ ///
public double? Duration { get; }
///
@@ -69,6 +72,8 @@ internal Attachment(ulong id, string filename, string url, string proxyUrl, int
Title = title;
ClipParticipants = clipParticipants;
ClipCreatedAt = clipCreatedAt;
+ if (waveform is not null)
+ WaveformBytes = Convert.FromBase64String(waveform);
}
internal static Attachment Create(Model model, BaseDiscordClient discord)