Skip to content

Commit

Permalink
[TASK] v2
Browse files Browse the repository at this point in the history
  • Loading branch information
Woeler committed Oct 29, 2024
1 parent 3658554 commit 21065fc
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 87 deletions.
17 changes: 10 additions & 7 deletions Readme.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
# Komoot PHP
NOTICE: Komoot has decided to add an invisible captcha to their login process. This renders this library unusable. I have sent them an email asking if we can get an alternative way to log in, but I have yet to receive a response.

This is a PHP library that can be used to interact with Komoot. It uses the same API the Komoot website uses. It is not officially supported by Komoot to integrate it in third party projects. I just needed a fancy way of interacting with Komoot for a personal project. That is why I created this package.

## Usage

### Authentication

You will need to use your Komoot account email address and password to log in.
You will need to use your Komoot account email address, userid and password to log in.
```php
use Woeler\KomootPhp\Api\Komoot;

// Create the api object
$api = new Komoot('[email protected]', 'my-komoot-password');

// Execute the login
$api->login();
$api = new Komoot('[email protected]', 'my-komoot-password', 1234); // Replace 1234 with your userid

// ... You can now start making api calls
```
Expand Down Expand Up @@ -46,3 +41,11 @@ If you have an endpoint that you wish to call, but it does not have a dedicated
```php
$api->customRequest('https://api.komoot.de/v007/some-other-endpoint', [], 'GET');
```

## Upgrading v1.x to v2.x

- Removed the `login()` method. It is no longer needed.
- The `Komoot` constructor now takes the userid as the third argument, this is required
- Removed the `setCookieJar()` method. It is no longer needed.
- Removed the `getCookieJar()` method. It is no longer needed.
- Removed the `setUserId()` method. It is no longer needed.
97 changes: 17 additions & 80 deletions src/Api/Komoot.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,87 +5,24 @@
namespace Woeler\KomootPhp\Api;

use GuzzleHttp\Client;
use GuzzleHttp\Cookie\CookieJar;
use GuzzleHttp\Cookie\SetCookie;
use Woeler\KomootPhp\Enums\PrivacySetting;
use Woeler\KomootPhp\Enums\Sport;
use Woeler\KomootPhp\Enums\TourType;

class Komoot
{
private Client $client;
private CookieJar $cookies;
private ?int $userid = null;

public function __construct(private readonly string $email, private readonly string $password, ?Client $client = null)
public function __construct(private readonly string $email, private readonly string $password, private readonly int $userid)
{
$this->client = $client ?? new Client();
$this->cookies = new CookieJar();
}

public function login(): void
{
$response = $this->client->post('https://account.komoot.com/v1/signin', [
'json' => ['email' => $this->email, 'password' => $this->password, 'reason' => 'header'],
]);

$headerSetCookies = $response->getHeader('Set-Cookie');

foreach ($headerSetCookies as $header) {
$this->cookies->setCookie(SetCookie::fromString($header));
}

$this->setAccountIdViaCookie();

$response = $this->client->get('https://account.komoot.com/actions/transfer', [
'cookies' => $this->cookies,
'query' => [
'type' => 'signin',
'reason' => 'header',
],
]);

$headerSetCookies = $response->getHeader('Set-Cookie');

foreach ($headerSetCookies as $header) {
$this->cookies->setCookie(SetCookie::fromString($header));
}
}

private function setAccountIdViaCookie(): void
{
$response = json_decode($this->client->get('https://account.komoot.com/api/account/v1/session', [
'cookies' => $this->cookies,
'query' => ['hl' => 'en'],
])->getBody()->getContents(), true);

$this->userid = (int) $response['_embedded']['profile']['username'];
}

public function getCookieJar(): CookieJar
{
return $this->cookies;
}

public function setCookieJar(CookieJar $cookieJar): self
{
$this->cookies = $cookieJar;

return $this;
}

public function getUserId(): ?int
{
return $this->userid;
}

public function setUserId(int $userId): self
{
$this->userid = $userId;

return $this;
}

public function getTours(int $page = 0, int $limit = 50, ?TourType $type = null): array
{
$params = ['page' => $page, 'limit' => $limit];
Expand All @@ -95,7 +32,7 @@ public function getTours(int $page = 0, int $limit = 50, ?TourType $type = null)
}

return json_decode($this->client->get('https://www.komoot.com/api/v007/users/'.$this->userid.'/tours/', [
'cookies' => $this->cookies,
'auth' => [$this->email, $this->password],
'query' => $params,
])->getBody()->getContents(), true);
}
Expand All @@ -120,59 +57,59 @@ public function getAllTours(?TourType $type = null): array
public function getTour(int $tourId): array
{
return json_decode($this->client->get('https://www.komoot.com/api/v007/tours/'.$tourId, [
'cookies' => $this->cookies,
'auth' => [$this->email, $this->password],
])->getBody()->getContents(), true);
}

public function getTourGpx(int $tourId): string
{
return $this->client->get('https://www.komoot.com/api/v007/tours/'.$tourId.'.gpx', [
'cookies' => $this->cookies,
'auth' => [$this->email, $this->password],
])->getBody()->getContents();
}

public function getTourPhotos(int $tourId): array
{
return json_decode($this->client->get('https://www.komoot.com/api/v007/tours/'.$tourId.'/cover_images/', [
'cookies' => $this->cookies,
'auth' => [$this->email, $this->password],
])->getBody()->getContents(), true);
}

public function deleteTour(int $tourId): void
{
$this->client->delete('https://www.komoot.com/api/v007/tours/'.$tourId, [
'cookies' => $this->cookies,
'auth' => [$this->email, $this->password],
]);
}

public function renameTour(int $tourId, string $name): array
{
return json_decode($this->client->patch('https://www.komoot.com/api/v007/tours/'.$tourId, [
'cookies' => $this->cookies,
'auth' => [$this->email, $this->password],
'json' => ['name' => $name],
])->getBody()->getContents(), true);
}

public function changeTourPrivacy(int $tourId, PrivacySetting $privacy): array
{
return json_decode($this->client->patch('https://www.komoot.com/api/v007/tours/'.$tourId, [
'cookies' => $this->cookies,
'auth' => [$this->email, $this->password],
'json' => ['status' => $privacy->value],
])->getBody()->getContents(), true);
}

public function changeTourSport(int $tourId, Sport $sport): array
{
return json_decode($this->client->patch('https://www.komoot.com/api/v007/tours/'.$tourId, [
'cookies' => $this->cookies,
'auth' => [$this->email, $this->password],
'json' => ['sport' => $sport->value],
])->getBody()->getContents(), true);
}

public function getUser(int $userId): array
{
return json_decode($this->client->get('https://www.komoot.com/api/v007/users/'.$userId, [
'cookies' => $this->cookies,
'auth' => [$this->email, $this->password],
])->getBody()->getContents(), true);
}

Expand All @@ -184,45 +121,45 @@ public function getSelfUser(): array
public function getCollection(int $collectionId): array
{
return json_decode($this->client->get('https://www.komoot.com/api/v007/collections/'.$collectionId, [
'cookies' => $this->cookies,
'auth' => [$this->email, $this->password],
])->getBody()->getContents(), true);
}

public function getCollectionTours(int $collectionId): array
{
return json_decode($this->client->get('https://www.komoot.com/api/v007/collections/'.$collectionId.'/compilation/', [
'cookies' => $this->cookies,
'auth' => [$this->email, $this->password],
])->getBody()->getContents(), true);
}

public function renameCollection(int $collectionId, string $name): array
{
return json_decode($this->client->patch('https://www.komoot.com/api/v007/collections/'.$collectionId, [
'cookies' => $this->cookies,
'auth' => [$this->email, $this->password],
'json' => ['name' => $name],
])->getBody()->getContents(), true);
}

public function changeCollectionDescription(int $collectionId, ?string $description): array
{
return json_decode($this->client->patch('https://www.komoot.com/api/v007/collections/'.$collectionId, [
'cookies' => $this->cookies,
'auth' => [$this->email, $this->password],
'json' => ['intro_plain' => $description ?? ''],
])->getBody()->getContents(), true);
}

public function changeCollectionPrivacy(int $collectionId, PrivacySetting $privacy): array
{
return json_decode($this->client->patch('https://www.komoot.com/api/v007/collections/'.$collectionId, [
'cookies' => $this->cookies,
'auth' => [$this->email, $this->password],
'json' => ['status' => $privacy->value],
])->getBody()->getContents(), true);
}

public function deleteCollection(int $collectionId): void
{
$this->client->delete('https://www.komoot.com/api/v007/collections/'.$collectionId, [
'cookies' => $this->cookies,
'auth' => [$this->email, $this->password],
]);
}

Expand All @@ -233,7 +170,7 @@ public function customRequest(string $endpoint, array $guzzleConfig = [], string
}

return json_decode($this->client->{strtolower($method)}($endpoint, [
'cookies' => $this->cookies,
'auth' => [$this->email, $this->password],
] + $guzzleConfig)->getBody()->getContents(), true);
}
}

0 comments on commit 21065fc

Please sign in to comment.