Topic-icon Instagram access_token long-lived

Active Subscriptions:

None
3 years 8 months ago #66628 by DoMeister
Thanks Alex, more straight forward.

Ok next do i need to define access to the key?

CANNOT ACCESS PROTECTED PROPERTY JFBCONNECTAUTHENTICATIONOAUTH2::$HTTP

Cheers
DM
The topic has been locked.
Support Specialist
3 years 8 months ago #66629 by alzander
We're close.. I can feel it! Replace:
$response = $provider->client->http->get('https://graph.instagram.com/access_token?grant_type=ig_exchange_token&client_secret=' . $provider->secretKey . 'access_token=' .  $provider->client->getToken());
With:
$response = $provider->client->query('https://graph.instagram.com/access_token?grant_type=ig_exchange_token&client_secret=' . $provider->secretKey);

Keep me posted!

Alex
The topic has been locked.
Active Subscriptions:

None
3 years 8 months ago #66630 by DoMeister
Hi Alex,
I tried the update you suggested with the following response
CALL TO UNDEFINED METHOD JFBCONNECTCONTROLLERAUTHENTICATE::SETTOKEN()

Below is a succesful example of the Postman query to get long-lived token so i gather we need the key, token and type.
{{ROOT_URL}}/access_token?client_secret={{APP_SECRET}}&access_token={{ACCESS_TOKEN}}&grant_type=ig_exchange_token

I then tried rewriting previous to match
$response = $provider->client->http->get('https://graph.instagram.com/access_token?client_secret=' . $provider->secretKey . '&access_token=' .  $provider->client->getToken() . 
'&grant_type=ig_exchange_token');
Same result as earlier: CANNOT ACCESS PROTECTED PROPERTY JFBCONNECTAUTHENTICATIONOAUTH2::$HTTP

hope some of this helps,
Thanks
DM
The topic has been locked.
Active Subscriptions:

None
3 years 8 months ago #66631 by DoMeister
Alex,
I took another look at this and used your 'query' suggestion. It now passes to '$this->setToken($longLivedToken);'
Error: CALL TO UNDEFINED METHOD JFBCONNECTCONTROLLERAUTHENTICATE::SETTOKEN()

I changed the class names of both setToken to discover which one it erors on.
Hoping this is the final point to address :)
            if ($provider->systemName == 'instagram')
            {
                // Fetch long-lived token here
                $response = $provider->client->query('https://graph.instagram.com/access_token?client_secret=' . $provider->secretKey . '&access_token=' .  $provider->client->getToken() . '&grant_type=ig_exchange_token');
                         
                if ($response->code >= 200 || $response->code < 400)
                {
                    if (strpos($response->headers['Content-Type'], 'application/json') !== false)
                    {
                        $longLivedToken = array_merge(json_decode($response->body, true), array('created' => time()));
                    }
                    else
                    {
                        parse_str($response->body, $longLivedToken);
                        $longLivedToken = array_merge($longLivedToken, array('created' => time()));
                    }

                    $this->setToken($longLivedToken);
                }
                else
                {
                    throw new Exception('Error code ' . $response->code . ' received long-lived token: ' . $response->body . '.');
                }
                               
                $provider->client->setToken($longLivedToken);
            }

Thx again
DM
The topic has been locked.
Support Specialist
3 years 8 months ago #66632 by alzander
If the only error you're seeing now is about setToken, then yeah, hopefully this is it.

You should be using $provider->client->setToken($longLivedToken) and the 2nd call (at the bottom) is unnecessary/problematic. Try:
if ($provider->systemName == 'instagram')
            {
                // Fetch long-lived token here
                $response = $provider->client->query('https://graph.instagram.com/access_token?client_secret=' . $provider->secretKey . '&access_token=' .  $provider->client->getToken() . '&grant_type=ig_exchange_token');
                         
                if ($response->code >= 200 || $response->code < 400)
                {
                    if (strpos($response->headers['Content-Type'], 'application/json') !== false)
                    {
                        $longLivedToken = array_merge(json_decode($response->body, true), array('created' => time()));
                    }
                    else
                    {
                        parse_str($response->body, $longLivedToken);
                        $longLivedToken = array_merge($longLivedToken, array('created' => time()));
                    }

                $provider->client->setToken($longLivedToken);
                }
                else
                {
                    throw new Exception('Error code ' . $response->code . ' received long-lived token: ' . $response->body . '.');
                }
                               
            }
Let me know if that gets you going or what other errors arise.

Thanks,
Alex
The topic has been locked.
Active Subscriptions:

None
3 years 8 months ago #66633 by DoMeister
Thanks Alex,
So we have good and bad news!

No error on running the script however it it's not saving the entry in jfbconnect_user_map.

So the user is returned to home page and a message is displayed on the next login attempt:
We were unable to retrieve your Instagram account information. Please try again.

I tried with a new account and an existing account with the same result.

What do you think we are missing?

Cheers
DM
The topic has been locked.
Active Subscriptions:

None
3 years 8 months ago #66637 by DoMeister
Hi Alex
I was waiting on your reply for the past few days. Could you let me know if you are able to help or if I should look elsewhere for solutions?

Thanks
DM
The topic has been locked.
Support Specialist
3 years 8 months ago #66638 by alzander
Had to get the time to step through the code and figure out how to properly get the token and update it. Got it now though. Please use the following, which I've tested locally to make sure the returned token can be used to fetch the user's profile and is properly stored in the database:
if ($provider->systemName == 'instagram')
            {
                // Fetch long-lived token here
                $response = $provider->client->query('https://graph.instagram.com/access_token?client_secret=' . $provider->secretKey . '&access_token=' .  $provider->client->getToken() . '&grant_type=ig_exchange_token');

                if ($response->code >= 200 || $response->code < 400)
                {
                    $longLivedToken = json_decode($response->body, true);
                    $token = $provider->client->getToken();
                    $token['access_token'] = $longLivedToken['access_token'];
                    $token['expires_in'] = $longLivedToken['expires_in'];

                    $provider->client->setToken($token);
                    $provider->setSessionToken();
                }
                else
                {
                    throw new Exception('Error code ' . $response->code . ' received long-lived token: ' . $response->body . '.');
                }

            }
Let us know how that goes, if you run into any issues or if you need assistance using the token to do something else. We'll investigate how to best incorporate this into the next release of JFBConnect to always fetch the long-lived token for Instagram in the best way possible.

Thanks,
Alex
The topic has been locked.
Active Subscriptions:

None
3 years 8 months ago #66639 by DoMeister
Alex,
Thanks for resolving this for me, I can now move on.
I need some time to jump into the next element, posting media to a profile. Probably a couple of ways to do this so I will need to research this more. If you have a preference/example for how this would be done to suit JFBC i would happily review and I'm also happy to share my progress.

I hope you can include the long-lived token in your next update, I think it has no negative impact and on the plus side gives extended options for development.

Many Thanks
DM
The topic has been locked.
Support Specialist
3 years 8 months ago #66643 by alzander
I don't have any suggestions on where to start there. I wasn't really sure that Instagram allowed posting content to profiles automatically using their API. It's something we've looked into a few times in the past and, while 5+ years ago, it was possible, I thought it was no longer possible.

The API lets you pull in feeds and images from profiles information to your site, but pushing back has generally been more limited. If you know of documentation somewhere that highlights what you're looking for though, point us to it and we'll gladly take a look.

Thanks, and all the best,
Alex
The topic has been locked.