# Permissions and cooldowns

> Choose who can use a command, where it works, and how often.

There are two ways to limit a command:

- **On the form.** No code. Best for most commands.
- **In code.** For rules the form cannot express, like "only on weekends" or "once per day per server".

## On the form

Switch the command form to **Advanced**, then open **Permissions**.

### Discord permissions

Pick the Discord permissions a member needs, like **Ban Members**. Discord hides the command from members without them.

This works for top-level slash commands only. It is not available in sub commands.

### Roles and channels

| Field | What it does |
|---|---|
| Allowed roles | Only members with one of these roles can use it. |
| Blocked roles | Members with any of these roles cannot use it. |
| Allowed channels | It only works in these channels. |
| Blocked channels | It does not work in these channels. |

Empty means no limit: **Everyone** and **Every channel**.

## In code

Put these at the top of the **Pre-hook**. Each one stops the command with an error when the check fails. You do not need an `if` around them.

### require_permission

```python
require_permission("ban_members")
```

The member needs every permission listed. Administrators always pass. Permission names are lowercase with underscores, like `manage_messages`, `kick_members`, `manage_server`.

### Roles

```python
allowed_roles("Staff", "Moderator")
banned_roles("Muted")
```

`allowed_roles` passes when the member has **any** of the roles. Use names, IDs or mentions.

### Channels

```python
allowed_channels("bot-commands")
banned_channels("general", "announcements")
```

Every check takes `error_message=` for your own text:

```python
allowed_roles("VIP", error_message="This command is for VIP members.")
```

## Cooldowns

A cooldown stops people from running a command too often.

```python
cooldown("30 seconds")
```

The time is plain English: `"10 seconds"`, `"5 minutes"`, `"1 hour"`, `"1 day"`.

### Per user, per server, or shared

By default each user has their own cooldown. Change who shares it with `key=`:

| Code | Who shares the cooldown |
|---|---|
| `cooldown("1 hour")` | Each user on their own |
| `cooldown("1 hour", key=server.id)` | The whole server |
| `cooldown("1 hour", key=channel.id)` | Everyone in one channel |

### Allow a few uses first

`count=` lets someone run it several times before the cooldown starts:

```python
cooldown("1 minute", count=3)
```

### A nice message

`error_message=` can show when the cooldown ends:

```python
cooldown("1 day", error_message="You already claimed today. Come back %relative%.")
```

| Placeholder | Shows |
|---|---|
| `%time%` | How long to wait, like `5 minutes` |
| `%relative%` | A live countdown, like **in 5 minutes** |
| `%at%` | The time it ends, in each reader's own timezone |
| `%timestamp%` | The raw time number, for your own Discord timestamp |

> **Tip:** Put `cooldown(...)` after your other checks. Then someone who fails a role check does not use up their cooldown.

## Checks in your own logic

To decide something without stopping the command, use `has_role` or `has_permission`. They give `True` or `False`:

```python
if has_role(user, "VIP"):
    reward = 200
else:
    reward = 100
```

Full list: [Checks reference](https://ccbot.app/docs/reference/checks).
