Skip to content

PubNubDevelopers/Live-Events-Demo

Repository files navigation

Live Events Application

Demo

A hosted version of the demo can be found at

Screenshot

Features of the Live Events Application and PubNub SDK used

Feature Description APIs/Primatives used
Chat Uses the PubNub Chat SDK to show how a a chat application can be implemented with a public channel with features such as history, precense, metadata, delete/restore messages. Public Channels, Join Channels, Create User, Presence, Send/Receive, History, Delete Message, Restore Message
Broadcasting Shows how Livepeer can make a real-time livestream with control over live playback, quality, and video/audio settings. Player, Livestream Playback, Stream
Moderation Uses the PubNub Chat SDK to show how you can moderate your Live Events application by allowing users to report users/messages and on the other hand allowing the moderator or broadcaster to mute or ban users from the stream. Flag/Report Messages, Flag/Report Message, Mute/Ban Users, Profanity Filtering

Installing / Getting started

To run this project yourself you will need a PubNub and Livepeer account.

Requirements

Get you PubNub Keys

  1. You’ll first need to sign up for a PubNub account. Once you sign up, you can get your unique PubNub keys from the PubNub Developer Portal.

  2. Sign in to your PubNub Dashboard.

  3. Click Apps, then Create New App.

  4. Give your app a name, and click Create.

  5. Click your new app to open its settings, then click its keyset.

  6. Enable the Presence feature on your keyset (check 'Presence Deltas' and 'Generate Leave on TCP FIN or RST')

  7. Enable the Message Persistence feature on your keyset and choose a duration

  8. Enable the App Context feature on your keyset. Make sure you check all the checkboxes related to events, i.e. User and Channel Metadata Events as well as Membership Events.

  9. The hosted variant of this app uses Functions for moderation, specifically https://www.pubnub.com/integrations/chat-message-profanity-filter/.

  10. Copy the Publish and Subscribe keys and paste them into your app as specified in the next step.

Building and Running

  1. Clone the repository

  2. In the file .env.example delete the extention .example and your keys here keeping the name of the keys the same.

Contributing

Please fork the repository if you'd like to contribute. Pull requests are always welcome.

Customization to change colors and demo content

  • To modify the application theme, modify the colors located at /tailwind.config.ts. Named colors are used throughout this application so changing them here will update the entire app.

Further information

chat.listenForEvents({
    channel: string;
    type?: "report";
    callback: (event: Event<"report">) => unknown;
}): () => void

For the moderator/broadcaster to listen to report events by users. Set this value to a dedicated PUBNUB_INTERNAL_ADMIN_CHANNEL where all report events are sent.

Server Component

You will need to set up a server component and replace the baseURL fround under components/chat/api/moderation.ts to point at your server. The server component ensures that your PubNub Secret Key is not stored on the client side of the application. All ban/mute functionality should happen on the server side of this demo as you will need to initialize your PubNub Instance with the Secret Key.

Server Component Code

Keys.js

const publish_key = 'publish_key'; //  ENTER YOUR PUBLISH KEY HERE
const subscribe_key = 'subscribe_key'; //  ENTER YOUR SUBSCRIBE KEY HERE
const secret_key = 'secret_key'; //  ENTER YOUR SECRET KEY HERE

const admin_key = 'admin'; //  ENTER ADMIN UUID HERE

module.exports = {
  publishKey: publish_key,
  subscribeKey: subscribe_key,
  secretKey: secret_key,
  userId: admin_key
}

Moderation.js

const config_file = require('./keys.js')
const { Chat } = require("@pubnub/chat");

const setRestrictions = async (req, res) => {
  // Get PubNub Admin UUID
  const chat = await Chat.init(config_file);

  // Parse ChannelID
  const channelID = req.body.channelID;
  const userID = req.body.userID;
  const ban = req.body.ban;
  const mute = req.body.mute;

  if (channelID == null || userID == null) {
    return res.status(500).send({
      message: 'Error: channelID or userID was called on null. Ensure content-type is application/json and the POST request contains a channelID and a userID parameter'
    })
  }

  if(ban == null){
    return res.status(500).send({
      message: 'Error: Have to include the current ban status when muting a user'
    })
  }

  // If the channel has been created grab the channel object
  const channelInstance = await chat.getChannel(channelID);
  const userInstance = await chat.getUser(userID);

  if(channelInstance == null || userInstance == null){
    return res.status(500).send({
      message: `Error: No channel instance matches the ID: ${channelID} or No user Instance matches the ID: ${userID}`
    })
  }

  await channelInstance.setRestrictions(userInstance, {
    ban: ban,
    mute: mute,
    reason: "Restricted by admin",
  });

  return res.status(200);
}

const deleteMessage = async (req, res) => {
  // Get PubNub Admin UUID
  const chat = await Chat.init(config_file);

  const messageID = req.body.messageID;
  const channelID = req.body.channelID;

  // If the channel has been created grab the channel object
  const channelInstance = await chat.getChannel(channelID);

  if(channelInstance == null){
    return res.status(500).send({
      message: `Error: No channel instance matches the ID: ${channelID}`
    })
  }

  const message = await channelInstance.getMessage(messageID);

  // Soft delete a message so it is able to be restored
  await message.delete({
    soft: true,
  });

  return res.status(200);
}

const restoreMessage = async (req, res) => {
  // Get PubNub Admin UUID
  const chat = await Chat.init(config_file);

  const messageID = req.body.messageID;
  const channelID = req.body.channelID;

  // If the channel has been created grab the channel object
  const channelInstance = await chat.getChannel(channelID);

  if(channelInstance == null){
    return res.status(500).send({
      message: `Error: No channel instance matches the ID: ${channelID}`
    })
  }

  const message = await channelInstance.getMessage(messageID);

  await message.restore();

  return res.status(200);
}

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages