Services can Cause Frustrations
After surpassing the challenges I previously mentioned, I started to look at populating both the viewer listbox and the events listbox. After taking a quick look at the non-existent documentation that is provided, it looked like dealing with the viewer listbox was going to be the easiest of the two to populate.
To my surprise it was a lot easier to get working then I originally thought it would be, in our client class, I needed to setup just two event handlers and create a little thread safe function to write to the view listbox. The code can be seen below to see just how simple it can be! The only downside I have found with it so far is that it takes a while for the box to update fully with your channel’s viewers, but that is a problem for the refactoring and improvement stage.
With this working so well I felt like I was on quite a roll and that the events box which would handle new followers, incoming raids, hosts, bits and subscriptions would work almost as well and be implemented just as easily… How wrong I was! I decided to start on the followers side as it seemed like it would be the easiest to handle, I managed to find a bit of code on a GitHub issue from one of the developers which whilst it helped me to learn about the need to implement the follower service, the code sample did not work (see a snippet of it below):
private void FollowerService_OnNewFollowersDetected(object sender, OnNewFollowersDetectedArgs e)
{
form.WriteChat(“Thank you for following ” + e.NewFollowers.Select(X => X.FromUserId));
form.WriteChat(“Thank you for following ” + e.NewFollowers.);
}
This is the first implementation after fixing up a few errors from the provided code but alas it only printed an enumerable string into chat, progress I guess but I was no further ahead then I was originally. After a few hours of searching for solutions and getting nowhere with support in the TwitchLib discord, I finally managed to get to the point of getting fifty or so user id’s to print out into the chatbox and event listbox with the below:
private void FollowerService_OnNewFollowersDetected(object sender, OnNewFollowersDetectedArgs e)
{foreach(var user in e.NewFollowers)
{
form.WriteChat(user.FromUserId);
form.AddEvent(user.FromUserId);
}}
The start of progress I guess, the new issue is that I obviously do not want the last fifty-ish followers, I only want new followers, otherwise it makes it pointless! After a bit of frustration, I took a step back and noticed that the datatype for e was a List, awesome I thought, lists can be traversed so I can at least move to the end of the list and work from there! Surely enough there was a last() call that I could append to e.NewFollowers… Except I have to assign it to a new variable because it doesn’t return a type of string, it returns a type of follower, the below is the third iteration which up until a few hours ago, bearing in mind, I started on this part 2 days ago (around 7-8 hours of “dev” time), got us the user id of the last follower but only updates once the bot is rebooted, which is not great but a massive leap forward.
private void FollowerService_OnNewFollowersDetected(object sender, OnNewFollowersDetectedArgs e)
{
TwitchLib.Api.Helix.Models.Users.Follow follower = e.NewFollowers.Last();form.WriteChat(follower.FromUserId);
form.AddEvent(follower.FromUserId);}
Next challenge is to convert the UserId to a string and it will be almost perfect, e.NewFollowers doesn’t provide a way to convert it and whilst there seemed to be a few ways within TwitchLib to do it, none of them seemed straightforward in implementing or were just too slow which was a pain. I took a large portion of the next day to read up on the different options and the best one that was coming out of it required me to read up on asynchronous calls a bit so I focused on that, which took a while but I feel I understand a bit more now. Finally I tried a slight modification to the code and after a couple of tests and a bit of modification, I was finally able to successfully turn the user id into a display name… On top of that, it had a side effect of fixing the issue where it would only update when the bot was reloaded! Yes, it still shows the last follower upon booting up, but it now shows any new follower which is absolutely amazing and below is the current state of the code that made it work:
private void FollowerService_OnNewFollowersDetected(object sender, OnNewFollowersDetectedArgs e)
{
TwitchLib.Api.Helix.Models.Users.Follow follower = e.NewFollowers.Last();var username = api.V5.Users.GetUserByIDAsync(follower.FromUserId).GetAwaiter().GetResult();
form.WriteChat(username.DisplayName + ” just followed, thanks!”);
form.AddEvent(“New follower ” + username.DisplayName);//form.WriteChat(follower.FromUserId);
//form.AddEvent(follower.FromUserId);
//form.WriteChat(username + ” just followed, thanks!”);
//form.AddEvent(“New follower ” + username);//foreach(var user in e.NewFollowers.Last())
//{
// form.WriteChat(user.FromUserId);
// form.AddEvent(user.FromUserId);
//}
//form.AddEvent(String.Join(“, “, e.NewFollowers));
//form.WriteChat(“Thank you for following ” + e.NewFollowers.Select(X => X.FromUserId));
//form.WriteChat(“Thank you for following ” + e.NewFollowers.);
}
I decided to leave the previous code in, commented out because I wanted to see the evolution of the function and share that with anyone that reads this. So far, we can get new followers now but at the beginning it loads up and presents us with the last follower we gained, that will be easy enough to fix, we just need to add an if statement in to check the follower’s follow date and make sure it is greater then the stream start date/time. The only other issue here is that there seems to be no real way to natively handle a user unfollowing and refollowing, it will still trigger the event handler.
These are the challenges that I will be facing for the next post, along with host, bits, subs and raid events (hopefully)!