janhenkes / teamleader-php-sdk Goto Github PK
View Code? Open in Web Editor NEWTeamleader API v2 PHP SDK
License: MIT License
Teamleader API v2 PHP SDK
License: MIT License
Hi!
I'm trying to automate my shopify into teamleader, with a webhook once a customer orders an item.
I've allowed my redirect into the TeamLeader integration as it allows me to interact when I go to the URL with my browser.
But the thing is that the webhook from shopify return me the fatal error that the access token is invalid.
I'm not sure how to go on with this issue. As I lose the data sent by shopify once I require the 'aquire-access-token.php' into the script.
Sorry, not really a bug or issue with your sdk but more the lack of my knowledge and unable to find any help about this on google..
Thanks!
Hi! Can you release a new version based of current master? Current stable is unusable due to api version errors
This repo can not be installed on PHP 8.1 since the composer.json file only allows ^7.1
.
If you want to keep backwards compatibility for PHP 7.4 (despite PHP 7 being end of life), please change this to ^7.1|^8.0
.
If you only want to allow supported PHP versions, please change this to ^8.0
.
TODO
Can you please help me with this?
Hi,
I just figured that the models definitions are out of date.
For instance, for Milestones are missing 'starts_on', 'budget', 'allocated_time' and more, the property 'due_on' for tasks has been replaced by 'due_at' etc.
Your package needs an update.
Thx,
When I call
$this->client->company()->getAll()
I get back only 100 items. I would expect to retrieve all of them as it worked like that in the past.
I am using v2.9.5
Can you please give me an example on how to do that?
It would be nice to be able to get the headers of the response in order to check the rate limit:
https://developer.teamleader.eu/#/introduction/general-principles/rate-limiting
Maybe in parseResponse(), return the headers together with the response body?
Hi,
I'm trying to make a script to send datas from a website form to teamleader. But when i test your sdk, it return me an error :
Fatal error: Uncaught Teamleader\Exceptions\InvalidAccessTokenException: Invalid access token, please acquire a new one. in C:\laragon\www\APITL\vendor\janhenkes\teamleader-php-sdk\src\Teamleader\Connection.php:322 Stack trace: #0 C:\laragon\www\APITL\vendor\janhenkes\teamleader-php-sdk\src\Teamleader\Connection.php(398): Teamleader\Connection->createRequest('POST', 'https://api.tea...', '{"first_name":"...') #1 C:\laragon\www\APITL\vendor\janhenkes\teamleader-php-sdk\src\Teamleader\Actions\Storable.php(34): Teamleader\Connection->post('contacts.add', '{"first_name":"...') #2 C:\laragon\www\APITL\vendor\janhenkes\teamleader-php-sdk\src\Teamleader\Actions\Storable.php(20): Teamleader\Entities\CRM\Contact->insert() #3 C:\laragon\www\APITL\SDK.php(19): Teamleader\Entities\CRM\Contact->save() #4 {main} thrown in C:\laragon\www\APITL\vendor\janhenkes\teamleader-php-sdk\src\Teamleader\Connection.php on line 322
This error come with your "addClient" example
Hi there.
First of all many thanks to all the people involved in this project for their time, I really appreciate it.
I would like to start using Teamleader API, but to be honest I still have not yet the concepts.
At the moment I created an integration, so I have a Client ID and a Secret ID.
Unfortunately reading your documentation I have no idea what comes next.
If somebody can provide a step by step guide of how to start using this SDK implementation I compromise to create a Pull Request to get all the information dumped on README file.
Thanks in advice.
Why do you force the 6.0 version of Guzzle HTTP ? This is very restrictive. I use 6.5 and cannot update your package...
Thank you for the package. Very useful
I was wondering if it would be possible to have the storage of the tokens set via a variable because I don't want to store them in /tmp
Thank you
due to the 'X-Api-Version' => '2021-09-01'
header for every request, we get following error:
Can not downgrade to a lower API version than 2022-09-15
https://developer.focus.teamleader.eu/#/introduction/changes-&-upgrades/upgrading-your-api-version
can these changes be implemented and the header upgraded or make the 'X-Api-Version' header optional?
currently unable to use this package
I'd prefer getting rid of the header, as it might break any time whenever teamleader decides to change the 'minimum date'. Breaking changes only affect 1% of the API requests.
If I install the package on my local.dev domain and I connect, then the authentication tokens are not generated again when connect on the production website. And vice versa. I have 2 separate apps created in teamleader so 2 separate client ids.
How to properly use it locally and on production?
vendor/janhenkes/teamleader-php-sdk/src/Teamleader/Connection.php:478
474โ throw new ApiException($exception->getMessage());
475โ }
I am using Laravel 8.83
Configuration
guzzlehttp/guzzle: 7.4.1
guzzlehttp/psr7: 2.1.0
PHP version: 7.4
Description:
The latest version of Guzzle (7.4.x) isn't supported by this library.
It throws an error on this line: https://github.com/janhenkes/teamleader-php-sdk/blob/master/src/Teamleader/Connection.php#L197
=>
"Call to undefined function GuzzleHttp\Psr7\rewind_body()"
Temporary fix:
Use an older version of Guzzle in your application. 6.5 does the trick here.
"guzzlehttp/guzzle": "^6.5",
According to the docs, only the access token should respect the expires_in variable from the response.
But when the access token expires using the default cache handler, the refresh token is also no longer available in the current logic.
Access tokens expire shortly (usually 1 hour) after they are issued for security reasons. If your integration needs to communicate with our API beyond the access token's lifespan, you will need to request a new access token using the refresh token which was issued with the access token. Note that refresh tokens can only be used once to get a new access token and refresh token.
However, if I look at Connection::storeTokens
, I see the following:
public function storeTokens(string $accessToken, string $refreshToken, int $expiresIn, int $expiresOn): void
{
$this->cacheHandler->set('accessToken', $accessToken, $expiresIn / 60);
$this->cacheHandler->set('refreshToken', $refreshToken, $expiresIn / 60);
$this->cacheHandler->set('tokenExpire', $expiresOn, $expiresIn / 60);
}
The default cache handler doesn't respect the $expiresAt
parameter and because of that I think tokenExpire
is saved to the cache. I think controlling if a cache item is valid should be the responsibility of the cache handler, not the Connection.
Refresh tokens will continue functioning until the user revokes them or uninstalls your integration.
This means one can effectively use a very large expiry. Taking into accounts the definition of the cachehandler interface and the information about the refresh token, that should be a very long time, like a year or month.
I see a couple of things I would change:
1: Make the default cache handler also save a timestamp in set
and let get
check that timestamp to ensure the cache isn't expired yet. (so you save an array with the timestamp and the value) and then update the storeTokens method.
// default cache handler
public function get($key)
{
$file = $this->getFileName($key);
if(!file_exists($file)) {
return null;
}
$handle = fopen($file, 'r');
$fileSize = filesize($file);
if ($fileSize === 0) {
return null;
}
$data = $this->maybe_unserialize(fread($handle, $fileSize));
if(!is_array($data) || $data['expires'] < time()) {
$this->forget($key);
return null;
}
return $data['value'];
}
public function set($key, $value, $expiresInMinutes)
{
$my_file = $this->getFileName($key);
$handle = fopen($my_file, 'w');
fwrite($handle, $this->maybe_serialize([ 'value'=> $value, 'expires'=> time() + ( $expiresInMinutes * 60)));
}
2: change the method to store the tokens.
public function storeTokens(string $accessToken, string $refreshToken, int $expiresIn, int $expiresOn): void
{
$this->cacheHandler->set('accessToken', $accessToken, $expiresIn / 60);
$this->cacheHandler->set('refreshToken', $refreshToken, 60 * 60 * 24 * 365); // a year.
}
3: change the method to get the access tokens. as the cache handler controls if an item is still valid, You dont have to check for expiry so it can be simplified a lot.
public method getAccessToken() : string {
$accesstoken = $this->cache->get('accessToken');
if($accesstoken)
{
return $accesstoken;
}
$refreshToken = $this->cache->get('refreshToken');
if($refreshToken) {
$this->acquireRefreshToken();
return $this->getAccessToken());
}
return false;
}
Hello,
I'm trying to update a company by ID but I keep getting the following error from the Teamleader API:
{"errors":[{"code":404000,"title":"Resource /companies.update/a0f2b5e2-b793-0c74-8b70-b564e1d4d5c8 not found.","status":404}]} {"e":"[object] (Teamleader\Exceptions\ApiException(code: 404): Error 404: {"errors":[{"code":404000,"title":"Resource /companies.update/xxxxxxx not found.","status":404}]}
I'm able to add a company with this PHP client but updating doesn't seem to work. Below the code I'm using:
<?php
$connection = new \Teamleader\Connection();
$connection->setClientId($clientId);
$connection->setClientSecret($clientSecret);
$client = new \Teamleader\Client($connection);
$company = [
'id' => 'xxxxxxx',
'name' => 'Customer 1',
//...
];
$client->company($company)->save();
Using findById() I'm able to get the customer using the same ID.
I am trying to use Teamleader\Actions\Attributes\Filter but it does not seem to have any effect on the data I am getting.
For example:
$companies = $client->company()->get($filter, $page);
will give me paginated data but it will have no effect on filters
As by the docs, the url returns as:
https://YOUR_REDIRECT_URI#token_type=Bearer&expires_in=900&access_token=TOKEN&state=STATE
in my case
http://127.0.0.1:8000/teamleader#access_token=[SECRET]&token_type=bearer&expires_in=3600
However I run into the problem that the url uses a #
instead of a ?
.
As these query string values do not appear in my $_GET
var https://stackoverflow.com/questions/2317508/get-fragment-value-after-hash-from-a-url-in-php
Could you be so kind as to explain how you solved this?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.