[Feature] Support sending voice messages (#3024)

* yup

* a
This commit is contained in:
Mihail Gribkov
2024-11-11 21:53:11 +03:00
committed by GitHub
parent 8b929690a9
commit 5904ecde5a
6 changed files with 52 additions and 5 deletions

View File

@@ -27,6 +27,16 @@ namespace Discord
/// </summary> /// </summary>
public bool IsThumbnail { get; set; } public bool IsThumbnail { get; set; }
/// <summary>
/// Gets or sets the duration of a voice message. <see langword="null"/> if the attachment is not a voice message.
/// </summary>
public double? DurationSeconds { get; set; }
/// <summary>
/// Gets or sets bytearray representing a sampled waveform. <see langword="null"/> if the attachment is not a voice message.
/// </summary>
public byte[] Waveform { get; set; }
#pragma warning disable IDISP008 #pragma warning disable IDISP008
/// <summary> /// <summary>
/// Gets the stream containing the file content. /// Gets the stream containing the file content.
@@ -44,7 +54,7 @@ namespace Discord
/// <param name="description">The description of the attachment.</param> /// <param name="description">The description of the attachment.</param>
/// <param name="isSpoiler">Whether or not the attachment is a spoiler.</param> /// <param name="isSpoiler">Whether or not the attachment is a spoiler.</param>
/// <param name="isThumbnail">Whether or not this attachment should be a thumbnail for a media channel post.</param> /// <param name="isThumbnail">Whether or not this attachment should be a thumbnail for a media channel post.</param>
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; _isDisposed = false;
FileName = fileName; FileName = fileName;
@@ -57,6 +67,8 @@ namespace Discord
} }
catch { } catch { }
IsSpoiler = isSpoiler; IsSpoiler = isSpoiler;
DurationSeconds = durationSeconds;
Waveform = waveform;
} }
/// <summary> /// <summary>
@@ -91,7 +103,7 @@ namespace Discord
/// <exception cref="FileNotFoundException">The file specified in <paramref name="path" /> was not found. /// <exception cref="FileNotFoundException">The file specified in <paramref name="path" /> was not found.
/// </exception> /// </exception>
/// <exception cref="IOException">An I/O error occurred while opening the file. </exception> /// <exception cref="IOException">An I/O error occurred while opening the file. </exception>
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; _isDisposed = false;
Stream = File.OpenRead(path); Stream = File.OpenRead(path);
@@ -99,6 +111,8 @@ namespace Discord
Description = description; Description = description;
IsSpoiler = isSpoiler; IsSpoiler = isSpoiler;
IsThumbnail = isThumbnail; IsThumbnail = isThumbnail;
DurationSeconds = durationSeconds;
Waveform = waveform;
} }
public void Dispose() public void Dispose()

View File

@@ -76,6 +76,11 @@ namespace Discord
/// </summary> /// </summary>
public string Waveform { get; } public string Waveform { get; }
/// <summary>
/// Gets the bytearray representing a sampled waveform. <see langword="null"/> if the attachment is not a voice message.
/// </summary>
public byte[] WaveformBytes { get; }
/// <summary> /// <summary>
/// Gets flags related to this to this attachment. /// Gets flags related to this to this attachment.
/// </summary> /// </summary>

View File

@@ -1,6 +1,7 @@
using Discord.Net.Converters; using Discord.Net.Converters;
using Discord.Net.Rest; using Discord.Net.Rest;
using Newtonsoft.Json; using Newtonsoft.Json;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
@@ -34,6 +35,9 @@ namespace Discord.API.Rest
{ {
var d = new Dictionary<string, object>(); var d = new Dictionary<string, object>();
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<string, object>(); var payload = new Dictionary<string, object>();
if (Content.IsSpecified) if (Content.IsSpecified)
payload["content"] = Content.Value; payload["content"] = Content.Value;
@@ -71,7 +75,11 @@ namespace Discord.API.Rest
{ {
id = (ulong)n, id = (ulong)n,
filename = filename, filename = filename,
description = attachment.Description ?? Optional<string>.Unspecified description = attachment.Description ?? Optional<string>.Unspecified,
duration_secs = attachment.DurationSeconds ?? Optional<double>.Unspecified,
waveform = attachment.Waveform is null
? Optional<string>.Unspecified
: Convert.ToBase64String(attachment.Waveform)
}); });
} }

View File

@@ -44,6 +44,8 @@ namespace Discord.API.Rest
{ {
var d = new Dictionary<string, object>(); var d = new Dictionary<string, object>();
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<string, object>(); var payload = new Dictionary<string, object>();
payload["type"] = Type; payload["type"] = Type;
@@ -79,7 +81,11 @@ namespace Discord.API.Rest
{ {
id = (ulong)n, id = (ulong)n,
filename = filename, filename = filename,
description = attachment.Description ?? Optional<string>.Unspecified description = attachment.Description ?? Optional<string>.Unspecified,
duration_secs = attachment.DurationSeconds ?? Optional<double>.Unspecified,
waveform = attachment.Waveform is null
? Optional<string>.Unspecified
: Convert.ToBase64String(attachment.Waveform)
}); });
} }

View File

@@ -1,8 +1,10 @@
using Discord.Net.Converters; using Discord.Net.Converters;
using Discord.Net.Rest; using Discord.Net.Rest;
using Newtonsoft.Json; using Newtonsoft.Json;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Text; using System.Text;
namespace Discord.API.Rest namespace Discord.API.Rest
@@ -35,6 +37,9 @@ namespace Discord.API.Rest
{ {
var d = new Dictionary<string, object>(); var d = new Dictionary<string, object>();
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<string, object>(); var payload = new Dictionary<string, object>();
if (Content.IsSpecified) if (Content.IsSpecified)
payload["content"] = Content.Value; payload["content"] = Content.Value;
@@ -76,7 +81,11 @@ namespace Discord.API.Rest
{ {
id = (ulong)n, id = (ulong)n,
filename = filename, filename = filename,
description = attachment.Description ?? Optional<string>.Unspecified description = attachment.Description ?? Optional<string>.Unspecified,
duration_secs = attachment.DurationSeconds ?? Optional<double>.Unspecified,
waveform = attachment.Waveform is null
? Optional<string>.Unspecified
: Convert.ToBase64String(attachment.Waveform)
}); });
} }

View File

@@ -1,5 +1,6 @@
using Discord.Rest; using Discord.Rest;
using System; using System;
using System.Buffers.Text;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Diagnostics; using System.Diagnostics;
@@ -35,6 +36,8 @@ namespace Discord
/// <inheritdoc /> /// <inheritdoc />
public string Waveform { get; } public string Waveform { get; }
/// <inheritdoc /> /// <inheritdoc />
public byte[] WaveformBytes { get; }
/// <inheritdoc />
public double? Duration { get; } public double? Duration { get; }
/// <inheritdoc cref="IAttachment.ClipParticipants" /> /// <inheritdoc cref="IAttachment.ClipParticipants" />
@@ -69,6 +72,8 @@ namespace Discord
Title = title; Title = title;
ClipParticipants = clipParticipants; ClipParticipants = clipParticipants;
ClipCreatedAt = clipCreatedAt; ClipCreatedAt = clipCreatedAt;
if (waveform is not null)
WaveformBytes = Convert.FromBase64String(waveform);
} }
internal static Attachment Create(Model model, BaseDiscordClient discord) internal static Attachment Create(Model model, BaseDiscordClient discord)