# Chat-Only vs Full Mode in Zakirullin Files Bot: Configuration and Behavior Guide

> Discover the difference between Chat-Only and Full mode in Zakirullin Files bot. Understand configuration and behavior for enhanced file management workflows.

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

---

**The Zakirullin Files bot offers two primary operational modes—Chat-Only (`"chat"`) restricts functionality to a simple append-only chat log with a reaction confirmation, while Full (`"full"`) enables complete organizational workflows with system directories, quick commands, and move-to keyboards.**

The **Files.md** Telegram bot by Artem Zakirullin supports user-configurable modes that fundamentally alter its interface and storage behavior. These modes are persisted in [`userconfig/config.json`](https://github.com/zakirullin/files.md/blob/main/userconfig/config.json) and enforced at runtime through conditional checks in the message handling pipeline. Understanding the distinction between **Chat-Only** and **Full** modes is essential for selecting the appropriate workflow for your note-taking needs.

## Mode Constants and Configuration Storage

The bot defines mode identifiers as constants in [`server/userconfig/userconfig.go`](https://github.com/zakirullin/files.md/blob/main/server/userconfig/userconfig.go). The active mode is stored as a string value in the per-user configuration file.

- **`ModeChat`**: Corresponds to the JSON value `"chat"`. When active, the bot restricts interaction to the chat window exclusively.
- **`ModeFull`**: Corresponds to the JSON value `"full"`. This unlocks the complete filesystem integration and command set.

Configuration updates are handled through methods like `cfg.SetMode(userconfig.ModeChat)` and `cfg.SetMode(userconfig.ModeFull)`, which persist the selection to disk.

## Feature Comparison: Chat-Only vs Full Mode

| Feature | Chat-Only Mode | Full Mode |
|---------|---------------|-----------|
| **Configuration Value** | `"chat"` | `"full"` |
| **User Interface** | Chat window only; displays 👌 reaction after save | Full UI with *move-to* keyboard for immediate organization |
| **Filesystem Layout** | Single [`chat.md`](https://github.com/zakirullin/files.md/blob/main/chat.md) file (append-only) | System directories created via `fs.CreateSystemDirs()` (`read/`, `shop/`, `watch/`, `journal/`, etc.) |
| **Available Commands** | Basic chat commands only | Extended quick-move commands (`/move-to-read`, `/move-to-shop`, `/move-to-watch`, `/move-to-journal`) |
| **Post-Save Behavior** | `SendReaction` with 👌 and immediate return | Continues to `showMoveTo()` for destination selection |

## Switching Between Modes

### Activating Chat-Only Mode

The `setChatOnlyMode` function in [`server/bot.go`](https://github.com/zakirullin/files.md/blob/main/server/bot.go) (lines 2771–2777) switches the configuration and presents a minimal prompt:

```go
func (b *Bot) setChatOnlyMode(_ []string) error {
    err := b.cfg.SetMode(userconfig.ModeChat)
    if err != nil {
        return fmt.Errorf("chat only mode: can't set chat only mode %w", err)
    }
    return b.showHTML(i18n.Tr("What's on your mind?"), nil)
}

```

This method strips away quick commands and prevents the creation of organizational directories.

### Activating Full Mode

The `setFullMode` implementation in [`server/bot.go`](https://github.com/zakirullin/files.md/blob/main/server/bot.go) (lines 2744–2770) performs three critical setup operations:

```go
func (b *Bot) setFullMode(_ []string) error {
    err := b.cfg.SetMode(userconfig.ModeFull)
    if err != nil {
        return fmt.Errorf("full mode: can't set notes only mode %w", err)
    }

    // Register quick-move shortcuts
    moveToCmds := []string{
        CmdShowMoveToDirOrFile,
        CmdMoveToRead,
        CmdMoveToShop,
        CmdMoveToWatch,
        CmdMoveToJournal,
    }
    for _, cmd := range moveToCmds {
        if err = b.cfg.AddMoveToCmd(cmd); err != nil {
            return fmt.Errorf("full mode: can't add quick command %w", err)
        }
    }

    // Initialize system directory structure
    if err = b.fs.CreateSystemDirs(); err != nil {
        return fmt.Errorf("full mode: can't create dirs: %w", err)
    }

    return b.ShowHome(nil)
}

```

## Runtime Message Handling Differences

After persisting a message to [`chat.md`](https://github.com/zakirullin/files.md/blob/main/chat.md), the bot checks `cfg.ChatOnlyMode()` to determine the next step. In [`server/bot.go`](https://github.com/zakirullin/files.md/blob/main/server/bot.go) (lines 503–508), the conditional logic diverges:

```go
msgHash, err := b.appendToChat(msg, b.cfg.Timezone())
if err != nil {
    return fmt.Errorf("append to chat: %w", err)
}

if b.cfg.ChatOnlyMode() {
    // Lightweight path: confirm and exit
    msgID, _ := u.MsgID()
    _ = b.tg.SendReaction(b.userID, msgID, "👌")
    return nil
}

// Full mode path: present organizational options
return b.showMoveTo([]string{msgHash})

```

In **Chat-Only** mode, the interaction ends after the reaction. In **Full** mode, the bot invokes `showMoveTo()` to display the keyboard interface for filing the note into specific directories or task lists.

## Summary

- **Chat-Only** mode stores `"chat"` in [`userconfig/config.json`](https://github.com/zakirullin/files.md/blob/main/userconfig/config.json), limits interaction to [`chat.md`](https://github.com/zakirullin/files.md/blob/main/chat.md), and confirms saves with a 👌 reaction via `SendReaction`.
- **Full** mode stores `"full"`, initializes organizational directories through `fs.CreateSystemDirs()`, populates quick commands via `AddMoveToCmd()`, and presents the *move-to* keyboard after each save.
- Mode switching is handled by `setChatOnlyMode` and `setFullMode` in [`server/bot.go`](https://github.com/zakirullin/files.md/blob/main/server/bot.go), which update the configuration and adjust the available UI elements accordingly.
- Runtime behavior is determined by the `ChatOnlyMode()` Boolean check in the message processing loop.

## Frequently Asked Questions

### How do I programmatically detect which mode is active?

Inspect the configuration using the helper method defined in [`server/userconfig/userconfig.go`](https://github.com/zakirullin/files.md/blob/main/server/userconfig/userconfig.go):

```go
if cfg.ChatOnlyMode() {
    fmt.Println("Bot is running in chat-only mode")
} else {
    fmt.Println("Bot is running in full mode")
}

```

You can also manually check the `mode` field in your [`userconfig/config.json`](https://github.com/zakirullin/files.md/blob/main/userconfig/config.json) file for the string values `"chat"` or `"full"`.

### Does switching from Full to Chat-Only mode delete my organized files?

No. Switching modes only affects the user interface and available commands. Any directories created by `CreateSystemDirs()` during Full mode operation persist on disk; the bot simply stops accessing them. Your existing notes in `read/`, `shop/`, or other system directories remain intact but inaccessible from the Chat-Only interface until you switch back.

### Why don't quick commands like /move-to-read work in Chat-Only mode?

Quick commands are explicitly registered only during Full mode initialization. The `setFullMode` function iterates through the `moveToCmds` slice and calls `cfg.AddMoveToCmd()` for each shortcut. In Chat-Only mode, these commands are never added to the configuration, so the Telegram bot framework does not recognize them as valid inputs.

### Can I use Chat-Only mode without creating any directories?

Yes. Chat-Only mode never invokes `fs.CreateSystemDirs()`. It operates exclusively with the single [`chat.md`](https://github.com/zakirullin/files.md/blob/main/chat.md) file, making it ideal for users who want a lightweight, serverless-feeling chat log without the overhead of hierarchical file management.