jump to navigation

Fun with Powershell, Part 1 – Intro/Twitter API Monday, 01/09/2012

Posted by Percy in Fun with Powershell, Programming, Technology.
Tags: , , ,
trackback

I’ve really been enjoying learning more about Powershell.  I’ve actually gotten to the point that I think about using it first, and then writing a full-fledged application second.  In the past, I’ve listed some of the things I’ve been able to do with Powershell, but I thought I might dig a little deeper and provide some more detailed info about the what and how of those kind of things.  Too, whenever I talk to developers or technology folks about Powershell, they all have the same reaction – “Isn’t that more for system administrators than for developers?”.  While I fervently agree that anyone administering any kind of system needs to know Powershell for their own sanity, it’s a great tool for developers as well.  So, I thought I would highlight how developers can use Powershell by throwing out some real world examples of how I’ve used it.  Also, I’m assuming that you know the basics of Powershell – declaring variables ($), calling methods on objects, piping input into commands, creating new objects, etc.  If you need more clarification, please let me know.

I don’t know how long this series will be, but here we go with part 1.

I was reading through my twitter feed the other day, and I came across this post from The Oatmeal:

“Is there a way to sort my Twitter followers by the number of followers they have? (in descending order)”

My first thought was “I’m sure I can do that in Powershell”.  Now, there are a number of web apps out there that will actually do this for you.  I even think the next tweet points to friendorfollow.com.  However, I thought it would be a neat learning exercise.  Before we begin, I figured I’d throw this out there – I honestly have no idea how this will work.  I don’t have some stock twitter API in my back pocket ready to use.  So, this will be “from scratch”.  So, here’s how I did it.

First off, I’m assuming that there is a twitter API, so I go to twitter’s website, and I click the link at the bottom labeled “Developers” (hey, that’s me!).  That takes me to dev.twitter.com, which has a link for Getting Started with the API.  Bingo!  After looking around there, I find that it’s just HTTP requests of the format “https://api.twitter.com/{Version}/{Controller}/{Action].{Format}?{Parameters}”.  So, in this case, the first thing to do is get the followers for a particular user.  So, the URL I’m going to use is https://api.twitter.com/1/friends/ids.xml?screen_name={your user name}, since I want to use the XML format.  That returns the list of all my followers.  So, now I need to get this into Powershell by firing up my trusted Posh IDE – PowerGUI.

With Powershell, you have access to any .NET library, including the ones in the core.  There’s a class called System.Net.WebClient that I think I can use.  Let me see what options I have:

New-Object System.Net.WebClient | Get-Member 

There’s a method called DownloadString, that takes in a string address as a parameter.  So, lets give this a try and see what happens:

$url = "https://api.twitter.com/1/friends/ids.xml?screen_name={your user name}"
$wc = New-Object System.Net.WebClient
$wc.DownloadString($url) 

That returns the XML response that I’m looking for.  So, now I need to put that string into an xml object, and see what options I have.

[xml] $data = $wc.DownloadString($url)
$data | Get-Member 

Now, one of the properties is called “id_list”.  If I look at the XML returned from the URL I passed in, that’s the root node.   So, by putting it in the XML object, Powershell has effectively serialized my XML into an object tree.  So, now I should be able to get each individual id.

$data.id_list.ids.id |
% {
	$_
} 

From that I can see the list of id’s. Alright, now I can loop through each one of my followers. So, the next step is getting the number of followers for each of those users. Luckily, there is another API call that can give us that information.  So, now, for each one of these users I want to call a URL of the following format - https://api.twitter.com/1/users/lookup.xml?user_id={User ID}&include_entities=true.

Note: The twitter API only allows 150 calls an hour per IP address.  I found this one out the hard way.  So, while you CAN loop through all your friends, I wouldn’t recommend it if you have more than 150 people your are following.

So, now I can do something like this within the loop:

$userUrl = "https://api.twitter.com/1/users/lookup.xml?user_id=$($_)&include_entities=true"
[xml] $userData = $wc.DownloadString($userUrl)

A little more testing tells me that the user name of the current follower can be found at $userData.users.user.screen_name and the follower count can be found at $userData.users.user.followers_count. Now, I want to see this data as a simple data set so I can sort the data. There’s a neat little trick I picked up while reading this article. You can dynamically declare an object structure by using a command similar to this:

$newObj = "" | Select-Object Property1, Property2, Property3

If you then do something like this:

$newObj | Get-Member

You’ll see “NoteProperty” types that correspond to the properties you declared earlier. Too, instead of doing multiple set operations on separate lines, you can do multiple set operations on one line – as long as you get the order correct. So, once I get the data for the user, I can do something like this:

$outputItem = "" | Select-Object Name, ScreenName, FollowersCount
$outputItem.Name, $outputItem.ScreenName, $outputItem.FollowersCount = $userData.users.user.name, $userData.users.user.screen_name, [int] $userData.users.user.followers_count

Now, if I just put $outputItem on a line all by itself, it’ll be returned as a result of this iteration of the loop. So, now my loop returns a data set which contains all the data I want to see. Just to make it a bit nicer, I can pipe it out to Out-GridView. That allows me to see the data and play with it all I want. So, if I put it all together, I’ve got a script that hits the Twitter API and will return a grid view of all of the people that you are following and their follower count in a little over 10 lines of code (and some of that simply for formatting):

$url = "https://api.twitter.com/1/friends/ids.xml?screen_name={your twitter name}"
$wc = New-Object System.Net.WebClient
[xml] $data = $wc.DownloadString($url)
$data.id_list.ids.id |
% {
    $userUrl = "https://api.twitter.com/1/users/lookup.xml?user_id=$($_)&include_entities=true"
    [xml] $userData = $wc.DownloadString($userUrl)
    $outputItem = "" | Select-Object Name, ScreenName, FollowersCount
    $outputItem.Name, $outputItem.ScreenName, $outputItem.FollowersCount = $userData.users.user.name, $userData.users.user.screen_name, [int] $userData.users.user.followers_count
    $outputItem
} | Out-GridView

So, there is is. In the interest of full disclosure, here is my script, with the user limiter code included as well as some commented code I was using for testing purposes:

cls
# New-Object System.Net.WebClient | Get-Member
$url = "https://api.twitter.com/1/friends/ids.xml?screen_name=katman26"
$wc = New-Object System.Net.WebClient
[xml] $data = $wc.DownloadString($url)
$count = 0
$data.id_list.ids.id |
% {
    if($count -lt 5)
    {
        $userUrl = "https://api.twitter.com/1/users/lookup.xml?user_id=$($_)&include_entities=true"
        [xml] $userData = $wc.DownloadString($userUrl)

        $outputItem = "" | Select-Object Name, ScreenName, FollowersCount
        $outputItem.Name, $outputItem.ScreenName, $outputItem.FollowersCount = $userData.users.user.name, $userData.users.user.screen_name, [int] $userData.users.user.followers_count
        $outputItem
    }
    $count++
} | Out-GridView

Let me know if you have any questions about this or any of the examples I’ve shown. I’m not a Powershell expert…yet. :)

Advertisement

Comments»

No comments yet — be the first.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 155 other followers