Skip to content

Commit

Permalink
[Feature] Support sending voice messages (#3024)
Browse files Browse the repository at this point in the history
* yup

* a
  • Loading branch information
Misha-133 authored Nov 11, 2024
1 parent 8b92969 commit 5904ecd
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 5 deletions.
18 changes: 16 additions & 2 deletions src/Discord.Net.Core/Entities/Messages/FileAttachment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@ public struct FileAttachment : IDisposable
/// </summary>
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
/// <summary>
/// Gets the stream containing the file content.
Expand All @@ -44,7 +54,7 @@ public struct FileAttachment : IDisposable
/// <param name="description">The description of the attachment.</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>
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;
Expand All @@ -57,6 +67,8 @@ public FileAttachment(Stream stream, string fileName, string description = null,
}
catch { }
IsSpoiler = isSpoiler;
DurationSeconds = durationSeconds;
Waveform = waveform;
}

/// <summary>
Expand Down Expand Up @@ -91,14 +103,16 @@ public FileAttachment(Stream stream, string fileName, string description = null,
/// <exception cref="FileNotFoundException">The file specified in <paramref name="path" /> was not found.
/// </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;
Stream = File.OpenRead(path);
FileName = fileName ?? Path.GetFileName(path);
Description = description;
IsSpoiler = isSpoiler;
IsThumbnail = isThumbnail;
DurationSeconds = durationSeconds;
Waveform = waveform;
}

public void Dispose()
Expand Down
5 changes: 5 additions & 0 deletions src/Discord.Net.Core/Entities/Messages/IAttachment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ public interface IAttachment : ISnowflakeEntity
/// </summary>
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>
/// Gets flags related to this to this attachment.
/// </summary>
Expand Down
10 changes: 9 additions & 1 deletion src/Discord.Net.Rest/API/Rest/UploadFileParams.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -34,6 +35,9 @@ public IReadOnlyDictionary<string, object> ToDictionary()
{
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>();
if (Content.IsSpecified)
payload["content"] = Content.Value;
Expand Down Expand Up @@ -71,7 +75,11 @@ public IReadOnlyDictionary<string, object> ToDictionary()
{
id = (ulong)n,
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)
});
}

Expand Down
8 changes: 7 additions & 1 deletion src/Discord.Net.Rest/API/Rest/UploadInteractionFileParams.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ public IReadOnlyDictionary<string, object> ToDictionary()
{
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>();
payload["type"] = Type;
Expand Down Expand Up @@ -79,7 +81,11 @@ public IReadOnlyDictionary<string, object> ToDictionary()
{
id = (ulong)n,
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)
});
}

Expand Down
11 changes: 10 additions & 1 deletion src/Discord.Net.Rest/API/Rest/UploadWebhookFileParams.cs
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -35,6 +37,9 @@ public IReadOnlyDictionary<string, object> ToDictionary()
{
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>();
if (Content.IsSpecified)
payload["content"] = Content.Value;
Expand Down Expand Up @@ -76,7 +81,11 @@ public IReadOnlyDictionary<string, object> ToDictionary()
{
id = (ulong)n,
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)
});
}

Expand Down
5 changes: 5 additions & 0 deletions src/Discord.Net.Rest/Entities/Messages/Attachment.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Discord.Rest;
using System;
using System.Buffers.Text;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
Expand Down Expand Up @@ -35,6 +36,8 @@ public class Attachment : IAttachment
/// <inheritdoc />
public string Waveform { get; }
/// <inheritdoc />
public byte[] WaveformBytes { get; }
/// <inheritdoc />
public double? Duration { get; }

/// <inheritdoc cref="IAttachment.ClipParticipants" />
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 5904ecd

Please sign in to comment.