You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

RestTextChannel.cs 13 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Threading.Tasks;
  7. using Model = Discord.API.Channel;
  8. namespace Discord.Rest
  9. {
  10. /// <summary>
  11. /// Represents a REST-based channel in a guild that can send and receive messages.
  12. /// </summary>
  13. [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
  14. public class RestTextChannel : RestGuildChannel, IRestMessageChannel, ITextChannel
  15. {
  16. /// <inheritdoc />
  17. public string Topic { get; private set; }
  18. /// <inheritdoc />
  19. public ulong? CategoryId { get; private set; }
  20. /// <inheritdoc />
  21. public string Mention => MentionUtils.MentionChannel(Id);
  22. /// <inheritdoc />
  23. public bool IsNsfw { get; private set; }
  24. internal RestTextChannel(BaseDiscordClient discord, IGuild guild, ulong id)
  25. : base(discord, guild, id)
  26. {
  27. }
  28. internal new static RestTextChannel Create(BaseDiscordClient discord, IGuild guild, Model model)
  29. {
  30. var entity = new RestTextChannel(discord, guild, model.Id);
  31. entity.Update(model);
  32. return entity;
  33. }
  34. internal override void Update(Model model)
  35. {
  36. base.Update(model);
  37. CategoryId = model.CategoryId;
  38. Topic = model.Topic.Value;
  39. IsNsfw = model.Nsfw.GetValueOrDefault();
  40. }
  41. /// <inheritdoc />
  42. public async Task ModifyAsync(Action<TextChannelProperties> func, RequestOptions options = null)
  43. {
  44. var model = await ChannelHelper.ModifyAsync(this, Discord, func, options).ConfigureAwait(false);
  45. Update(model);
  46. }
  47. public Task<RestGuildUser> GetUserAsync(ulong id, RequestOptions options = null)
  48. => ChannelHelper.GetUserAsync(this, Guild, Discord, id, options);
  49. public IAsyncEnumerable<IReadOnlyCollection<RestGuildUser>> GetUsersAsync(RequestOptions options = null)
  50. => ChannelHelper.GetUsersAsync(this, Guild, Discord, null, null, options);
  51. /// <inheritdoc />
  52. public Task<RestMessage> GetMessageAsync(ulong id, RequestOptions options = null)
  53. => ChannelHelper.GetMessageAsync(this, Discord, id, options);
  54. /// <inheritdoc />
  55. public IAsyncEnumerable<IReadOnlyCollection<RestMessage>> GetMessagesAsync(int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null)
  56. => ChannelHelper.GetMessagesAsync(this, Discord, null, Direction.Before, limit, options);
  57. /// <inheritdoc />
  58. public IAsyncEnumerable<IReadOnlyCollection<RestMessage>> GetMessagesAsync(ulong fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null)
  59. => ChannelHelper.GetMessagesAsync(this, Discord, fromMessageId, dir, limit, options);
  60. /// <inheritdoc />
  61. public IAsyncEnumerable<IReadOnlyCollection<RestMessage>> GetMessagesAsync(IMessage fromMessage, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null)
  62. => ChannelHelper.GetMessagesAsync(this, Discord, fromMessage.Id, dir, limit, options);
  63. /// <inheritdoc />
  64. public Task<IReadOnlyCollection<RestMessage>> GetPinnedMessagesAsync(RequestOptions options = null)
  65. => ChannelHelper.GetPinnedMessagesAsync(this, Discord, options);
  66. /// <inheritdoc />
  67. /// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
  68. public Task<RestUserMessage> SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null)
  69. => ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, options);
  70. /// <inheritdoc />
  71. /// <exception cref="ArgumentException">
  72. /// <paramref name="filePath" /> is a zero-length string, contains only white space, or contains one or more
  73. /// invalid characters as defined by <see cref="System.IO.Path.GetInvalidPathChars"/>.
  74. /// </exception>
  75. /// <exception cref="ArgumentNullException">
  76. /// <paramref name="filePath" /> is <c>null</c>.
  77. /// </exception>
  78. /// <exception cref="PathTooLongException">
  79. /// The specified path, file name, or both exceed the system-defined maximum length. For example, on
  80. /// Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260
  81. /// characters.
  82. /// </exception>
  83. /// <exception cref="DirectoryNotFoundException">
  84. /// The specified path is invalid, (for example, it is on an unmapped drive).
  85. /// </exception>
  86. /// <exception cref="UnauthorizedAccessException">
  87. /// <paramref name="filePath" /> specified a directory.-or- The caller does not have the required permission.
  88. /// </exception>
  89. /// <exception cref="FileNotFoundException">
  90. /// The file specified in <paramref name="filePath" /> was not found.
  91. /// </exception>
  92. /// <exception cref="NotSupportedException"><paramref name="filePath" /> is in an invalid format.</exception>
  93. /// <exception cref="IOException">An I/O error occurred while opening the file.</exception>
  94. /// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
  95. public Task<RestUserMessage> SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null)
  96. => ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, options);
  97. /// <inheritdoc />
  98. /// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
  99. public Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null)
  100. => ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, options);
  101. /// <inheritdoc />
  102. public Task DeleteMessageAsync(ulong messageId, RequestOptions options = null)
  103. => ChannelHelper.DeleteMessageAsync(this, messageId, Discord, options);
  104. /// <inheritdoc />
  105. public Task DeleteMessageAsync(IMessage message, RequestOptions options = null)
  106. => ChannelHelper.DeleteMessageAsync(this, message.Id, Discord, options);
  107. /// <inheritdoc />
  108. public Task DeleteMessagesAsync(IEnumerable<IMessage> messages, RequestOptions options = null)
  109. => ChannelHelper.DeleteMessagesAsync(this, Discord, messages.Select(x => x.Id), options);
  110. /// <inheritdoc />
  111. public Task DeleteMessagesAsync(IEnumerable<ulong> messageIds, RequestOptions options = null)
  112. => ChannelHelper.DeleteMessagesAsync(this, Discord, messageIds, options);
  113. /// <inheritdoc />
  114. public Task TriggerTypingAsync(RequestOptions options = null)
  115. => ChannelHelper.TriggerTypingAsync(this, Discord, options);
  116. /// <inheritdoc />
  117. public IDisposable EnterTypingState(RequestOptions options = null)
  118. => ChannelHelper.EnterTypingState(this, Discord, options);
  119. public Task<RestWebhook> CreateWebhookAsync(string name, Stream avatar = null, RequestOptions options = null)
  120. => ChannelHelper.CreateWebhookAsync(this, Discord, name, avatar, options);
  121. public Task<RestWebhook> GetWebhookAsync(ulong id, RequestOptions options = null)
  122. => ChannelHelper.GetWebhookAsync(this, Discord, id, options);
  123. public Task<IReadOnlyCollection<RestWebhook>> GetWebhooksAsync(RequestOptions options = null)
  124. => ChannelHelper.GetWebhooksAsync(this, Discord, options);
  125. public Task<ICategoryChannel> GetCategoryAsync(RequestOptions options = null)
  126. => ChannelHelper.GetCategoryAsync(this, Discord, options);
  127. private string DebuggerDisplay => $"{Name} ({Id}, Text)";
  128. //ITextChannel
  129. /// <inheritdoc />
  130. async Task<IWebhook> ITextChannel.CreateWebhookAsync(string name, Stream avatar, RequestOptions options)
  131. => await CreateWebhookAsync(name, avatar, options).ConfigureAwait(false);
  132. /// <inheritdoc />
  133. async Task<IWebhook> ITextChannel.GetWebhookAsync(ulong id, RequestOptions options)
  134. => await GetWebhookAsync(id, options).ConfigureAwait(false);
  135. /// <inheritdoc />
  136. async Task<IReadOnlyCollection<IWebhook>> ITextChannel.GetWebhooksAsync(RequestOptions options)
  137. => await GetWebhooksAsync(options).ConfigureAwait(false);
  138. //IMessageChannel
  139. /// <inheritdoc />
  140. async Task<IMessage> IMessageChannel.GetMessageAsync(ulong id, CacheMode mode, RequestOptions options)
  141. {
  142. if (mode == CacheMode.AllowDownload)
  143. return await GetMessageAsync(id, options).ConfigureAwait(false);
  144. else
  145. return null;
  146. }
  147. /// <inheritdoc />
  148. IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(int limit, CacheMode mode, RequestOptions options)
  149. {
  150. if (mode == CacheMode.AllowDownload)
  151. return GetMessagesAsync(limit, options);
  152. else
  153. return AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>();
  154. }
  155. /// <inheritdoc />
  156. IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(ulong fromMessageId, Direction dir, int limit, CacheMode mode, RequestOptions options)
  157. {
  158. if (mode == CacheMode.AllowDownload)
  159. return GetMessagesAsync(fromMessageId, dir, limit, options);
  160. else
  161. return AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>();
  162. }
  163. /// <inheritdoc />
  164. IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(IMessage fromMessage, Direction dir, int limit, CacheMode mode, RequestOptions options)
  165. {
  166. if (mode == CacheMode.AllowDownload)
  167. return GetMessagesAsync(fromMessage, dir, limit, options);
  168. else
  169. return AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>();
  170. }
  171. /// <inheritdoc />
  172. async Task<IReadOnlyCollection<IMessage>> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options)
  173. => await GetPinnedMessagesAsync(options).ConfigureAwait(false);
  174. /// <inheritdoc />
  175. async Task<IUserMessage> IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options)
  176. => await SendFileAsync(filePath, text, isTTS, embed, options).ConfigureAwait(false);
  177. /// <inheritdoc />
  178. async Task<IUserMessage> IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options)
  179. => await SendFileAsync(stream, filename, text, isTTS, embed, options).ConfigureAwait(false);
  180. /// <inheritdoc />
  181. async Task<IUserMessage> IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options)
  182. => await SendMessageAsync(text, isTTS, embed, options).ConfigureAwait(false);
  183. //IGuildChannel
  184. /// <inheritdoc />
  185. async Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
  186. {
  187. if (mode == CacheMode.AllowDownload)
  188. return await GetUserAsync(id, options).ConfigureAwait(false);
  189. else
  190. return null;
  191. }
  192. /// <inheritdoc />
  193. IAsyncEnumerable<IReadOnlyCollection<IGuildUser>> IGuildChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
  194. {
  195. if (mode == CacheMode.AllowDownload)
  196. return GetUsersAsync(options);
  197. else
  198. return AsyncEnumerable.Empty<IReadOnlyCollection<IGuildUser>>();
  199. }
  200. //IChannel
  201. /// <inheritdoc />
  202. async Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
  203. {
  204. if (mode == CacheMode.AllowDownload)
  205. return await GetUserAsync(id, options).ConfigureAwait(false);
  206. else
  207. return null;
  208. }
  209. /// <inheritdoc />
  210. IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
  211. {
  212. if (mode == CacheMode.AllowDownload)
  213. return GetUsersAsync(options);
  214. else
  215. return AsyncEnumerable.Empty<IReadOnlyCollection<IGuildUser>>();
  216. }
  217. // INestedChannel
  218. /// <inheritdoc />
  219. async Task<ICategoryChannel> INestedChannel.GetCategoryAsync(CacheMode mode, RequestOptions options)
  220. {
  221. if (CategoryId.HasValue && mode == CacheMode.AllowDownload)
  222. return (await Guild.GetChannelAsync(CategoryId.Value, mode, options).ConfigureAwait(false)) as ICategoryChannel;
  223. return null;
  224. }
  225. }
  226. }