wernull

Getting Started With the Yahoo! Fantasy Sports API

When I first started building my fantasybots.com service, there were many hurdles I ran across while learning to work with the Yahoo! Sports API. First off, the documentation is horrible and has actually gotten worse over the years. Also, it appears community relations with independent developers were abandoned back in 2010. The following are some tips on getting setup using Node and Express.

Setting up Yahoo! app

Go to https://developer.yahoo.com/apps/create/ and create an app. The callback domain says optional but will need to be set for the way we will be doing authentication. This callback domain needs to be a domain you control and can be used for both development and production. Under API Permissions check the Fantasy Sports box and then click the create app button. This will give you the two OAuth keys needed for the next section.

Communicating with the API

While you could setup your own OAuth, I went with a library that took care of most of that along with making the API easier to work with. There are a few out there but I went with fantasy-sports. The documentation on GitHub is straight forward with plenty of code examples.

This library is setup for using the token stored in a browser cookie but I have had no problems storing the token on the back-end for automated request when the user is not on the site.

The API allows you to request JSON but it is very apparent that XML is the primary format. The returned JSON is very messy and overly complicated. Also, if you ever need to POST back to the API it only accepts XML.

Local development

Unfortunately, Yahoo! doesn’t allow you to set the callback domain to a localhost address, but it does allow you to use any subdomain of the url set. In order to have a development workflow that did not require pushing changes to a staging server, what I did was use ngrok. This is an amazing service that I use almost every day at home and work. If you pay for the service, they will allow you to setup your custom domain to tunnel traffic to your localhost environment https://ngrok.com/docs#custom-domains. Once all that is setup then local development is a breeze.

The Data

Be careful when working with the JSON returned from the API. It appears to just be a conversion of XML:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
{
  players: {
    0: {
        player: [
            [{
                    player_key: "346.p.8851"
                }, {
                    player_id: "8851"
                }, {
                    name: {
                        full: "Devin Mesoraco",
                        first: "Devin",
                        last: "Mesoraco",
                        ascii_first: "Devin",
                        ascii_last: "Mesoraco"
                    }
                }, {
                    status: "DL"
                }, {
                    on_disabled_list: "1"
                }, {
                    editorial_player_key: "mlb.p.8851"
                }, {
                    editorial_team_key: "mlb.t.17"
                }, {
                    editorial_team_full_name: "Cincinnati Reds"
                }, {
                    editorial_team_abbr: "Cin"
                }, {
                    uniform_number: "39"
                }, {
                    display_position: "C"
                }, {
                    headshot: {
                        url: "http://l.yimg.com/iu/api/res/1.2/6lZ3W5sQgW6GvYDqstn64Q--/YXBwaWQ9c2hhcmVkO2NoPTIzMzY7Y3I9MTtjdz0xNzkwO2R4PTg1NztkeT0wO2ZpPXVsY3JvcDtoPTYwO3E9MTAwO3c9NDY-/https://s.yimg.com/xe/i/us/sp/v/mlb_cutout/players_l/20150406/8851.png",
                        size: "small"
                    },
                    image_url: "http://l.yimg.com/iu/api/res/1.2/6lZ3W5sQgW6GvYDqstn64Q--/YXBwaWQ9c2hhcmVkO2NoPTIzMzY7Y3I9MTtjdz0xNzkwO2R4PTg1NztkeT0wO2ZpPXVsY3JvcDtoPTYwO3E9MTAwO3c9NDY-/https://s.yimg.com/xe/i/us/sp/v/mlb_cutout/players_l/20150406/8851.png"
                }, {
                    is_undroppable: "0"
                }, {
                    position_type: "B"
                }, {
                    eligible_positions: [{
                        position: "C"
                    }, {
                        position: "Util"
                    }, {
                        position: "DL"
                    }]
                },
                [],
                []
            ]
        ]
    }

Here is where a library like lodash will come in handy. Also, a huge mistake I did was assume that an object in an array would always be in the same position. For example, { display_position: "C" } in the above JSON is at players['0'].player[0][10], however, if that player was no on the “DL” then the { status: "DL" } is left out and display_position then becomes players['0'].player[0][9]. So what you have to do is either loop through the player[0] array or use lodash to find the object by property.

There are many things I have encountered in my two years of working with this API. Feel free to reach out if you have any questions.

The Coffee Machine Has WIFI?

One day a new shiny office coffee machine showed up. Unlike the previous one, this machine had a large touchscreen instead of buttons. Of course, the first time I try to use it it locks up and says “trash full.” After tracking down the office manager, I watched her open the front, press a small button on the inside, enable the settings screen and that is when I saw a small WIFI icon in the bottom corner. This was the first time I thought about messing with it, but I didn’t have the time or any specific reason.

Fast forward a few months and I run into this wonderful article about automation and I now have a reason. How sweet would it be to initiate a cup of coffee from my desk then have it ready after walking across the office and up the stairs. However, our machine does not provide the cup. That means I either have to tackle anyone who tries to get in my way to chat or I have it wait after brewing and program a button to dispense. But that’s a problem that can be worried about once the experiment is successful.

After discussing this with a coworker, I decided to try and find the machine on our local network. Keep in mind I’m not a network guy and have never done anything like this before, but they make it look like so much fun on TV. He pointed me to a tool called NMAP and I started learning how to use it. In the meantime, he simply walked upstairs, opened the machine’s settings, and tried to find the IP address that way. Unfortunately, that section of the menu was password protected.

I decided to keep working on the network side and ran a scan of every IP in the network. A small part of me was afraid of receiving a call from the IT department, but I guess that didn’t trigger any warnings. The results were a very large list of ip addresses and open ports. I was able to filter out most results by eliminating any machine with anti-virus software. Anything with http/https was checked out in a browser and anything with ssh was inspected through the terminal. While I was unsuccessful in actually finding or gaining access to the coffee machine, I did find my way into a few printers and the smart TV.

The next step was to do a little research. Soon I realized trying to find user manuals was as sketchy as looking for random hardware drivers. I managed to find some promotional pdf’s and a few distributors of the machine but have yet to find any sort of service or user material. A few things that caught my eye were add on items to the product. The manufacture offers a paid service to remotely monitor your machine. Also, a credit card processor is an optional item. One would hope that these services have even the most basic of security. Perhaps thinking this wanna be hacker has any chance at cracking the machine is a bit of a stretch. Looks like this experiment will have to come down to good ol’ social engineering.

To be continued…

That New Blog Smell

It’s been a few years and this blog has become stagnant. Over that time I have worked on some interesting projects both at work and on the side and decided it’s time to share some of those stories. So just like most developers out there, the first thing I did instead of actually writing was rebuild the blog onto a new platform. If you build it, the words will come.

After a few times of the old WordPress site going down because of MySQL issues, I knew I wanted to rebuild it in something more stable. Static sites have become popular recently and I can see why. They offer performance and stability; just not a user friendly CMS for writers. However, as a developer, there are many options geared towards our crowd. I chose to use Octopress from a colleague recommendation. It runs on Jekyll which we have used many times around the office for small websites. I had a feeling using Jekyll for it’s intended purpose was going to be a lot smoother, especially with a framework like Octopress to bundle commonly used modifications. And I must say, so far I am very pleased.

Leaving the Country Made Me a Better Web Developer

After spending a short time where English is not the primary language, I have learned first hand the importance of proper translation. There have been many times when I was translating a website that I did not put much thought into how those random arrangement of characters fit into the place they were suppose to go. However, I have now seen what it looks like for translations to be an after thought. The problem is not that the message is broken, but that it gives off a bad impression and sometimes can be interpreted as offensive or insensitive.

It’s not that this is new to me, but that I never understood how important it was until I was on the receiving end. This has given me a whole new perspective on the importance of being diligent with my localization tasks. Another thing I have noticed are how many things are designed without relying on text and use clever illustrations to convey the message like on road signs and exit lights. I have seen this being done using meaningful icons on websites, but I always looked at that from a design prospective and not a localization tactic.

It feels like to me that most cultures are better at a multilingual society than the United States. This shows from their intuitive solutions to overcoming a language barrier. My time abroad has not only changed my impression of other cultures, but given me stronger awareness to the importance of my attention to detail.

WordPress Unbranded / Simple Admin Plugin

WordPress makes a great CMS for clients on a budget. However, many of those clients don’t know and don’t need to know what WordPress is. This plugin is built to make the admin experience a little more personal for those who just need to log in and make a few copy changes.

Download / GitHub

Instructions:

Unzip and copy the folder into your plugin directory. Activate it from the Installed Plugins page. Plugin options can be found at Settings / WP Unbranded

Options:

  • Remove “Howdy”
  • Remove WordPress logo and link drop down from the admin bar
  • Replace user name drop down with just a logout button
  • Change login page image
  • Change login page image link to homepage url
  • Change Admin footer