private async Task Send(PubSubPacketModel packet)
 {
     await this.Send(JSONSerializerHelper.SerializeToString(packet));
 }
        /// <summary>
        /// Processes the received text packet.
        /// </summary>
        /// <param name="packetText">The receive text packet</param>
        /// <returns>An awaitable task</returns>
        protected override Task ProcessReceivedPacket(string packetText)
        {
            Logger.Log(LogLevel.Debug, "Twitch PubSub Packet Received: " + packetText);

            PubSubPacketModel packet = JSONSerializerHelper.DeserializeFromString <PubSubPacketModel>(packetText);

            if (packet != null)
            {
                switch (packet.type)
                {
                case "RECONNECT":
                    this.OnReconnectReceived?.Invoke(this, new EventArgs());
                    break;

                case "RESPONSE":
                    this.OnResponseReceived?.Invoke(this, JSONSerializerHelper.DeserializeFromString <PubSubResponsePacketModel>(packetText));
                    break;

                case "MESSAGE":
                    PubSubMessagePacketModel messagePacket = JSONSerializerHelper.DeserializeFromString <PubSubMessagePacketModel>(packetText);
                    this.OnMessageReceived?.Invoke(this, messagePacket);
                    try
                    {
                        PubSubMessagePacketDataModel messageData = messagePacket.messageData;
                        if (messageData != null)
                        {
                            if (messagePacket.topicType == PubSubTopicsEnum.UserWhispers)
                            {
                                this.OnWhisperReceived?.Invoke(this, messageData.data_object.ToObject <PubSubWhisperEventModel>());
                            }
                            else if (messagePacket.topicType == PubSubTopicsEnum.ChannelBitsEventsV1)
                            {
                                this.OnBitsV1Received?.Invoke(this, messageData.data_object.ToObject <PubSubBitsEventV1Model>());
                            }
                            else if (messagePacket.topicType == PubSubTopicsEnum.ChannelBitsEventsV2)
                            {
                                this.OnBitsV2Received?.Invoke(this, messageData.data_object.ToObject <PubSubBitsEventV2Model>());
                            }
                            else if (messagePacket.topicType == PubSubTopicsEnum.ChannelBitsBadgeUnlocks)
                            {
                                this.OnBitsBadgeReceived?.Invoke(this, messageData.data_object.ToObject <PubSubBitBadgeEventModel>());
                            }
                            else if (messagePacket.topicType == PubSubTopicsEnum.ChannelSubscriptionsV1)
                            {
                                PubSubSubscriptionsEventModel subscription = JSONSerializerHelper.DeserializeFromString <PubSubSubscriptionsEventModel>(messagePacket.message);
                                if (subscription.IsGiftedSubscription || subscription.IsAnonymousGiftedSubscription)
                                {
                                    this.OnSubscriptionsGiftedReceived?.Invoke(this, JSONSerializerHelper.DeserializeFromString <PubSubSubscriptionsGiftEventModel>(messagePacket.message));
                                }
                                else
                                {
                                    this.OnSubscribedReceived?.Invoke(this, subscription);
                                }
                            }
                            else if (messagePacket.topicType == PubSubTopicsEnum.ChannelPointsRedeemed)
                            {
                                this.OnChannelPointsRedeemed?.Invoke(this, messageData.data_object.ToObject <PubSubChannelPointsRedemptionEventModel>());
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Logger.Log(ex);
                    }
                    break;

                case "PONG":
                    this.OnPongReceived?.Invoke(this, new EventArgs());
                    break;
                }
            }
            return(Task.FromResult(0));
        }