I got an email from Meetup.com 5 days ago, that basically every API request will be paid since August 15, 2019. $ 30/month, that's like my phone bill.
95 % of data on Friends Of Php depend on Meetup.com API - updated daily. The website is free, so it might kill the content or I'd have to move to crawlers and hope for the lack of protection on Meetup.com against them.
Unless we use Oauth2 before August 15. I never used it, but how hard that can be, right?
There is no information about Meetup.com API upgrade on their blog, so I'll share the email to give you an idea:
API Keys will be replaced by OAuth: We will be removing API keys on August 15, 2019 and requiring you to authenticate with OAuth.
Move to OAuth soon for continued free API access: Until August 15, members will be able to apply for OAuth access free of charge. After August 15, anyone who wants to apply for API access through OAuth will need to have a Meetup Pro account in order to do so.
This is a simple task, that in the end has simple 15 lines of new code. But documentation turned it into almost 3 hours of work.
It seems like OAuth2 must be something very new, because Guzzle supports only Oauth (1). If the last commit in 2014 can be called "supports".
After a bit of Googling if found kamermans/guzzle-oauth2-subscriber. I tried to copy-paste the code
Why would you put the newest content first, right? You know, like on Twitter, Facebook, basically any news, messages...
So now you can imagine I'm using the latest Guzzle 6 and trying to implement a solution for Guzzle 4 & 5.
Fuck-Up #1 is a natural consequence of trying to support multiple versions at one branch/tag. Instead of putting all code to one branch, let always the last branch support the latest LTS dependencies.
What does that mean?
Let's look at Symfony repository. Instead of "Symfony" imagine any package that is version. Now there is Symfony 4, so there was version 3, 2, 1 in the past. Like Guzzle 6, 5, 4...
Now you've decided to upgrade and look for
CHANGELOG.md (because you haven't heard about Rector yet):
But how do you upgrade from Symfony 3? In the latest branch, there is always context-aware information. Do you need any older version? Switch to branch
I love this, because it focuses on mainstream, providing minimal needed data, but also allows the same for minorities.
The Symfony docs does the same:
I wrote about this in detail in What can You Learn from Menstruation post.
After I figured out the
README is not text for programmers but for detectives, I've found the code with middleware I though I was looking for:
<?php $oauth = new OAuth2Middleware($grant_type); $stack = HandlerStack::create(); $stack->push($oauth); $client = new Client([ 'auth' => 'oauth', 'handler' => $stack, ]);
This supposes to work... but instead I got as useless exceptions as "cannot authenticate". After 60 minutes of trying, I went to sleep with frustration.
In the morning I've noticed little note:
Tried it and it worked. WTF? Why there is a broken code first, then "working alternative" second?
This is a common problem with double complexity = exponential bugs. If you translate your website to English and German, it will have more translation bugs than the English-only version. Of course, German might be important to your business, but the alternative code has as little added value as having a website in American English and British English.
It's important to know, that I don't try to make this about the specific documentation, but rather about any open-source documentation and how it's written.
If I'd be sending an invoice to my employer, it would look like this:
Let's pause a bit and think - what do we really need, when we use the package for the first time?
If we agree on these as our priorities, then all we need is working piece of code.
How do we know the code is working?
Instead of having documentation with text (= "weak strings"), the best would be:
That's the perfect documentation, because we can skip the verification and detective part and trust it by validated contract.
Now finally to the solution ↓
composer require guzzlehttp/guzzle:^6.3 composer require kamermans/guzzle-oauth2-subscriber
<?php declare(strict_types=1); require __DIR__ . '/vendor/autoload.php'; use GuzzleHttp\Client; use kamermans\OAuth2\GrantType\ClientCredentials; use kamermans\OAuth2\OAuth2Middleware; // get these here: https://secure.meetup.com/meetup_api/oauth_consumers $meetupComOauth2Key = '123'; $meetupComOauth2Secret = 'ABC'; // boilerplate code for Oauth2 $oAuth2Client = new Client([ // URL for access_token request 'base_uri' => 'https://secure.meetup.com/oauth2/access', ]); $oAuth2Config = [ 'client_id' => $meetupComOauth2Key, 'client_secret' => $meetupComOauth2Secret, ]; $clientCredentials = new ClientCredentials($oAuth2Client, $oauthConfig); $oAuth2Middleware = new OAuth2Middleware($clientCredentials); // the main code $client = new Client(); $client->getConfig('handler')->push($oAuth2Middleware); // call anything $response = $client->request('GET', '...'); var_dump($response);
But does it still work?