Skip to content

Commit 8905a41

Browse files
committed
Add PrivateChannel#retrieveOpenPrivateChannel
For users which want to send DMs to a friend on which an interaction was called
1 parent 90d7e69 commit 8905a41

File tree

3 files changed

+57
-2
lines changed

3 files changed

+57
-2
lines changed

src/main/java/net/dv8tion/jda/api/entities/channel/concrete/PrivateChannel.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,17 @@
2626
/**
2727
* Represents the connection used for direct messaging.
2828
*
29+
* <p>This channel may communicate with different users in interactions triggered by user-installed apps:
30+
* <ul>
31+
* <li>In bot DMs, this channel will send messages to {@link net.dv8tion.jda.api.JDA#getSelfUser() this bot}.</li>
32+
* <li>In friend DMs, this channel will send messages to that friend,
33+
* from the bot itself, this is different from where the interaction was executed.
34+
* <br>Note: As friend DMs are detached channels, you will need to {@linkplain #retrieveOpenPrivateChannel() retrieve an open channel first}.
35+
* </li>
36+
* </ul>
37+
*
2938
* @see User#openPrivateChannel()
39+
* @see #retrieveOpenPrivateChannel()
3040
*/
3141
public interface PrivateChannel extends MessageChannel
3242
{
@@ -40,7 +50,6 @@ public interface PrivateChannel extends MessageChannel
4050
* <li>A message is deleted</li>
4151
* <li>This account sends a message to a user from another shard (not shard 0)</li>
4252
* <li>This account receives an interaction response, happens when using an user-installed interaction</li>
43-
* <li>This channel represents a DM channel between friends, happens when using an user-installed interaction</li>
4453
* </ul>
4554
* The consequence of this is that for any message this bot receives from a guild or from other users, the user will not be null.
4655
*
@@ -64,6 +73,27 @@ public interface PrivateChannel extends MessageChannel
6473
@CheckReturnValue
6574
RestAction<User> retrieveUser();
6675

76+
/**
77+
* Retrieves a {@link PrivateChannel} that is guaranteed to be open.
78+
* <br>For detached {@link PrivateChannel PrivateChannels},
79+
* it essentially transforms this into an attached {@link PrivateChannel}.
80+
*
81+
* <p>This is only useful for interactions started in Friend DMs (with user-installed apps),
82+
* as this will return a valid channel to communicate between your bot and the friend,
83+
* not between the interaction's caller and the friend.
84+
*
85+
* <p><b>Note:</b> Open private channels does not imply you can successfully send messages to the recipient.
86+
*
87+
* @throws net.dv8tion.jda.api.exceptions.DetachedEntityException
88+
* If this channel is detached and {@link #getUser()} returns {@code null},
89+
* this only happens if Discord does not send us the recipient, which should not happen.
90+
*
91+
* @return A {@link RestAction} to retrieve an open {@link PrivateChannel}.
92+
*/
93+
@Nonnull
94+
@CheckReturnValue
95+
RestAction<PrivateChannel> retrieveOpenPrivateChannel();
96+
6797
/**
6898
* The human-readable name of this channel.
6999
*

src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/PrivateChannelImpl.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@
2020
import net.dv8tion.jda.api.entities.User;
2121
import net.dv8tion.jda.api.entities.channel.ChannelType;
2222
import net.dv8tion.jda.api.entities.channel.concrete.PrivateChannel;
23+
import net.dv8tion.jda.api.requests.RestAction;
2324
import net.dv8tion.jda.internal.entities.channel.AbstractChannelImpl;
2425
import net.dv8tion.jda.internal.entities.channel.mixin.concrete.PrivateChannelMixin;
26+
import net.dv8tion.jda.internal.requests.CompletedRestAction;
2527

2628
import javax.annotation.Nonnull;
2729
import javax.annotation.Nullable;
@@ -60,6 +62,13 @@ public User getUser()
6062
return user;
6163
}
6264

65+
@Nonnull
66+
@Override
67+
public RestAction<PrivateChannel> retrieveOpenPrivateChannel()
68+
{
69+
return new CompletedRestAction<>(getJDA(), this);
70+
}
71+
6372
@Override
6473
public long getLatestMessageIdLong()
6574
{

src/main/java/net/dv8tion/jda/internal/entities/channel/concrete/detached/DetachedPrivateChannelImpl.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import net.dv8tion.jda.api.entities.channel.ChannelType;
2222
import net.dv8tion.jda.api.entities.channel.concrete.PrivateChannel;
2323
import net.dv8tion.jda.api.exceptions.DetachedEntityException;
24+
import net.dv8tion.jda.api.requests.RestAction;
2425
import net.dv8tion.jda.internal.entities.channel.AbstractChannelImpl;
2526
import net.dv8tion.jda.internal.entities.channel.mixin.concrete.PrivateChannelMixin;
2627

@@ -44,7 +45,8 @@ public DetachedPrivateChannelImpl(JDA api, long id, @Nullable User user)
4445
@Override
4546
public DetachedEntityException detachedException()
4647
{
47-
return new DetachedEntityException("Cannot perform action in friend DMs");
48+
return new DetachedEntityException("Cannot perform action in friend DMs, as they are not open DMs, " +
49+
"you might want to retrieve one through #retrieveOpenPrivateChannel()");
4850
}
4951

5052
@Override
@@ -67,6 +69,20 @@ public User getUser()
6769
return user;
6870
}
6971

72+
@Nonnull
73+
@Override
74+
public RestAction<PrivateChannel> retrieveOpenPrivateChannel()
75+
{
76+
if (user == null)
77+
{
78+
// This code path only runs if for whatever reason Discord doesn't send us the recipients in the interaction
79+
// as [[InteractionEntityBuilder#createPrivateChannel]] doesn't throw when the recipient is absent
80+
throw detachedException();
81+
}
82+
83+
return user.openPrivateChannel();
84+
}
85+
7086
@Override
7187
public long getLatestMessageIdLong()
7288
{

0 commit comments

Comments
 (0)