A Simple Example

Here you can follow along as we create a fully functional Twitch extension.

Extension Functionality

As a simple example, we will create a panel Extension that lets a broadcaster set a “Message of the Day” for their viewers.

On the Broadcaster Live Dashboard we will display a text input field and a button. When the button is pressed, the input message will be sent to all current viewers and displayed in the panel. In addition, any new viewers who visit the channel will see the most recent message the broadcaster sent.

Viewer Panel Code

First up let’s build the Panel Extension that will be shown to each viewer on the broadcaster’s channel page (e.g. https://twitch.tv/muxy). This Viewer Panel will display the message to each viewer.

<html>
  <head>
    <style>
      @import url('//fonts.googleapis.com/css?family=Roboto');

      body {
        font-family: 'Roboto', sans-serif;
      }
    </style>

    <!--
      Twitch only allows loading assets from certain white-listed domains. Above we reference a font
      from Google's font CDN.

      Here we load the latest version of Muxy's JavaScript SDK, however in production you will have
      to download this file into your extension's folder and reference the local copy.

      You can download specific versions by replacing `latest` with a version number (e.g. `2.0.0`), or keep this as-is to automatically load the most recent version in development.
    -->
    <script src="//ext-cdn.muxy.io/medkit/latest/medkit.umd.js"></script>

    <!--
      Here is the entire code block needed to power the panel. It uses Muxy's state loading to get
      the last sent message, and easy event binding to get notified when a new message is comes through.
    -->
    <script type="text/javascript">
      /*
       * Muxy has an optional debug system to ease setting common values when developing, and more
       * powerful features when building advanced systems! Here we set a debug channel to fake
       * the viewer's location. This would be replaced with the actual channel when running on
       * Twitch. NOTE: The call to `Muxy.debug` must occur before the call to `Muxy.setup` for
       * the options to be set correctly.
       */
      const opts = new Muxy.default.DebuggingOptions();
      opts.channelID('126955211').role('viewer');
      Muxy.debug(opts);

      /*
       * All Muxy-powered extensions begin by initializing the SDK. This is done by simply calling
       * `setup()` on the global Muxy object with your extension's Client ID, and then creating an
       * SDK object.
       */
      Muxy.setup({ clientID: 'replaceme' });
      const sdk = new Muxy.SDK();

      /*
       * The new SDK object has a `loaded` function that returns a Promise which will resolve once
       * communication with the backend has been established. It will fail with an error if
       * something goes wrong.
       */
      sdk.loaded().then(() => {
        /*
         * First we will ask the SDK to load all extension state from the backend. This function
         * returns a Promise that will resolve with an object containing several fields representing
         * state for everything from the extension as a whole, to the broadcaster-set channel state,
         * even down to state stored for the specific viewer.
         */
        sdk.getAllState().then(function(state) {
          /*
           * The `channel` field of the `state` object will contain data set by the broadcaster.
           */
          document.querySelector('#motd').innerText = state.channel.motd || 'Enjoy the show!';
        }).catch(function(err) {
          /*
           * If this request fails, the server will respond with a human-readable error message.
           */
          console.error(err);
        });

        /*
         * Next we will set up an event listener on the SDK that will listen for a named event
         * coming to the extension.
         */
        sdk.listen('motd', function(event) {
          document.querySelector('#motd').innerText = event.motd;
        }).catch(function(err) {
          console.error(err);
        });
      });
    </script>
  </head>

  <!--
    Not much markup is needed.
  -->
  <body>
    <h3>Message of the Day</h3>
    <p id="motd"></p>
  </body>
</html>

Broadcaster Live Dashboard Code

Next let’s put together the Live Dashboard Extension that will only appear on the broadcaster’s live dashboard after they have activated the extension (e.g. https://www.twitch.tv/muxy/dashboard/live). This Live Dashboard Extension will allow the broadcaster to set a message.

<html>
  <head>
    <!-- We load and initialize the Muxy SDK in the same way as on the panel. -->
    <script src="//ext-cdn.muxy.io/medkit/latest/medkit.umd.js"></script>

    <script type="text/javascript">
      /*
       * Here we are using the debug system to give the SDK a hint that this will run on the
       * broadcaster's dashboard and have the same rights a broadcaster does. This is only needed
       * and used when developing an extension. Once it is deployed to production, the backend will * use the correct rights from the extension system. You can leave these lines in and they will
       * be ignored when running in production.
       */
      const opts = new Muxy.default.DebuggingOptions();
      opts.channelID('126955211').role('broadcaster');
      Muxy.debug(opts);

      Muxy.setup({ clientID: 'replaceme' });
      const sdk = new Muxy.SDK();

      function changeMotd() {
        const motd = document.querySelector('#motd').value;

        /*
         * We wait for the SDK to confirm it is loaded each time the button is clicked. In a real
         * extension you may want a more robust solution, although there is no harm in calling
         * this function multiple times.
         */
        sdk.loaded().then(() => {
          /*
           * First we send the updated message state to the backend. This ensures that future
           * requests to get the extension state will have the most recent message.
           */
          sdk.setChannelState({
            motd: motd
          });

          /*
           * Then we broadcast an event to all current viewers with the new message. This will
           * allow the panel extension to update its message without continuously polling
           * the backend.
           */
          sdk.send('motd', { motd: motd });
        });
      }
    </script>
  </head>

  <!--
    Not much markup is needed.
  -->
  <body>
    <textarea id="motd">Hello, world!</textarea>
    <p>
      <button onclick="changeMotd()">Set MOTD</button>
    </p>
  </body>
</html>

Next Steps