# Events (Events)

KaMenu supports executing a predefined list of actions at specific moments in the menu, through `Events` key configuration. The event system allows you to run specific logic at key moments such as when the menu opens or closes.

***

## Supported events

| Event name | Trigger timing                  | Supported variables                                               |
| ---------- | ------------------------------- | ----------------------------------------------------------------- |
| `Open`     | Before the menu opens           | `{data:*}`, `{gdata:*}`, `{meta:*}`, `%papi_var%`                 |
| `Close`    | After the menu closes           | `{data:*}`, `{gdata:*}`, `{meta:*}`, `%papi_var%`, `$(input_key)` |
| `Click`    | List of actions to be triggered | `{data:*}`, `{gdata:*}`, `{meta:*}`, `%papi_var%`                 |

**Important note:**

* `Open` The event is triggered before the menu opens, so**not supported** `$(input_key)` input variables (because the input box is not yet shown)
* `Close` The event is triggered after the menu closes and supports all variable formats, including `$(input_key)`

***

## Basic syntax

### Simple event (execute unconditionally)

```yaml
Events:
  Open:
    - 'tell: &aWelcome to this server!'
    - 'sound: entity.player.levelup'
```

### Conditional event (execute conditionally)

```yaml
Events:
  Open:
    - condition: "condition expression"  # optional
      allow:
        - 'action 1 executed when the condition is met'
        - 'action 2 executed when the condition is met'
      deny:
        - 'action 1 executed when the condition is not met'
        - 'action 2 executed when the condition is not met'
```

***

## How to call the list of actions to be triggered

**First configure the action list**

```yaml
Events:
  Click:
    hello:
      - 'tell: &aHello! Welcome to the server.'
      - 'tell: &aHave a great time here!'
```

**Use `actions` action activation:**

```yaml
Bottom:
  type: 'notice'
  confirm:
    text: '&a[ Confirm ]'
    actions:
      - 'actions: hello'  # Executes the `hello` list of actions configured above
```

**Use `Clickable text` activation:**

```yaml
Body:
  text:
    type: 'message'
    text: 'Please <text="click to greet";actions=hello;hover=Click to execute hello action> to see the welcome message'
```

```yaml
Bottom:
  type: 'notice'
  confirm:
    text: '&a[ Confirm ]'
    actions:
      - 'hovertext: Please <text="[click to greet]";actions=hello;hover=Click to execute hello action> to see the welcome message'  
```

***

## Special actions

### Return action

In the event action list, you can use `return` action to interrupt the execution of subsequent actions:

```yaml
Events:
  Open:
    - condition: 'hasPerm.kamenu.admin'
      allow:
        - 'tell: &aWelcome, admin!'
      deny:
        - 'tell: &cYou do not have permission!'
        - 'return'  # Interrupt subsequent actions
        - 'tell: You will never see this message'
```

**Notes:**

* `Open` In the event, `return` will**prevent the menu from opening**
* `Close` In the event, `return` it only interrupts the remaining actions (because the menu has already closed)
* `return` In the conditional branches `allow` and `deny` both branches are effective

***

## Use cases

### 1. Permission check

**Unconditional check:**

```yaml
Events:
  Open:
    - 'tell: &aWelcome to this server!'
    - 'sound: entity.player.levelup'
```

**Conditional check:**

```yaml
Events:
  Open:
    - condition: '%player_is_op% == true'
      allow:
        - 'tell: &aYou have opened the admin menu'
      deny:
        - 'tell: &cYou do not have permission to open this menu'
        - 'return'  # Non-OP players won't see the menu
```

### 2. Compound condition check

```yaml
Events:
  Open:
    - condition: '%player_level% >= 10 && %player_health% >= 15'
      allow:
        - 'tell: &aCondition met: level>=10 and health>=15'
        - 'title: title=&6Welcome;subtitle=&fVIP player;in=5;keep=40;out=10'
      deny:
        - 'tell: &7Requirements not met: level>=10 and health>=15 required'
```

### 3. Data initialization

**First visit detection:**

```yaml
Events:
  Open:
    - condition: '{data:first_visit} == null'
      allow:
        - 'tell: &eWelcome on your first visit! Data initialized'
        - 'set-data: first_visit %timestamp%'
        - 'set-data: visit_count 1'
        - 'title: title=&6Welcome newcomer;subtitle=&fThis is your first visit;in=10;keep=60;out=20'
      deny:
        - 'tell: &7Welcome back! This is your {data:visit_count} visit'
        - 'set-data: visit_count {data:visit_count} + 1'
```

### 4. Status check

```yaml
Events:
  Open:
    - condition: '{meta:temp_banned} == true'
      allow:
        - 'tell: &cYou have been temporarily banned and cannot access this menu'
        - 'return'
    - condition: '%player_health% <= 5'
      allow:
        - 'tell: &eYour health is very low, please be careful'
```

### 5. Greeting system

```yaml
Events:
  Open:
    - condition: '%player_health% >= 20'
      allow:
        - 'tell: &aYour health is very good!'
      deny:
        - 'tell: &7You need to pay attention to your health'
    - condition: '%player_level% >= 30'
      allow:
        - 'tell: &6You have reached level 30!'
```

### 6. Close event handling

```yaml
Events:
  Close:
    - 'tell: &aThanks for using this menu'
    - 'set-meta: last_visit %timestamp%'
    - 'set-data: total_visits {data:total_visits} + 1'
    - 'sound: entity.experience_orb.pickup'
```

***

## Complete example

### Example 1: Permission control for the admin menu

```yaml
Title: '&8» &4&lAdmin Panel &8«'

Settings:
  can_escape: false

Events:
  Open:
    - condition: 'hasPerm.kamenu.admin'
      allow:
        - 'tell: &aWelcome to the admin panel'
      deny:
        - 'tell: &cYou do not have permission to access this menu!'
        - 'sound: block.note_block.bass'
        - 'return'

Body:
  welcome:
    type: 'message'
    text: '&7Admin control panel - please operate with caution'

Bottom:
  type: 'notice'
  confirm:
    text: '&c[ Close ]'
    actions:
      - 'close'
```

### Example 2: Welcome system for the shop menu

```yaml
Title: '&8» &6&lServer Shop &8«'

Settings:
  after_action: CLOSE

Events:
  Open:
    # First visit detection
    - condition: '{data:shop_first_visit} == null'
      allow:
        - 'tell: &aWelcome to the server shop! This is your first visit'
        - 'set-data: shop_first_visit true'
        - 'title: title=&6Welcome;subtitle=&fFirst visit reward has been issued;in=5;keep=60;out=20'
      deny:
        - 'tell: &7Welcome back! Continue shopping'
    
    # VIP player welcome
    - condition: 'hasPerm.vip.gold'
      allow:
        - 'tell: &6Honored Gold Card member, welcome!'
    
    # Display balance
    - 'tell: &fCurrent balance: &e%player_balance%'

Body:
  welcome:
    type: 'message'
    text: '&7Please choose the item you need'

Bottom:
  type: 'notice'
  confirm:
    text: '&a[ Browse Items ]'
    actions:
      - 'tell: &aBrowsing items...'
```

### Example 3: Survey menu with data tracking

```yaml
Title: '&8» &b&lPlayer Survey &8«'

Settings:
  can_escape: false
  after_action: WAIT_FOR_RESPONSE

Events:
  Open:
    # Check whether it has already been filled out
    - condition: '{data:questionnaire_completed} == true'
      allow:
        - 'tell: &aYou have already completed the survey, thanks for participating!'
        - 'return'
    
    - 'tell: &ePlease fill out the survey below'
  
  Close:
    # Mark completion time
    - 'set-data: questionnaire_completed true'
    - 'set-data: questionnaire_date %timestamp%'
    - 'tell: &aThank you for completing the survey!'
    - 'title: title=&aCompleted;subtitle=&fThank you for your participation;in=5;keep=40;out=10'

Inputs:
  rating:
    type: 'slider'
    text: 'Server rating (1-10)'
    min: 1
    max: 10
    default: 5
  
  feedback:
    type: 'input'
    text: 'Comments or suggestions'
    multiline:
      max_lines: 5
      height: 100
    max_length: 500

Bottom:
  type: 'confirmation'
  confirm:
    text: '&a[ Submit ]'
    actions:
      - 'tell: &aSubmitted successfully!'
      - 'close'
  deny:
    text: '&c[ Cancel ]'
    actions:
      - 'tell: &cSubmission canceled'
      - 'close'
```

### Example 4: Menu with multi-condition checks

```yaml
Title: '&8» &5&lVIP Exclusive Features &8«'

Settings:
  can_escape: false

Events:
  Open:
    # Multiple checks
    - condition: '%player_level% < 30'
      allow:
        - 'tell: &cYour level is below 30'
        - 'return'
    
    - condition: '!hasPerm.vip.basic'
      allow:
        - 'tell: &cYou need VIP permission to access this menu'
        - 'return'
    
    - condition: '%player_health% < 10'
      allow:
        - 'tell: &eYour health is low, please be careful'
    
    # Passed all checks
    - 'tell: &aWelcome to VIP exclusive features'
    - 'sound: entity.player.levelup'

Body:
  welcome:
    type: 'message'
    text: '&6VIP exclusive feature area'

Bottom:
  type: 'notice'
  confirm:
    text: '&a[ Confirm ]'
    actions:
      - 'tell: &aStarting to use VIP features'
```

***

## Notes

1. **Execution order**
   * `Open` Events are executed before the menu is parsed
   * `Close` Events are executed after the menu closes
   * Event action lists are executed in order
2. **Scope of Return**
   * `Open` The event's `return` will prevent the entire menu from opening
   * `Close` The event's `return` only interrupts the remaining actions
   * `return` effective for nested conditional checks
3. **Variable restrictions**
   * `Open` The event does not support `$(input_key)`(input box not shown)
   * `Close` The event supports all variable formats
   * Conditional checks support all built-in methods and operators
4. **Performance considerations**
   * Avoid performing large time-consuming operations in events
   * Use `return` Interrupt unneeded logic in time
   * For complex conditional checks, it is recommended to use parentheses to clarify precedence
5. **Error handling**
   * If a conditional check fails, it will not prevent the menu from opening (unless you use `return`)
   * Action execution failures do not affect subsequent actions
   * It is recommended to use `tell` actions to provide feedback information

***

## Related documentation

* [🔍 Conditional checks](/plugins/kamenu-en/menu/conditions.md) - Learn the detailed syntax of condition expressions
* [🤖 Actions](/plugins/kamenu-en/menu/actions.md) - Learn all available action types
* [💾 Data storage](/plugins/kamenu-en/data/storage.md) - Learn about data storage and variable usage


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://katacr.gitbook.io/plugins/kamenu-en/menu/events.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
