Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Converting from ESPN v2 API to v3 #95

Closed
mkreiser opened this issue Mar 9, 2019 · 47 comments

Comments

@mkreiser
Copy link
Owner

commented Mar 9, 2019

ESPN have updated their fantasy football API from v2 to v3. This project is built for v2 and requires significant work for update to v3. This issue tracks the necessary tasks to complete this conversion. The conversion work will occur on the v3-api-conversion branch (protected).

  • Update README with conversion work notice
  • Investigate new route structure
  • Compare v3 route structure to the class design of this project
  • Design new classes, reusing existing structure where appropriate
  • Prep codebase on v3-api-conversion branch for new design (remove deprecated code, etc)
  • Make changes to base classes (BaseObject, etc)
  • Implement new designs
  • Ensure JSDoc documentation is comprehensive and high-quality
  • Clean up unit tests if needed
  • Write integration tests
  • Write migration notes and update README
  • Merge v3-api-conversion branch to master
  • Publish 0.9.0 for testing
  • Publicize new work
  • Publish 1.0.0 for production
  • 🎉
@mkreiser mkreiser self-assigned this Mar 9, 2019
@mkreiser

This comment has been minimized.

Copy link
Owner Author

commented Mar 9, 2019

🎉 Update README with conversion work notice

#96

@mkreiser mkreiser pinned this issue Mar 9, 2019
@mkreiser

This comment has been minimized.

Copy link
Owner Author

commented May 11, 2019

🎉 Investigate new route structure

So ESPN's v3 api is... interesting. ESPN has maintained a minimal route structure, returning most of the data through a single route. Params are passed that affects how the response is populated.

http://fantasy.espn.com/apis/v3/games/ffl/seasons/2018/segments/0/leagues/336358?view=mDraftDetail&view=mLiveScoring&view=mMatchupScore&view=mPendingTransactions&view=mPositionalRatings&view=mSettings&view=mTeam&view=modular&view=mNav

So

http://fantasy.espn.com/apis/v3/games/ffl/seasons/<SEASON_ID>/segments/0/leagues/<LEAGUE_ID>?<PARAMS>

This does not align with the structure of this project well, again :(

Other routes include:

ALL PLAYERS http://fantasy.espn.com/apis/v3/games/ffl/seasons/2018/players?scoringPeriodId=0&view=players_wl
ALL FREE AGENTS http://fantasy.espn.com/apis/v3/games/ffl/seasons/2019/segments/0/leagues/336358?scoringPeriodId=0&view=kona_player_info
Pro League organization info https://site.web.api.espn.com/apis/site/v2/teams?region=us&lang=en&leagues=nfl%2Cnba%2Cmlb%2Cnhl
Pro team schedule http://fantasy.espn.com/apis/v3/games/ffl/seasons/2019/?view=proTeamSchedules
Roster at a given week http://fantasy.espn.com/apis/v3/games/ffl/seasons/2018/segments/0/leagues/336358?forTeamId=9&scoringPeriodId=13&view=mRoster

Now, there is an easy way to get player information, which should enable some interesting data analysis tools.

@mkreiser

This comment has been minimized.

Copy link
Owner Author

commented May 11, 2019

🎉 Compare v3 route structure to the class design of this project

At face value, the new route structure does not line up with the existing project. The mono route does not work with the existing design of this project, which attempts to take advantage of a couple different routes. However, the v3 route handles many params that construct different data responses. This project may be able to utilize this pattern instead of the route pattern. The route pattern is significantly more desirable, but we've got what we've got.

@mkreiser

This comment has been minimized.

Copy link
Owner Author

commented May 11, 2019

🎉 Design new classes, reusing existing structure where appropriate

Existing classes:

BaseObject: Should be fine as is
BaseCacheableObject: Should be fine as is
BaseAPIObject: Needs significant adjustments to handle new route structure + route params

Boxscore classes: Need to investigate data response more. Should be able to generalize BoxscorePlayerStats
League: Should be able to mirror organization of new response
NFLGame: Should be able to hookup to API
NFLTeam: Should be able to hookup to API
Player: Basic mapping updates. May be able to add more support with new player info routes
Roster: Needs a good bit of clean up
Scoreboard classes: Need to investigate data more
Team: Basic mapping updates

New classes

Will design as I dig into the data more

@mkreiser

This comment has been minimized.

Copy link
Owner Author

commented May 12, 2019

🎉 Prep codebase on v3-api-conversion branch for new design (remove deprecated code, etc)

#98. Will move code in from the master branch as development progresses.

Note: Removed support for Node 6, which was EOL'ed end of April 2019.

@mkreiser

This comment has been minimized.

Copy link
Owner Author

commented May 13, 2019

👷 Make changes to base classes (BaseObject, etc)

#99 in progress

@mpcen

This comment has been minimized.

Copy link

commented May 18, 2019

Any ideas on how to get previous seasons BoxScores yet?

@mkreiser

This comment has been minimized.

Copy link
Owner Author

commented May 26, 2019

@mpcen Hit http://fantasy.espn.com/apis/v3/games/ffl/seasons/<SEASON_ID>/segments/0/leagues/<LEAGUE_ID>?view=mBoxscore&view=mMatchupScore&view=mSchedule&view=mScoreboard&view=mSettings&view=mStatus&view=mTeam&view=mRoster&view=modular&view=mNav

The schedule attribute contains every box score of every game of the season. Be warned, the response was +650000 lines for my 8 league, 17 week league 😱. You can filter down the response by removing view parameters and setting X-Fantasy-Filter: {"schedule":{"filterIds":{"value":[<ID_FROM_SCHEDULE_ARRAY_THING>]}}} on the request header.

This project is going to (try to) simplify this significantly like it did for the v2 API.

@mkreiser

This comment has been minimized.

Copy link
Owner Author

commented May 26, 2019

🎉 Make changes to base classes (BaseObject, etc)

#99 is merged. Will probably need updates in the future to support filtering data on requests.

@mkreiser

This comment has been minimized.

Copy link
Owner Author

commented May 26, 2019

Starting with player data next, since it'll probably 🤞be easier to start with than boxscore/scoreboard data.

@mpcen

This comment has been minimized.

Copy link

commented May 27, 2019

Looks like it only gets boxscores from 2018. Nothing prior - huge RIP

@mkreiser

This comment has been minimized.

Copy link
Owner Author

commented May 28, 2019

@mpcen Yup. Last year ESPN decided to no longer preserve that data. There's a few reddit threads on it. From now on, there's only current and previous year available in detail, so download any data you wish to preserve.

@travisryan

This comment has been minimized.

Copy link

commented Jun 18, 2019

Hey, glad it looks like you're making progress. I'm wanting to use this to run a playoff combining two different leagues after 13 week regular season. Basically I'd only need the scoreboard info, etc for each team of a league. It looks like you've checked in the meat of the project. Any way I can get started on my project with the v3 branch?

@mkreiser

This comment has been minimized.

Copy link
Owner Author

commented Jun 22, 2019

👷 Implement new designs

Player done with #101

@mkreiser

This comment has been minimized.

Copy link
Owner Author

commented Jun 22, 2019

@travisryan Not yet for scoreboard info. Still a work in progress.

@mkreiser

This comment has been minimized.

Copy link
Owner Author

commented Jun 24, 2019

👷 Implement new designs

Team handled in #102.
Boxscore model handled in #103.

Next, take a basic shot at a client class to call the ESPN API. May start an alpha package with that.

@travisryan

This comment has been minimized.

Copy link

commented Jun 24, 2019

I'm new to Node but would like to test some of these changes. I have the new branch checked out and then built the module. Copied the dist folder to my new test project. And have the following code:

// From local build
var League = require ('./dist/index-node.js');

var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send('Hello World!');
});
app.listen(3001, function () {
console.log('Example app listening on port 3000!');
//const league = League({ leagueId: 1209139, seasonId: 2018 });
const league = new League({ leagueId: 1209139, seasonId: 2018 });
league.read().then(() => console.log(league)); // Prints loaded league

});

It didn't like the "new" word for League, and I tried without and that was just as bad. What might I be doing wrong, etc?

Thanks!

@mkreiser

This comment has been minimized.

Copy link
Owner Author

commented Jun 25, 2019

@travisryan That's the old branch that corresponds to the v2 ESPN API, which ESPN deleted. So that code won't work (it'll blow up on the read call).

if you want to play with the new stuff, you'll need to check out the v3-api-conversion branch. Currently nothing is hooked up to the API, so it doesn't really do anything. I'm working on a basic client on the client branch (branches from v3-api-conversion). I think it works once exported on index.js but I haven't tested it yet.

@travisryan

This comment has been minimized.

Copy link

commented Jun 25, 2019

ok cool. Thanks for the info. I THINK i checked out the v3 one but I def didn't get far. :) I'll be watching this closely as I think this project is pretty cool and hope to use it. Let me know if I can help at all.

@travisryan

This comment has been minimized.

Copy link

commented Jul 3, 2019

Would love to try the client. Any updates? :) Is the client something we need or just a test client so you know if your code works etc?

@mkreiser

This comment has been minimized.

Copy link
Owner Author

commented Jul 4, 2019

@travisryan Will put some work in on and off this long-ish weekend. Definitely trying to get something out the door soon so people can start building with this. The client is very close to being done and merged. I'm going to try to finish testing it today and get that code merged. Then going to update the README with new instructions and try to merge this feature branch into the master branch and publish a beta package.

@travisryan

This comment has been minimized.

Copy link

commented Jul 4, 2019

@mkreiser Awesome! Thanks for all your work!

@mkreiser

This comment has been minimized.

Copy link
Owner Author

commented Jul 4, 2019

👷 Implement new designs

#106 starts a base client with Boxscore + free agent player data. Gonna update READMEs, then merge this into master. Then publish a beta package.

@shibdib

This comment has been minimized.

Copy link

commented Jul 6, 2019

Looking forward to the v3 update. I'll dig in a bit and see if I can contribute some PR's

@mkreiser

This comment has been minimized.

Copy link
Owner Author

commented Jul 7, 2019

Merged current work to master and published as 0.9.0. README is updated with how to use the new stuff.

@travisryan

This comment has been minimized.

Copy link

commented Jul 9, 2019

@mkreiser ok I'm a bit of a noob I guess with NodeJS in some respects. I've tried adding your update module via npm install and also built it with your scripts and keep running into different errors just trying to test. I'm testing it in a .js or .mjs file on the commandline. What's the best way to get a simple example to work? I've gotten errors on the import where it didn't like the { char. For that I added --experimental-modules but then it says Client isn't in the packages, etc.

HELP! :)

@TylerJAllen

This comment has been minimized.

Copy link

commented Jul 9, 2019

When I call .getBoxscoreForWeek(), I am receiving numerical values for homeTeamId and awayTeamId. I am seeing a team.js file in the code that has a schema (Team.responseMap) but I'm not seeing how to actually receive a populated team object that includes the actual team nickname. Instructions would be appreciated!

@travisryan

This comment has been minimized.

Copy link

commented Jul 9, 2019

@TylerJAllen how are you calling the code? can you past a simple example? Are you launching Express, or calling from nodejs commandline, etc?

@TylerJAllen

This comment has been minimized.

Copy link

commented Jul 9, 2019

I'm using express and calling node app.js in terminal.

here is a shortened version of my code:

const { Client } = require("espn-fantasy-football-api/node");
const myClient = new Client({ leagueId: my league id here });

myClient.setCookies({ espnS2: "my espnS2 string", SWID: "my SWID string"});

let data;

myClient.getBoxscoreForWeek({ seasonId: 2018, scoringPeriodId: 5, matchupPeriodId: 5 }).then((boxscores) => {
   data = boxscores;
});

app.get("/", function (req, res) {
	res.status(200).send(data);
});

app.listen(3000, function () {
  console.log("Example app listening on port 3000!");
});

When viewing the data in localhost: 3000, I'm seeing this:

[  
  {
    "homeScore": 93.14,
    "homeTeamId": 16,
    "homeRoster": [ //populated with player objects ],
    "awayScore": 122.3,
    "awayTeamId": 9,
    "awayRoster": [ //populated with player objects ]
  },
{
    "homeScore": 104.02,
    "homeTeamId": 12,
    "homeRoster": [ //populated with player objects ],
    "awayScore": 86.5,
    "awayTeamId": 17,
    "awayRoster": [ //populated with player objects ]
  },
{
    "homeScore": 86.18,
    "homeTeamId": 18,
    "homeRoster": [ //populated with player objects ],
    "awayScore": 108.44,
    "awayTeamId": 10,
    "awayRoster": [ //populated with player objects ]
  },
{
    "homeScore": 66.3,
    "homeTeamId": 5,
    "homeRoster": [ //populated with player objects ],
    "awayScore": 81.72,
    "awayTeamId": 1,
    "awayRoster": [ //populated with player objects ]
  },
{
    "homeScore": 98.32,
    "homeTeamId": 15,
    "homeRoster": [ //populated with player objects ],
    "awayScore": 112.7,
    "awayTeamId": 3,
    "awayRoster": [ //populated with player objects ]
  },
{
    "homeScore": 95.4,
    "homeTeamId": 14,
    "homeRoster": [ //populated with player objects ],
    "awayScore": 108.98,
    "awayTeamId": 11,
    "awayRoster": [ //populated with player objects ]
  },
]

I tried using const { Team } = require("espn-fantasy-football-api/node"); to see if I could get the team nicknames and team stats but haven't figured out how.

@travisryan

This comment has been minimized.

Copy link

commented Jul 10, 2019

I'm also not sure how to use the Team object to get the names.

@mkreiser

This comment has been minimized.

Copy link
Owner Author

commented Jul 10, 2019

@TylerJAllen @travisryan I built the model but didn't connect it to anything. Will connect via client soon™

@travisryan

This comment has been minimized.

Copy link

commented Jul 11, 2019

@mkreiser that makes sense. I thought looking at the client that you just had a couple functions so far. Figured you had more work to do. It's just exciting you're so close. Thanks!

@shibdib

This comment has been minimized.

Copy link

commented Jul 12, 2019

Looking forward to you fleshing this out, already have the current functionality added to a slack bot I'm working on

https://i.imgur.com/ReknIfc.png

@travisryan

This comment has been minimized.

Copy link

commented Jul 19, 2019

Any more updates on this? Getting really excited for football season in general! :)

@pejmanjohn

This comment has been minimized.

Copy link

commented Jul 25, 2019

I'm in a similar place as @TylerJAllen. Using express and seeing my league data with getBoxscoreforWeek call. Excited to see more wired up in client. Thanks for pushing it so far.

@travisryan

This comment has been minimized.

Copy link

commented Jul 30, 2019

@mkreiser any more progress? We're only a few weeks away. Hope everything is going well for you, and appreciate all you do for this project!

@mkreiser

This comment has been minimized.

Copy link
Owner Author

commented Aug 3, 2019

Sorry for taking forever on this. Been tired by the time I get home. Banged it out tonight. #114

Published as 0.10.0. Let me know what you guys want next. My current idea is NFL team schedules.

@ajg102

This comment has been minimized.

Copy link

commented Aug 3, 2019

Hey just wanted to say great work on this so far @mkreiser.

Something I noticed with the recent teams addition is that you have the teams function as getTeams in the README, but left it as getTeamsAtWeek in the client. Nbd, just figured I'd put it here in case anyone else gets a 'getTeams' is not a function error.

Also, right now it seems to be returning the most recent standings regardless of period. Is that supposed to happen right now as Im not entirely sure ESPN keeps standings by individual week?

@mkreiser

This comment has been minimized.

Copy link
Owner Author

commented Aug 3, 2019

@ajg102 Good catch. I'll update that (made the change right before merging).

Yes right now those standings are the latest always. Can see if there's another data point that is week dependent.

@travishenson

This comment has been minimized.

Copy link

commented Aug 16, 2019

First off, I wanted to say great work and thank you for doing all of this work. It's definitely shaping up to be a really powerful tool! @mkreiser

One question I have is if you know of a way to display the "Schedule" of each time based on a team ID. My league uses a custom power rankings formula that I'm attempting to automate. The formula uses the highest and lowest points for of each team, and I was wondering if you knew of a way to access those data points.

Once again, thanks a ton for all of this work!

@travisryan

This comment has been minimized.

Copy link

commented Aug 22, 2019

Ok I was able to add logo, logoType, and fix the space in the name. I've never pushed to a remote repository I didn't own. Can anyone help me figure out how to submit it? :)

@travisryan

This comment has been minimized.

Copy link

commented Aug 22, 2019

Here are the changes in src/team/teams.js. name is edited with a space, and lines below are added for logo.

name: {
key: 'location',
manualParse: (responseData, data) => ${data.location} ${data.nickname}
},
logo: 'logo',
logoType: 'logoType',

@joe-salomon

This comment has been minimized.

Copy link

commented Aug 23, 2019

@travisryan, you can fork the project and do a pull request with your changes: Github's Fork & Pull Workflow

@mkreiser

This comment has been minimized.

Copy link
Owner Author

commented Aug 24, 2019

Hey all. Sorry for disappearing. Work has been hectic and it's been hard to get time and motivation to this. My FF team is also probably going to suffer lol.

@travishenson From this project, you could pull all of the boxscores per week (scoringPeriodId). Definitely not ideal but could work. Can look into a schedule route.

@travisryan I've got a PR up at #120 for the spacing. Will throw a few more PRs up here to deal with the raised items.

@ArthurSilveira

This comment has been minimized.

Copy link

commented Aug 26, 2019

Hi, just found this today. Was surprised nothing else exists out there. How close are you all? Can I help with anything?

@travisryan

This comment has been minimized.

Copy link

commented Aug 28, 2019

I'm trying to use getBoxscoreForWeek and using a different scoring/matchup period. I only get the first week matchup even if I specify a scoringPeriodId = 2. Can anyone else verify if this works for them?

NEVERMIND. I think I'm a moron. :)

@Ikendiken

This comment has been minimized.

Copy link

commented Sep 3, 2019

I'm not sure it matters, but I switched out the espnS2 and the SWID cookies for the 'espnAuth' cookie containing just the swid and it seems to be working fine.

axios.interceptors.request.use(request => {
  if (client.isAuthenticated) {
    request.headers['Cookie'] = `espnAuth: {"swid":"${client.swid}"`
  }
  return request
})
@mkreiser mkreiser closed this Sep 29, 2019
@mkreiser mkreiser unpinned this issue Sep 29, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
You can’t perform that action at this time.