AgoraIO-Extensions / agora-rtc-react

Agora RTC React SDK
https://agoraio-extensions.github.io/agora-rtc-react/
MIT License
31 stars 11 forks source link

How can I assign attributes to users (name / avatar) #199

Closed muhammedanaskhan closed 5 months ago

muhammedanaskhan commented 5 months ago

What kind of problem do you need help?

Is there any way to add attributes to users in a video conference, I thought of utilizing the useCurrentUID to make this work, but the currentUID changes with page re-route, let's say there's a lobby page where user enters the name and selects avatar and joins the meet, the meet is on another route, then one can map the user info fetched from backend with respective UIDs ( i thought to do with this approach), but UID changes with the route so this completely fails the approach I thought, is there any better way to do this,

guoxianzhe commented 5 months ago

@muhammedanaskhan You can specify UID when you JoinChannel. https://github.com/AgoraIO-Extensions/agora-rtc-react/blob/main/packages/agora-rtc-react/src/types.ts#L27. Then you will get the same uid when you join the channel in every times.

muhammedanaskhan commented 5 months ago

Thanks for helping me out @guoxianzhe . Highly appreciate!!

ttebify commented 4 months ago

You can creatively pass the UID as a string by extracting minimal information from your user or model for the meeting and encoding it first to json and then in base64, which can be decoded on the client to retrieve the embedded data. Here is an example using PHP for the server and a web application:

// ... Other codes
$connectionData = $user->only(['id', 'name', 'email', 'avatar']);

if ($request->boolean('screen_share', false)) {
    $connectionData['name'] = "$user->name's Screen";
    $connectionData['screen_share'] = true;
} else if (isset($config['displayName'])) {
    $connectionData['name'] = $config['displayName'];
}

$jsonData = json_encode($connectionData); // Convert to a string
$userDataAsString = base64_encode($jsonData); // Encode

$config = config('services.agora');
$channelName = 'live_session_' . $meeting->code;
$tokenExpireTs = now()->addSeconds(1 * 60 * 60); // 1 hour

try {
    $token = RtcTokenBuilder::buildTokenWithUserAccount(
        appID: $config['app_id'],
        appCertificate: $config['secret'],
        channelName: $channelName,
        userAccount: $userDataAsString,
        role: RtcTokenBuilder::RolePublisher,
        privilegeExpireTs: $tokenExpireTs->getTimestamp(),
    );

    return response()->json([
        'token' => $token,
        'channel' => $channelName,
        'uid' => $userDataAsString,
        'meeting' => $meeting,
    ]);
} catch (Exception $e) {
    return response()->json(['error' => 'Failed to generate token'], 500);
}

Client:

type DataFromUID = {
    id: string;
    name: string;
    avatar: string;
    email: string;
    screen_share?: boolean;
};

export function decodeData(encodedData: string): DataFromUID | null {
    try {
        const jsonData = atob(encodedData);
        return JSON.parse(jsonData) as DataFromUID;
    } catch (error) {
        console.error("Failed to decode user data: ", error);
        return null;
    }
}

// Usage
const Participant = ({ participant }: ParticipantProps) => {
    const userData = decodeData(participant.uid as string);
    return (
        <Avatar
            src={userData?.avatar}
            size={"lg"}
            name={userData?.name}
            className={avatar}
        />
    );
};

And the generated token looks really cool:

eyJpZCI6IjAxajJicjBuY2tkN2NmN3JnZHNxYXcxY2Y4IiwibmFtZSI6Ik1hbGNvbG0gTGFya2luIiwiZW1haWwiOiJuYXRoZW4uc2NodWx0ekBleGFtcGxlLmNvbSIsImF2YXRhciI6Imh0dHBzOlwvXC9jaGlsaW5rLnRlc3RcL2ltYWdlc1wvZGVmYXVsdC1hdmF0YXIucG5nIn0=

If using React, here is a helpful hook to get the UID of the current user:

import { useCurrentUID } from "agora-rtc-react";

const localUid = useCurrentUID();