It seems that you're using an outdated browser. Some things may not work as they should (or don't work at all).
We suggest you upgrade newer and better browser like: Chrome, Firefox, Internet Explorer or Opera

×
Hey,

is there a way to get a productResponse from "catalog.gog.com/v1/catalog"-api by a product ID? I can't find the endpoint. Btw is there an official documentation for the catalog api?

When I use the "https://api.gog.com/v2/games/1295420179" or "https://api.gog.com/products?ids=1444036272%2C1444035366" endpoint, I dont get the price data. Thats why I ask.

Thanks alot
Post edited September 24, 2022 by medy94
avatar
medy94: [...] price data.
https://api.gog.com/products/1863909997/prices?countryCode=DE

Mind you, only store-listed IDs get prices, so for many IDs you'll simply get "not found" errors.
Post edited September 24, 2022 by WinterSnowfall
The prices API (at least the one with multiple IDs) is horribly unreliable, I would recommend against it if you value data consistency. Periodically crawling the catalog is the method I use currently for prices in GOG DB,
Is there any endpoint I can use to get total time spent on particular game? Or even better time per date?
Is there a limit to how many requests you can make to the GOG api? Is it better practice to grab things when needed to get the latest data or is it better to send a request like every hour or 2 and just store all the JSON files and then parse through them?
Post edited October 06, 2022 by user deleted
avatar
Lord Krex: Is there a limit to how many requests you can make to the GOG api?
I stumbled upon this on the partner program support page: https://support.gog.com/hc/en-us/articles/4405004689297-How-to-join-the-GOG-Affiliate-Program
"Note that there is a 200 request/hour/IP on the api.gog.com/products/* endpoint. There is no limit on the V1/games and V2/games"
You can get around the 200 requests by providing a Galaxy login token ;). You also should make use of connection pooling for making many requests at a time, there is a limit on new connections (no idea what that is, just don't open a connection per request and you're good).
avatar
Lord Krex: Is it better practice to grab things when needed to get the latest data or is it better to send a request like every hour or 2 and just store all the JSON files and then parse through them?
That really depends on what you need. If you want to generate changelogs or do any kind of monitoring, periodic updates are necessary. If you can get away with on demand fetching or on demand + caching, that's definitely easier to implement. Caching everything also has the benefit of speeding up loading times, so decide for yourself. When it comes to general programming advice: get something working first, worry about speeding it up with caching later.
avatar
pawel-t: Is there any endpoint I can use to get total time spent on particular game? Or even better time per date?
Total time is definitely available, because it's on user profiles. I just can't tell you how it's called right now. Sorry for this half answer, but I figured it's better than ignoring you for now.
Post edited October 07, 2022 by Yepoleb
avatar
Lord Krex: Is there a limit to how many requests you can make to the GOG api?
avatar
Yepoleb: I stumbled upon this on the partner program support page: https://support.gog.com/hc/en-us/articles/4405004689297-How-to-join-the-GOG-Affiliate-Program
"Note that there is a 200 request/hour/IP on the api.gog.com/products/* endpoint. There is no limit on the V1/games and V2/games"
You can get around the 200 requests by providing a Galaxy login token ;). You also should make use of connection pooling for making many requests at a time, there is a limit on new connections (no idea what that is, just don't open a connection per request and you're good).
avatar
Lord Krex: Is it better practice to grab things when needed to get the latest data or is it better to send a request like every hour or 2 and just store all the JSON files and then parse through them?
avatar
Yepoleb: That really depends on what you need. If you want to generate changelogs or do any kind of monitoring, periodic updates are necessary. If you can get away with on demand fetching or on demand + caching, that's definitely easier to implement. Caching everything also has the benefit of speeding up loading times, so decide for yourself. When it comes to general programming advice: get something working first, worry about speeding it up with caching later.
Hmmm thanks for the advice. I'm using PHP on the backend and based on the quick googling connection pooling really isn't possible. However, it sounds like I can set up a cron job, open a connection every few hours and grab all the data I need before closing the connection and then just parse through the JSON... staying well under this limit. At least that what I gather based on what was stated here?

I have already got a PHP script written to grab all the listings from embed.gog.com and through all the JSON in a folder then parsing through it on the front end with JQuery. I assume if I only open a few connections every few hours and grab everything at one time then I won't kicked off by the GOG overlords lol.
avatar
Yepoleb: You can get around the 200 requests by providing a Galaxy login token ;)
Can you explain a little more in detail how to this?
avatar
Yepoleb: "Note that there is a 200 request/hour/IP on the api.gog.com/products/* endpoint. There is no limit on the V1/games and V2/games"
You can get around the 200 requests by providing a Galaxy login token ;).
That no longer seems to be the case - I've not noticed any throttling and I'm not passing any kind of Galaxy token for my queries. Not that I would encourage anyone to outright abuse the APIs, but I'm definitely querying in excess of 200 requests per hour at times with no ill effects.

avatar
Lord Krex: I assume if I only open a few connections every few hours and grab everything at one time then I won't kicked off by the GOG overlords lol.
I use a single connection to scan all known GOG product IDs for updates every day. Never got throttled in this era, though it used to be quite different a couple of years ago, when API throttling was indeed very much a thing.

avatar
Lord Krex: Can you explain a little more in detail how to this?
You really shouldn't need to, but I've linked to an example here.
Post edited October 10, 2022 by WinterSnowfall
avatar
WinterSnowfall: I use a single connection to scan all known GOG product IDs for updates every day. Never got throttled in this era, though it used to be quite different a couple of years ago, when API throttling was indeed very much a thing.
That's good to know, if that is the case I won't worry about it for api.gog.com as I'm only updating the json files for each game like once every hour and I may increase that to like 4 hours.

avatar
WinterSnowfall: You really shouldn't need to, but I've linked to an example here.
Unfortunately, that is in python and my python knowledge is limited... haven't wrote anything in python in like 6 years lol. I'm trying to do this in PHP. Can you give me a general overview? What I am trying to do is access gameplay.gog.com to get achievements from my account. That requires OAuth2 auth.

I'm trying to do this based off this example: https://stackoverflow.com/questions/25423924/oauth-2-0-in-php-using-curl

In my request I'm sending is:

"$url= 'auth.gog.com/token?client_id='+ $clientId + '&client_secret='+ $clientSecret +'&grant_type='+ $grantType +'&code=' + $code + '&redirect_uri=' + $redirect_uri;"

So all my variables have the required info... I got the code via my browser as recommended via the api docs.

But what am I using for redirect_uri? Should it be gameplay.gog.com? GOG API docs say to use the same uri used in the auth method which was https://embed.gog.com/on_login_success?origin=client is that what I should use?

If so I'm not sure what to do with the response? Do I need send just the access token along with my request to gameplay.gog.com? The docs are quite clear on how that should look / work. That's where I'm confused.
Post edited October 10, 2022 by user deleted
avatar
Lord Krex: If so I'm not sure what to do with the response? Do I need send just the access token along with my request to gameplay.gog.com? The docs are quite clear on how that should look / work. That's where I'm confused.
Haven't implemented this myself mind you, but AFAIK all you need to do it place the token you got in a cookie you then pass to API calls. I believe that's what the python code does essentially. If you managed to get the token, then the hard part is done.

When in doubt try to see what the website does in a browser, because the website itself calls many of these APIs, if not all.
avatar
Lord Krex: In my request I'm sending is:

"$url= 'auth.gog.com/token?client_id='+ $clientId + '&client_secret='+ $clientSecret +'&grant_type='+ $grantType +'&code=' + $code + '&redirect_uri=' + $redirect_uri;"

So all my variables have the required info... I got the code via my browser as recommended via the api docs.

But what am I using for redirect_uri? Should it be gameplay.gog.com? GOG API docs say to use the same uri used in the auth method which was https://embed.gog.com/on_login_success?origin=client is that what I should use?

If so I'm not sure what to do with the response? Do I need send just the access token along with my request to gameplay.gog.com? The docs are quite clear on how that should look / work. That's where I'm confused.
I think the redirect_uri is only needed if you integrate the whole login procedure into your own service. You tell the login server where to forward you next after the login has succeeded. If you are not using a browser to do the login you can even ignore this. Just put in any valid URI.

What is important is the JSON response you are getting. From the documentation:

{
"expires_in": 3600,
"scope": "",
"token_type": "bearer",
"access_token":"XXX",
"user_id": "48628349957132247",
"refresh_token": "YYY",
"session_id": "6354900816570477251"
}

I have shortened the tokens to XXX and YYY, these strings are of course longer.

If you have just gotten the token in $response from the cURL call simply make an object out of it and add a new property for the token expiration.

$OAUTH = json_decode($response);
$OAUTH->expire_time = time() + $OAUTH->expires_in - 60;

expires_in is in seconds, so the token will expire in 1 hour. That is why I have set the expiration to 59 minutes after the current time. Before doing any request to an URL that requires a token you must check the current time() against $OAUTH->expire_time. If time() > $OAUTH->expire_time then you must refresh the token.

If the token is still valid, using it is pretty simple. You just need to add an Authorization header to your cURL calls. The header looks like this:

$authHeader = 'Authorization: Bearer ' . $OAUTH->access_token;

Note that there is a space after the : and after 'Bearer'! And that's how you use it:

$url = "any valid GOG API url";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, [$authHeader]);
$response = curl_exec($ch);

If the token has already become invalid you need to refresh it by calling this URL:

$url = "https://auth.gog.com/token?client_id=46899977096215655&client_secret=9d85c43b1482497dbbce61f6e4aa173a433796eeae2ca8c5f6129f2dc4de46d9&grant_type=refresh_token&refresh_token=" . $OAUTH->refresh_token;

EDIT: And that is why cutting and pasting code is never a good idea. The forum shows every ampersand in the URL as &_amp_; even though it is just an &.

The response will be a JSON with a new token. Treat it just like a new token.

I would also recommend saving the token to the harddrive:

file_put_contents(__DIR__ . "/OAUTH.json", json_encode($OAUTH, JSON_PRETTY_PRINT));

Because according to my experience the refresh token never times out. Even after several months it was still valid. So as long as you have a valid refresh token you never have to go through the login procedure again.

Hope this helps.

P.S.: Yes, the above examples are without error checking to illustrate the principle. Please always check if cURL calls succeed, if the result you received is as expected (e.g. a valid JSON), do retries on timeouts, etc.
Post edited October 10, 2022 by Geralt_of_Rivia
avatar
Geralt_of_Rivia: snip
Awesome. Thanks for the detailed explanation, I will look into implementing this sometime this week. :)
Post edited October 11, 2022 by user deleted
avatar
pawel-t: Is there any endpoint I can use to get total time spent on particular game? Or even better time per date?
avatar
Yepoleb: Total time is definitely available, because it's on user profiles. I just can't tell you how it's called right now. Sorry for this half answer, but I figured it's better than ignoring you for now.
No problem. I tried to find a way to get time spent on playing per day or at least like total from last 2 weeks. In that case I can count it on daily basis.

Thank you for your answer.
Is there an easy way to find out if a GOG promo URL leads to an old or a new style promo page?