discord-php / DiscordPHP

An API to interact with the popular messaging app Discord
MIT License
985 stars 236 forks source link

Cannot set channel-specific permissions to Member/Role #1012

Closed php-wizard closed 1 year ago

php-wizard commented 1 year ago

Environment

Describe the bug Channel::setPermissions seems to have no effect on text channels

Additional context

I have a Discord\Parts\Channel instance $channel, and a member instance, which i obtained via

React\Async\await($guild->members->fetch($memberId,true)->then(function ($member) use($channel){
 // mute $member on the channel
});

Now, i am trying to "mute" the member on the channel, where for muting i mean

This is the code i have tried, which fails on text channels (and i haven't tested yet on voice channels)

$result = React\Async\await($guild->members->fetch($memberId,true)->then(function ($member) use($channel){

  if($channel->allowVoice()) $promise = $channel->muteMember($member); // this is a voice channel
  else $promise = $channel->setPermissions($member,[],ChannelPermission::TEXT_PERMISSIONS); // this is a text channel

  return $promise->then(
        function($something){
                    echo "muted";
             return "Muted";
        },
        function($rejectReason){
                echo "rejected";
            return "Could not mute specified user: " . $rejectReason->getMessage();                         
        });

});

When trying the above for a text channel, "muted" gets printed out like it succeeded, but actually it had no effect. I may have passed wrong values to $channel->setPermissions().

Now, the declaration of Channel::setPermission() is

public function setPermissions(Part $part, array $allow = [], array $deny = [], ?string $reason = null): ExtendedPromiseInterface

The first param can be a Role or a Member, the second one seems to be the permissions i want to "unlock" (allow), and in this case no one, and the third param seems to be the permissions i want to deny. I have passed ChannelPermission::TEXT_PERMISSIONS , which is defined in Discord\Parts\Permissions\Permission (parent of ChannelPermissions) as:

/**
     * Array of permissions that only apply to text channels.
     * i.e. indicated T in documentation.
     *
     * @var array
     */
    public const TEXT_PERMISSIONS = [
        'add_reactions' => 6,
        'send_messages' => 11,
        'send_tts_messages' => 12,
        'manage_messages' => 13,
        'embed_links' => 14,
        'attach_files' => 15,
        'read_message_history' => 16,
        'use_external_emojis' => 18,
        'manage_webhooks' => 29,
        'use_application_commands' => 31,
        'manage_threads' => 34,
        'create_public_threads' => 35,
        'create_private_threads' => 36,
        'use_external_stickers' => 37,
        'send_messages_in_threads' => 38,
    ];

So, send_messages is in the permissions i am denying, but it has no effect. I cannot figure out what's wrong, and whether it was correct to pass that ChannelPermission::TEXT_PERMISSIONS to the third param (or anything else i am missing). Anyone can help me? Thank you

SQKo commented 1 year ago

The library does not support use of react/async in v7.x, The support was added in v10.x only

Also you are not supposed to use the permission constants directly like ChannelPermission::TEXT_PERMISSIONS (they are just the bit position, not the value), you need to create the ChannelPermission object first then set the $channel_permission->text_permission_here = false, Or Use the simple 'allow' 'deny' associative array as shown in the documentation: https://discord-php.github.io/DiscordPHP/ in the section of "Set permissions of a member or role"

// Member can send messages and attach files,
// but can't add reactions to message.
$channel->setPermissions($member, [
    'send_messages',
    'attach_files',
], [
    'add_reactions',
])->done(function () {
    // ...
});

or:

$allow = new ChannelPermission($discord, [
    'send_messages' => true,
    'attach_files' => true,
]);

$deny = new ChannelPermission($discord, [
    'add_reactions' => true,
]);

$overwrite = $channel->overwrites->create([
    'allow' => $allow,
    'deny' => $deny,
]);

// Member can send messages and attach files,
// but can't add reactions to message.
$channel->setOverwrite($member, $overwrite)->done(function () {
    // ...
});