New Tool Release: Bluesky Live

Bluesky Logo

Somewhat recently Bluesky added the ability to mark/set yourself as Live on Bluesky and link out from Bluesky to a given service. At the moment that is a short list of services, but includes Twitch and Stream.place among others.

If you were to set yourself as Live manually on Bluesky, you are maxed to 4 hours, so you would need to remember and come back to bump your time or manually remove the status if you ended before 4 hours.

Given Bluesky oAuth is a thing, and because App Passwords are not tooooo much fun with work with IMO, so I built a tool to implement Bluesky oAuth as an adventure in how Bluesky does oAuth (thats likely gonna be a separate post as it’s pretty interesting and in depth).

I’m still tweaking/optimising how my code runs as there are some caching layers that could be added to speed up operations, but I digress!

AND SO via the powers of Twitch oAuth and Twitch eventsub, pair the two services together to do Bluesky Live AUTOMATICALLY! (Anyone using Stream.place it’s native to the platform)

MAGIC!

The only drawback is that Bluesky oAuth is a smidge brittle, as outlined in this Issue on GitHub I authored, even when you have your Client configured as confidential. And understanding how scopes work is FUN! (Follow up post soon)

Well what does it do?

First of all it handles the 4 hour max issue, by “bumping” the expiration time automatically whilst the Twitch channel is live. As well as:

When you go live on Twitch

  • Mark your Bluesky as live with a link to your Twitch
  • Applies your stream title as the title as Bluesky live entry
  • Applies your stream thumbnail to the Bluesky live entry

When you change your Title or Category

  • Applies your new stream title as the title as Bluesky live entry
  • Applies your new stream thumbnail to the Bluesky live entry

When you go offline on Twitch

  • Delete the live status

Periodically/every 15 minutes

  • Updates the thumbnail from Twitch to Bluesky
  • Updates the title from Twitch to Bluesky
  • Rebump the expire timer
  • Sanity check and remove the status

But wait, there’s more

Yes there is MORE!

Kylo Ren yelling MORE on loop
MORE!

Since this tool pairs your Twitch account with a Bluesky Account, when the job runs to maintain Bluesky live status, it can see if you are live elsewhere (manually set or auto set by another service), if that elsewhere is not Twitch then I won’t overwrite or attempt to manage it.

But, if it IS Twitch, then I’ll maintain the live status (and the thumbnail), so if you manually marked yourself as live on another channel, the tool will maintain the thumbnail and expire timer till that channel goes offline (or you manually remove it) which is great if you are guesting on another stream, or doing a Dungeons and Dragons show for example elsewhere on Twitch when it’s not dual streamed to your own channel.

Why 4 Hours

No idea, but on the upside it does mean that if the oAuth breaks due to the brittleness or other reasons, and the tool cannot write to your Bluesky account any more, the status will self disappear on its own.

Then you just need to reauthenticate to the tool and away it goes

Ok, let me use it

You can find the tool over at https://bluesky.chatbot.barrycarlyon.co.uk/ and it comes with the bonus of listing who is live using the tool! FREE DISCOVERY!

Starship Discovery care of https://memory-alpha.fandom.com/wiki/Star_Trek:_Discovery

And yes it works with custom Bluesky handles, like mine barrycarlyon.co.uk and should work with ANY PDS (personal data server).

Support can be found via my Discord, check the site for the invite link down the bottom right, and/or support the tool via my ko-fi! Or drop me a line thru the usual channels.

Free support methods? Well retweet/repost the Twitter or Bluesky posts about it! (or the ones about this blog post that I don’t have the links to yet!)

A screenshot of the Tool showing a handful of live streamers on Twitch whom are using the tool.

Twitch App Access Tokens – YAY ANNOUNCEMENTS!

You may have read the previous post about Twitch App Access Tokens doing more, and my sadness about Send Chat Announcement not being supported, well yesterday that was rolled out!

A screenshot of an announcement in Twitch Chat with the wording "BarryCarlyon: I made this using an App Access Token"

But Wait, theres MORE

Yes, there is more to the MORE!

Send Chat Announcement includes the same control/ability that Send Chat Message has, the ability to control if that Announcement goes to all Channels if the channel is in shared chat mode, with the default being true/send only to home channel.

So broadly this means you can run a Twitch chat bot off JUST the App Access token, as most functions a chat bot will do day to day in the primary function thread can use the Token.

Which has the added benefit of not having to juggle tokens, user refresh tokens, saving those, as to get a new App Access Token, it’s just load ClientID and Secret from env and go get a new token! And of course App Access Tokens has a longer life time of around 60 days or so, which means less refresh operations overall!

To also note there are no additional permission/scope changes here! You should be all good to go if already using conduits and were user token-ing to send announcements.

So What Else?

The Change Log offered the following:

  • channel.chat.notification now emits Watch Streak events! No longer will a bot need to listen to IRC for this single event (oooooh wait first-msg maybe that soon…), also payloads for announcements updated in line with the Send Chat Announcement change, notably as it’s not a breaking change it’s added to V1,
  • channel.bits.use has been updated to support “Custom Power-ups” whatever those are…
  • AND FINALLY: Theres a RSS Feed for the change log now!

Help?

If you need further help please join as over on the Twitch Dev Discord or Support Forums! And for anything Feature Request – Uservoice!

Twitch App Access Tokens can do MORE!

In the beginning App Access Tokens could just load public data, that didn’t need any oAuth scopes, from Twitch API. And so any given developers project had to maintain a user access token(s) for users of their application.

Then extensions were introduced, bundled in Extensions are Subscriber support, allowing extensions and their EBS to read a given viewers subscription status to a channel, outside of the Extension JS Helper function to check the status in client side code. That then leaves how does an Extension EBS (aka Backend Service) perform the same call (since you should never trust the client) to perform the same check.

And so Extension generated App Access Tokens, could call Get Broadcaster Subscriptions. The first endpoint that is scoped that an app access token could load on behalf of a user.

Since then various aspects of Twitch Developer Tools have come and gone, we lost WebSub, and we lost PubSub, and we lost both (over time) in favour of EventSub. There is a bunch of other stuff that happened but the important part here is that with the loss of PubSub, Eventsub achieved “featured parity” with PubSub and a number of other things introduced Chat over Eventsub.

EventSub

An Extensions ability to grant the ability for an app access token to call subscriber information is baked into the “install an extension” work flow.

An extension that offers the Subscription and Chat permissions (chat here has it's own endpoint using JWT), but subscriptions grant the power for app access tokens to be able to read.

But EventSub introduced the dual (or even triple) legged auth approach.

First a user will need to perform a user oAuth loop, either Implicit, Authorization Code, or DCF (Device Code Flow). This then creates a link between the user and the ClientID along with the scopes requested.

Combine that with the recently added Get Authorization By User endpoint to check what scopes your ClientID has to a given user, you can check permissions before trying to create EventSub Subscriptions for Webhooks or Conduits.

So for eventsub the pattern is:

  • Check the conditions and scopes needed for the EventSub Type/Topic
  • For the user’s in the condition get that user to user authenticate with the needed scopes
  • Generate an active app access token (if you don’t have one already)
  • Create the Subscription

As an aside you can use “user.authorization.grant” to easily monitor for new user authentications and create subscriptions as a follow up, if say your user token gen is air gapped from your Eventsub handler. This is a pattern I use on the IGDB Extension to monitor for authentications and create subscriptions to stream.online/offline and channel.update (which yes are public topics but become cost 0 _if_ the user is authenticate to the Client ID, and I use the user.authorization.revoke to unsubscribe since I only want to keep cost 0 subscriptions), becuase the IGDB Extension config page launches an implicit flow since I don’t need the user token ever I just need to auth so creating one with a refresh token is overkill, but I digress….

So that briefly is how EventSub dual legged auth operates.

Chat Over EventSub

Then along came Chat over Eventsub and a bunch of separate topics essentially providing IRC chat as a already JSON-ifed consumable feed.

This also came with Conduits and the ability for chat bots to scale to as many channels as needed, because the broadcaster auth’s the chatbot to be present on their channel. It is similar to how adding Discord Bot to a Discord Server works from a broadcaster point of view.

But chat over eventsub specified two user ID’s in the condition. (which yes can be the same ID but we’ll skip that for simplicity).

So first a developer would

  • Create a Client ID (generally owned by their own Twitch profile but the other of a Client ID is irrelevant, it’s always whom auths to the client that is important)
  • Create a Twitch account with the username of the bot they want to use
  • User Authenticate the bot to the Client ID with the relevant scopes
  • Then authentication any number of broadcasters to the Client ID
  • Now you can rejoin all channels with one API request (update shard), great for restarts or outages, as restart the websocket, call update shard, and then the bot is back in all rooms, no more slow roll rejoins or rate limit joins/etc.

So that is briefly the triple legged auth of chat over eventsub.

So What about App Access Tokens on the API?

Send Chat Message was introduced at the same time as chat over eventsub and is the first “proper” endpoint that worked with App Access Tokens following prior auth from the user(s) involved, (the broadcaster_id and sender_id)

This meant that for “general” operations a chat bot still needed to load and maintain either the broadcasters user token for Start Commercial for example, or the bots own token for Banning a User from chat.

So a bot would be juggling and maintaining up to three tokens,

  • A broadcasters token for broadcaster based operations
  • A bot token for doing moderation actions (for example), or sending chat
  • An app access token for subscription management (or sending chat)

But, now, as of yesterday! For the most part that is no more!

Well Spill the Beans then!

TWENTY ONE API endpoints now support this pattern of using an App Access Token after performing prior user(s) authentication(s). Look for the Beta tag under the Authorization section of each endpoint.

Here is the list:

Update April 3rd: Send Chat Announcement is now supported on this pattern!

Anything marked in bold with a * has additional scope requirements compared to the user token version, please check the docs, but I suspect your bot will likely already have obtained the scopes.

So now a chat bot broadly doesn’t need to maintain or even keep on file a user access token for itself or the broadcaster, as most general operations a bot is gonna do will work using the App Access Token. This also comes with the bonus that a user access code flow token is only good for 4 hours but an app access token is good for much longer. (Remember to utilise the Validate Token Endpoint to check time remaining on a token)

I’ll note that “Get Clips Download” supports this pattern, but that API was introduced with the pattern.

But a Sadness

However, the obvious missing endpoint that doesn’t support this pattern is Send Chat Announcement which I hope is supported soon, I think that’s the only one I need to token juggle for at the moment.

Update April 3rd: Send Chat Announcement is now supported!

Summary

Thats it! Go forth an App Access Token! And hopefully more of the API will support this pattern over time!

If you need further help please join as over on the Twitch Dev Discord or Support Forums! And for anything Feature Request – Uservoice

Bonus Thought

Cronjobs that need to do something on multiple users/broadcasters, the script starts, loads the token, does the job and just switches the user ID no token switchin’!

Google oAuth and offline access

Been doing a lot of various stuff and things for CohhCarnage and some of that stuff has involved building an achievements tracking system for the website.

One of those achievements, is for YouTube Subscription. Where the achievement is awarded to the logged in user, if the user has subscribed to a given YouTube channel, in this case Cohh’s YouTube.

In order to make sure that people can’t “cheat” the system, we ask them to link their Google/YouTube account with the website and use the relevant API to look up their Subscription status.

Initially this worked fine, but I ran into some issues where the oAuth token stored has expired and thus I can’t do a status check, for cases where the user links their YouTube to their Cohhilition Account then doesn’t subscribe on YouTube until after 24 hours later (or some caching issue with Google).

So, the simple fix using Googles PHP Library for oAuth’ing is to just do a

<?php

$client->setAccessType('offline')

Now, this works fine for the most part, you happily get a refresh token, and can thus renew your token.

Then comes a hiccup, if for whatever reason you have offline access type on, and the user has previously authorised the application and it’s offline permission, you DON’T get a refresh token in some cases. Some user cases include:

  • you’ve lost their token,
  • or got a bad one
  • or the user managed to find the authentication loop (again) when they shouldn’t, and thus a new code/token combo is generated

Normally you are using something like:

<?php

$client = new Google_Client();
$client->setClientId($client_id);
$client->setClientSecret($client_secret);
$client->setRedirectUri($redirect_uri);
$client->addScope("email");
$client->addScope("profile"); 
$client->setAccessType('offline');// last forever/give me a refresh

But in order to make sure that you get a refresh_token EVERY time someone goes through the authentication loop, you have to adjust as follows:

<?php

$client = new Google_Client();
$client->setClientId($client_id);
$client->setClientSecret($client_secret);
$client->setRedirectUri($redirect_uri);
$client->addScope("email");
$client->addScope("profile"); 
$client->setAccessType('offline');// last forever/give me a refresh
$client->setApprovalPrompt('force');// force a refresh token return everytime

Apparently, using

'offline'

is supposed to imply

'force'

according to some Stack Overflows posts, but this doesn’t seem the case.

In the end my full Google_Client setup looks like:

<?php

        $client = new Google_Client();
        $client->setAuthConfig($consumer);
        $client->addScope('profile');
        $client->addScope('email');
        $client->addScope('https://www.googleapis.com/auth/youtube.readonly');
        $client->setAccessType('offline');// asks for a refresh token
        $client->setApprovalPrompt('force');// forces the refresh token being returned
        $client->setIncludeGrantedScopes(true);
        $client->setRedirectUri($callback);

Just an odd thing I came across recently that I thought I would write up. Most of the notes here are from Stack Overflow post on the subject

Some Random Useful Things

Some random useful things:

Twitter, is scrapping Basic Auth! Which means no more simple curl calls, its on to OAuth.

Check out http://dev.twitter.com/pages/basic_to_oauth for how to update your Apps/Usage, and http://countdowntooauth.com/ for a handy countdown.

In other twitter news, I use Notifo to forward my twitter replies to my iPhone, which uses Push.ly to grab the stream. Twitter has currently borked @Replies both in apps and on the website, however Notifo announced they have updated their website with a new design, (hurrah), and a desktop client (further hurrah).
So with my mac and growl I now get Growl @ Responses….. SUCCESS!

Thats enough twitter! I was linked in a random IRC channel to http://jsfiddle.net/, which is a sort of real time code and run/test interface for several different javascript libs, including MooTools, and jQuery. Its currently in Alpha and under “heavy development”, so far I have found it quite useful, since it saves a lot of time in prototyping something. Looking forward to when they add user accounts, will be easier to track my own fiddles, heres the 5th version of me fiddling with jQuery UI tabs yes it has basic version control!

Facebook next, came across this today: http://developers.facebook.com/roadmap pretty much nails the coffin shut on FBML and suggests that we will all be using iFrames instead….

Not sure if this is a good thing or a bad thing, since iFrames are not always the most secure of things, but will make sending more upto date stuff to a Facebook page easier. And no longer stuck with Facebook caching, which in itself is a useful thing….

Also they are moving to a larger oauth setting with the use of oauth version 2! And scrapping their Rest API.

So there is a lot of change going on within two of the larger things I have been involved with (in terms of building things for clients), so in this vein when is the Last.FM api moving to oAuth too, tho it does use a token based Auth now?!

I’m gonna need to do a lot of recoding/refactoring for things that use FBML and basic Auth….

Is oAuth the future for all API’s? What do you think?

Edit:

O and I am going to invest in one of these!