serenity/model/channel/channel_id.rs
1#[cfg(feature = "model")]
2use std::sync::Arc;
3
4#[cfg(feature = "model")]
5use futures::stream::Stream;
6
7#[cfg(feature = "model")]
8use crate::builder::{
9 Builder,
10 CreateAttachment,
11 CreateForumPost,
12 CreateInvite,
13 CreateMessage,
14 CreateStageInstance,
15 CreateThread,
16 CreateWebhook,
17 EditChannel,
18 EditMessage,
19 EditStageInstance,
20 EditThread,
21 GetMessages,
22};
23#[cfg(all(feature = "cache", feature = "model"))]
24use crate::cache::{Cache, GuildChannelRef};
25#[cfg(feature = "collector")]
26use crate::collector::{MessageCollector, ReactionCollector};
27#[cfg(feature = "collector")]
28use crate::gateway::ShardMessenger;
29#[cfg(feature = "model")]
30use crate::http::{CacheHttp, Http, Typing};
31#[cfg(feature = "model")]
32use crate::json::json;
33use crate::model::prelude::*;
34
35#[cfg(feature = "model")]
36impl ChannelId {
37 /// Broadcasts that the current user is typing to a channel for the next 5 seconds.
38 ///
39 /// After 5 seconds, another request must be made to continue broadcasting that the current
40 /// user is typing.
41 ///
42 /// This should rarely be used for bots, and should likely only be used for signifying that a
43 /// long-running command is still being executed.
44 ///
45 /// **Note**: Requires the [Send Messages] permission.
46 ///
47 /// # Examples
48 ///
49 /// ```rust,no_run
50 /// use serenity::model::id::ChannelId;
51 ///
52 /// # async fn run() {
53 /// # let http: serenity::http::Http = unimplemented!();
54 /// let _successful = ChannelId::new(7).broadcast_typing(&http).await;
55 /// # }
56 /// ```
57 ///
58 /// # Errors
59 ///
60 /// Returns [`Error::Http`] if the current user lacks permission to send messages to this
61 /// channel.
62 ///
63 /// [Send Messages]: Permissions::SEND_MESSAGES
64 #[inline]
65 pub async fn broadcast_typing(self, http: impl AsRef<Http>) -> Result<()> {
66 http.as_ref().broadcast_typing(self).await
67 }
68
69 /// Creates an invite for the given channel.
70 ///
71 /// **Note**: Requires the [Create Instant Invite] permission.
72 ///
73 /// # Errors
74 ///
75 /// If the `cache` is enabled, returns [`ModelError::InvalidPermissions`] if the current user
76 /// lacks permission. Otherwise returns [`Error::Http`], as well as if invalid data is given.
77 ///
78 /// [Create Instant Invite]: Permissions::CREATE_INSTANT_INVITE
79 pub async fn create_invite(
80 self,
81 cache_http: impl CacheHttp,
82 builder: CreateInvite<'_>,
83 ) -> Result<RichInvite> {
84 builder.execute(cache_http, self).await
85 }
86
87 /// Creates a [permission overwrite][`PermissionOverwrite`] for either a single [`Member`] or
88 /// [`Role`] within the channel.
89 ///
90 /// Refer to the documentation for [`GuildChannel::create_permission`] for more information.
91 ///
92 /// Requires the [Manage Channels] permission.
93 ///
94 /// # Errors
95 ///
96 /// Returns [`Error::Http`] if the current user lacks permission, or if an invalid value is
97 /// set.
98 ///
99 /// [Manage Channels]: Permissions::MANAGE_CHANNELS
100 pub async fn create_permission(
101 self,
102 http: impl AsRef<Http>,
103 target: PermissionOverwrite,
104 ) -> Result<()> {
105 let data: PermissionOverwriteData = target.into();
106 http.as_ref().create_permission(self, data.id, &data, None).await
107 }
108
109 /// React to a [`Message`] with a custom [`Emoji`] or unicode character.
110 ///
111 /// [`Message::react`] may be a more suited method of reacting in most cases.
112 ///
113 /// Requires the [Add Reactions] permission, _if_ the current user is the first user to perform
114 /// a react with a certain emoji.
115 ///
116 /// # Errors
117 ///
118 /// Returns [`Error::Http`] if the current user lacks permission.
119 ///
120 /// [Add Reactions]: Permissions::ADD_REACTIONS
121 #[inline]
122 pub async fn create_reaction(
123 self,
124 http: impl AsRef<Http>,
125 message_id: impl Into<MessageId>,
126 reaction_type: impl Into<ReactionType>,
127 ) -> Result<()> {
128 http.as_ref().create_reaction(self, message_id.into(), &reaction_type.into()).await
129 }
130
131 /// Deletes this channel, returning the channel on a successful deletion.
132 ///
133 /// **Note**: Requires the [Manage Channels] permission.
134 ///
135 /// # Errors
136 ///
137 /// Returns [`Error::Http`] if the current user lacks permission.
138 ///
139 /// [Manage Channels]: Permissions::MANAGE_CHANNELS
140 #[inline]
141 pub async fn delete(self, http: impl AsRef<Http>) -> Result<Channel> {
142 http.as_ref().delete_channel(self, None).await
143 }
144
145 /// Deletes a [`Message`] given its Id.
146 ///
147 /// Refer to [`Message::delete`] for more information.
148 ///
149 /// Requires the [Manage Messages] permission, if the current user is not the author of the
150 /// message.
151 ///
152 /// # Errors
153 ///
154 /// Returns [`Error::Http`] if the current user lacks permission to delete the message.
155 ///
156 /// [Manage Messages]: Permissions::MANAGE_MESSAGES
157 #[inline]
158 pub async fn delete_message(
159 self,
160 http: impl AsRef<Http>,
161 message_id: impl Into<MessageId>,
162 ) -> Result<()> {
163 http.as_ref().delete_message(self, message_id.into(), None).await
164 }
165
166 /// Deletes messages by Ids from the given vector in the given channel.
167 ///
168 /// The Discord API supports deleting between 2 and 100 messages at once. This function
169 /// also handles the case of a single message by calling `delete_message` internally.
170 ///
171 /// Requires the [Manage Messages] permission.
172 ///
173 /// **Note**: Messages that are older than 2 weeks can't be deleted using this method.
174 ///
175 /// # Errors
176 ///
177 /// Returns [`ModelError::BulkDeleteAmount`] if an attempt was made to delete 0 or more
178 /// than 100 messages.
179 ///
180 /// Also will return [`Error::Http`] if the current user lacks permission to delete messages.
181 ///
182 /// [Manage Messages]: Permissions::MANAGE_MESSAGES
183 pub async fn delete_messages<T: AsRef<MessageId>>(
184 self,
185 http: impl AsRef<Http>,
186 message_ids: impl IntoIterator<Item = T>,
187 ) -> Result<()> {
188 let ids =
189 message_ids.into_iter().map(|message_id| *message_id.as_ref()).collect::<Vec<_>>();
190
191 let len = ids.len();
192
193 if len == 0 || len > 100 {
194 return Err(Error::Model(ModelError::BulkDeleteAmount));
195 }
196
197 if ids.len() == 1 {
198 self.delete_message(http, ids[0]).await
199 } else {
200 let map = json!({ "messages": ids });
201
202 http.as_ref().delete_messages(self, &map, None).await
203 }
204 }
205
206 /// Deletes all permission overrides in the channel from a member or role.
207 ///
208 /// **Note**: Requires the [Manage Channel] permission.
209 ///
210 /// # Errors
211 ///
212 /// Returns [`Error::Http`] if the current user lacks permission.
213 ///
214 /// [Manage Channel]: Permissions::MANAGE_CHANNELS
215 pub async fn delete_permission(
216 self,
217 http: impl AsRef<Http>,
218 permission_type: PermissionOverwriteType,
219 ) -> Result<()> {
220 let id = match permission_type {
221 PermissionOverwriteType::Member(id) => id.into(),
222 PermissionOverwriteType::Role(id) => id.get().into(),
223 };
224 http.as_ref().delete_permission(self, id, None).await
225 }
226
227 /// Deletes the given [`Reaction`] from the channel.
228 ///
229 /// **Note**: Requires the [Manage Messages] permission, _if_ the current user did not perform
230 /// the reaction.
231 ///
232 /// # Errors
233 ///
234 /// Returns [`Error::Http`] if the current user did not perform the reaction, and lacks
235 /// permission.
236 ///
237 /// [Manage Messages]: Permissions::MANAGE_MESSAGES
238 #[inline]
239 pub async fn delete_reaction(
240 self,
241 http: impl AsRef<Http>,
242 message_id: impl Into<MessageId>,
243 user_id: Option<UserId>,
244 reaction_type: impl Into<ReactionType>,
245 ) -> Result<()> {
246 let http = http.as_ref();
247 let message_id = message_id.into();
248 let reaction_type = reaction_type.into();
249 match user_id {
250 Some(user_id) => http.delete_reaction(self, message_id, user_id, &reaction_type).await,
251 None => http.delete_reaction_me(self, message_id, &reaction_type).await,
252 }
253 }
254 /// Deletes all of the [`Reaction`]s associated with the provided message id.
255 ///
256 /// **Note**: Requires the [Manage Messages] permission.
257 ///
258 /// [Manage Messages]: Permissions::MANAGE_MESSAGES
259 ///
260 /// # Errors
261 ///
262 /// Returns [`Error::Http`] if the current user lacks permission
263 ///
264 /// [Manage Messages]: Permissions::MANAGE_MESSAGES
265 #[inline]
266 pub async fn delete_reactions(
267 self,
268 http: impl AsRef<Http>,
269 message_id: impl Into<MessageId>,
270 ) -> Result<()> {
271 http.as_ref().delete_message_reactions(self, message_id.into()).await
272 }
273
274 /// Deletes all [`Reaction`]s of the given emoji to a message within the channel.
275 ///
276 /// **Note**: Requires the [Manage Messages] permission.
277 ///
278 /// # Errors
279 ///
280 /// Returns [`Error::Http`] if the current user lacks permission.
281 ///
282 /// [Manage Messages]: Permissions::MANAGE_MESSAGES
283 #[inline]
284 pub async fn delete_reaction_emoji(
285 self,
286 http: impl AsRef<Http>,
287 message_id: impl Into<MessageId>,
288 reaction_type: impl Into<ReactionType>,
289 ) -> Result<()> {
290 http.as_ref()
291 .delete_message_reaction_emoji(self, message_id.into(), &reaction_type.into())
292 .await
293 }
294
295 /// Edits a channel's settings.
296 ///
297 /// Refer to the documentation for [`EditChannel`] for a full list of methods.
298 ///
299 /// **Note**: Requires the [Manage Channels] permission. Modifying permissions via
300 /// [`EditChannel::permissions`] also requires the [Manage Roles] permission.
301 ///
302 /// # Examples
303 ///
304 /// Change a voice channel's name and bitrate:
305 ///
306 /// ```rust,no_run
307 /// # use serenity::builder::EditChannel;
308 /// # use serenity::http::Http;
309 /// # use serenity::model::id::ChannelId;
310 /// # async fn run() {
311 /// # let http: Http = unimplemented!();
312 /// # let channel_id = ChannelId::new(1234);
313 /// let builder = EditChannel::new().name("test").bitrate(64000);
314 /// channel_id.edit(&http, builder).await;
315 /// # }
316 /// ```
317 ///
318 /// # Errors
319 ///
320 /// If the `cache` is enabled, returns a [`ModelError::InvalidPermissions`] if the current user
321 /// lacks permission. Otherwise returns [`Error::Http`], as well as if invalid data is given.
322 ///
323 /// [Manage Channels]: Permissions::MANAGE_CHANNELS
324 /// [Manage Roles]: Permissions::MANAGE_ROLES
325 #[inline]
326 pub async fn edit(
327 self,
328 cache_http: impl CacheHttp,
329 builder: EditChannel<'_>,
330 ) -> Result<GuildChannel> {
331 builder.execute(cache_http, self).await
332 }
333
334 /// Edits a [`Message`] in the channel given its Id.
335 ///
336 /// Message editing preserves all unchanged message data, with some exceptions for embeds and
337 /// attachments.
338 ///
339 /// **Note**: In most cases requires that the current user be the author of the message.
340 ///
341 /// Refer to the documentation for [`EditMessage`] for information regarding content
342 /// restrictions and requirements.
343 ///
344 /// # Errors
345 ///
346 /// See [`EditMessage::execute`] for a list of possible errors, and their corresponding
347 /// reasons.
348 #[inline]
349 pub async fn edit_message(
350 self,
351 cache_http: impl CacheHttp,
352 message_id: impl Into<MessageId>,
353 builder: EditMessage,
354 ) -> Result<Message> {
355 builder.execute(cache_http, (self, message_id.into(), None)).await
356 }
357
358 /// Follows the News Channel
359 ///
360 /// Requires [Manage Webhook] permissions on the target channel.
361 ///
362 /// **Note**: Only available on news channels.
363 ///
364 /// # Errors
365 ///
366 /// Returns [`Error::Http`] if the current user lacks permission. [Manage Webhook]:
367 /// Permissions::MANAGE_WEBHOOKS
368 pub async fn follow(
369 self,
370 http: impl AsRef<Http>,
371 target_channel_id: impl Into<ChannelId>,
372 ) -> Result<FollowedChannel> {
373 http.as_ref().follow_news_channel(self, target_channel_id.into()).await
374 }
375
376 /// Attempts to find a [`GuildChannel`] by its Id in the cache.
377 #[cfg(feature = "cache")]
378 #[inline]
379 #[deprecated = "Use Cache::guild and Guild::channels instead"]
380 pub fn to_channel_cached(self, cache: &Cache) -> Option<GuildChannelRef<'_>> {
381 #[allow(deprecated)]
382 cache.channel(self)
383 }
384
385 /// First attempts to retrieve the channel from the `temp_cache` if enabled, otherwise performs
386 /// a HTTP request.
387 ///
388 /// It is recommended to first check if the channel is accessible via `Cache::guild` and
389 /// `Guild::members`, although this requires a `GuildId`.
390 ///
391 /// # Errors
392 ///
393 /// Returns [`Error::Http`] if the channel retrieval request failed.
394 #[inline]
395 pub async fn to_channel(self, cache_http: impl CacheHttp) -> Result<Channel> {
396 #[cfg(feature = "temp_cache")]
397 {
398 if let Some(cache) = cache_http.cache() {
399 if let Some(channel) = cache.temp_channels.get(&self) {
400 return Ok(Channel::Guild(GuildChannel::clone(&*channel)));
401 }
402 }
403 }
404
405 let channel = cache_http.http().get_channel(self).await?;
406
407 #[cfg(all(feature = "cache", feature = "temp_cache"))]
408 {
409 if let Some(cache) = cache_http.cache() {
410 if let Channel::Guild(guild_channel) = &channel {
411 use crate::cache::MaybeOwnedArc;
412
413 let cached_channel = MaybeOwnedArc::new(guild_channel.clone());
414 cache.temp_channels.insert(cached_channel.id, cached_channel);
415 }
416 }
417 }
418
419 Ok(channel)
420 }
421
422 /// Gets all of the channel's invites.
423 ///
424 /// Requires the [Manage Channels] permission.
425 ///
426 /// # Errors
427 ///
428 /// Returns [`Error::Http`] if the current user lacks permission.
429 ///
430 /// [Manage Channels]: Permissions::MANAGE_CHANNELS
431 #[inline]
432 pub async fn invites(self, http: impl AsRef<Http>) -> Result<Vec<RichInvite>> {
433 http.as_ref().get_channel_invites(self).await
434 }
435
436 /// Gets a message from the channel.
437 ///
438 /// If the cache feature is enabled the cache will be checked first. If not found it will
439 /// resort to an http request.
440 ///
441 /// Requires the [Read Message History] permission.
442 ///
443 /// # Errors
444 ///
445 /// Returns [`Error::Http`] if the current user lacks permission.
446 ///
447 /// [Read Message History]: Permissions::READ_MESSAGE_HISTORY
448 #[inline]
449 pub async fn message(
450 self,
451 cache_http: impl CacheHttp,
452 message_id: impl Into<MessageId>,
453 ) -> Result<Message> {
454 let message_id = message_id.into();
455
456 #[cfg(feature = "cache")]
457 if let Some(cache) = cache_http.cache() {
458 if let Some(message) = cache.message(self, message_id) {
459 return Ok(message.clone());
460 }
461 }
462
463 let message = cache_http.http().get_message(self, message_id).await?;
464
465 #[cfg(feature = "temp_cache")]
466 if let Some(cache) = cache_http.cache() {
467 use crate::cache::MaybeOwnedArc;
468
469 let message = MaybeOwnedArc::new(message.clone());
470 cache.temp_messages.insert(message_id, message);
471 }
472
473 Ok(message)
474 }
475
476 /// Gets messages from the channel.
477 ///
478 /// **Note**: If the user does not have the [Read Message History] permission, returns an empty
479 /// [`Vec`].
480 ///
481 /// # Errors
482 ///
483 /// Returns [`Error::Http`] if the current user lacks permission.
484 ///
485 /// [Read Message History]: Permissions::READ_MESSAGE_HISTORY
486 pub async fn messages(
487 self,
488 cache_http: impl CacheHttp,
489 builder: GetMessages,
490 ) -> Result<Vec<Message>> {
491 builder.execute(cache_http, self).await
492 }
493
494 /// Streams over all the messages in a channel.
495 ///
496 /// This is accomplished and equivalent to repeated calls to [`Self::messages`]. A buffer of at
497 /// most 100 messages is used to reduce the number of calls necessary.
498 ///
499 /// The stream returns the newest message first, followed by older messages.
500 ///
501 /// # Examples
502 ///
503 /// ```rust,no_run
504 /// # use serenity::model::id::ChannelId;
505 /// # use serenity::http::Http;
506 /// #
507 /// # async fn run() {
508 /// # let channel_id = ChannelId::new(1);
509 /// # let ctx: Http = unimplemented!();
510 /// use serenity::futures::StreamExt;
511 /// use serenity::model::channel::MessagesIter;
512 ///
513 /// let mut messages = channel_id.messages_iter(&ctx).boxed();
514 /// while let Some(message_result) = messages.next().await {
515 /// match message_result {
516 /// Ok(message) => println!("{} said \"{}\".", message.author.name, message.content,),
517 /// Err(error) => eprintln!("Uh oh! Error: {}", error),
518 /// }
519 /// }
520 /// # }
521 /// ```
522 pub fn messages_iter<H: AsRef<Http>>(self, http: H) -> impl Stream<Item = Result<Message>> {
523 MessagesIter::<H>::stream(http, self)
524 }
525
526 /// Returns the name of whatever channel this id holds.
527 ///
528 /// DM channels don't have a name, so a name is generated according to
529 /// [`PrivateChannel::name()`].
530 ///
531 /// # Errors
532 ///
533 /// Same as [`Self::to_channel()`].
534 pub async fn name(self, cache_http: impl CacheHttp) -> Result<String> {
535 let channel = self.to_channel(cache_http).await?;
536
537 Ok(match channel {
538 Channel::Guild(channel) => channel.name,
539 Channel::Private(channel) => channel.name(),
540 })
541 }
542
543 /// Pins a [`Message`] to the channel.
544 ///
545 /// **Note**: Requires the [Manage Messages] permission.
546 ///
547 /// # Errors
548 ///
549 /// Returns [`Error::Http`] if the current user lacks permission, or if the channel has too
550 /// many pinned messages.
551 ///
552 /// [Manage Messages]: Permissions::MANAGE_MESSAGES
553 #[inline]
554 pub async fn pin(self, http: impl AsRef<Http>, message_id: impl Into<MessageId>) -> Result<()> {
555 http.as_ref().pin_message(self, message_id.into(), None).await
556 }
557
558 /// Crossposts a [`Message`].
559 ///
560 /// Requires either to be the message author or to have manage [Manage Messages] permissions on
561 /// this channel.
562 ///
563 /// **Note**: Only available on news channels.
564 ///
565 /// # Errors
566 ///
567 /// Returns [`Error::Http`] if the current user lacks permission, and if the user is not the
568 /// author of the message.
569 ///
570 /// [Manage Messages]: Permissions::MANAGE_MESSAGES
571 pub async fn crosspost(
572 self,
573 http: impl AsRef<Http>,
574 message_id: impl Into<MessageId>,
575 ) -> Result<Message> {
576 http.as_ref().crosspost_message(self, message_id.into()).await
577 }
578
579 /// Gets the list of [`Message`]s which are pinned to the channel.
580 ///
581 /// **Note**: Returns an empty [`Vec`] if the current user does not have the [Read Message
582 /// History] permission.
583 ///
584 /// # Errors
585 ///
586 /// Returns [`Error::Http`] if the current user lacks permission to view the channel.
587 ///
588 /// [Read Message History]: Permissions::READ_MESSAGE_HISTORY
589 #[inline]
590 pub async fn pins(self, http: impl AsRef<Http>) -> Result<Vec<Message>> {
591 http.as_ref().get_pins(self).await
592 }
593
594 /// Gets the list of [`User`]s who have reacted to a [`Message`] with a certain [`Emoji`].
595 ///
596 /// The default `limit` is `50` - specify otherwise to receive a different maximum number of
597 /// users. The maximum that may be retrieve at a time is `100`, if a greater number is provided
598 /// then it is automatically reduced.
599 ///
600 /// The optional `after` attribute is to retrieve the users after a certain user. This is
601 /// useful for pagination.
602 ///
603 /// **Note**: Requires the [Read Message History] permission.
604 ///
605 /// **Note**: If the passed reaction_type is a custom guild emoji, it must contain the name.
606 /// So, [`Emoji`] or [`EmojiIdentifier`] will always work, [`ReactionType`] only if
607 /// [`ReactionType::Custom::name`] is Some, and **[`EmojiId`] will never work**.
608 ///
609 /// # Errors
610 ///
611 /// Returns [`Error::Http`] if the current user lacks permission to read messages in the
612 /// channel.
613 ///
614 /// [Read Message History]: Permissions::READ_MESSAGE_HISTORY
615 pub async fn reaction_users(
616 self,
617 http: impl AsRef<Http>,
618 message_id: impl Into<MessageId>,
619 reaction_type: impl Into<ReactionType>,
620 limit: Option<u8>,
621 after: impl Into<Option<UserId>>,
622 ) -> Result<Vec<User>> {
623 let limit = limit.map_or(50, |x| if x > 100 { 100 } else { x });
624
625 http.as_ref()
626 .get_reaction_users(
627 self,
628 message_id.into(),
629 &reaction_type.into(),
630 limit,
631 after.into().map(UserId::get),
632 )
633 .await
634 }
635
636 /// Sends a message with just the given message content in the channel.
637 ///
638 /// **Note**: Message content must be under 2000 unicode code points.
639 ///
640 /// # Errors
641 ///
642 /// Returns a [`ModelError::MessageTooLong`] if the content length is over the above limit. See
643 /// [`CreateMessage::execute`] for more details.
644 #[inline]
645 pub async fn say(
646 self,
647 cache_http: impl CacheHttp,
648 content: impl Into<String>,
649 ) -> Result<Message> {
650 let builder = CreateMessage::new().content(content);
651 self.send_message(cache_http, builder).await
652 }
653
654 /// Sends file(s) along with optional message contents. The filename _must_ be specified.
655 ///
656 /// Message contents may be passed using the `builder` argument.
657 ///
658 /// Refer to the documentation for [`CreateMessage`] for information regarding content
659 /// restrictions and requirements.
660 ///
661 /// # Examples
662 ///
663 /// Send files with the paths `/path/to/file.jpg` and `/path/to/file2.jpg`:
664 ///
665 /// ```rust,no_run
666 /// # use serenity::http::Http;
667 /// # use std::sync::Arc;
668 /// #
669 /// # async fn run() -> Result<(), serenity::Error> {
670 /// # let http: Arc<Http> = unimplemented!();
671 /// use serenity::builder::{CreateAttachment, CreateMessage};
672 /// use serenity::model::id::ChannelId;
673 ///
674 /// let channel_id = ChannelId::new(7);
675 ///
676 /// let paths = [
677 /// CreateAttachment::path("/path/to/file.jpg").await?,
678 /// CreateAttachment::path("path/to/file2.jpg").await?,
679 /// ];
680 ///
681 /// let builder = CreateMessage::new().content("some files");
682 /// channel_id.send_files(&http, paths, builder).await?;
683 /// # Ok(()) }
684 /// ```
685 ///
686 /// Send files using [`File`]:
687 ///
688 /// ```rust,no_run
689 /// # use serenity::http::Http;
690 /// # use std::sync::Arc;
691 /// #
692 /// # async fn run() -> Result<(), Box<dyn std::error::Error>> {
693 /// # let http: Arc<Http> = unimplemented!();
694 /// use serenity::builder::{CreateAttachment, CreateMessage};
695 /// use serenity::model::id::ChannelId;
696 /// use tokio::fs::File;
697 ///
698 /// let channel_id = ChannelId::new(7);
699 ///
700 /// let f1 = File::open("my_file.jpg").await?;
701 /// let f2 = File::open("my_file2.jpg").await?;
702 ///
703 /// let files = [
704 /// CreateAttachment::file(&f1, "my_file.jpg").await?,
705 /// CreateAttachment::file(&f2, "my_file2.jpg").await?,
706 /// ];
707 ///
708 /// let builder = CreateMessage::new().content("some files");
709 /// let _ = channel_id.send_files(&http, files, builder).await;
710 /// # Ok(())
711 /// # }
712 /// ```
713 ///
714 /// # Errors
715 ///
716 /// See [`CreateMessage::execute`] for a list of possible errors, and their corresponding
717 /// reasons.
718 ///
719 /// [`File`]: tokio::fs::File
720 pub async fn send_files(
721 self,
722 cache_http: impl CacheHttp,
723 files: impl IntoIterator<Item = CreateAttachment>,
724 builder: CreateMessage,
725 ) -> Result<Message> {
726 self.send_message(cache_http, builder.files(files)).await
727 }
728
729 /// Sends a message to the channel.
730 ///
731 /// Refer to the documentation for [`CreateMessage`] for information regarding content
732 /// restrictions and requirements.
733 ///
734 /// # Errors
735 ///
736 /// See [`CreateMessage::execute`] for a list of possible errors, and their corresponding
737 /// reasons.
738 pub async fn send_message(
739 self,
740 cache_http: impl CacheHttp,
741 builder: CreateMessage,
742 ) -> Result<Message> {
743 builder.execute(cache_http, (self, None)).await
744 }
745
746 /// Starts typing in the channel for an indefinite period of time.
747 ///
748 /// Returns [`Typing`] that is used to trigger the typing. [`Typing::stop`] must be called on
749 /// the returned struct to stop typing. Note that on some clients, typing may persist for a few
750 /// seconds after [`Typing::stop`] is called. Typing is also stopped when the struct is
751 /// dropped.
752 ///
753 /// If a message is sent while typing is triggered, the user will stop typing for a brief
754 /// period of time and then resume again until either [`Typing::stop`] is called or the struct
755 /// is dropped.
756 ///
757 /// This should rarely be used for bots, although it is a good indicator that a long-running
758 /// command is still being processed.
759 ///
760 /// ## Examples
761 ///
762 /// ```rust,no_run
763 /// # use serenity::{http::Http, Result, model::id::ChannelId};
764 /// # use std::sync::Arc;
765 /// #
766 /// # fn long_process() {}
767 /// # fn main() {
768 /// # let http: Arc<Http> = unimplemented!();
769 /// // Initiate typing (assuming http is `Arc<Http>`)
770 /// let typing = ChannelId::new(7).start_typing(&http);
771 ///
772 /// // Run some long-running process
773 /// long_process();
774 ///
775 /// // Stop typing
776 /// typing.stop();
777 /// # }
778 /// ```
779 ///
780 /// # Errors
781 ///
782 /// Returns [`Error::Http`] if the current user lacks permission
783 /// to send messages in this channel.
784 pub fn start_typing(self, http: &Arc<Http>) -> Typing {
785 http.start_typing(self)
786 }
787
788 /// Unpins a [`Message`] in the channel given by its Id.
789 ///
790 /// Requires the [Manage Messages] permission.
791 ///
792 /// # Errors
793 ///
794 /// Returns [`Error::Http`] if the current user lacks permission.
795 ///
796 /// [Manage Messages]: Permissions::MANAGE_MESSAGES
797 #[inline]
798 pub async fn unpin(
799 self,
800 http: impl AsRef<Http>,
801 message_id: impl Into<MessageId>,
802 ) -> Result<()> {
803 http.as_ref().unpin_message(self, message_id.into(), None).await
804 }
805
806 /// Retrieves the channel's webhooks.
807 ///
808 /// **Note**: Requires the [Manage Webhooks] permission.
809 ///
810 /// # Errors
811 ///
812 /// Returns [`Error::Http`] if the current user lacks permission.
813 ///
814 /// [Manage Webhooks]: Permissions::MANAGE_WEBHOOKS
815 #[inline]
816 pub async fn webhooks(self, http: impl AsRef<Http>) -> Result<Vec<Webhook>> {
817 http.as_ref().get_channel_webhooks(self).await
818 }
819
820 /// Creates a webhook in the channel.
821 ///
822 /// # Errors
823 ///
824 /// See [`CreateWebhook::execute`] for a detailed list of possible errors.
825 pub async fn create_webhook(
826 self,
827 cache_http: impl CacheHttp,
828 builder: CreateWebhook<'_>,
829 ) -> Result<Webhook> {
830 builder.execute(cache_http, self).await
831 }
832
833 /// Returns a builder which can be awaited to obtain a message or stream of messages in this
834 /// channel.
835 #[cfg(feature = "collector")]
836 pub fn await_reply(self, shard_messenger: impl AsRef<ShardMessenger>) -> MessageCollector {
837 MessageCollector::new(shard_messenger).channel_id(self)
838 }
839
840 /// Same as [`Self::await_reply`].
841 #[cfg(feature = "collector")]
842 pub fn await_replies(&self, shard_messenger: impl AsRef<ShardMessenger>) -> MessageCollector {
843 self.await_reply(shard_messenger)
844 }
845
846 /// Returns a builder which can be awaited to obtain a reaction or stream of reactions sent in
847 /// this channel.
848 #[cfg(feature = "collector")]
849 pub fn await_reaction(self, shard_messenger: impl AsRef<ShardMessenger>) -> ReactionCollector {
850 ReactionCollector::new(shard_messenger).channel_id(self)
851 }
852
853 /// Same as [`Self::await_reaction`].
854 #[cfg(feature = "collector")]
855 pub fn await_reactions(
856 &self,
857 shard_messenger: impl AsRef<ShardMessenger>,
858 ) -> ReactionCollector {
859 self.await_reaction(shard_messenger)
860 }
861
862 /// Gets a stage instance.
863 ///
864 /// # Errors
865 ///
866 /// Returns [`Error::Http`] if the channel is not a stage channel, or if there is no stage
867 /// instance currently.
868 pub async fn get_stage_instance(self, http: impl AsRef<Http>) -> Result<StageInstance> {
869 http.as_ref().get_stage_instance(self).await
870 }
871
872 /// Creates a stage instance.
873 ///
874 /// # Errors
875 ///
876 /// Returns [`Error::Http`] if there is already a stage instance currently.
877 pub async fn create_stage_instance(
878 self,
879 cache_http: impl CacheHttp,
880 builder: CreateStageInstance<'_>,
881 ) -> Result<StageInstance> {
882 builder.execute(cache_http, self).await
883 }
884
885 /// Edits the stage instance
886 ///
887 /// # Errors
888 ///
889 /// Returns [`ModelError::InvalidChannelType`] if the channel is not a stage channel.
890 ///
891 /// Returns [`Error::Http`] if the channel is not a stage channel, or there is no stage
892 /// instance currently.
893 pub async fn edit_stage_instance(
894 self,
895 cache_http: impl CacheHttp,
896 builder: EditStageInstance<'_>,
897 ) -> Result<StageInstance> {
898 builder.execute(cache_http, self).await
899 }
900
901 /// Edits a thread.
902 ///
903 /// # Errors
904 ///
905 /// Returns [`Error::Http`] if the current user lacks permission.
906 pub async fn edit_thread(
907 self,
908 cache_http: impl CacheHttp,
909 builder: EditThread<'_>,
910 ) -> Result<GuildChannel> {
911 builder.execute(cache_http, self).await
912 }
913
914 /// Deletes a stage instance.
915 ///
916 /// # Errors
917 ///
918 /// Returns [`Error::Http`] if the channel is not a stage channel, or if there is no stage
919 /// instance currently.
920 pub async fn delete_stage_instance(self, http: impl AsRef<Http>) -> Result<()> {
921 http.as_ref().delete_stage_instance(self, None).await
922 }
923
924 /// Creates a public thread that is connected to a message.
925 ///
926 /// # Errors
927 ///
928 /// Returns [`Error::Http`] if the current user lacks permission, or if invalid data is given.
929 #[doc(alias = "create_public_thread")]
930 pub async fn create_thread_from_message(
931 self,
932 cache_http: impl CacheHttp,
933 message_id: impl Into<MessageId>,
934 builder: CreateThread<'_>,
935 ) -> Result<GuildChannel> {
936 builder.execute(cache_http, (self, Some(message_id.into()))).await
937 }
938
939 /// Creates a thread that is not connected to a message.
940 ///
941 /// # Errors
942 ///
943 /// Returns [`Error::Http`] if the current user lacks permission, or if invalid data is given.
944 #[doc(alias = "create_public_thread", alias = "create_private_thread")]
945 pub async fn create_thread(
946 self,
947 cache_http: impl CacheHttp,
948 builder: CreateThread<'_>,
949 ) -> Result<GuildChannel> {
950 builder.execute(cache_http, (self, None)).await
951 }
952
953 /// Creates a post in a forum channel.
954 ///
955 /// # Errors
956 ///
957 /// Returns [`Error::Http`] if the current user lacks permission, or if invalid data is given.
958 pub async fn create_forum_post(
959 self,
960 cache_http: impl CacheHttp,
961 builder: CreateForumPost<'_>,
962 ) -> Result<GuildChannel> {
963 builder.execute(cache_http, self).await
964 }
965
966 /// Gets the thread members, if this channel is a thread.
967 ///
968 /// # Errors
969 ///
970 /// It may return an [`Error::Http`] if the channel is not a thread channel
971 pub async fn get_thread_members(self, http: impl AsRef<Http>) -> Result<Vec<ThreadMember>> {
972 http.as_ref().get_channel_thread_members(self).await
973 }
974
975 /// Joins the thread, if this channel is a thread.
976 ///
977 /// # Errors
978 ///
979 /// It may return an [`Error::Http`] if the channel is not a thread channel
980 pub async fn join_thread(self, http: impl AsRef<Http>) -> Result<()> {
981 http.as_ref().join_thread_channel(self).await
982 }
983
984 /// Leaves the thread, if this channel is a thread.
985 ///
986 /// # Errors
987 ///
988 /// It may return an [`Error::Http`] if the channel is not a thread channel
989 pub async fn leave_thread(self, http: impl AsRef<Http>) -> Result<()> {
990 http.as_ref().leave_thread_channel(self).await
991 }
992
993 /// Adds a thread member, if this channel is a thread.
994 ///
995 /// # Errors
996 ///
997 /// It may return an [`Error::Http`] if the channel is not a thread channel
998 pub async fn add_thread_member(self, http: impl AsRef<Http>, user_id: UserId) -> Result<()> {
999 http.as_ref().add_thread_channel_member(self, user_id).await
1000 }
1001
1002 /// Removes a thread member, if this channel is a thread.
1003 ///
1004 /// # Errors
1005 ///
1006 /// It may return an [`Error::Http`] if the channel is not a thread channel
1007 pub async fn remove_thread_member(self, http: impl AsRef<Http>, user_id: UserId) -> Result<()> {
1008 http.as_ref().remove_thread_channel_member(self, user_id).await
1009 }
1010
1011 /// Gets a thread member, if this channel is a thread.
1012 ///
1013 /// `with_member` controls if ThreadMember::member should be `Some`
1014 ///
1015 /// # Errors
1016 ///
1017 /// It may return an [`Error::Http`] if the channel is not a thread channel
1018 pub async fn get_thread_member(
1019 self,
1020 http: impl AsRef<Http>,
1021 user_id: UserId,
1022 with_member: bool,
1023 ) -> Result<ThreadMember> {
1024 http.as_ref().get_thread_channel_member(self, user_id, with_member).await
1025 }
1026
1027 /// Gets private archived threads of a channel.
1028 ///
1029 /// # Errors
1030 ///
1031 /// It may return an [`Error::Http`] if the bot doesn't have the permission to get it.
1032 pub async fn get_archived_private_threads(
1033 self,
1034 http: impl AsRef<Http>,
1035 before: Option<u64>,
1036 limit: Option<u64>,
1037 ) -> Result<ThreadsData> {
1038 http.as_ref().get_channel_archived_private_threads(self, before, limit).await
1039 }
1040
1041 /// Gets public archived threads of a channel.
1042 ///
1043 /// # Errors
1044 ///
1045 /// It may return an [`Error::Http`] if the bot doesn't have the permission to get it.
1046 pub async fn get_archived_public_threads(
1047 self,
1048 http: impl AsRef<Http>,
1049 before: Option<u64>,
1050 limit: Option<u64>,
1051 ) -> Result<ThreadsData> {
1052 http.as_ref().get_channel_archived_public_threads(self, before, limit).await
1053 }
1054
1055 /// Gets private archived threads joined by the current user of a channel.
1056 ///
1057 /// # Errors
1058 ///
1059 /// It may return an [`Error::Http`] if the bot doesn't have the permission to get it.
1060 pub async fn get_joined_archived_private_threads(
1061 self,
1062 http: impl AsRef<Http>,
1063 before: Option<u64>,
1064 limit: Option<u64>,
1065 ) -> Result<ThreadsData> {
1066 http.as_ref().get_channel_joined_archived_private_threads(self, before, limit).await
1067 }
1068
1069 /// Get a list of users that voted for this specific answer.
1070 ///
1071 /// # Errors
1072 ///
1073 /// If the message does not have a poll.
1074 pub async fn get_poll_answer_voters(
1075 self,
1076 http: impl AsRef<Http>,
1077 message_id: MessageId,
1078 answer_id: AnswerId,
1079 after: Option<UserId>,
1080 limit: Option<u8>,
1081 ) -> Result<Vec<User>> {
1082 http.as_ref().get_poll_answer_voters(self, message_id, answer_id, after, limit).await
1083 }
1084
1085 /// Ends the [`Poll`] on a given [`MessageId`], if there is one.
1086 ///
1087 /// # Errors
1088 ///
1089 /// If the message does not have a poll, or if the poll was not created by the current user.
1090 pub async fn end_poll(self, http: impl AsRef<Http>, message_id: MessageId) -> Result<Message> {
1091 http.as_ref().expire_poll(self, message_id).await
1092 }
1093}
1094
1095#[cfg(feature = "model")]
1096impl From<Channel> for ChannelId {
1097 /// Gets the Id of a [`Channel`].
1098 fn from(channel: Channel) -> ChannelId {
1099 channel.id()
1100 }
1101}
1102
1103#[cfg(feature = "model")]
1104impl From<&Channel> for ChannelId {
1105 /// Gets the Id of a [`Channel`].
1106 fn from(channel: &Channel) -> ChannelId {
1107 channel.id()
1108 }
1109}
1110
1111impl From<PrivateChannel> for ChannelId {
1112 /// Gets the Id of a private channel.
1113 fn from(private_channel: PrivateChannel) -> ChannelId {
1114 private_channel.id
1115 }
1116}
1117
1118impl From<&PrivateChannel> for ChannelId {
1119 /// Gets the Id of a private channel.
1120 fn from(private_channel: &PrivateChannel) -> ChannelId {
1121 private_channel.id
1122 }
1123}
1124
1125impl From<GuildChannel> for ChannelId {
1126 /// Gets the Id of a guild channel.
1127 fn from(public_channel: GuildChannel) -> ChannelId {
1128 public_channel.id
1129 }
1130}
1131
1132impl From<&GuildChannel> for ChannelId {
1133 /// Gets the Id of a guild channel.
1134 fn from(public_channel: &GuildChannel) -> ChannelId {
1135 public_channel.id
1136 }
1137}
1138
1139impl From<WebhookChannel> for ChannelId {
1140 /// Gets the Id of a webhook channel.
1141 fn from(webhook_channel: WebhookChannel) -> ChannelId {
1142 webhook_channel.id
1143 }
1144}
1145
1146impl From<&WebhookChannel> for ChannelId {
1147 /// Gets the Id of a webhook channel.
1148 fn from(webhook_channel: &WebhookChannel) -> ChannelId {
1149 webhook_channel.id
1150 }
1151}
1152
1153/// A helper class returned by [`ChannelId::messages_iter`]
1154#[derive(Clone, Debug)]
1155#[cfg(feature = "model")]
1156pub struct MessagesIter<H: AsRef<Http>> {
1157 http: H,
1158 channel_id: ChannelId,
1159 buffer: Vec<Message>,
1160 before: Option<MessageId>,
1161 tried_fetch: bool,
1162}
1163
1164#[cfg(feature = "model")]
1165impl<H: AsRef<Http>> MessagesIter<H> {
1166 fn new(http: H, channel_id: ChannelId) -> MessagesIter<H> {
1167 MessagesIter {
1168 http,
1169 channel_id,
1170 buffer: Vec::new(),
1171 before: None,
1172 tried_fetch: false,
1173 }
1174 }
1175
1176 /// Fills the `self.buffer` cache with [`Message`]s.
1177 ///
1178 /// This drops any messages that were currently in the buffer. Ideally, it should only be
1179 /// called when `self.buffer` is empty. Additionally, this updates `self.before` so that the
1180 /// next call does not return duplicate items.
1181 ///
1182 /// If there are no more messages to be fetched, then this sets `self.before` as [`None`],
1183 /// indicating that no more calls ought to be made.
1184 ///
1185 /// If this method is called with `self.before` as None, the last 100 (or lower) messages sent
1186 /// in the channel are added in the buffer.
1187 ///
1188 /// The messages are sorted such that the newest message is the first element of the buffer and
1189 /// the newest message is the last.
1190 ///
1191 /// [`Message`]: crate::model::channel::Message
1192 async fn refresh(&mut self) -> Result<()> {
1193 // Number of messages to fetch.
1194 let grab_size = 100;
1195
1196 // If `self.before` is not set yet, we can use `.messages` to fetch the last message after
1197 // very first fetch from last.
1198 let mut builder = GetMessages::new().limit(grab_size);
1199 if let Some(before) = self.before {
1200 builder = builder.before(before);
1201 }
1202 self.buffer = self.channel_id.messages(self.http.as_ref(), builder).await?;
1203
1204 self.buffer.reverse();
1205
1206 self.before = self.buffer.first().map(|m| m.id);
1207
1208 self.tried_fetch = true;
1209
1210 Ok(())
1211 }
1212
1213 /// Streams over all the messages in a channel.
1214 ///
1215 /// This is accomplished and equivalent to repeated calls to [`ChannelId::messages`]. A buffer
1216 /// of at most 100 messages is used to reduce the number of calls necessary.
1217 ///
1218 /// The stream returns the newest message first, followed by older messages.
1219 ///
1220 /// # Examples
1221 ///
1222 /// ```rust,no_run
1223 /// # use serenity::model::id::ChannelId;
1224 /// # use serenity::http::Http;
1225 /// #
1226 /// # async fn run() {
1227 /// # let channel_id = ChannelId::new(1);
1228 /// # let ctx: Http = unimplemented!();
1229 /// use serenity::futures::StreamExt;
1230 /// use serenity::model::channel::MessagesIter;
1231 ///
1232 /// let mut messages = MessagesIter::<Http>::stream(&ctx, channel_id).boxed();
1233 /// while let Some(message_result) = messages.next().await {
1234 /// match message_result {
1235 /// Ok(message) => println!("{} said \"{}\"", message.author.name, message.content,),
1236 /// Err(error) => eprintln!("Uh oh! Error: {}", error),
1237 /// }
1238 /// }
1239 /// # }
1240 /// ```
1241 pub fn stream(
1242 http: impl AsRef<Http>,
1243 channel_id: ChannelId,
1244 ) -> impl Stream<Item = Result<Message>> {
1245 let init_state = MessagesIter::new(http, channel_id);
1246
1247 futures::stream::unfold(init_state, |mut state| async {
1248 if state.buffer.is_empty() && state.before.is_some() || !state.tried_fetch {
1249 if let Err(error) = state.refresh().await {
1250 return Some((Err(error), state));
1251 }
1252 }
1253
1254 // the resultant stream goes from newest to oldest.
1255 state.buffer.pop().map(|entry| (Ok(entry), state))
1256 })
1257 }
1258}