You Know It's Going to Kill Me in the Basement Later

Streamed

Moving mod actions to a mod controller namespace, PR #1807. RSS feed cache key filename length bug, issue #1826. VPN IP blocking and collateral damage, issue #1828. Database host configuration PR, #1829. Contributing documentation reorganization, #1831. Removing credentials requirement in dev, #1830 and #1832. Mastodon OAuth state parameter security fix. Hatchbox deployment and zero-downtime deploys. The office hours footer hack with SSH and file touching. Chael’s modmail PR, #1822, a big one. Flags, karma, and community moderation norms. Happy holidays, office hours on winter break.

scratch


topics
  issues
    rss filename too long https://github.com/lobsters/lobsters/issues/1826
    vpn block https://github.com/lobsters/lobsters/issues/1828
  PRs
    database_host https://github.com/lobsters/lobsters/pull/1829
    contributing https://github.com/lobsters/lobsters/pull/1831
    no creds in dev https://github.com/lobsters/lobsters/pull/1830 ->
    rm creds migration warning https://github.com/lobsters/lobsters/pull/1832
    first pass on modmail! https://github.com/lobsters/lobsters/pull/1822
  domainscontroller
    also origins
    test origins rss
  mastodoncontroller
  


title
  that is evocative but not informative

post-stream
    

Transcripts are generated with whisperx, so they mistranscribe basically every username and technical term. They're OK but not great, advice appreciated.

Recording



03:14ChaelCodes Happy Monday!
ChaelCodes lol
marcoroth_ πŸ‘‹πŸΌ
ChaelCodes I made them small, because it's better than 30+ files
in seriousness yeah so that's gonna be a big chunk of the stream here this morning afternoon is chael has been taking some great initiative on improving the dev setup experience so i'm really excited to look at that and otherwise oh hey marco congrats on your award For anybody who doesn't know Marco just won a was at the rails luminary award. pushcx https://rubyonrails.org/2025/12…
ChaelCodes πŸ‘‹
marcoroth_ Thank you!
yeah chill Thank you that makes them a lot easier to handle. So speaking of rails PRS.

04:08it's a. was thinking a lot about this i've been thinking a lot about herb and reaction view the last two months or so they really are the most interesting thing that's happened to herb and action view in a very long time and they're just they're technically impressive and ChaelCodes So true!! πŸ’―
They help with something that's really been a sore spot. So well-earned, nice recognition. So yeah, this is a Rails app, Lobsters. You like my transitions? I would make a terrible DJ between all the dead air and the bad transitions. pushcx This is Lobsters office hours, ask questions anytime!
And oh, I've got to put the thing in chat here. this is lobsters hours questions anytime so yeah if folks have questions about the site or the code base or the community or the moderation or well really anything that's decently related we're happy to talk about it and then otherwise i do maintenance here on stream So let's take a look. I don't think there have been issues filed. Ah, VPN stuff. Yeah. So I know what this one is, and I tagged it as a bug. I don't remember if this came up last stream. This came up in the chat room. I had enabled some more caching. caching saves to the file system you remember we already had one bug related to how the url is complicated and turned into a file name well this person has a rss feed where they go to slash so you can go to like slash tag slash linux great you can also go to slash tag linux or i don't know security or release or unix i'm just picking off of the related ones and then you see all of those and so if we tag a rss on the end well firefox is going to download it but like congrats you can have an rss feed and they have like 30 plus yeah they say 30 tags it's i think it's more like 50 tags in one rss feed And so the cache is failing to generate a valid file name. I should mention.

07:57I promise I haven't gotten into the eggnog yet. Just getting up to full speed here.

08:58So that's a fun one. And then what's the new one? This one is definitely going to be... Yeah. It's not TLS. This one is... It's not really invalid.

09:35So I did this one on the last screen. that we have had to ban a bunch of IPs that we saw bad behavior from.

10:46What's the other one? I think it was Molad.

11:18I'm not the same. What do I want to say? It's not friendly fire. And it's not a false positive. Collateral damage. I'm dealing with. I'm preventing abuse.

...48really anything to do there yeah so i didn't grab either of those vr links for the notes so let's put those in the notes because i did issues before prs and then let's grab the

12:26Alrighty, let's jump over to polls. All right, so we have. OK, so we have a bunch from Chael here. And then. Story image preview which got a round of edits so okay i'm chill is there any suggested order here these don't look like they have a dependency order, but maybe i'll do the dev container setup last. Or is it the only one with comments and I should look at it first. ChaelCodes No dependency order, skip the devcontainer one
Because this was part of what kicked off our conversation was.

13:23skip the dev container ah because it's still got a something unchecked okay so let's get these three open and i'll just go in tab order do you want to save on typing and i could like discord call you to just add you to the stream

14:01ChaelCodes Yeah, give me a minute
No creds in dev.

...10hugoarnal_ Hi there! Finally able to catch the office hours on time :-)
Sure. I can vamp. I've got other stuff to do. there's yeah. Oh, Hey Hugo. Welcome. Yeah, the flip side of keeping a pretty regular schedule is if it doesn't line with yours, it will never line up with yours. Unless you're off for the holidays, maybe. All right, so where's... Let's look at app controllers mod. Did I have... No. So what do I want? Let's look at... controllers mod stories controller. So there's some functionality to push around here in domains controller. And I'm going to use my own work as a template.

15:21Don't have story finder, but inheriting from mod controller means it's just mods. And then, yeah, I really didn't need to use this template. We will need a params, but that's already there. graefchen Heya chat & pushcx limesHi
So let's do that. And I wanted to, what was the number on it? Where's my personal browser? It's over there.

...57ChaelCodes Ready!
Yeah, so it's... ...mod actions to a mod controller. That's related to 18.07. And...

16:27not really related to world 59 okay so 1807 is about hats controller because there's a whole bunch of this okay give me like well you know jj makes it easy to juggle stuff so let's go back to new on main and then my steps here. Okay. Let me pull up discord, which is going to be off screen here. Give me just a second.

17:31discord oh my god and then close the discord ads okay i'm gonna mute myself just so that we don't have like weird voice stuff as i'm getting her connected

24:11ChaelCodes pushcx is currently figuring out OBS settings
ChaelCodes We DID NOT plan this
Frici πŸ‘‹
graefchen Heya Frici limesHi
ChaelCodes testing
ChaelCodes testing testing
hugoarnal_ testing confirmed
ChaelCodes Thank hugo
ChaelCodes Chael says "I can just type"
ChaelCodes Pushcx says "It's so much nicer if they can hear you though"
Frici Right now unless its on my end we can't hear any of you HahaSweat
ChaelCodes That is correct
Frici the my end bit or the inaudible bit ? JinxLUL
ChaelCodes The inaudible bit
pushcx Yeah, this is me having hassles
ChaelCodes We did not prepare for this
hugoarnal_ heard something
Frici oh a blurpl
hugoarnal_ we're hearing discord sounds
Thank you.

27:18pushcx Yeah, something is very confused in the audio stack
ChaelCodes unsuccessful audio attempt
hugoarnal_ sadge
Okay.

...49ChaelCodes **do not attempt audio live**
ChaelCodes **especially do not attempt audio through linux and Discord live**
Frici you are muted and now choppy
pushcx Yeah, no luck on audio
Was I muted there for the last 30 seconds? Goddammit, can't do anything. All right, yeah. Yeah, no luck.

28:04Frici well were muted*
ChaelCodes choppy now :(
Both muted and choppy, that's brutal. hugoarnal_ it's good now
marcoroth_ seems to be fine now
Frici sounds like its getting a bit better
All right, so I've got the workaround open and I won't close it. ChaelCodes Better now
Yeah, I was muted.

...21Frici less choppines
Frici Yeah ok better now
Well, I hope nobody ever gets the impression that I'm any kind of professional about this. ChaelCodes Back to hats!
So at least we're back to baseline competency as opposed to, you know, more and more dead air while I'm struggling to add a caller. All right, so this, I will come back to this. And then let's jump through Chail's PRs.

...57Frici I have no idea what your audiostack is like but then again nobody has an idea what the audiostack is like on Linux JinxLUL
No, no, I'm going to punt on the hats, because as long as I have you live, I would like to be able to talk about these. Yeah, and honestly, I don't know what it is, because it's mostly Pulse audio, but there's still stuff labeled also, because it's just one desktop that's been upgraded for years, or one... I mean, honestly, I have... the same home directory that I've had since 98? ChaelCodes Yeah, I've been trying to catch the streams, but Monday is a 2 kids days, and Thrusday I'm live.
Frici pulseaudio sits on top of alsa anyway tbf , so would have it anyway
Somewhere in like 97, 98, there was a hard drive crash and I lost my home directory. ChaelCodes But soon I'll be remixing my schedule!
I didn't, I managed to keep the vimrc because I had copied that one to my work computer. hugoarnal_ quite impressive
And I think my bash profile, but that was about it. Yeah, I don't, I don't even want to know what All right. So. So Chael and we're talking about ways to improve the development setup because speaking of things that have been around for a minute lobsters is a 13 year old rails app and for a framework that values convention over configuration there are like nine ways to configure anything and since we've been around for a long time we have all of them so we've Frici I was expecting that sentence to end with "and thus we found the secret 14th way to go about it"
talked about offline a little about how to simplify things okay database host db is this like a yeah no we don't have a secret 14th way secret 14th way is i write a web framework

31:07ChaelCodes These are all small, easy to merge changes that make the giant PR easier.
So this is host DB is some kind of Docker-specific thing. ChaelCodes YES! Your maria container is db.
DB is the name of this other image, so it somehow turns this into go look at the port from MariaDB.

...47okay i almost wondered from our discussion if it was going to be possible to completely drop the config database yaml and just put the credentials only in an environment variable or put something like this and just have a stub file because there is a setting or two in here yeah like the timeout

32:22At this point.

...40Oh, I get it. So if you're passing the string DB, that becomes a local host name and Docker. takes that host name and shoves it into DNS somehow. ChaelCodes Rails really needs a database.yml. If you want a dtabase.yml instead of a database.yml.sample, I could do that!
Okay. Yeah, I mean, it's not going to that full database URL string.

33:21ChaelCodes ENV.fetch('ENVIRONMENT_VARIABLE_NAME'){ "default if value not found" }
all right i think i mean it would be nice to get rid of the step one of the reasons for having the sample i guess we could do that as a separate line like yeah let's make that an initializer that If you are in development and the server starts, if we can hook... Yeah, very familiar pattern. If we could hook an initializer early enough in the Rails setup to copy database YAML sample to database YAML in dev, that would be an improvement too. ChaelCodes You already do that in bin/setup
But we do need to keep it out of Git because as soon as somebody configures this, and I know some people want to have a username and password even on their local MariaDB. All right. This is... I do? Must be why I like the idea. It's my idea, huh? Aha. Good. All right. Well, that's probably as good as we can do then. Let's go ahead and merge this.

35:22And then the big one for end fetch, which I can guess what this one's going to look like.

...37I can't guess what is. Oh, this site work file is. Yeah, speaking of things I already do, this one is some legacy code. ChaelCodes READ MY DESCRIPTIONS
And now that it's a couple years old, don't actually need to set the credentials. ChaelCodes Please, I beg you
We call credentials and initialization can handle an empty value. We need the credentials to test certain features, but not to start. However, this reason site work was preventing the real server from starting in development unless they're set. I will do so, I'm not used to people writing especially thorough PR messages. Now the error is still put in the log, production still requires credentials, and the credentials are still included in the documentation, but the server can actually start without them.

36:43I think if I remember, I only wrote the raise to force people to come and read the comment.

37:22if they're all optional. So the specific API keys for people who are not Chao are things like the Twitter API key, the Mastodon API key, and a couple of other things. And the code base's use of them has generally been, You know, I can't say we're 100%, but given the content of this PR, I would guess we are 100% careful about, hey, if we don't have that configured, we're just going to remove the feature. So like if you spin up a dev instance, you won't see the connect to GitHub button because you don't have a GitHub API key. And we do that for sister sites that don't want to set things up and just to make the site, the code base a little bit more robust.

38:33ChaelCodes Well, it's more that it spins up. Sister sites will still complain in production.
but if all of the API keys are optional,

...58ChaelCodes I don't know if we hide the pushdown buttons.
ChaelCodes Or GitHub auth.
Yeah, that one's a little special because the original author of the codebase, JCS, wrote pushdown. And so I think he assumed that pushdown would always be there. And a lot of that early stuff, the idea of gently supporting sister sites, or at least not giving them so many time bombs, really didn't come about until the codebase was a couple of years old.

39:49So, so Chael, at this point,

40:10Is there value to even printing this message? Because it's been, I don't know, a year or two. And I think it's safe to say that any developer would have seen this message already. And honestly, there's only two known sister sites that are live. ChaelCodes New contributors might need to see it.
We could probably just delete this completely.

...44New contributors? ChaelCodes But if you want me to delete it, I'm happy to do so.
OK.

...55I would hope that new contributors are working through the setup steps, but people skim.

41:06ChaelCodes Standard didn't like that I used puts.
Secret key base.

...15marcoroth_ doesn't rails have a message for that itself?
yeah it doesn't marco it's possible but sometimes we miss those code paths due to predating features and so even though we've generally been real deliberate about updates Sometimes there's like a check missing in the auto-generated config files because during the exact point release of Rails that introduced something, we didn't add a new value and so we don't go down that code path. I don't have a lot of confidence there though.

42:07Yeah, Chill, I think this is safe to just delete if you want to do that. Like everybody's had, let's go look at how old this is.

...39ChaelCodes Aye aye, captain!
Yeah, it's now over a year old. I think it's okay to delete. We have a not terribly principled lack of support to sister sites. It's sort of a, I don't want to break them unnecessarily, but at the same time, if they show up in our bug tracker wanting features, I tell them to go away. I don't know where the line is, but

43:13Yeah, I think it's safe to just go ahead and remove. 2_mousetail_4_mousetail You are under no obligation to support them
All right, I'm gonna go and roll ahead. It sounds like Chael's gonna edit that now. So we are gonna read her PR note first.

...34Hi, Mousetail. Yeah, and if you look at our README, the README pretty explicitly says

...48We're happy to take contributions. But we're reluctant to take on work that's not useful to our site. So please understand if we don't want to adopt your custom feature.

44:08But then at the same time, if you hang out on stream, you'll hear me like audibly chewing on not wanting to blow up sister sites, even though there's only a couple of them. Just being a maintainer. 2_mousetail_4_mousetail Blowing things up is usually best avoided
All right, so jail thinks it's a good idea to move dev environment setup over to contributing. So when someone's contributing, they have access to everything they need in one place. In addition, it means the readme stays focused on using lobsters and creating sister site, direct potential contributors to contributing, but doesn't contain the full dev setup. Let's take a look.

...49ChaelCodes Spoilers for RubyEvents too.
yeah and i do like if you look at the file that chael is removing i am actually okay with blowing things up as long as they're obvious so like what i did here because we changed how we managed credentials was i was like hey if it looks like you did use the code base prior to this change let's at least give you a clear error message it's not going to work not going to keep supporting the old thing there isn't going to be a fallback i'm not sending out a deprecation warning but at least when it blows up it gives you a very clear error message and tells you where to go and fix things

46:06marcoroth_ πŸ‘€
okay so this is all the familiar contributing text honestly i don't mind the the small implication in the readme that if you are setting up a dev end you are going to send us prs and that would be very nice

47:04ChaelCodes Why else is someone setting up a dev environment?
Well, this all seems totally straightforward. And yeah, makes the instructions a little clearer and more coherent.

...22ChaelCodes Easy to merge day!
All right. Let's go ahead and

...42ChaelCodes Then... *boss music starts* ModMailllllllll
Mod mail, yeah. Yeah, that's less of an easy PR, in part because it's a slightly under-detailed feature.

...55Oh, I figured in the two seconds the other PR took, you'd already do this. Do you want to just close this one and open another? Or do you want me to just take care of this, Joe?

48:22ChaelCodes Yeah, close it. I was still getting everything set up on Windows.
Ah, okay. So let's grab that, and then...

49:25That's. Go ahead. All right. So let's. Okay. then I'm going to give you a minute and assume you're going to make a PR to delete that file. And if you want to name check this one to save me writing a comment. All right. ChaelCodes I am
Oh, and now that I've merged a couple comments you don't have to wait on me clicking the run workflow button that's convenient where did my commit go ah thank you

50:26So go there, over to after main, and let's go edit that. All right. Yes, we're back to where I expected. So controllers, mod, controllers, not mod, the mains. That's the one I'm editing. Let's put from on the left. And we're going to take edit and update out. And uninitialize can also go. Honestly, is there going to be anything left? Yes, there's going to be the implicit show action. So I will leave the controller.

51:32What are you mad about? Edit and update are not explicitly defined. Yes, they are. We've moved them. And then...

52:06Show and then there's. What's the name here? Rats. Yeah, rats.

...28So that one stays put. And then. That stays put.

...41Origin stays put, but then these come over to the mod controller. ID author. Those are for origins, I think.

53:12Where's the section here? So we will say that we have domains.

...28Dashboards. Tools. And. Slate data.

...45This one's a tool.

54:05These go here with domains.

...12Now this comment doesn't make any sense because it can't happen. And these are also just for reading.

...31Now we're going to do the same thing again for origin.

...41And I will just copy paste, because that's the Rails way. Origins only looks like there is just create, edit, and update. Yeah. So all of this comes out of here.

55:24How does this get work without this? I got to test that one. So let's say, wait. So there's domains, also origins, test, origins, RSS.

...51Don't need that.

56:02Merchants identifier format.

...20No, they can't come out. I didn't put it underneath, that's why.

57:13there's that and then all of this can come over to the origins controller

...46Actually, the show... The show isn't here. The show is on home controller. I can just delete these. Yeah. Oh, domains ban is not in the mod namespace. There's one more. Yeah, I should take that right now.

58:27Let's move that over. I think I already did the route, didn't I? Domains, ban. Yes, I already did the route. I wasn't thinking about the fact that it was a separate controller. Ban controller. That's now part of the inheritance. Why do we have typed false? I guess something is generating survey sigs now. OK. Mod mains band control. All right. ChaelCodes Does Lobsters use Sorbet?
mad about it does you just are out of date somehow oh no i didn't get the right name it's mod mod controller more mods per mod no we don't use sorbet i think rails has started generating it maybe or maybe i was thinking about sorbet It just didn't quite seem worth the cost of adding it. If I was going to, I would really want to add some kind of proper service layer and start cleaning up the way marcoroth_ RBS Inline + Sorbet is actually great
business logic is smeared across models and controllers in this app but yeah what's rbs inline

01:00:22And I do have a lot of familiarity with Sorbet because I worked at Stripe in the Stripe monolith that used Sorbet, that started Sorbet. marcoroth_ Sorbet now understands RBS
So I like it a lot, but it's got some costs for a small code base like this. And it mostly prevents the kinds of errors that we don't really have of And that's not in the sense of we don't have type errors. It's we don't have big teams that need to hide their types from each other.

01:01:12Interesting.

...22marcoroth_ but yeah, in apps it might not be worth it until you reach a certain team size
ChaelCodes Oh!! rbs in the same file.
All right. Here's Chao.

...38Good. Speaking of easy merges.

...54ChaelCodes Whoa! A new PR! Where did that come from?
marcoroth_ @ChaelCodes yeah, and the `#: ` syntax feels so natural
It must have come from someone very kind and generous. Thanks, Joe.

01:02:12Oh, I didn't grab that. I do try and get all these links in the notes because it saves me so much time when I'm archiving these.

...29And I'll just reorder these so that they go together.

...44So I bet I have a few specs to update.

...58ChaelCodes I can see that!
Or not. I have an origin spec.

01:03:19And this is testing the thing that didn't move, just the GAD. Okay. I guess I didn't write any specs of this basic crud. There we go. Domain, spec and features and routing.

...40So these. I'll go over them all.

01:04:21And there was a instantly a typo, even in the shortest spec. All right. And then there's a request spec for domains. No, a feature spec for domains. Create, ban, unban, create. All right. These all go over to mods. So let's just rename it. And then this becomes visit slash mod.

01:05:24Let's see how many specs still fail. It's got to be one or two, right? Yeah, there must be like route helpers. Although a lot of this mod functionality is not linked to. You just have to know that you can create and ban. And I know it because I'm the mod. All right.

...54This old one can just go away. Vim must have left it somehow. Likewise, this one can go away. Routing has no unrouted actions. What is that about?

01:06:30That's going to be a real one.

...52Why do you still think there's an origins controller? Because did I not remove the five?

01:07:06I did. And domains. Does this not know how to deal with namespace controllers?

...28How did this not fail for the others then?

...53How I didn't move the views.

01:08:21into views mod domains.

...38Okay. Where's this getting the idea?

...54Actions by controller. So we have something that's still referencing it, huh?

01:09:24I guess it's this?

...34Let's try commenting these out real quick. See if that spec chills out.

...48No.

01:10:09This kind of hassle where I'm building up a data structure just to destructure it.

...23I wish types were cheaper to create in Ruby. In the sense of, like in Haskell, I would just be like, oh, we have a controller action that has a controller and an action and then everything would be well typed instead of this or list of actions instead of this kind of ad hoc it's an array of two element arrays or no it's a hash of arrays yeah

01:11:53an action dispatch journey around. That is evocative, but not informative.

01:12:17Doesn't have attributes. Can I go to YAML? I need something better than inspect there. Otherwise, I'm going to jump into the debugger. So if I go into domains, then you think we're getting origins for domain. which oh this should origins controller still has to exist okay yeah this shouldn't be here all right so pretty roundabout way but that did catch an error

01:13:30And I know I left the view in place, so that'll be fine. OK. Let's go turn off that debugging. And run the suite again. See how we're doing.

...59Should be a second block of failures.

01:14:07Maybe these two happen to be next to each other. All right. Let's start from routing.

...35Oh, this is fine, actually. Yeah, this is failure to update the test.

...47Correctly recognizes that it's in the subdirectory. That's fine.

01:15:01It's different. Oh, the format. The format thing broke.

...26So that's why this constraint must be here instead of using the resource.

...42Can we just do this? Just copy it in and you'll be happy. You're happier. That's going to be two failures, right, instead of four? What changed? Edit, update, yeah, the domain's banned. OK, so same thing for those.

01:16:12And then we're going to have the same thing here for origins. I don't love that I have cut and pasted these.

01:18:06So change that guy. Place this guy. And we'll do it here, too. And there. What did I leave in?

...39What do not define constants within a block okay we'll just put them up in the global scope. If you like that so much.

01:19:04what was the other failure was that often spec requests or features features this might even be that same bug so maybe it's fixed noop okay so this is this is routing so this is good this is expected let's go through the view app view domains edit how did i get there app view domain edit

01:20:03Yeah, they just need the word.

...19Brails, are you kidding me? You called it edit mod domain and not mod domain edit? Some of these transformations. theGeekPirate hah
Not quite what I expect.

...47It's a little confused about the namespace, I guess. All right, so this becomes mod create and domain ban. This becomes the mod ban. Yeah, let's grab all those. Let's just do it again.

01:21:39That's viewing. That's viewing. Also viewing. Viewing mod. No. This was the one that becomes silly. Edit mod domain path. Boy, I hate it.

01:22:25But I don't want to fight against this in Rails. It feels like the kind of thing where like, yes, I could break out of resources and I could name these paths.

...44But the fact that it is the Rails template is I've learned not to swim upstream against these things. And you know, in the learned helplessness kind of way.

01:23:15This is the one I did already. Did already.

...26And we've wrapped around. OK. So let's go ahead and do origin. ChaelCodes I think it helps keep Rails consistent between apps, which makes it easy for those looking at a codebase for the first time.
It's viewing. It's viewing. Also viewing. Yeah. That is a nice city. So then this becomes edit mod origin. Right. Or it's just not named.

01:24:19No, it's here. Edit model origin. Okay. Hard to catch everything. So edit model origin.

...33Fine. Or domain. That's the one I didn't move. Extra white space. More extra white space. I must have copied and pasted.

01:25:12all right moving this stuff around is going to be a bit of a shotgun diff but at least i can do it in one because this is just mod functionality in a srs commercial project i would have to copy everything over or have the routes existing oh because i moved the helper yeah

...58Find or initialize domain. Wait, this is domain ban that's mad. All right, let's look at domain ban. This must have been inheriting from the other one, which I don't love.

01:26:29I would rather duplicate this code than have these two share it by inheritance.

01:27:12OK, there's half of ours, more even. And this is saying that a path was generated wrong.

...29Run 25. OK, so the controller generated the wrong route.

01:28:02Do I need to say the namespace? It's like it's trying to generate a route and then overwrite it with the URL I give. And hit line four. Yeah.

...31I say namespace mod.

...44Don't need that space in there.

01:29:04I guess I have to give the URL explicitly. Pass an array to the model option. Okay, robot, let's try it. Speaking of ad hoc data structures, because there isn't a type defined, please use symbols for polymorphic route algorithms. I guess that counts as a type error.

...58Okay. Alrighty. What's the other one then?

01:30:11Ah, same bug, because it was the same form. All right. Let's run everything again from the top. And standard. I don't think there will be any breakman warnings, because I don't think domains or origins do anything.

...50okay that's that's a pretty big diff let's give it a skim though so this file moved this is routes changed file moved whitespace cleanup

01:31:41That feels pretty good. Let's edit this description, though, because there's one more thing to say. Origins controller failed to... What's missing? It's... What's the name of it?

01:32:10Acquire logged... Check fixes to use a to put in on namespace. Namespace? Controller space? I don't know. It's kind of both. It was reported by, I don't know how to pronounce the diuresis. So like an American, I will say Peter Stockley. grab everything and rebase on domain and then bring main up

01:33:30So it's a pretty good time. I'm about halfway through the stream to give a bumper that this is Lobster's office hours. And I am deploying Lobster's right now. Luckily, it's a zero downtime deploy. pushcx This is Lobsters office hours, toss questions into chat anytime!
So this is Lobster's office hours. hugoarnal_ how does it manage 0 downtime?
Ask questions into chat any time. So I do my little bumper. pushcx https://hatchbox.io/
How does it manage zero downtime? So we use a nice deployment and provisioning system called Hatchbox. And Hatchbox is a whole bunch of scripts. Oh, hello, sir. Hello, sir. The cat is here. You may hear him say hello. You want to do your trick? No. You want to come up? hugoarnal_ hi cat o/
hello good boy we'll see if he goes up in his filing cabinet spot and i'll turn on the webcam for him but he doesn't usually in the winter and it gets cold in this by my desk in the winter because the old windows in the old building are not well insulated so he doesn't like going up on the filing cabinet where it's cooler so anyways hatchbox here let's go to product so it puts the site in a directory named for the app and then it has this releases folder and there is a current symlink So when you do a release it checks out the code base into the releases folder and then it updates this sim link and it kicks puma and caddy is our. what's the right term for it reverse proxy so the caddy web server. talks to puma and when puma goes away caddy just kind of hangs on to incoming connections. For a minute and it's a system D service, so the Puma workers finished servicing the request there on and then they see that the. boss process wants to go away, and so they stopped serving and they. exit out and then, when all of the workers finish or it hits a timeout. Puma closes up shop and restarts with the new code and then Caddy bridges the gap. So if our boot time was really high, it would be possible for things to start timing out, but we have improved our boot time and we have a pretty small app. We're only I think we're 14 and a half thousand lines of code, something in that neighborhood. Let's check, brails stats. So the site comes up in, call it about 30 seconds per worker. Oh, we're coming up on 15. We're getting there.

01:37:11I've been saying 14 and a half for like two years.

...20Alrighty.

...26So anyways, I'm pretty happy paying Hatchbox a couple of bucks a month for provisioning and deployment. Provisioning and deployment have been major hassles for me as a web developer. I have used most of the open source solutions like Puppet and Chef and Capistrano and others. I have bounced off of Nix and a couple of others.

01:38:52hugoarnal_ Sad that it's closed source, would've loved checking the code
I mean, yes, it's closed source, but you can see all of the things I just described as a user. Like you can dump out the caddy file or, you know, you can break deployment of the caddy file and then read it out of the TMP directory. pushcx https://github.com/lobsters/lob…
And if you're curious, yeah, all of our production setup is up here on GitHub. And there's some notes in the readme. And I know they're there because Chael just touched the readme. So if you take a look at it, here's what the settings look like on Hatchbox and where to put things. And then all of this stuff is kind of automated into place, mostly by the post deploy hook. that updates some things and fires off the root deploy hook, which does some last steps for provisioning and configuration and i don't mind maintaining you know let's round up and call this a hundred line bash script that has to be deliberate about acting item potently if it was getting past 200 i would feel grumpy that hatchbox was incomplete but this is good enough for me And so this is copying out stuff like convenience features or installing packages like. The big one recently has been. Not in here, oh no there it is IP tables persistent for. I don't know if you were here for the start of the stream, but I dealt with an issue from someone pointing out that their VPN wasn't working very well because we banned a bunch of VPNs for sending us malicious traffic. And I would guess off the top of my head that the VPNs were doing vulnerability scanning, but why would we want to accept vulnerability scan traffic? I don't know. I might roll those back because The one thing about the way we're set up is we don't have, well, we don't really have a WAF, a web application firewall. And those are better about maintaining timelines and recognizing bad behavior and imposing sentences as opposed to execution. And so I'm saying like, hey, if you vulnerability scan the site, we're going to drop traffic from your IP for a day or two. But since it's just me grepping for stuff in the logs and then banning IPs, the default is a death sentence where it's like, okay, that's blocked until I go back and unblock it. So I don't know. I poked around a little and there are a couple of caddy plugins that do basic web application firewall stuff.

01:42:27Maybe I will add one at some point. Let me see how that goes. Alrighty. So my other thing to update was the Mastodon controller.

01:43:11Which is over in settings.

...21Trying to remember how this flow goes.

...55Yeah, okay, so this is kind of the... Speaking of things that should be off in a controller, this could probably move off to its own controller.

01:44:09I don't think I want to do another big shotgun debug right this second.

01:45:01So the hassle here is we need more state because we effectively have think the term is probably session fixation. I'm not sure if the term applies if you fail to properly salt in the first place. Big baby. So the cat is on my lap and needs lots of love.

01:46:05Yeah, we don't really put much in the session.

...27That is the best place for this. It's just got to get deleted otherwise.

01:47:19bsandro hello cyberpals
Yeah, that's how we're doing it. Let's copy from. And let's split this. Where do we do it on GitHub?

...56And this has to take a state. hugoarnal_ hi there
No, this goes into the redirect.

01:48:27Oh hey be Sandra.

...33that's really tacky that I have this object passing state down through multiple methods like this.

...49Just like as soon as you see something like that you want it on the instance. But we don't really, these objects have such an odd lifestyle.

01:49:21And then here.

...32Why does it call it code? ChaelCodes hello
That's such a bad name.

01:50:07Let's copy it.

...29This comes back with a.

...59Let's check on this.

01:51:42Let's get a colon there and redirect underscore URIs.

01:52:30If the state parameter was used, what is the state parameter? That is what I want.

01:53:06So that's when I'm hitting slash authorize.

...18So I don't have to pass this down at least.

...27Let's go in order, scope, and then state.

...41So if we give it to them there, when they come back, it'll be here.

01:54:13Doesn't equal session.

...29OK, let's look at this data. That's pretty small. So this is just like the GitHub. a lot state that we want to round trip of random value because otherwise a bad actor could get someone to visit the Mastodon callback URL on our site and connect the Mastodon account. because it wouldn't have something in the session state that links it to the actual logged in user looking at the Mastodon callback URL. Let's see if the test pass. I think so, because I don't think we really have many tests of the Mastodon API or the GitHub API. External services are so painful to test. So I just punted. Yeah. Ooh, break man noticed though.

01:56:04An updated possible unprotected redirect. No, this is a protected redirect that we are doing on purpose. What is the... Where is the darn breakband config?

...35And the warning is 96E.

...53So I'm going to keep my note.

01:57:07is the one I wish I could add a little text to to explain what it is and why it is, because it tripped up a bunch of contributors. Let's inspect the new warnings. Let's note this one. Yes, let's go ahead and remove the fingerprint of the old one and save to the same file. And the diff just notices that some things move a little bit. That's fine. That's normal. And then this is the big change. Good.

01:58:01Can I test this locally?

...09I think so. I think I can.

...24So I've got this. My password gets pushcx dev. And I thought the password got stepped on.

...44I thought I reset those in dev. Guess not. And then. Let's see. Where's my... It's okay, buddy. It's okay, cat. I just touched something.

01:59:15All right. Mastodon. So if I click disconnect and connect to... Even on Ruby social. Yeah, I already when I developed this, I copied the Mastodon API key in here. So let's log in here, which.

...46Ruby social. And it kicked me over to prod because the API key connected. into prod. It's not going to.

02:00:13So if I log in, no, I've lost the OAuth flow. I was going to say, if I logged in in this browser, I still lost the chain of the OAuth flow. I need to do this in a browser where I'm already logged in. Yeah, so I'm going to start from localhost. So I'm doing this off screen because, well, number one, it's live mode or light mode. But then also it's going to flash some personal stuff by. So now I will go to slash settings. And. Connect Mastodon to Ruby social.

02:01:09And it says linked. And if we go to prod, and again, I'm doing this off stream, that's Mastodon state key should get logged. I just want to see that it round tripped from the remote server, even if prod didn't do anything with it, because that's the bug I'm fixing. So what was the URL there? Mastodon connect?

...47No, Mastodon callback? Mastodon callback.

02:02:11So I'm checking the prod log. And yes, it came back with a code.

...31But not a state.

...41Well, that was supposed to be there.

...53Why do we think that happened? Is it not called Mastodon Callback? It is.

02:03:46Did my local server log the URL that was spitting out? Yes. So when it left local, it had this new thing attached. Where'd the Mastodon API go?

02:04:18So we'll get to authorize, expects a parameter called state, arbitrary value to pass through to your server when the authorizes rejects the authorization request. How is it passed through? Because you didn't do it like GitHub did. This will also be present in the URI. Redirect URI code equals blah state. And I am looking at prod and seeing it goes to slash settings, mastodon callback, instance equals code equals. Oh no, it is there. It is there. I just didn't see it properly because the logs are kind of a wall of text. Okay. Alright, well, I'll update my prescription and then I'll have fewer bugs. Great, so this looks like it'll work.

02:06:07Close the window so I can see what the heck I'm doing.

...37Would they have to be... No, actually I don't think you'd have to be in the middle of the flow.

02:07:24all right let's main that i gotta alias that thing and lobsters deploy all right so that was my to-do list for the stream we're at about two hours and i usually go for about three So I can dig in my backlog, but now is a great time to ask questions if folks have them, especially because this is going to be my last stream because I'm going to take a minute off for the holidays. Folks are in town. ChaelCodes ModMail?
Yeah, that's the end of that. And if there aren't more questions, I can dig around in my backlog because, you know, never done.

02:08:24bsandro what's better, christmas or new year? :D
ChaelCodes It's ready for review~
What's better, Christmas or New Year? Oh, something from you, champ? hugoarnal_ how does lobste.rs know it's office time? fixed schedule or pinging twitch?
I would say New Year is better. I have a personal story there. Oh, no, Hugo, it's a terrible hack, like a lot of our codebase. hugoarnal_ oh my god hahaha
so it's a footer in the layout where if a file exists on prod then go ahead and link to the office hours stream and when I start broadcasting on OBS it has a script that runs hugoarnal_ it's so awesome I love it
ssh lobsters and touch this file and then when i stop the stream it goes ssh lobsters delete this file and there's the hardest part of this whole setup actually was i wanted to have the ability to not turn on this footer the Because, you know, the Twitch channel is named my username and I wanted the option to be able to stream stuff and not turn this footer on. So if I ever was like, oh, I'm going to become... an overwatch streamer i don't know whatever i probably don't want to turn on the office hours banner for that that'd be a little inappropriate and the hardest thing was getting an option into obs so that when i start streaming it pops up a dialog box and gives me a like so bad i couldn't customize the buttons and so it's a little text box that says do you want to enable the the live link type y slash n it's like if you want to plug in something interactive into obs you're off into like developing a whole application and i wanted literally one bit of data I was almost tempted to have it on my system say, well, if like the scratch file for a stream exists and it's been edited in the last 10 minutes, then go ahead and do this. I did not. I just felt a little foot gunny to set myself up like that. Anyways, a lot of code is pretty simple. hugoarnal_ any other example of such hacks?
marcoroth_ lol
are you mad about why is there a red black syntax errors found are you mad about that yield yeah you are obviously i do not have herb installed other examples of such hacks i mean besides the caddy file stuff

02:11:56I'm sure there are.

02:12:09Yeah, you know, heinous inline partial is the other big. I won't explain the whole thing because I know there's a bunch of stream regulars that have heard me, but I'll give you the link. Can I just say lobsters main? We don't need a line number on that one.

...34And I guess I'm thinking of it because, you know, Marco laughed at my dumb joke. Config initializers. pushcx https://github.com/lobsters/lob…
bsandro just googled briefly, if you retrieve whole page of your twitch page there is a 'isLiveBroadcast":true' there if stream is active
There is a performance hack in the code base called heinous on inline partial that marcoroth_ my personal goal for Herb is to make sure you don't need to heinous inline partial anmore
bsandro verified and it still works
In lines one partial into another because an ERP the lookup of a partial by file name is kind of surprisingly expensive because it's a very expressive set of options.

02:13:18Oh be Sandra like a.

...25But yeah be Sandra if I did that. Then I would still have that problem of I can't stream my incredible slave aspire runs without turning it on because it's not enough for the code base. And you know i'm totally fine with the existing footer thing.

02:14:06Doesn't look like it's there. I grepped for it.

...26hugoarnal_ probably dislikes being curled
You know, Marco, the way I might get to not needing... Oh, that's probably true.

...40What don't you like? 301 to what? Oh, www. I'm so sorry, Twitch. Okay, it is in here somewhere.

...58Is live is not zero? That's a little different than is live is one. Or you said is live broadcast. Is live broadcast true? None of a deep cut. And you know, the hack I would replace it with is definitely not going to be like, let me grab all of this and load a JSON parser. It's going to be like, grab this string out of it. But that would be so indirect. And then prod takes a network dependency on a third party API I would rather just manually toggle.

02:15:49bsandro yeah that's fair
hugoarnal_ I guess you could also grep title for "[Lobsters Office Hours]"
So yeah, speaking of disliking being curled, I use people probably know YTDLP. pushcx https://github.com/yt-dlp/yt-dl…
It's an invaluable app in the modern age for downloading things from. Oh, yeah. Oh, Hugo. Actually, that's a little bit of a hack. But that would also, as long as I updated my stream title with the name of whatever neat game I was playing, that would work. In reality, I'm going to forget. So let me not change this automation. dlamz https://github.com/lwthiker/cur… πŸ‘€
But speaking of getting mad, I use YTDLP to grab conference videos so that I can watch them on the go or just watch them at my own speed or just otherwise more conveniently than on a website with like 20 megs of JavaScript on it. and i saw a neat channel and i was like cool actually you know and i like this stuff that i've seen going years back so let me just kind of grab it all and dump it in my queue to watch and i did not realize that unlike most channels there were more than 20 videos on there and so somewhere around video 137 youtube was like hey how about you off and so now i get the like sign in to prove you're not a bot if i visit youtube for my ip it will unlike my terrible waft probably expire in a couple of days but for the moment it's inconvenient

02:18:02All right, I got to grab some more water. I'm starting to cough back in 30 seconds.

...30hugoarnal_ youtube is kind of doubling down on downloaders too these days
All right.

...36YouTube is, oh, is YouTube actually making strides to block downloaders? dlamz yt-dlp has sleeps from YouTube lately yeah
I know they're occasionally, it seems to have settled down the last couple of months, but they occasionally try to break ad blockers. It's linked on that, or it's mentioned here, but. Sponsor Block is such an invaluable extension for, like, YouTube is kind of unwatchable without uBlock Origin and Sponsor Block. Sleeps. chamlis_ I've had good results with the delays etc specified here for archiving whole channels https://github.com/TheFrenchGho…
Oh, yeah, I don't care, because when I download something, I tell it to start downloading, and then three days later, I pick up the download and watch it. I don't care if it sleeps for a minute or something in between. DMC You should be able to use the streams API and the user_login query param https://dev.twitch.tv/docs/api/… (it only returns live users), came in mid convo and not sure what you're looking for
Archives for... Ooh. Channelist, that is super useful. Because this is not the first time I've run into this limitation. And YTDLP does have a thing where I think it's dash capital I. You can say when you give it a playlist or a channel, you can say like start at video 100 and download to 199. And then when I come back a couple of days later, start at 200 and go to 299. but a better script would be convenient.

02:20:12DMC, I should be able to use the streams API, but I cannot get an API token because... DMC, we're just kind of kicking around the... pushcx https://lobste.rs/
If you look on... the website that this stream is about maintaining when i'm not talking about scraping youtube down at the bottom there is a little footer that when i'm doing the office hour streams it links to the office hour stream and someone asked how that's wired up and the answer is in a very simple and mildly janky way and then DMC Ahhhhh
I think that nerd sniped the channel into going, well, what if you actually used an API instead of just SCPing files around with terrible OBS scripting? And first of all, that's a personal attack. Second, weren't quite improvements and like third is yeah i'm sure they have a proper api but the hassle is because the channel is just my username if i want to stream non-office hour stuff i want to make sure this doesn't turn on because that would be weird and self promo that i don't want to do

02:21:45bsandro I like the hack better tbh, that means we're not bound eternally to twitch
But yeah, I cannot get a Twitch API key because I'm not so vulnerable to SIM swapping. That is not an invitation to try. It's just they think my phone number is VoIP. And then they have an anti-spam control on getting an API key that they call a security control. hugoarnal_ @bsandro absolutely, it's so great I love it
DMC That makes sense it's part of your OBS setup then (I was wondering if you were just trying to find lives streams)
pushcx https://www.twitch.tv/chaelcode…
have talked to twitch employees i took another run at it last month because i watched chael's stream and chael has like how do i put it production values is is the general term Oh, weird. Chael is recommending me and I am looking at Chael and so on. Okay. Hall of Mirrors. graefchen I honestly sometimes prefer the "dumb and manual" way of doing it is sometimes way better than doing it automatically. limesLurk
But if you actually look at her stream, she has like things that pop up when people do things and other clever API integrations and they're all just kind of neat. ChaelCodes Oh! Alerts!
So I took another run at finding an employee to see if I could get the get someone to just be like, yeah, look, This guy is really unlikely to start spamming us. Alerts. Yeah, I called them chyrons and you were like, that's not called that. So I was trying to find how to describe them. And I explained to the employee that, hey, I'm hitting this anti-spam control and it thinks my number is void. And then they were like, they were an honest to God engineer and they gave me the tier one answer of, Why don't you get another phone number? And it's like, I literally don't have another phone number. It's just my phone number. bsandro don't you guys have phones?
And I don't want to pay $5 to $15 a month for another phone number just to give you hours of content every week. I don't know. Yeah, yeah, Bissandra, that was kind of the moment. Getting that, that is a deep cut. I actually know that one.

02:24:17Would I be a jerk if I came back like three weeks later and I sent him that meme? Probably. Would I be satisfied being a jerk? A little bit. A little bit. DMC (I'm also an employee LUL ) I'm not on the auth side and can't speak to allow listing for 2FA with voip
God, that would be... For anybody who doesn't know this one, that was Diablo, right? Diablo.

...43Oh, hi DMC. Oh, yeah, I wondered what the wrench icons next to you meant. All right, so yeah. pushcx https://www.youtube.com/watch?v…
Is there not a know your meme for it? DMC The black wrench = Staff, the other purple wrench is my tenure badge
The gist of it was everybody wanted this guy on stage to announce a new PC Diablo game, and instead he, to a live audience, announced a mobile game with microtransactions. and the audience was not making happy, exciting faces. graefchen That is also why the 3 letter name, I assume. Getting a 3 letter name is hard, when not being staff. limesO
And kind of off script, he was like, don't you guys have phones? DMC hahaha
Being on stage is rough. theGeekPirate I haven't signed up for Claude because they don't accept my VoIP number =b
Oh, Gravechen, I just assumed, like, 50-something nerd. Because it is such a, like, 40s... DMC @graefchen That's a bit how I got my 3 letter one bogaShh
know if you were born between 1960 and i don't know 1980 there was a whole thing where nerds were like well obviously i'm going to use my initials and lobsters was started by a guy who is jcs ah yeah geek pirate i did want to try claude luckily i found someone who worked there and i was like hey Can you exempt me from this? And they were like, yeah, sure, you sound fine.

02:26:22graefchen I know the ways from Joe limesSmug
theGeekPirate Yeah I figured I could send an email, but ehhhh :D
Running a site that's full of programmers is actually pretty handy for my hassles with terrible or at least overzealous false positives from anti-spam systems.

...42Hi, boss. Boss, I can't play fetch. bsandro Discord extorting my phone number is actually the reason I dropped that platform entirely
I'm going to have to get a second webcam, a fetch cam, just for when the cat wants to play fetch.

02:27:09Wow, this looks really nice. so like oh okay wait as long as i'm completely popping the conversation stack in my mind marco i think the most likely way i get rid of heinous inline partial is move all the views over to paper graft because it does the pre-compiling like erb and ChaelCodes LUL LUL LUL So long ago
marcoroth_ Jean?
chamlis_ byroot?
ChaelCodes John Hawthorne?
i saw some performance numbers that survived a conversation with oh god i'm blanking on his name he's come on the stream if you say the words rails and performance he shows up and explains what you're doing wrong by route yes thank you chanlis so they survived ChaelCodes Oh
performance number said that papercraft is like within five percent or so of erb with the compilation stuff properly enabled and i really do like that style of then it's all ruby code and then i could do things like test our views a lot better than we do now and i could get rid of the very painful coupling between controllers and views where it does the magic instance variable thing, and I don't love that, and I haven't loved that for 20 years.

02:28:58ChaelCodes He _used_ to be on Twitch, btw
I don't know. I'm kind of avoiding thinking about it because of all of the stuff happening in Rails and Ruby these last couple of months. marcoroth_ You technically also get all of that with ViewComponents
Because like, if I'm going to start rewriting, do I want to do a small rewrite?

02:29:27ChaelCodes streamed with a different John.
marcoroth_ but, the papercraft vs. ERB is just a matter of style on how you like to write the syntax
Well, John Hawthorne is another classic Ruby Jean.

...36DMC Do it in elixir :P ( I would have said that in my prior job)
Yeah, yeah, it really is now.

...45ChaelCodes O_O
ChaelCodes WHAT
ChaelCodes JEAN and JOHN
You know, DMC, you say Elixir. pushcx https://gleam.run/
I have been looking at Gleam. Yeah, Jean, Jean.

02:30:07theGeekPirate Yeah, Gleam looks sexy
DMC I have heard good things but haven't read up on Gleam yet
Because I have notes towards designing my own programming language. And that's why, where is it? ChaelCodes Wait, @DMC what is Twitch mostly built in right now?
pushcx https://lobste.rs/s/4inlhr/lang…
I recently submitted, oh God, I love, love this article.

...31DMC I have the rust programming book on my desk to read this holiday break
It is a long article on DMC @ChaelCodes Go and React mostly
things that you should consider, you should learn about, and then design features that you should consider in a programming language. And it is great. Oh my God, this is such a great post. ChaelCodes Awwwww.
It has so much interesting food for thought. And I started going through it and looking stuff up, and I realized that my dream language is like 80% of the way to Gleam. theGeekPirate That's like me and Odin
That last 20% is probably a huge incompatibility though.

02:31:23ChaelCodes I heard it was Ruby once, when the codebase leak happened, but they were in the middle of migrating.
bsandro isn't Twitch basically open source now after that huge leak couple of years ago? :D
Odin, oh yeah. It's funny the way the conversation heads and people jinx each other in chat.

...51bsandro bsandrEvil
Oh, Chael, I really appreciate that you got this little design note. I think that's really useful for making it clear what emails people are going to get.

02:32:12marcoroth_ I've been really enjoying C LUL
ChaelCodes Thank you~
DMC It went Rails, Ember and Rails, before microservices, (Go got its grips in at that point) then went Ember -> React. I was hired when I started because I knew Ember well
Man, speaking of the big PR, this is a big one.

...31Yeah, I've worked with Ember. You know, you can't go wrong using a web framework by Yehuda Katz, like Rails or Ember. Maybe we can get Yehuda to write a web framework in Gleam. DMC Yehuda's brother was working at Twitch :D
There is one actually in Gleam called Wisp. Doesn't look half bad. Huh, that's interesting. This PR, well, we'll see if we're out of sync. graefchen @marcoroth_ C is also an amazing language. Even of you are prone to shoot ya leg off. limesD
This PR didn't pick up that Chael is now approved. Oh, God, it's such a small internet. Thank you, DMC. That's a wonderful fact.

02:34:00bsandro of everything I've used so far I still like C the most too
marcoroth_ @graefchen Yeah, but there are also some ways to make that harder
graefchen I know. I know.
that's a really that's a really smooth way of doing this with the space separated ids i saw it down in the form but that really is a nice way of taking advantage of the fact that the mods are all programmers every once in a while we get one of these on lobsters where it's like we could build out a whole ui but the user knows what json is

...31DMC I also did Yehuda and Tom Dale's early Ember inperson training forever and a half ago. Worked with Tom a bit when I was working on Fastboot before taking the Twitch gig
Email to all recipients and add a message to their inbox unless the message was sent by the recipient. OK, so that must mean user.

...53ChaelCodes Yes
My mail and my mail messages can't be updated or destroyed. ChaelCodes Recipient in the conversation
yes i think that's a good call mod mail is visible in the activity log and on the user profile excellent that's a pretty good example subject by the way please stop fighting i mean I bet if I looked in my outgoing DMs, I have probably said that exact subject.

02:35:39theGeekPirate @DMC You must have joined at the tail end of Ember, right?
ChaelCodes I had LOTS OF FUN imagining moderation scenarios
theGeekPirate (Ember usage at Twitch)
You know, people think of moderating a web forum as glamorous work with supercars and bespoke suits and zeppelins, but actually there's a lot of, don't make me pull this car over, honestly yeah i try not to get too silly but there's a few of these in the tests too where the test data is like please stop being a jerk or please don't put blog names in titles because i used to do a lot of those edits

02:36:29DMC Before the decision to do the react rewrite
theGeekPirate nods
all right so we got references recipients so you did go with multiple recipients okay just want to show that mods messages are working you know dmc one of the running topics on this site is or on this stream is like almost every time i stream we see something new and janky in the github ui and it's very often about syncing state and in this case we saw it with one of chael's prs was approved but i still had to approve for pr and then also that pr interface was stalled and just like spinning and i didn't even call it out because that one is not even hugoarnal_ is github even still in ruby?
graefchen Ya dont get a supercar, but another thing with a roaring motor limesGiggle Especally when they are happy limesGiggle
kind of funny usually they're they're funnier like seeing two navigation bars or seeing the rest of the page missing styling or that kind of thing i believe the back end is hugo they're still on there they're very famously actually on rails master now and

02:37:56DMC @theGeekPirate I joined in 2016, I'm almost at my 10 year
marcoroth_ @hugoarnal_ yeah, and also most of their views are still ERB
A lot of it has gotten chalked up to GitHub rewriting the front end to React. Wow. Congrats, DMC. Long run.

02:38:13theGeekPirate DMC Yeah okay, I was confused because of your badge
theGeekPirate Could have sworn I've seen you around longer
So anyways, I occasionally gripe about stuff in the Twitch dashboard, but honestly, it's pretty dang reliable.

...34theGeekPirate My only connections to ex Twitch staff are creating an emote for DJ Wheat way back when, and my roommate knowing FishStix from Tribes =b
This is working OK, so you made a username test. Compose send message. If you can't. Edit messages, what does it do? OK, the subject and the references. Sure.

02:39:01Chael, before I dig in the code, if I edit stuff, does it add something to the conversation?

...13DMC They only have 5 and 10 eyar badges, so I get the 10 year badge soon (the new badges just showed up last week too haha)
Like an entry that says, like, push CX added comment reference blah blah, or removed comment reference blah blah. Because that would be... ChaelCodes Oh.
Very nice. ChaelCodes Follow-up PR.
And then that same vein of what you noted in your description of not wanting to allow editing to confuse people.

...45theGeekPirate You guys need to do the whole Steam thing with a new badge every year ^_^
Okay. ChaelCodes Good idea.
That's cool. theGeekPirate (at least updating the hover text)
To be clear on this, I gave you a very underspecified feature. It was not like you were given DMC dmcRUN
ChaelCodes Which is GOOD because I don't know if I could deliver that
mock-ups and a proper five pager or something ah so dmc do you work on keeping the site up would you say you are run dmc it's about as funny as this stream gets Oh, they've got their own emoji. ChaelCodes I made a lot of decisions to make my like easier
DMC run. ChaelCodes *life
Add disabled checkbox, monactivity.

02:40:51Big baby. Cat is not always great with like theory of mind. So he wants me to play fetch, but he hasn't brought me the toy. And he wants me to throw the toy I don't have. Buddy, you have to get it. He's like 90% of the way to fetch. He brings it back. And when he wants to play, usually he brings it. But then sometimes he just shows up and wants to play fetch and nobody has the toy. And there's some no take only throw kind of interaction. Mod note added, yeah.

02:41:42Okay, so the activity is just the existence of the conversation rather than every message in the conversation. That makes sense. And then as long as you're doing a foreign key over, this is really promising. All right. 39 files, man. And I thought moving the controller gave me a big diff. Excellent. More action.

02:42:44That scares me. So with Mod Controller,

02:43:00The reason I introduced mod controller, did I explain it in the controller? No, of course not. The entire purpose, the primary purpose of this controller is so that all of the mod controllers under it can be forced to run this before action. So your PR is probably going to fail the build because this will run in addition to, oh, you put skip before action in there. I see it now. Because I wanted to know that anything in there was for sure protected because it's really hard to ensure. I mean, we saw it just earlier on the stream, the origin controller was missing this before action. And that kind of bug is so dang easy to make in Rails that I made this controller for that. So let's add it.

02:44:30What's the name of the added thing? Yeah, the custom comps.

02:45:04This is getting confused. This is the parent class of all controllers under slash mod, which is period. ChaelCodes Awkward moment - I am a mod/ controller.
Standard standard RB enforces this in

...38so that we can't forget to check yeah this this is the documentation the fact that this is missing is why you wrote a skip before action because if you had seen this here or in the check which i should add it to the the cop This wouldn't happen, so that's why I'm immediately over here, because this was not documented in the right place.

02:46:25And then let's go look at the. Error message on this guy.

...44ChaelCodes Should ModMail be a regular controller?
must inherit force off chale it should be both where we've gotten with a lot of these things is both because the moderators are going to have extra buttons and so if you look at like stories controller It has an edit method.

02:47:23And that has an edit form. There is also a mod stories controller. And there is a mod stories edit template. Because moderators are allowed to do extra things like change the URL, merge stories, mark them as unavailable. Delete them. And having a bunch of ifs shotgunned throughout the controller action and the view led to a whole lot of bugs. and i know the really responsible like capital e enterprise development pattern here would be to move the moderator control plane out to its own entirely separate app that has its own auth flow that has x and y and z that you know has all of its data in a protected database but that's really overkill I am happy with a let's at least start moving all of the mod stuff under this mod namespace so that we can enforce authentication and not have functionality that has to have a bunch of conditionals around whether the user is a regular user or a moderator. Because we've had so many bugs where if a moderator yeah so like one of the characteristic ones was a moderator you can edit your own story for a couple of hours to like fix a typo or clean up the title as a moderator you can always edit a story but if you edit your own story you can do it outside of the window where you were allowed to do it as an as a user but if you edit your own story outside of that window it goes, oh, this is a user editing their own story. And so then it doesn't log that you did a moderation action. And then somehow a mod has edited things without putting an entry in the mod log. And that kind of bug is really scary because it gets at our core value around transparency.

02:49:50So that is a very long and sidewinding way of explaining why I jump at seeing That skip before action.

02:50:14ChaelCodes Okay, I made a note. But that's more files.
Yeah. And It's not just files it's also duplication like forms mostly get duplicated rather than being reused and i'm okay with that, even as it's a little bit weird that when the mods edit something that form could be out of sync or laid out very differently from the story editing. i'm okay with that. it's less bad than. The bugs we've had over the years related to. Honestly, the other thing we could do is say that mods aren't users and that you could be logged in as a user or a moderator rather than moderators being like a Boolean on the user class. But that's real painful.

02:52:01Oh, look at that background job. Beautiful. It is so nice that we get to start having background jobs. Mod mail message. Okay. What is a mod mail ID? Is that the PK or does it get a short ID? guess I can drop down to the migration. ChaelCodes pk
Update.

...53ChaelCodes Do you want a short id?
Yes, please. people in social software are weird about auto incrementing ids i'm not super worried about the information leak of there have been 84 mod mail conversations and you can count how many between your last one but people get hang-ups about having low numbers or funny numbers

02:53:29You have done such a better job of keeping business logic out of controllers.

02:54:07Here's some references and recipients.

...25ChaelCodes I'll add more comments.
ChaelCodes This supports the form.
You know, because Ruby is so eager to give you back a nil,

...45It might have to be like a dig.

02:55:49Okay, so here's our background job. I got to skip ahead and see the schema because I can't quite picture it. OK, so modmail is the parent. And messages is the individual entries. OK. Why didn't you wait? Oh, this must be the author. user. Yeah. And that's you're matching our style of naming these by the table rather than the role, which is fine. And then there must be odd male reference. Yeah. Oh, okay. Polymorphic. That's nice for expansion. And then recipients.

02:57:21Okay. All right. I can picture that in my head now.

...53Deliver now. Yeah, I think this one could be... There's a way on mailers, it might just be called deliver later, that just queues it in a background job, and I think that would be appropriate here. Let me check.

02:58:29ChaelCodes I copied your existing NotificationJob.
yeah deliver later and since it's part of active job i think that'll just all go in to our existing queue system i mean yeah the existing stuff probably does deliver now but It predates our use of active job background queue. ChaelCodes Okay
Yeah. Notifications also predates.

02:59:29ChaelCodes Hey.
Actually, until I think this year.

...43ChaelCodes Do you ever play with code suggestions in GitHub?
Yeah, this year.

...58I'm not sure what you're asking by ChaelCodes Nevermind
I mean, I just wrote one. Okay. Once or twice on a PR when there's like a... ChaelCodes I didn't see you click the button. I thought it needed the diff.
If this was literally the only thing I wanted to see tweaked on a PR, I would just write the suggestion and hit commit on it to make the record, but... ChaelCodes Yeah, the domains mean I have a big rebase ahead, so I need the roundtrip anyway.
just to save the round trip with the... Oh, no, it's... Yeah, when I hit the button, it just fills in the thing. I don't know. Maybe it takes a different, like a proper patch file style.

03:01:06Yeah. Yeah, I'm sorry to give you a big diff.

...25I'm glad this doesn't look like it was too much pain. The real test of one of these kind of things is always when the third item comes in. ChaelCodes Surprisingly good!
Oh, this not null or this. I can see how that would have cost you a bunch of time.

03:02:13Come on now, references. ChaelCodes Nah. I just copied the other two.
Yes. Comment references. Story references. Nice. Don't they? Oh. Well, maybe it cost me a bunch of time. Not to pat myself on the back. It's just sometimes I see these lines of code where I'm like, that looks like somebody lost an hour to that. Has one mod activity. Nice.

03:03:13yeah this is one of the things where active record doesn't feel very expressive because the inverse of this code is up in the controller and there isn't a nice way to have like a virtual attribute that maps between the two

03:04:32ChaelCodes Wait. THAT method is for the form.
ChaelCodes The other one was not.
ChaelCodes TODO is yours too
ChaelCodes I copied it
ChaelCodes THAT took me a lot of time. :[
Is there a dependent exception?

03:05:13ChaelCodes I kept calling it `plaintext_body` like the other instead of `plaintext_message`
The plain text body like the other instead of plain text message.

...26Oh, like the linkified in the plain text? Yeah.

03:06:00nice oh good thanks for including plain text we do actually have people who are using i mean besides me using mine ChaelCodes Can i get a supercut of every time pushcx compliments me code?
So I'm glad we're serving up plain text. Is this our first HTML message? Do you use plural? No.

...58graefchen plain text ... that reminds me of a paper I want to read again. limesSit
They're individual mailers.

03:07:08Yeah. Looks like this is our first HTML email. Wild.

...25Oh no, I'm misreading. This is a view. I was just sort of assuming that this was a version of the thing that came after. All right. I like that you picked up my use of the emojis to indicate to mods that things are private. You had an emoji... ChaelCodes Mailbox is in activity log because it's a mail.
earlier i wonder if there's a yeah so i had been thinking of the key as being part of whoa github i selected text and the text disappeared for a second yeah it didn't happen again what if i reload nope Oh, man, joy frontend box. ChaelCodes Key is in messages because it's a mod.
Mailbox is in activity log because it's a mail. Makes sense. Keys in messages because it's a mod. OK. I'm wondering if that should be a constant. It's not like I was careful about how I did it. Dom ID. ChaelCodes (And mail are already *envelopes* - not mailboxes as I said previously)
What is Dom ID?

03:09:17Are you kidding? You know how many times in the code base I have reinvented one of these conventions.

...33Does it only use the ID, or if you change the to param of the model, does it use that?

...45Write a helper like person record.

...53ChaelCodes Show source on GitHub?
marcoroth_ I think it uses to_param
I should have thought of making methods.

03:10:08ChaelCodes Or trust Marco.
What is param key?

...28The string to use for param names. Oh, so it's for the class. not the name of the attribute.

...52Wait, how did I land on DOM class? I want a DOM ID.

03:11:02Calls record key for DOM ID.

...13Turns a string representation that is suitable for use can be overridden to customize the default generated string representation.

...50What is two key?

03:12:04All key attributes, if any, is set. What is a key attribute?

...16The record's PK wrapped in an array.

...30OK. We have a whole bunch of places where view, comment, comment is one of them.

...47So why it catches my eye is we have a bunch of things like, well, we have an input for the ID equals comment folder, whatever. And then if you go look in application.js, Let's see.

03:13:11marcoroth_ I have a open issue for a Herb linter rule that "suggests" to use dom_id over constructing it yourself
Yeah. You can find it doing the same kind of logic. And it's like the inverse or the parallel. Yeah. I was not aware DOM ID existed. maybe it's new since i started using rails and i don't know 0.8 or 0.9 whatever that was maybe it's not actually be even funnier if it's not all right well learn something every pr

03:14:08marcoroth_ Introduced in Rails 4
Can I give myself the excuse that I was distracted by all the other things introduced in Rails 4? Can I say it with a straight face?

...42I don't understand this code. If the message has an author, which they should, but this else looks up from the user,

03:15:54ChaelCodes I promise you that all of this was copied from code you already have.
ChaelCodes But yes. I will fix that.
I entirely believe you, Cheo. We have lots of odd corners. If that one's in notification or something. What was the file name there? Inbox mod mail message. So inbox message, probably. Ah, yeah. So this author underscore username, it's not author dot username. Real subtle. This one, what's happening here is it's optional on messages because there is a sentinel value where if the author is null, it is from system. And then the knowledge that a message can be from system and not have an author is kind of gutshot throughout the code base. I wish we had just created a username system. There are so many ifs around this.

03:17:06ChaelCodes Okay, so that one **is** on me.
Yeah. And so it says, if author, author, username, lsystem, because we didn't really commit to the null object pattern here. No, I'm not going to jump on you for the difference between an underscore and a dot. That's hard to see.

...46ChaelCodes But I'll test for deleted users to make up for it.
Could we use the null object pattern here? We only soft delete users. We never actually delete them from the database. veqqio Just dropping in to say hi and wish everyone well, merry christmas, happy new years etc. <3
I mean, I say that and I have seen a gap in user IDs because there was one place where in like 2013 maybe that JCS got real mad at somebody who invited like four or five people to set up a voting ring and he actually deleted them from the database. And then like last year, I had to clean up some associated records that were still lingering because Rails doesn't lean into foreign key enforcement.

03:18:43As long as we're looking at this line of code ChaelCodes Yeah.
ChaelCodes Got it.
ChaelCodes No if.
I'm pretty sure in your model, I don't want to lose my place and scroll up and down, that the user is required to be present and you don't have a concept of a message from system, which you might introduce in a future PR for like that little moderation note that I kind of wished for of, push CF to change the subject of this conversation or added references, but yeah, I don't know.

03:19:27ChaelCodes Oh.
hugoarnal_ @veqqio happy holidays to you too
ChaelCodes That would still have a user.
Oh, and hey Beck, thanks for dropping in.

...53ChaelCodes The person who added or removed a recipient or reference.
it would have the user who did it maybe, but the semantics have changed. And so if you presented it as a message could a viewer distinguish that from like pushcx wrote you a message that says i deleted the reference blah blah it would be nice if it had a visual indication that it was not a message from the person the mod notes ui is specifically confusing right now because of this where if you note a conversation it logs it in the table with who noted it and so it looks at first like the moderator sent the message i don't we get used to it because there's only like four of us but

03:20:59changed here. Oh, a space. Okay.

03:21:35All right, now I'm going to scroll way back up and way back down because white space is not off.

...50That's better.

03:22:04ChaelCodes Herb did not like that you had a multi-line erb thing.
user is moderator herb did not like that i had a multi-line herb thing oh the case when yeah i've noticed erb can be a little odd about case statements i don't totally understand what that one's about

...49I don't understand this edit to the cache key.

03:23:06ChaelCodes I should have comment.
Why is it here in the first place? I had a reason for that, and I should definitely have written a comment on that one, but did not.

...35ChaelCodes There are now MULTIPLE users
ChaelCodes Multiple recipients
ChaelCodes We don't use ma.item.user_id == @user.id as a conditional anywhere
ChaelCodes But we do check mod vs non mod
ChaelCodes Okay
right then shouldn't it shouldn't the cache key just change to user id yeah we don't use it as conditional but there's like the controls change on these items so like if you have a comment If it's your comment, you should see the edit link.

03:24:39ChaelCodes I'll do @user.id but that's a cache per user.
Okay.

...50Yeah.

03:25:09ChaelCodes Is there an edit link?
Maybe not. I feel like I don't have a lot of confidence in why I made that part of the part of the cache key.

...25Well, yeah, if we render stories list detail and stories comment, those have a bunch of conditionals based on whether you're the author.

03:26:02ChaelCodes Oh, okay
ChaelCodes Probably should've check those.
yeah not to be the type theory guy but it feels like every predicate that appears in the view should probably appear in the cache key and they sufficiently advanced type system could enforce that but we might just have to settle for talking marco into enforcing that Actually, Marco, did you catch that one? That's not bad for herb.

...48marcoroth_ yeah, been actually toying with that
I don't know if it's quite that universal because we have a bunch of ifs. Yeah, they're all dependent on item and then attributes of item.

03:27:11Yeah, so this cache key is technically wrong because the moderator could change their username and we wouldn't invalidate the cache. Huh, I never noticed that till now.

...31And I don't wanna add it to the cache key. It feels like, I mean like it would be technically correct, but it would be noisier and in practice, the moderator is not going to change their username.

...57marcoroth_ or, just remove the cache call πŸ™ˆ
But then these story and comment attributes. ChaelCodes lol
This page loads brutally slowly without the cache. Like it's a. It's a 30 second load without the cache.

03:28:36I'm pretty sure I avoided one plus ends in here.

...46marcoroth_ huh, because of inefficient queries or just because you are rendering so many items?
ChaelCodes It's not bad in dev.
even still it is slow i think it's just so many items let me let me pull it up in prod i'm doing this off stream because well i could do it on local dev but

03:29:13Yeah, but Chael, in your dev, you have so many fewer objects in your database. You have a couple thousand instead of a couple of million.

...41ChaelCodes Well, yes, which implies it's the queries.
ChaelCodes Which makes sense with all the joins.
Votes is kind of the... marcoroth_ do you need to see them all at once?
ChaelCodes We might be missing an include?
yeah that's her maybe i did let a one plus n sneak in there oh yeah it's probably the polymorphic i think you can't do a polymorphic join or can't preload across a polymorphic, right? There's some restriction like that.

03:30:15Yeah, it's queries. I pulled it up in prod and it's doing a whole bunch of one plus ends. It's at least doing only one per activity, but each one of those is loaded individually rather than like all the stories and their associated objects together or all the comments.

...46That might be worth double checking because the behavior could have changed. Maybe I got smarter about that, but I didn't think you could do any kind of preloading across a polymorphic.

03:31:13I do like these. It's in your screenshot, but you captured the style of comments and messages with the byline.

...29Oh my God, I'm only half way through this PR and I'm a half an hour over.

...53In my dream, Braille's would be better at projections like if i could make a class called like hydrated mod activity i could join across to the alternate tables and i would have one model for that projection and even if it's read only would let me encapsulate some of the things like hide the abstraction where if i do a left outer join i have a ton of null columns and a sufficiently clever active record could hide that from me i'm aware how how much i'm asking for like at that point you know i might as well also ask for the moon on a string

03:32:58No current references.

03:33:36Did we properly use content for? Did I refactor that? I guess I did. No.

03:34:32Hey, it's my thing.

...38Nails, mail messages. ChaelCodes YUP
I gave you a merge conflict here because I leaked and I moved for your parents and I moved domains and origins. OK, yeah, I saw these. Oh, wait, I didn't see.

03:35:14Thank you.

...45And because it's polymorphic, yeah, the references to comments and stories can't have a FK index. Shame.

03:36:15chinmay22222 when do i get the ability to downvote? i've seen comments with a negative score but don't see a downvote button
Yeah, we definitely do that one in factories, the padding.

...24Chinmay, we do not have downvotes. We only have flagging. And it's, I want to say, can flag.

...48chinmay22222 ah flag
chinmay22222 yeah yeah
yeah if you have 50 karma you can flag stuff to the mods because we kind of assume at that point you understand the rules around topicality and some of the community norms just because you've seen a bunch of stuff wouldn't hurt if that also said like 90 days yeah i know we look an awful lot like reddit and hn but we do not have down votes please do not use flags to punish things ChaelCodes I have 52 Karma!
ChaelCodes I can flag everything!
marcoroth_ watch out!
And we are literally reviewing code right now that will make flags more valuable because I would like to get to the point where, and this is months off at least, but I would like to get to the point where most flags start modmail conversations. Because there are that few of them. And they are that high signal.

03:38:01Well, Chael has seen the UI for mods and admins where mods do see who flagged things and we do occasionally catch a pattern like alice is flagging every comment bob posts oh okay alice knock that off i think i think once there was someone who in my scenario was Alice and absolutely refused to stop flagging. And I was like, you get that the only next step I can do is ban you. And they were like, you know, from my cold dead hands. And I think that's how that worked out. Was there somebody?

03:39:13chinmay22222 i think asking for a reason for flagging does quite a bit to prevent it from becoming like reddit
Whoa, there's a few that mention flags.

...26Maybe not.

...41Oh, yeah, OK. There was one user. I'll user flag 1500 stories for weird or no users. No reasons.

03:40:02hugoarnal_ 1509, that's dedication
ChaelCodes Me, tomorrow.
know hugo you say that but there is one user i'm not going to call them out by name because it's not bad behavior it was just odd there is one user who has hidden I think at this point they're at like 75% of the stories on the site because they are slowly reading their way through the entire site. And so if they click hide on a story, it won't appear on the homepage. And so as they read the site, they click hide on every single story. chinmay22222 bruh
hugoarnal_ lol that's awesome
And so they're reading the current day's stories and then they're going back through the database years and years and years.

...54hugoarnal_ wait you can hide stories?
marcoroth_ Clever use of "Mark as read" Kappa
ChaelCodes lol
nesh that's right that was nesh oh and apparently they like to post other abuse yeah there must have been a lot going on here and yeah hugo i'm not logged in actually i am logged in locally right

03:41:28Yeah, there's a hide link under every story. That link should probably disappear for mod leaders, actually. No tapping out for mods.

...47hugoarnal_ ohh that's why I don't see it lol
Actually, that is on my backlog that mods should not be able to filter tags. chinmay22222 is 389 your normal inbox or does it include modmail and other mod stuff
and hiding stories is the same functionality maybe that should be in the like the code path that set someone as the moderator chin may it's both normal and abnormal so i have email notifications for messages turned on so when they show up in my personal inbox chinmay22222 ah
in my email client i'll see like a a message that just says like oh thanks for explaining that or oh sure got it you know like just a an acknowledgement message and then i don't click through to mark it as red and then i swear my personal email is an inbox zero no no it's its own kind of wreck Modmail will help fix these problems.

03:43:06User, Modmail, yes. Great. Modmail spec.

...34Ah, so here's where Chael was getting creative with some of the scenarios. I have concerns about your recent behavior.

...49That is the kind of message we send sometimes.

03:44:17Hot damn.

...48I don't love using let like this valid and invalid attributes to share data between tests. I tend to repeat data because the chore of editing it is pretty small and it means less scrolling in the test.

03:45:21ChaelCodes Got it. Leave a note and I'll do it.
Hey, I made it to the mute button before I sneezed.

03:46:07When I say fairly recent, I mean maybe the last two years. I've tried to get away from even shared setup like these objects that get reused. I'm kind of okay with user, but I don't know. Every time I have to scroll up in an RSpec file, I get less inclined to use let. But I realize that refactoring tests is almost never worth the risk.

...46So it's really subject to lava layer. Oh, I finally reached the end of the PR. Oh, nice. You even tested for mods.

03:47:23Doppp Congrats Marco!
ChaelCodes Yay!
Ah, nice. Did you edit this in since I was scrolling up and down the diff? ChaelCodes Yes
Anyways, yeah. Let's go finish review because sometimes I forget to click this button because it's not on the other tab. All right.

...54Three, with your plan. Two.

03:49:12ChaelCodes lol
It's not a, oh, I should have a message in here. Yeah.

...25I should link this. What is today? Well, 22. Yeah. ChaelCodes Thanks. That'll really help me.
Oh, you know, if I was really smart, when I hit the bottom of that PR, I would have gone, bam, and turned on. You like that? ChaelCodes Before you go, may I recommend raiding milesfoob? It'll make his day. He's the guy from the Discord message about me at SF Ruby.
It's the closest thing I have to a Chiron or an overlay. I'll try and get this posted fast. ChaelCodes `/raid @milesfoob`
Rating Miles Foob. The Discord. message i vaguely know the username but yeah that's a great idea so yeah perfect timing i'm here at the end of the stream so if anybody has any last questions put your hand up right now but i ran long because i'm gonna take a holiday break and i hope you all get a chance to do the same spend time with your friends and family etc hugoarnal_ Great stream! Wanted to say that I've been lurking Lobsters while on my way to work every morning for the past few months and it's been a blast. Thank you for keeping the site up after all these years ;-)
So I will say, happy holidays and happy new year. And let's see, raid miles. Huh, didn't autocomplete that one.

03:50:50ChaelCodes Happy Holidays!!
Frici Happy Holidays!
And now I can't actually read the last message. Ah, there it goes. Thanks, Hugo. The Twitch UI was hiding your message because it had its command palette open. But yeah, thanks for reading. Thanks for your kind words. Drop by the chat room sometime. marcoroth_ Happy Holidays!
hugoarnal_ Happy holidays!
And it's pretty straightforward to pick up an invite that way if you don't know anybody. ChaelCodes Yes
yeah with that let's go slash raid miles foob i think that starts a countdown timer right invalid username miles foob slash raid at mile no matches do i have to be following them or something

03:51:51ChaelCodes It's definitely the right username.
ChaelCodes I'll get with him.
Twitch.tv slash miles. ChaelCodes There's features to turn off raids.
Okay. Follow. What is knock?

03:52:08ChaelCodes Probably has it on.
I don't know what that means.

...16ChaelCodes Knock invites them to Stream Together on Twitch
Slash raid. ChaelCodes the feature we can't use
No, I followed him, but it didn't. There's a knock button on his profile. I don't know how to do that. ChaelCodes Following does not affect raids
Oh, your account needs to be phone verified in order to use stream together. What? That's not the thing I want to do. hugoarnal_ maybe try with no @
Okay. All right. Following does not affect rates. So great.

...49Ha, you got it. Hugo got it. It doesn't have an app. ChaelCodes WHOA
Here we go. All right, everybody. Happy New Year. Take care. ChaelCodes TWITCH EXPERT
ChaelCodes lol
I'll be back on January 5. Yes.

03:53:11Did it go?

...21I think it went. I swear, Twitch.