Checking your win by inwi balance on a terminal
Here's how you can check your win data usage on a terminal because <note to self: insert convincing reason here before publishing>
Time for some recon. I fired off the Firefox network devtools and started inspecting. There are two endpoints of interest:
- Login endpoint (/api/v1/auth/login): exchanges a username/password combo for a set of tokens
- Offer detail endpoint (/api/v1/subscriptions/<ID>/offer-detail): returns statistics about the subscription
After decoding the JWT access token returned by the login endpoint, I notice that its exp claim has a generous time to live of about 7 days. The refresh token lasts twice as long. For starters I decided to use this set of tokens instead of writing code that actually logs me in, it might come in handy if they ever decide to slap a captcha on the login form. For the record, here's what the login response looks like:
{
"account": {
"email": "yours.truly@domain.ext",
"firstName": "Yours",
"lastName": "Truly",
"accountIdSF": "XXXXXXXXXXXXXXXXXX",
...
},
"subscriptions": [
{...}
],
"carts": [],
"tokens": {
"id": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"accessToken": "eyJ...",
"expiresIn": 604800,
"refreshToken": "eyJ...",
"refreshExpiresIn": 1296000,
"tokenType": "Bearer"
}
}
Grab the accessToken, refreshToken and accountIdSF fields, we'll be using them from here on out.
The second endpoint contains the information we need. We're gonna request it by sending a typical Bearer token-powered GET request to the endpoint above, while making sure to use the accountIdSF value as a subscription ID in the URL.
$ curl https://api.win.ma/api/v1/subscriptions/XXXXXXXXXXXXXXXXXX/offer-detail -H 'Authorization: Bearer eyJhb...'
Buried in its JSON response is an array of assets, each with the following structure, abbreviated to only include the relevant portions:
{
"accountId": "XXXXXXXXXXXXXXXXXX",
"type": "OTHER",
"name": "Internet 4G",
...,
"balance": {
"consumedValue": "4171424572",
"defaultValue": "50000000000",
"defaultUnitValue": "BYTE",
"expireDate": "2025-05-28T23:45:35.000+0000",
"labelBalanceAr": "4G أنترنيت",
"labelBalanceFr": "Forfait Internet 4G",
"displayorder": 100,
"consumedUnit": "BYTE",
...
},
"dateCycleStart": "2024-10-28T22:45:35.000+0000",
"dateCycleEnd": "2025-04-28T22:45:35.000+0000",
"dateCycleFutureStart": "2025-04-28T22:45:35.000+0000",
"dateCycleFutureEnd": "2025-05-28T22:45:35.000+0000",
"dateOfferEnd": "2025-05-28T22:45:35.000+0000",
"oneTimeBaseCharge": 0
},
So we'll need to traverse the array in question and look for this entry, then parse out the balance.consumedValue
and balance.defaultValue
fields. Nothing some good old PHP can't handle:
$balance = array_values(
array_filter($offerDetails->assets, fn($asset) => $asset->name === 'Internet 4G')
)[0]->balance;
printf("Until %s\n", $balance->expireDate);
printf(
"%.2f MB / %.2f MB (%.2f %%)\n",
$balance->restValue / 1000 / 1000,
$balance->defaultValue / 1000 / 1000,
$balance->restValue / $balance->defaultValue * 100.0
);
The schrewdly perceptive readers will notice that I'm dividing by 1000 to display the values in a human-readable form. As it turns out, a 50 Go subscription is stored as 50 * 1000 * 1000 (50000000000) instead of 50 * 1024 * 1024 (52428800) for some unknown reason. This means that I'm only getting about 47.7 gigabytes per month though I will have to measure that more thoroughly to be sure.
Refreshing expired access tokens can be done by sending them to the https://api.win.ma/api/v1/auth/refresh-token
endpoint as a GET query parameter:
function refreshTokens()
{
$tokens = json_decode(file_get_contents(__DIR__ . '/win-forfait.json'));
$ch = curl_init('https://api.win.ma/api/v1/auth/refresh-token?refreshToken=' . $tokens->refreshToken);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($ch);
if($response === false)
{
echo "Failed to refresh tokens:\n";
echo curl_error($ch), "\n";
echo "Try logging in with php {$argv[0]} --login\n";
exit(1);
}
file_put_contents(__DIR__ . '/win-forfait.json', $response);
echo "Tokens refreshed\n";
}
And last but not least, logging in is a matter of sending an email and password JSON request to the https://api.win.ma/api/v1/auth/login
endpoint:
$ curl https://api.win.ma/api/v1/auth/login \
-H 'Content-Type: application/json' \
--data '{"email": "yours.truly@domain.ext", "password": "..."}'
I couldn't figure out how to securely prompt the user for a password in PHP so I'll leave that as an exercise for the reader.
And with that you can have a command-line PHP script that you can use to monitor your internet usage! Full script available in this gist: https://gist.github.com/azihassan/6f0e1ad62a84a962386361609bc5cca4
Areas of improvement:
- A caching mechanism
- A way to check passes
- A way to safely input passwords
Commentaires
Enregistrer un commentaire