# How to Customize Quick Buttons in Zakirullin Files Bot: A Developer's Guide

> Learn to customize quick buttons in Zakirullin Files bot. Modify bot settings and implement command handlers to tailor the user experience for developers.

- Repository: [Artem Zakirullin/files.md](https://github.com/zakirullin/files.md)
- Tags: how-to-guide
- Published: 2026-05-21

---

**Quick buttons in the Zakirullin Files bot are customized by modifying the `AvailableQuickBtns` slice in [`server/bot_settings.go`](https://github.com/zakirullin/files.md/blob/main/server/bot_settings.go), implementing command handlers in [`server/bot.go`](https://github.com/zakirullin/files.md/blob/main/server/bot.go), and managing user preferences through [`server/userconfig/quick_cmds.go`](https://github.com/zakirullin/files.md/blob/main/server/userconfig/quick_cmds.go).**

The Zakirullin Files bot uses a flexible quick-button system that allows users to personalize their keyboard with one-tap actions like **Later**, **Search**, or **Habits**. This guide explains how to customize quick buttons in Zakirullin Files bot by modifying the source code, adding new functionality, and managing the user configuration layer.

## Understanding Quick Button Architecture

The quick button system relies on three interconnected components that handle the catalog, user preferences, and UI rendering.

### The Three-Component System

1. **AvailableQuickBtns** – The master catalog of all possible buttons that the bot can display. This slice in [`server/bot_settings.go`](https://github.com/zakirullin/files.md/blob/main/server/bot_settings.go) (lines 30‑42) declares every button with its label, emoji, and underlying command.
2. **User Configuration** – Personal quick-button selections stored per user. The methods `AddQuickCmd`, `DelQuickCmd`, and `QuickCmds` in [`server/userconfig/quick_cmds.go`](https://github.com/zakirullin/files.md/blob/main/server/userconfig/quick_cmds.go) manage these persistent lists.
3. **Keyboard Rendering** – The UI construction logic in `bot.showQuickBtnsSettings` ([`server/bot_settings.go`](https://github.com/zakirullin/files.md/blob/main/server/bot_settings.go), lines 25‑73) builds two sections: enabled buttons (with a `➖` delete icon) and available buttons (with a `➕` add icon).

## Adding a New Quick Button

To add a custom quick button that users can select, you must declare the button, create a handler, and rebuild the server.

### Step 1: Declare the Button Catalog Entry

Add your button to the `AvailableQuickBtns` slice in [`server/bot_settings.go`](https://github.com/zakirullin/files.md/blob/main/server/bot_settings.go):

```go
var AvailableQuickBtns = []tg.Btn{
    tg.NewBtn("Later", tg.NewCmd(CmdLater, nil)),
    // …existing buttons…
    tg.NewBtn("MyNew", tg.NewCmd("my_new_cmd", nil)),   // ← add here
}

```

The settings panel reads this slice directly, so the new entry automatically appears in the "add" list.

### Step 2: Create the Command Handler

First, define a constant in [`server/bot.go`](https://github.com/zakirullin/files.md/blob/main/server/bot.go) (around line 170):

```go
const (
    // …existing Cmd… 
    CmdMyNew = "my_new_cmd"
)

```

Then register the handler in the `bot.handlers` map:

```go
handlers := map[string]func([]string) error{
    // …other handlers…
    CmdMyNew: b.handleMyNew,
}

```

Finally, implement the handler method:

```go
func (b *Bot) handleMyNew(_ []string) error {
    // your custom logic here
    return b.showHTML("You pressed MyNew!", nil)
}

```

### Step 3: Deploy Changes

Rebuild the server binary with `go build ./cmd/server` and restart the service. Users will now see "MyNew ➕" in the quick-button settings panel and can add it to their personal row.

## Modifying Existing Quick Buttons

You can remove or rename existing buttons by editing the catalog and handler maps.

### Removing Buttons

Delete the entry from `AvailableQuickBtns` in [`server/bot_settings.go`](https://github.com/zakirullin/files.md/blob/main/server/bot_settings.go):

```go
// Remove this line to delete the Random button
// tg.NewBtn("Random", tg.NewCmd(CmdRandomNote, nil)),

```

The button disappears from the "add" list immediately. However, users who already added it to their personal panel will continue seeing it until they remove it via the settings UI.

### Renaming Labels and Changing Emojis

Change the first argument of `tg.NewBtn` to modify the visible label without affecting functionality. For emoji customization, modify the `i18n.Emoji` calls or update locale files under `server/i18n`. For example, changing the "Later" emoji:

```go
// server/i18n/strings.en.yml
emoji:
  later: "⏰"   # replaces default emoji

```

The `i18n.Emoji("later")` call inside `showQuickBtnsSettings` will render ⏰ instead of the default.

## How User Selections Persist

When users tap the `➕` icon, the bot invokes `addToQuickBtns` (line 82 in [`server/bot_settings.go`](https://github.com/zakirullin/files.md/blob/main/server/bot_settings.go)). This method validates the command and calls `c.cfg.AddQuickCmd(cmd)` (defined in [`server/userconfig/quick_cmds.go`](https://github.com/zakirullin/files.md/blob/main/server/userconfig/quick_cmds.go), lines 7‑28). Conversely, the `➖` icon triggers `delFromQuickBtns`, which calls `c.cfg.DelQuickCmd`.

All modifications pass through a per-user mutex (`c.userLock()`) to prevent race conditions during concurrent updates.

## Internationalization Support

Button labels are plain strings, while emoji prefixes are generated via `i18n.Emoji` calls. To support multiple languages, add translation entries to locale files in `server/i18n`. The UI automatically selects the correct emoji based on the user's language preference without requiring changes to the button logic.

## Practical Code Examples

### Example 1: Adding a Weather Quick Button

```go
// server/bot_settings.go – add to the catalogue
var AvailableQuickBtns = []tg.Btn{
    // …existing entries…
    tg.NewBtn("Weather", tg.NewCmd(CmdWeather, nil)),
}

// server/bot.go – command constant
const (
    CmdWeather = "weather"
)

// server/bot.go – handler registration
handlers := map[string]func([]string) error{
    CmdWeather: b.showWeather,
}

// server/bot_settings.go – implementation
func (b *Bot) showWeather(_ []string) error {
    forecast := "☀️ Clear sky, 23 °C"
    return b.showHTML(fmt.Sprintf("Current weather: %s", forecast), nil)
}

```

### Example 2: Removing the Random Button

```go
// server/bot_settings.go – delete the Random entry
var AvailableQuickBtns = []tg.Btn{
    tg.NewBtn("Later", tg.NewCmd(CmdLater, nil)),
    // tg.NewBtn("Random", tg.NewCmd(CmdRandomNote, nil)), // REMOVED
    tg.NewBtn("Search", tg.NewCmd(CmdSearch, nil)),
}

```

### Example 3: Changing the Emoji for Later

```yaml

# server/i18n/strings.en.yml

emoji:
  later: "⏰"
  search: "🔍"

```

## Summary

- **Catalog Definition**: Modify `AvailableQuickBtns` in [`server/bot_settings.go`](https://github.com/zakirullin/files.md/blob/main/server/bot_settings.go) to add or remove available quick buttons.
- **Handler Implementation**: Register new commands in [`server/bot.go`](https://github.com/zakirullin/files.md/blob/main/server/bot.go) constants and handler maps, then implement the corresponding methods.
- **User Persistence**: User selections are stored via `AddQuickCmd` and `DelQuickCmd` in [`server/userconfig/quick_cmds.go`](https://github.com/zakirullin/files.md/blob/main/server/userconfig/quick_cmds.go), protected by `c.userLock()` mutex.
- **UI Rendering**: The `showQuickBtnsSettings` method constructs the settings panel using `➕` (`addBtn`) and `➖` (`delBtn`) indicators based on the user's current configuration.
- **Deployment**: Changes require rebuilding the Go binary and restarting the server to reflect in the Telegram interface.

## Frequently Asked Questions

### Where are quick button definitions stored?

Quick button definitions are stored in the `AvailableQuickBtns` slice in [`server/bot_settings.go`](https://github.com/zakirullin/files.md/blob/main/server/bot_settings.go) (lines 30‑42). This slice contains `tg.Btn` objects that define the label, command, and emoji for every button available in the catalog.

### How do I remove a quick button that users have already added?

Delete the button from `AvailableQuickBtns` in [`server/bot_settings.go`](https://github.com/zakirullin/files.md/blob/main/server/bot_settings.go) to prevent new additions. Existing users will still see the button in their personal row until they manually remove it via the settings UI using the `➖` icon, which triggers `delFromQuickBtns` and calls `c.cfg.DelQuickCmd`.

### Can I customize the emoji for existing quick buttons?

Yes. Emojis are resolved through `i18n.Emoji` calls in the rendering logic. Modify the emoji values in the locale files under `server/i18n` (such as [`strings.en.yml`](https://github.com/zakirullin/files.md/blob/main/strings.en.yml)) to change the displayed emoji without altering the button's command or functionality.

### How does the bot handle concurrent quick button updates?

The bot uses a per-user mutex accessed via `c.userLock()` to serialize modifications. When a user taps `➕` or `➖`, the `addToQuickBtns` or `delFromQuickBtns` methods lock the user context before calling `c.cfg.AddQuickCmd` or `c.cfg.DelQuickCmd`, preventing race conditions during simultaneous updates.