英文:
A way to send Direct Message to all Server Members? Java Discord Api
问题
我想编写一个命令,向所有服务器成员发送私信,这可能吗?
我知道如何向消息的作者发送直接消息,但不知道如何向所有服务器成员发送。
英文:
I wanted to script a command to send an Private Message to all Server Members, is that possible?
I know how to send a DM to the Author of the message but not to all Server Members.
答案1
得分: 1
是的,你可以,假设你有目标服务器的 ID,通过它你可以调用你的机器人的 JDA 实例:
jda.getGuildById(<ID>);
或者如果你只有名称,也可以使用以下方法:
jda.getGuildsByName(<NAME>, <CASE_SENSITIVE>)
名称方式会返回一个包含所有匹配名称的列表,但这相当不实用,因为获取 ID 很容易。
你可能已经以其他方式获取了你的 Guild
对象(也许通过监听器?),这不重要。
现在你可以选择调用 guild.getMembers()
或 guild.getMemberCache()
,哪个更合适呢?
guild.getMemberCache()
默认情况下更有效率,最终它实现了 Iterable
接口,所以在你所有的意图和目的中,最好使用 getMemberCache()
,而 getMembers()
的好处是会返回一个列表,这样更容易进行进一步处理。
现在你有了 List<Member>
或 MemberCacheView
,让我们遍历它吧。
最简单的选项是使用 forEach()
方法,或者使用普通的 for each 循环:
for (Member member : guild.getMemberCache())
或者:
guild.getMemberCache().forEach(member -> <DO_SOMETHING>)
(如果你选择使用 guild.getMembers()
,用法完全相同)
现在实际上要发送消息了:
记住我们正在遍历 Member
对象,但 JDA 不允许我们通过它们打开私人聊天通道,所以我们需要:
PrivateChannel channel = member.getUser().openPrivateChannel().complete();
注意,在这里你需要等待同步的 complete()
并正常接收 PrivateChannel
对象,或者你可以在打开 PrivateChannel
时将一个 consumer 传递给队列方法,在通道可用时会立即执行:
Consumer<PrivateChannel> messageSender = channel -> channel.sendMessage("Hey~~!").queue();
user.openPrivateChannel().queue(messageSender);
或者:
user.openPrivateChannel().queue(channel -> channel.sendMessage("Hey~~!").queue());
现在我们有了通道,发送消息很简单:
channel.sendMessage("Hey~~!").queue();
因此,将所有内容组合起来,我们得到:
Guild guild; // 通过监听器或 JDA 池获得的 Guild 对象
for (Member member : guild.getMemberCache()) { // 遍历缓存的成员
User user = member.getUser(); // 将成员对象转换为 User 对象
user.openPrivateChannel().queue(channel ->
channel.sendMessage("Hey~~!").queue()); // 打开通道并发送消息
/* 现在你可以选择关闭通道,以将其从 JDA 的映射中移除 */
channel.close().queue();
}
以上为翻译内容。
英文:
Yes you can, suppose you have your target server's ID, with that you can call on your bot's jda instance
jda.getGuildById(<ID>);
Or if you just have the name, it's also possible with
jda.getGuildsByName(<NAME>, <CASE_SENSITIVE>)
The name one will return a list with all the matching names, this is quite impractical, since getting the ID is so easy.
You might have gotten your Guild
object some other way (Through a listener maybe?), it does not matter.
Now you can either call guild.getMembers()
or guild.getMemberCache()
which one should you choose?
guild.getMemberCache()
is, by default more efficient and in the end it implements the Iterable
interface, so for all your intents and purposes, it should be better to use getMemberCache()
, the benefit of getMembers()
is that you'll get it as a list, making is trivial to do more processing.
Now you have your List<Member>
or MemberCacheView
, let's iterate through it
here the simplest option is the forEach()
method, or just a for each loop:
for (Member member : guild.getMemberCache())
Or:
guild.getMemberCache().forEach(member -> <DO_SOMETHING>)
(If you choose to use guild.getMembers()
it would be exactly the same)
Now to actually send your messages:
Remember we are iterating over Member
objects, but JDA does not allow us to open private channels through that, so we need
PrivateChannel channel = member.getUser().openPrivateChannel().complete();
Note that here you need to either wait for the synchronous complete()
and receive the PrivateChannel
object normally, or you can pass a consumer to the queue method when opening the PrivateChannel
, which will be executed as soon as the channel is available:
Consumer<PrivateChannel> messageSender = channel -> channel.sendMessage("Hey~~!").queue();
user.openPrivateChannel().queue(messageSender);
Or:
user.openPrivateChannel().queue(channel -> channel.sendMessage("Hey~~!").queue());
Now we have the channel and sending a message is simple
channel.sendMessage("Hey~~!").queue();
So putting it all together we get:
Guild guild; //Guild you got from a listener, or from the JDA pool
for(Member member : guild.getMemberCache()) { //Iterating over cached members in the guild
User user = member.getUser(); //Converting the member object to a User
user.openPrivateChannel().queue(channel->
channel.sendMessage("Hey~~!").queue()); //Opening the channel and sending the message
/* Now you can optionally close the channel to remove it from the JDA's mapping */
channel.close().queue();
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论