Introduction

WireChat allows you to define how users are represented within your application. You can configure attributes such as display names, profile avatars, and profile URLs to provide a consistent experience across conversations and components.


#Panel access

To decide which users can open a WireChat panel, you may implement your own authorization logic inside the User model. WireChat will call the canAccessWireChatPanel() method whenever a panel is being accessed via a route.

namespace App\Models;

use Wirechat\Wirechat\Panel;
use Wirechat\Wirechat\Traits\InteractsWithWireChat;
use Wirechat\Wirechat\Contracts\WireChatUser;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements WireChatUser
{
    use InteractsWithWireChat;
    // ...

    public function canAccessWireChatPanel(Panel $panel): bool
    {
        return $this->hasVerifiedEmail();
    }
}

The canAccessWireChatPanel() method should return true or false depending on whether the user is allowed to enter the given $panel. In this example, access is restricted to users who have verified their email address.

Because the current $panel is available, you can apply different rules for each panel. For instance, you may require stricter checks for an admin chat panel, while keeping other panels open to all users:


namespace App\Models;

use Wirechat\Wirechat\Panel;
use Wirechat\Wirechat\Traits\InteractsWithWireChat;
use Wirechat\Wirechat\Contracts\WireChatUser;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements WireChatUser
{
    use InteractsWithWireChat;
    // ...

    public function canAccessWireChatPanel(Panel $panel): bool
    {
        if ($panel->getId() === 'admin') {
            return $this->is_admin && $this->hasVerifiedEmail();
        }

        return true;
    }
}

#Action Permissions

You may configure which features a user has access to by defining permission methods on the User model.

#Allow Users to Create Chats

Determine if the "create chat" action should be visible to the current user:

namespace App\Models;

use Wirechat\Wirechat\Traits\InteractsWithWireChat;
use Wirechat\Wirechat\Contracts\WireChatUser;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements WireChatUser
{
    use InteractsWithWireChat;

    public function canCreateChats(): bool
    {
        return $this->hasVerifiedEmail();
    }
}

You can also add conditions based on your own application logic, such as checking subscriptions, roles, or other permissions.


#Allow Users to Create Groups

Determine if the "create group" action should be visible to the current user:

namespace App\Models;

use Wirechat\Wirechat\Traits\InteractsWithWireChat;
use Wirechat\Wirechat\Contracts\WireChatUser;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements WireChatUser
{
    use InteractsWithWireChat;

    public function canCreateGroups(): bool
    {
        return $this->hasVerifiedEmail();
    }
}

#Attributes

User attributes define how names, avatars, and profile links appear throughout chats.

#User’s Name

By default, WireChat uses the name attribute from your User model. You may override this by defining the getWirechatNameAttribute() method:

use Wirechat\Wirechat\Traits\InteractsWithWireChat;
use Wirechat\Wirechat\Contracts\WireChatUser;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements WireChatUser
{
    use InteractsWithWireChat;

    public function getWirechatNameAttribute(): string
    {
        return $this->display_name ?? $this->name;
    }
}

#Avatar URL

Set the URL that should be used for the user’s avatar across chats, member lists, and chat info:

namespace App\Models;

use Wirechat\Wirechat\Traits\InteractsWithWireChat;
use Wirechat\Wirechat\Contracts\WireChatUser;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements WireChatUser
{
    use InteractsWithWireChat;

    public function getWirechatAvatarUrlAttribute(): string
    {
        return $this->avatar_url ?? asset('images/default-avatar.png');
    }
}

#Profile URL

When a user’s name or avatar is clicked, WireChat will use the getWirechatProfileUrlAttribute() method to determine where to redirect:

use Wirechat\Wirechat\Traits\InteractsWithWireChat;
use Wirechat\Wirechat\Contracts\WireChatUser;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements WireChatUser
{
    use InteractsWithWireChat;

    public function getWirechatProfileUrlAttribute(): string
    {
        return route('profile.show', $this->id);
    }
}

#Searching Users

WireChat provides a flexible way to control how users are searched when starting new conversations or adding members to a group.

By default, a simple search is performed on your User model, but you can fully customize this behavior.

#Customizing Searchable Attributes

If no custom callback is defined, WireChat will search your User model using the attributes you specify:

use Wirechat\Wirechat\Panel;

public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->searchableAttributes(['name', 'email', 'username']);
}

In this example, a query like "john" will match users where the name, email, or username contains "john".


To fully control the search logic, define a callback using searchUsersUsing(). Always wrap your results in WireChatUserResource to maintain a consistent structure:

use Wirechat\Wirechat\Panel;
use Wirechat\Wirechat\Http\Resources\WireChatUserResource;

public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->searchUsersUsing(function (string $needle) {
            return WireChatUserResource::collection(
                \App\Models\User::query()
                    ->where('is_active', true)
                    ->where('name', 'like', "%{$needle}%")
                    ->limit(20)
                    ->get()
            );
        });
}

Important: Always return results using WireChatUserResource. This ensures a consistent structure with id, type, wirechat_name, and wirechat_avatar_url across both Livewire and API responses.

In this example:

  • Only active users are returned.
  • The search is limited to the name field.
  • Using WireChatUserResource guarantees standardized responses.

Once configured, all user searches whether starting chats, creating groups, or adding members will follow your defined logic and return standardized results.


#Conversations

You can access a user's conversations i.e the conversations they are a member of , either through the Wirechat UI or programmatically.

  • Via Wirechat UI

Navigate to the /chats route to view your active conversations. Conversations that you have deleted, groups you have exited, or conversations without any messages will not appear in the list.

  • Programmatically
$auth = auth()->user();
$conversations = $auth->conversations()->get();

You can also apply scopes to filter conversations:

Exclude Blank Conversations

$conversations = $auth->conversations()->withoutBlanks()->get();

Exclude Deleted Conversations

$conversations = $auth->conversations()->withoutDeleted()->get();

Note: Scopes only take effect when the user is authenticated.


#Conversation Membership

Check whether a user is part of a conversation using the belongsToConversation() method:

$conversation = Wirechat\Wirechat\Models\Conversation::first();
$user->belongsToConversation($conversation); // Returns a boolean

#Check if a Conversation Exists Between Users

$anotherUser = User::first();
$user->hasConversationWith($anotherUser); // Returns a boolean