BrandGhost

Perfect Twitter Thread Screenshots Using .NET C#

Interested in building your very own social media assistant in C#? In this series, we work through building out an application using #dotnet where we interface with popular social media platforms to get analytics and eventually help with content creation! In this episode, I demonstrate how you can use Selenium to make your very own twitter thread screenshot taker! Say goodbye to watermarked or paid for screenshot generators for twitter threads... Now you have the source code for your very own!...
View Transcript
Hey, so thanks for checking out another episode of the automated social media assistant. This video in particular is going to be about taking screenshots of Twitter threads. And I wanted to put this together because it's something that's been bothering me a little bit because there's a whole bunch of websites that do this for you where you put in a thread and then they'll try to like watermark it and whatever else. And I'm like, man, like I can build this. Like I don't need to go have some watermarked pictures or pay for some service. like I can put this together, we can make a video about it and then put the code out there for people to use. So, felt like a good opportunity. So, if this sounds like an interesting topic, please give the video a thumbs up, leave a comment below for that YouTube algorithm, and of course, subscribe to the channel if you like stuff like this. So, let's get switched over to the code. Awesome. So, I am here in Visual Studio. I have a ton of commented out code. This is pretty nasty, so I apologize, but it's functional, so that's the cool part. I'm going to jump back over to program.cs here. Um, this is up on GitHub, so we'll have a link in the description for it. But for the social media assistant, we're kind of just playing out with some uh some entry points, I guess. Uh, we had something for getting Tik Tok followers. Now, I'm just kind of adding in some functionality for these uh tweet threads, if you will, for screenshots. So, it's not really organized in a good way yet, but we're kind of just building out functionality, like I said. So, you can see at the start here, I have um a list of tweet IDs. So, an improvement that I I want to make for this is that you can give it the actual like URL to the the thread, and then it will go dynamically figure out which responses to that are the right um replies to to include in the thread. So, that's something I'll figure out later. But, um, for now, I just have all of the IDs for the tweets that I'm interested in. And what we're actually going to do is use Selenium, uh, in headless mode to be able to load up those web pages, take screenshots, and then, uh, aspect ratio size them to the correct output. So, again, this code is available on GitHub. Um, it's not perfect by any means, but you can take it and play with it. So, we're going to pass in this array of these tweet IDs. And then I have a background color here. So, this is just going to translate to white for us in RGB. And then we're going to jump over to this create from tweet IDs method on our screenshotter class. So, go ahead and jump into that. You can see this is the method, right? Takes in the background color and the tweet ids. The first thing we're going to do is create a uh web driver instance for Selenium. And then we're just going to change the window size to give it uh I picked 800 by 1200. You could play around with this, but this seemed to be enough to to for a thread or I guess a individual tweet to be able to fit it properly on screen for me. But experiment with this, right, the next thing we're going to do is basically get I'm just using link here and doing a select to basically iterate over all of the tweet IDs and call this create tweet screenshot method. So, let me jump into that. And this is where the code, if it wasn't already pretty gnarly, starts to just be really cluttered. So, I'll explain it and kind of why I have a bunch of stuff commented out. So, the first part is really just navigating to um this publish. Twitter.com page with the right URL for your tweet. Um you can see here that I would probably want to clean up this URL a little bit. So when you go to experiment with this, you'll want to uh definitely clean up the query URL. Um all should be functional once you just figure out the URL you want there. But assigning this is going to navigate the browser selenium in headless mode to this page. Now what we want to do for there is we want to wait for some content to be present. But one of the tricky things and why there's so much commented out code here is that there's a bit of a trick going on. And that's that the content becomes available before we've actually number one scrolled it into view. And number two, if you watch it, it goes super fast. Um, but when you do this manually in your browser, the actual like tweet um visual, like you can see it kind of grow. And I I feel like what's happening is that if you don't wait an appropriate amount of time, you'll see that it starts to clip. Now, I've been trying everything I can think of to basically wait um like explicitly until something's available. And I've tried waiting for certain HTML content to be present. Uh waiting for the right bounds to be uh conditions around the bounds of a control to be met. Nothing seems to work. But if I wait for literally 1 second, I hate having thread. Anywhere. Um, but if I have that, it uh seems to work. So, for now, good enough. So, let me go ahead and comment that back out. Um, or comment it in, I guess. Uncomment it. And, uh, I'm going to take this part out because this was not working. And let me go ahead and delete the break points, too, because I'm sure when I go to run this, I'm going to forget. Cool. Let me scroll back up. So, what we're going to do is uh at least a minimum wait for one of these uh we're using XP path here. So, we're just going to wait for this Twitter widget to be present. There's a number that follows that seems to change. So, we don't get the whole number. We just wait for this to be present in XPath. So, that works. You can see that I tried some different ways to scroll to see if maybe that would affect if we can scroll things into view properly. Um didn't make a difference, right? So if I just call scroll to element and perform that action with this setup here um or move to also worked as long as I wait 1 second all of this seems to work. The trouble seems to be that if I try waiting and using different mechanisms to wait again um some of the the stuff that I had tried out here was you can kind of see in this code that's commented out like waiting for um the actual bounds of the element to be visible and within screen uh limits. I tried seeing if we could uh set a height and then when we retry the method again, we actually prove that the height is not changing. That also doesn't work. Um so I am totally at a loss, but I want to come back to this at some point and really kill off this thread. So I'll figure it out at some point. Okay, so all that's commented out, but it's to do the same thing. The next thing we do is actually take the screenshot. And there's a little bit of code here just to actually um when we take the screenshot, it's of the entire browser window. So, we're going to take the element bounds and the offset and then actually crop out just the element itself and we're going to store that into an image. So, that's what this code does. Uh this was just saving it to disk so I could double check it. But anyway, at this point, when we leave the method, we now have um I made a little object. What is it called? A tweet screenshot. Um it just has a tweet ID and an image on it. It's a record. So anyway, that gets returned. I'm going to scroll back up here. And so we finish this. We have all of the tweet screenshots in an array. Now, the next and sort of final step that we have to do is especially because I want to be able to post this to Instagram, it's picky about the aspect ratio when you take uh a bunch of pictures and try to do like a multiple picture post so you can swipe through them. I wanted to be able to have a tweet thread that you could swipe through. And if the aspect ratios are a little bit off, you'll notice that you'll get funny clipping and I just didn't want to deal with it. So, what I do, um, it's a little bit a little bit weird, I guess, but the the width always seems to be the exact same. So, doing a max width here is kind of just it's kind of pointless, but uh, I left a comment just so I can come back to this at some point. the max height. The reason why this is important is we want to sort of scale everything up to um the max height that we have for one of our tweets because in a thread you might have a paragraph, you might have like a oneliner. So, we want to get the max height. What we're going to do from there is basically aspect scale everything up to the max dimensions uh based on the largest sort of tweet screenshot that we have. And we're going to do that by filling in the background with the color that we passed in. In my case, it's white. So when we do that, we're gonna basically have the largest tweet will kind of take up the whole image. And anything that's smaller is going to take up the normal size that it has, but it will have a background. Um, in this case, white. So that way all of the output pictures should be the same dimensions. So that's what this code does in a loop. It really, you can see like fills uh fill rectangle to put a background color in and then draws the image the from the screenshot that we took onto like a a canvas if you will. And then we can save that out. So once I return another uh record type up, just going to scroll back up. Actually, it's uh it's in program.cs. So all the way back here, you can see I have this for each loop around the whole thing. And I'm just going to try basically saving it and disposing of the image after. Um, and I think that's mostly it. So, let's go ahead and run this and see what happens. And of course, while I'm recording it, it will probably break. So, let's see. Remember, it's based on waiting 1 second for every um tweet in the thread. So, that's unfortunate. Perhaps it could go faster without that. Cool. So, it's done. I'm going to bring over the output window and see what it output. And it's a little small. So, let me open this. And I'll scroll in for you. Okay. So, here's uh one. And I actually I guess I was wrong. Um I should have mentioned that I'm trying to I need to meet an aspect ratio requirement. So, even though this was the biggest uh tweet, I still needed to scale it properly so that it would meet an aspect ratio. I believe this is uh I can't eyeball it cuz it's it's either one by one or five by or 4x5. Yeah. Um but they all have to meet it. I can't tell if that's perfectly square or not. It looks like it, but I might be wrong. So, when I go to the next one, my keyboard's not working. Um, you can see, right? This also worked as I go across. You'll notice that some of these are smaller. Like this next one's a really good example. Um, it's the same overall size, but the tweet itself is centered in the middle. So you can go through and basically what I'm able to do at this point is I can go upload this to some place like Instagram, make a post and really this social media assistant is all about just giving us some tools and we'll find ways to actually automate some of these processes later as we build out these tools. That's it. And I think I just wanted to be able to demonstrate that today and kind of what we've added into the automated social media assistant. So, if that was interesting to you, please give the video a thumbs up. Leave a comment below, especially if you know how to solve that silly Selenium issue and actually guarantee that something has finished rendering and it's uh sort of at steady state. I'd love to hear. And of course, subscribe to the channel if you want to see more content like this and follow the journey of the automated social media

Frequently Asked Questions

What tools do I need to take screenshots of Twitter threads using .NET C#?

You'll need to use Selenium in headless mode for loading the web pages and taking screenshots. Additionally, you'll be working within Visual Studio to write and run your C# code.

How can I ensure that the screenshots maintain the correct aspect ratio for Instagram?

I scale the images to the maximum height of the tweets while keeping the width consistent. This way, all images will have the same dimensions, ensuring they fit properly when uploaded to Instagram.

Is the code for this project available for me to use or modify?

Yes, the code is available on GitHub, and I'll provide a link in the description of the video. You can take it, play with it, and make improvements as you see fit.

These FAQs were generated by AI from the video transcript.
An error has occurred. This application may no longer respond until reloaded. Reload