(ifcbrk) feature: news channel publishing (#1530)
* Added PublishAsync to Messages. * Added missing implementation. * 1. Aligned with naming standards 2. Clarified xml docs 3. Properly threw exceptions instead of failing silently. * Additional documentation included. * Removed un-needed comments. Co-authored-by: Matt Smith <v-matsm@microsoft.com>
This commit is contained in:
@@ -57,6 +57,21 @@ namespace Discord
|
|||||||
/// </returns>
|
/// </returns>
|
||||||
Task UnpinAsync(RequestOptions options = null);
|
Task UnpinAsync(RequestOptions options = null);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Publishes (crossposts) this message.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="options">The options to be used when sending the request.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// A task that represents the asynchronous operation for publishing this message.
|
||||||
|
/// </returns>
|
||||||
|
/// <remarks>
|
||||||
|
/// <note type="warning">
|
||||||
|
/// This call will throw an <see cref="InvalidOperationException"/> if attempted in a non-news channel.
|
||||||
|
/// </note>
|
||||||
|
/// This method will publish (crosspost) the message. Please note, publishing (crossposting), is only available in news channels.
|
||||||
|
/// </remarks>
|
||||||
|
Task CrosspostAsync(RequestOptions options = null);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Transforms this message's text into a human-readable form by resolving its tags.
|
/// Transforms this message's text into a human-readable form by resolving its tags.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -695,6 +695,15 @@ namespace Discord.API
|
|||||||
var ids = new BucketIds(channelId: channelId);
|
var ids = new BucketIds(channelId: channelId);
|
||||||
await SendAsync("POST", () => $"channels/{channelId}/typing", ids, options: options).ConfigureAwait(false);
|
await SendAsync("POST", () => $"channels/{channelId}/typing", ids, options: options).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
public async Task CrosspostAsync(ulong channelId, ulong messageId, RequestOptions options = null)
|
||||||
|
{
|
||||||
|
Preconditions.NotEqual(channelId, 0, nameof(channelId));
|
||||||
|
Preconditions.NotEqual(messageId, 0, nameof(messageId));
|
||||||
|
options = RequestOptions.CreateOrClone(options);
|
||||||
|
|
||||||
|
var ids = new BucketIds(channelId: channelId);
|
||||||
|
await SendAsync("POST", () => $"channels/{channelId}/messages/{messageId}/crosspost", ids, options: options).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
//Channel Permissions
|
//Channel Permissions
|
||||||
public async Task ModifyChannelPermissionsAsync(ulong channelId, ulong targetId, ModifyChannelPermissionsParams args, RequestOptions options = null)
|
public async Task ModifyChannelPermissionsAsync(ulong channelId, ulong targetId, ModifyChannelPermissionsParams args, RequestOptions options = null)
|
||||||
|
|||||||
@@ -44,8 +44,10 @@ namespace Discord.Rest
|
|||||||
};
|
};
|
||||||
return await client.ApiClient.ModifyMessageAsync(msg.Channel.Id, msg.Id, apiArgs, options).ConfigureAwait(false);
|
return await client.ApiClient.ModifyMessageAsync(msg.Channel.Id, msg.Id, apiArgs, options).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Task DeleteAsync(IMessage msg, BaseDiscordClient client, RequestOptions options)
|
public static Task DeleteAsync(IMessage msg, BaseDiscordClient client, RequestOptions options)
|
||||||
=> DeleteAsync(msg.Channel.Id, msg.Id, client, options);
|
=> DeleteAsync(msg.Channel.Id, msg.Id, client, options);
|
||||||
|
|
||||||
public static async Task DeleteAsync(ulong channelId, ulong msgId, BaseDiscordClient client,
|
public static async Task DeleteAsync(ulong channelId, ulong msgId, BaseDiscordClient client,
|
||||||
RequestOptions options)
|
RequestOptions options)
|
||||||
{
|
{
|
||||||
@@ -115,6 +117,7 @@ namespace Discord.Rest
|
|||||||
{
|
{
|
||||||
await client.ApiClient.AddPinAsync(msg.Channel.Id, msg.Id, options).ConfigureAwait(false);
|
await client.ApiClient.AddPinAsync(msg.Channel.Id, msg.Id, options).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task UnpinAsync(IMessage msg, BaseDiscordClient client,
|
public static async Task UnpinAsync(IMessage msg, BaseDiscordClient client,
|
||||||
RequestOptions options)
|
RequestOptions options)
|
||||||
{
|
{
|
||||||
@@ -240,6 +243,7 @@ namespace Discord.Rest
|
|||||||
|
|
||||||
return tags.ToImmutable();
|
return tags.ToImmutable();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int? FindIndex(IReadOnlyList<ITag> tags, int index)
|
private static int? FindIndex(IReadOnlyList<ITag> tags, int index)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@@ -253,6 +257,7 @@ namespace Discord.Rest
|
|||||||
return null; //Overlaps tag before this
|
return null; //Overlaps tag before this
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ImmutableArray<ulong> FilterTagsByKey(TagType type, ImmutableArray<ITag> tags)
|
public static ImmutableArray<ulong> FilterTagsByKey(TagType type, ImmutableArray<ITag> tags)
|
||||||
{
|
{
|
||||||
return tags
|
return tags
|
||||||
@@ -260,6 +265,7 @@ namespace Discord.Rest
|
|||||||
.Select(x => x.Key)
|
.Select(x => x.Key)
|
||||||
.ToImmutableArray();
|
.ToImmutableArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ImmutableArray<T> FilterTagsByValue<T>(TagType type, ImmutableArray<ITag> tags)
|
public static ImmutableArray<T> FilterTagsByValue<T>(TagType type, ImmutableArray<ITag> tags)
|
||||||
{
|
{
|
||||||
return tags
|
return tags
|
||||||
@@ -279,5 +285,14 @@ namespace Discord.Rest
|
|||||||
return MessageSource.Bot;
|
return MessageSource.Bot;
|
||||||
return MessageSource.User;
|
return MessageSource.User;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Task CrosspostAsync(IMessage msg, BaseDiscordClient client, RequestOptions options)
|
||||||
|
=> CrosspostAsync(msg.Channel.Id, msg.Id, client, options);
|
||||||
|
|
||||||
|
public static async Task CrosspostAsync(ulong channelId, ulong msgId, BaseDiscordClient client,
|
||||||
|
RequestOptions options)
|
||||||
|
{
|
||||||
|
await client.ApiClient.CrosspostAsync(channelId, msgId, options).ConfigureAwait(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ namespace Discord.Rest
|
|||||||
IReadOnlyCollection<IEmbed> IMessage.Embeds => Embeds;
|
IReadOnlyCollection<IEmbed> IMessage.Embeds => Embeds;
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
IReadOnlyCollection<ulong> IMessage.MentionedUserIds => MentionedUsers.Select(x => x.Id).ToImmutableArray();
|
IReadOnlyCollection<ulong> IMessage.MentionedUserIds => MentionedUsers.Select(x => x.Id).ToImmutableArray();
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public IReadOnlyDictionary<IEmote, ReactionMetadata> Reactions => _reactions.ToDictionary(x => x.Emote, x => new ReactionMetadata { ReactionCount = x.Count, IsMe = x.Me });
|
public IReadOnlyDictionary<IEmote, ReactionMetadata> Reactions => _reactions.ToDictionary(x => x.Emote, x => new ReactionMetadata { ReactionCount = x.Count, IsMe = x.Me });
|
||||||
|
|
||||||
|
|||||||
@@ -148,6 +148,18 @@ namespace Discord.Rest
|
|||||||
TagHandling roleHandling = TagHandling.Name, TagHandling everyoneHandling = TagHandling.Ignore, TagHandling emojiHandling = TagHandling.Name)
|
TagHandling roleHandling = TagHandling.Name, TagHandling everyoneHandling = TagHandling.Ignore, TagHandling emojiHandling = TagHandling.Name)
|
||||||
=> MentionUtils.Resolve(this, 0, userHandling, channelHandling, roleHandling, everyoneHandling, emojiHandling);
|
=> MentionUtils.Resolve(this, 0, userHandling, channelHandling, roleHandling, everyoneHandling, emojiHandling);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
/// <exception cref="InvalidOperationException">This operation may only be called on a <see cref="RestNewsChannel"/> channel.</exception>
|
||||||
|
public async Task CrosspostAsync(RequestOptions options = null)
|
||||||
|
{
|
||||||
|
if (!(Channel is RestNewsChannel))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Publishing (crossposting) is only valid in news channels.");
|
||||||
|
}
|
||||||
|
|
||||||
|
await MessageHelper.CrosspostAsync(this, Discord, options);
|
||||||
|
}
|
||||||
|
|
||||||
private string DebuggerDisplay => $"{Author}: {Content} ({Id}{(Attachments.Count > 0 ? $", {Attachments.Count} Attachments" : "")})";
|
private string DebuggerDisplay => $"{Author}: {Content} ({Id}{(Attachments.Count > 0 ? $", {Attachments.Count} Attachments" : "")})";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ namespace Discord.WebSocket
|
|||||||
model.Content = text;
|
model.Content = text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
/// <exception cref="InvalidOperationException">Only the author of a message may modify the message.</exception>
|
/// <exception cref="InvalidOperationException">Only the author of a message may modify the message.</exception>
|
||||||
/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
|
/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
|
||||||
@@ -147,7 +147,19 @@ namespace Discord.WebSocket
|
|||||||
public string Resolve(TagHandling userHandling = TagHandling.Name, TagHandling channelHandling = TagHandling.Name,
|
public string Resolve(TagHandling userHandling = TagHandling.Name, TagHandling channelHandling = TagHandling.Name,
|
||||||
TagHandling roleHandling = TagHandling.Name, TagHandling everyoneHandling = TagHandling.Ignore, TagHandling emojiHandling = TagHandling.Name)
|
TagHandling roleHandling = TagHandling.Name, TagHandling everyoneHandling = TagHandling.Ignore, TagHandling emojiHandling = TagHandling.Name)
|
||||||
=> MentionUtils.Resolve(this, 0, userHandling, channelHandling, roleHandling, everyoneHandling, emojiHandling);
|
=> MentionUtils.Resolve(this, 0, userHandling, channelHandling, roleHandling, everyoneHandling, emojiHandling);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
/// <exception cref="InvalidOperationException">This operation may only be called on a <see cref="SocketNewsChannel"/> channel.</exception>
|
||||||
|
public async Task CrosspostAsync(RequestOptions options = null)
|
||||||
|
{
|
||||||
|
if (!(Channel is SocketNewsChannel))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Publishing (crossposting) is only valid in news channels.");
|
||||||
|
}
|
||||||
|
|
||||||
|
await MessageHelper.CrosspostAsync(this, Discord, options);
|
||||||
|
}
|
||||||
|
|
||||||
private string DebuggerDisplay => $"{Author}: {Content} ({Id}{(Attachments.Count > 0 ? $", {Attachments.Count} Attachments" : "")})";
|
private string DebuggerDisplay => $"{Author}: {Content} ({Id}{(Attachments.Count > 0 ? $", {Attachments.Count} Attachments" : "")})";
|
||||||
internal new SocketUserMessage Clone() => MemberwiseClone() as SocketUserMessage;
|
internal new SocketUserMessage Clone() => MemberwiseClone() as SocketUserMessage;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user