[SOLVED] Backend Service: Broadcast to PubSub from Backend using Auth.Token JWT

I ended up getting it working per the docs.

The extension auth,token is passed to the extension backend.

The backend parses the auth.token from the viewer auth callback to get the JWT info.

The backend broadcasts data to the PubSub via a POST.

// C#
public void SendFromExtensionBackEnd()
        {
            try
            {
                if (string.IsNullOrEmpty(_mAuthToken))
                {
                    return;
                }

                string[] parts = _mAuthToken.Split(".".ToCharArray());
                string str = parts[1];
                int mod4 = str.Length % 4;
                if (mod4 > 0)
                {
                    str += new string('=', 4 - mod4);
                }
                byte[] data = Convert.FromBase64String(str);
                string json = Encoding.UTF8.GetString(data);
                JObject jwt = JObject.Parse(json);
                if (null != jwt &&
                    null != jwt["channel_id"])
                {
                    string url = string.Format("https://api.twitch.tv/extensions/message/{0}",
                        jwt["channel_id"].ToString());

                    JObject sendBody = CreateSendBody(importantInfo);
                    if (null != sendBody)
                    {
                        string sendContent = sendBody.ToString();
                        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
                        request.Method = "POST";
                        request.ContentType = VALUE_CONTENT_TYPE;
                        request.Headers[HEADER_AUTHORIZATION] = string.Format("{0}{1}",
                            VALUE_AUTHORIZATION,
                            _mAuthToken);
                        request.Headers[HEADER_CLIENT_ID] = VALUE_CLIENT_ID;
                        byte[] bytes = Encoding.UTF8.GetBytes(sendContent);
                        request.ContentLength = bytes.Length;
                        using (Stream stream = request.GetRequestStream())
                        {
                            stream.Write(bytes, 0, bytes.Length);
                            stream.Flush();
                            stream.Close();
                        }
                        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                        if (null != response)
                        {
                            response.Close();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.Error.Write(ex);
                Console.Error.WriteLine();
            }
        }

And then preparing the body I’m doing a little extra by compressing the message on the backend.

        const string HEADER_AUTHORIZATION = "Authorization";
        const string VALUE_AUTHORIZATION = "Bearer ";
        const string VALUE_CONTENT_TYPE = "application/json";
        const string HEADER_CLIENT_ID = "Client-Id";

        public JObject CreateSendBody(string message)
        {
            byte[] bytes = Encoding.ASCII.GetBytes(message);
            using (MemoryStream ms = new MemoryStream())
            {
                using (ZipOutputStream zipStream = new ZipOutputStream(ms))
                {
                    zipStream.SetLevel(9);

                    ZipEntry zipEntry = new ZipEntry("a.json");
                    zipEntry.DateTime = DateTime.Now;
                    zipStream.PutNextEntry(zipEntry);

                    zipStream.Write(bytes, 0, bytes.Length);
                    zipStream.Flush();
                    zipStream.CloseEntry();
                    zipStream.IsStreamOwner = false;
                    zipStream.Close();

                    ms.Position = 0;
                    bytes = ms.ToArray();
                }
            }

            string compressed = Convert.ToBase64String(bytes);

            JObject jobject = new JObject();
            jobject.Add("content_type", VALUE_CONTENT_TYPE);
            jobject.Add("message", compressed);
            JArray targets = new JArray();
            targets.Add("broadcast");
            jobject.Add("targets", targets);
            return jobject;
        }

I updated the decompression library on the frontend to use this.

https://stuk.github.io/jszip/

The backend compresses with SharpZipLib with max compression (9).

1 Like