logo
On this page

Send virtual gifts

The virtual gifting function is a novel feature found in social apps that allows users to send virtual gifts to a host. These gifts can take the form of a variety of items, ranging from a cup of coffee to a car.

The aim of this function is to enhance interactivity and liveliness within social apps. By sending virtual gifts, viewers can connect with the host during live shows.

This document will explain how to implement virtual gifting.

Prerequisites

Before you begin, make sure you complete the integration by referring to the Quick start with co-hosting.

Implementation

Create a virtual-gifting entrance

Create an entrance for sending virtual gifts, which is a button that can be clicked to send virtual gifts. To do so, add a button by configuring the bottomMenuBarConfig and listening to the corresponding event.

Untitled
  @override
  Widget build(BuildContext context) {
    final hostConfig = ZegoUIKitPrebuiltLiveStreamingConfig.host(
      plugins: [ZegoUIKitSignalingPlugin()],
    );

    // Create a virtual-gifting button.
    final giftButton = ZegoMenuBarExtendButton(
      index: 0,
      child: ElevatedButton(
        style: ElevatedButton.styleFrom(shape: const CircleBorder()),
        onPressed: () {
          // Send a virtual gift.
          sendGift();
        },
        child: const Icon(Icons.blender),
      ),
    );

    final audienceConfig = ZegoUIKitPrebuiltLiveStreamingConfig.audience(
      plugins: [ZegoUIKitSignalingPlugin()],
    )
      ..bottomMenuBar.coHostExtendButtons = [giftButton]
      ..bottomMenuBar.audienceExtendButtons = [giftButton];

    return SafeArea(
      child: ZegoUIKitPrebuiltLiveStreaming(
        appID: yourAppID /*input your AppID*/,
        appSign: yourAppSign /*input your AppSign*/,
        userID: localUserID,
        userName: 'user_$localUserID',
        liveID: widget.liveID,
        config: (widget.isHost ? hostConfig : audienceConfig),
      ),
    );
  }
1
Copied!

Implement the gift-sending logic

When the viewers click the gift sending button, it triggers the corresponding API of your business server. The request parameters can be like this:

Untitled
{
    "room_id": "room888",   // The livestream room ID
    "user_id": "user987",   // The user ID of the gift sender
    "user_name": "James",   // The user name of the gift sender
    "gift_type": 1001,      // Gift type
    "gift_count": 2,         // Number of gifts
    "access_token": "fasd2r34dfasd...fasdf",    // The Token used for authentication
    "timestamp": 1670814533,    // Request timestamp
}
1
Copied!

You have the flexibility to modify request parameters based on your business requirements. Once a viewer requests to send a gift, your server will perform the following actions:

  • Verify if the user's account balance meets the required amount based on the parameters.
  • Deduct the fees from the user's account balance.
  • Increase the gift amount for the host.

The viewer receives a corresponding status code after processing. A message queue is then created to notify the host and other viewers about the gift.

The demo employs Next.js to showcase how ZEGOCLOUD Server API is called. You may download the source code for reference.

Notify the host and viewers to display gift animation

To display gift animations to the host and viewers, send a notification using the send in-room messages API with MessageType: 2.

We recommend combining multiple gifts into a single message to avoid exceeding the rate limit of 10 requests per second per app ID. For example:

Note

While this signaling ensures delivery under normal network conditions, it may be lost in rare cases, such as when the gift receiver experiences network issues and fails to receive the signal.

Untitled
{
    "FromUserId": "serverID",
    "RoomId": "room888",
    "MessageType": 2,
    "Priority": 1,
    "MessageBody": {
        "Message": [
            {
                "user_id": "user987",
                "user_name": "James",
                "gift_type": 1001, 
                "gift_cout": 2,
                "timestamp": 1670814533,
            },
            ...
        ],
        "ExtendedData":"",
    }
}
1
Copied!

Listen to gift messages and display gift animation

To display the gift animation, simply monitor the gift message on the client. Once a new gift message arrives, play the animation. Different roles require different gift message callbacks.

For cool animation effects, use our express mp4 player to the gift file on the screen.

Gift sender

After sending a gift, the gift sender can confirm its successful delivery by checking the status code of the gift-sending API. If the API returns a success code, the gift animation will display.

Untitled
  Widget sendButton() {
    return ElevatedButton(
      onPressed: () {
        if (selectedGiftItemNotifier.value == null) {
          return;
        }

        final giftItem = selectedGiftItemNotifier.value!;
        final giftCount = int.tryParse(countNotifier.value) ?? 1;
        Navigator.of(context).pop();

        /// local play
        ZegoGiftManager().playList.add(PlayData(giftItem: giftItem, count: giftCount));

        /// notify remote host
        ZegoGiftManager().service.sendGift(name: giftItem.name, count: giftCount);
      },
      child: const Text('SEND'),
    );
  }
1
Copied!

Host and rest of the viewers

Suppose the server uses an unreliable signaling channel to broadcast messages. In that case, it needs to monitor the notification callback method onInRoomCommandReceived of unreliable messages to determine whether someone has sent a gift. When a new gift notification is received, it displays the gift effect.

If the server uses an unreliable signaling channel to broadcast messages, it can monitor the onInRoomCommandReceived notification callback method for unreliable messages. This allows it to detect when a gift has been sent. Upon receiving a new gift notification, the gift effect will display.

Untitled
  @override
  void initState() {
    super.initState();

    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      subscriptions.add(ZegoUIKit()
          .getSignalingPlugin()
          .getInRoomCommandMessageReceivedEventStream()
          .listen((event) {
        onInRoomCommandMessageReceived(event);
      }));
    });
  }

  @override
  void dispose() {
    super.dispose();

    for (final subscription in subscriptions) {
      subscription?.cancel();
    }
  }

  void onInRoomCommandMessageReceived(ZegoSignalingPluginInRoomCommandMessageReceivedEvent event) {
    final messages = event.messages;

    // You can display different animations according to gift-type
    for (final commandMessage in messages) {
      final senderUserID = commandMessage.senderUserID;
      final message = utf8.decode(commandMessage.message);
      debugPrint('onInRoomCommandMessageReceived: $message');
      if (senderUserID != _localUserID) {
        final gift = ZegoGiftProtocol.fromJson(message);
        recvNotifier.value = gift.giftItem;
      }
    }
  }
1
Copied!

Run a demo

To access the sample code for this feature, download it from here.