From 4601955803062e113ceb2fce9d7228f80644d1d0 Mon Sep 17 00:00:00 2001 From: nsmle Date: Sat, 20 Aug 2022 05:18:57 +0700 Subject: [PATCH 1/6] Add feature seen story --- examples/seen-story.php | 44 ++++++++++++++++++++ src/Instagram/Api.php | 20 ++++++++- src/Instagram/Transport/StoryInteraction.php | 40 ++++++++++++++++++ src/Instagram/Utils/Endpoints.php | 2 + 4 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 examples/seen-story.php create mode 100644 src/Instagram/Transport/StoryInteraction.php diff --git a/examples/seen-story.php b/examples/seen-story.php new file mode 100644 index 0000000..03c210e --- /dev/null +++ b/examples/seen-story.php @@ -0,0 +1,44 @@ +login($credentials->getLogin(), $credentials->getPassword()); + + // we need instagram user id + $profile = $api->getProfile('starwars'); + sleep(1); + $feedStories = $api->getStories($profile->getId()); + + if (count($feedStories->getStories())) { + /** @var \Instagram\Model\StoryMedia $story */ + foreach ($feedStories->getStories() as $story) { + $storyId = $story->getId(); + $ownerId = intval($feedStories->getOwner()->id); + $storyTakenAt = strtotime($story->getTakenAtDate()->format("Y-m-d h:i:sa")); + $storySeenAt = time(); + + $seenStory = $api->seenStory($storyId, $ownerId, $storyTakenAt, $storySeenAt); + echo "Seen story {$storyId} : {$seenStory} \n"; + } + } else { + echo 'No stories' . "\n"; + } + +} catch (InstagramException $e) { + print_r($e->getMessage()); +} catch (CacheException $e) { + print_r($e->getMessage()); +} diff --git a/src/Instagram/Api.php b/src/Instagram/Api.php index 497cf1d..8ddcc5c 100644 --- a/src/Instagram/Api.php +++ b/src/Instagram/Api.php @@ -59,7 +59,8 @@ LocationData, LiveData, ReelsDataFeed, - TimelineDataFeed + TimelineDataFeed, + StoryInteraction }; use Psr\Cache\CacheItemPoolInterface; use Instagram\Utils\{InstagramHelper, OptionHelper}; @@ -393,6 +394,23 @@ public function getStoriesOfHighlightsFolder(StoryHighlightsFolder $folder): Sto return $hydrator->getFolder(); } + /** + * @param int $storyId + * @param int $ownerId + * @param int $takenAt + * @param int $seenAt + * + * @return string + * + * @throws Exception\InstagramAuthException + * @throws Exception\InstagramFetchException + */ + public function seenStory(int $storyId, int $ownerId, int $takenAt, int $seenAt): string + { + $storyInteraction = new StoryInteraction($this->client, $this->session); + return $storyInteraction->seen($storyId, $ownerId, $takenAt, $seenAt); + } + /** * @param Media $media * diff --git a/src/Instagram/Transport/StoryInteraction.php b/src/Instagram/Transport/StoryInteraction.php new file mode 100644 index 0000000..6df0110 --- /dev/null +++ b/src/Instagram/Transport/StoryInteraction.php @@ -0,0 +1,40 @@ + $storyId, + 'reelMediaOwnerId' => $ownerId, + 'reelId' => $ownerId, + 'reelMediaTakenAt' => $takenAt, + 'viewSeenAt' => $seenAt + ]; + + $data = $this->postJsonDataFeed(Endpoints::SEEN_STORY_URL, $formParams); + + if (!$data->status) { + throw new InstagramFetchException('Whoops, looks like something went wrong!'); + } + + return $data->status; + } +} diff --git a/src/Instagram/Utils/Endpoints.php b/src/Instagram/Utils/Endpoints.php index 63252ea..d33eb4a 100644 --- a/src/Instagram/Utils/Endpoints.php +++ b/src/Instagram/Utils/Endpoints.php @@ -24,6 +24,8 @@ class Endpoints const TIMELINE_URL = 'https://i.instagram.com/api/v1/feed/timeline/'; + const SEEN_STORY_URL = 'https://i.instagram.com/api/v1/stories/reel/seen/'; + /** * @param int $accountId * From 5332714d3e9f18e9743d0a58207c9a4a53b5b6dd Mon Sep 17 00:00:00 2001 From: nsmle Date: Sat, 20 Aug 2022 07:32:06 +0700 Subject: [PATCH 2/6] Add feature like & unlike story --- examples/like-unlike-story.php | 47 ++++++++++++ src/Instagram/Api.php | 28 +++++++ src/Instagram/Transport/StoryInteraction.php | 77 +++++++++++++++++++- src/Instagram/Utils/Endpoints.php | 4 + 4 files changed, 152 insertions(+), 4 deletions(-) create mode 100644 examples/like-unlike-story.php diff --git a/examples/like-unlike-story.php b/examples/like-unlike-story.php new file mode 100644 index 0000000..be0ab80 --- /dev/null +++ b/examples/like-unlike-story.php @@ -0,0 +1,47 @@ +login($credentials->getLogin(), $credentials->getPassword()); + + // we need instagram user id + $profile = $api->getProfile('starwars'); + sleep(1); + $feedStories = $api->getStories($profile->getId()); + + if (count($feedStories->getStories())) { + /** @var \Instagram\Model\StoryMedia $story */ + foreach ($feedStories->getStories() as $story) { + + /** Like Story */ + $likeStory = $api->likeStory($story->getId()); + echo "Like story {$story->getId()} : {$likeStory} \n"; + + /** Unlike Story * + $unlikeStory = $api->unlikeStory($story->getId()); + echo "Unlike story {$story->getId()} : {$unlikeStory} \n"; + /**/ + + } + } else { + echo 'No stories' . "\n"; + } + +} catch (InstagramException $e) { + print_r($e->getMessage()); +} catch (CacheException $e) { + print_r($e->getMessage()); +} diff --git a/src/Instagram/Api.php b/src/Instagram/Api.php index 8ddcc5c..554e64a 100644 --- a/src/Instagram/Api.php +++ b/src/Instagram/Api.php @@ -411,6 +411,34 @@ public function seenStory(int $storyId, int $ownerId, int $takenAt, int $seenAt) return $storyInteraction->seen($storyId, $ownerId, $takenAt, $seenAt); } + /** + * @param int $storyId + * + * @return string + * + * @throws Exception\InstagramAuthException + * @throws Exception\InstagramFetchException + */ + public function likeStory(int $storyId): string + { + $storyInteraction = new StoryInteraction($this->client, $this->session); + return $storyInteraction->like($storyId); + } + + /** + * @param int $storyId + * + * @return string + * + * @throws Exception\InstagramAuthException + * @throws Exception\InstagramFetchException + */ + public function unlikeStory(int $storyId): string + { + $storyInteraction = new StoryInteraction($this->client, $this->session); + return $storyInteraction->unlike($storyId); + } + /** * @param Media $media * diff --git a/src/Instagram/Transport/StoryInteraction.php b/src/Instagram/Transport/StoryInteraction.php index 6df0110..f144e02 100644 --- a/src/Instagram/Transport/StoryInteraction.php +++ b/src/Instagram/Transport/StoryInteraction.php @@ -6,6 +6,7 @@ use Instagram\Exception\InstagramFetchException; use Instagram\Utils\Endpoints; +use Instagram\Utils\OptionHelper; class StoryInteraction extends AbstractDataFeed { @@ -21,7 +22,7 @@ class StoryInteraction extends AbstractDataFeed */ public function seen(int $storyId, int $ownerId, int $takenAt, int $seenAt): string { - $formParams = [ + $params = [ 'reelMediaId' => $storyId, 'reelMediaOwnerId' => $ownerId, 'reelId' => $ownerId, @@ -29,10 +30,78 @@ public function seen(int $storyId, int $ownerId, int $takenAt, int $seenAt): str 'viewSeenAt' => $seenAt ]; - $data = $this->postJsonDataFeed(Endpoints::SEEN_STORY_URL, $formParams); + return $this->postData(Endpoints::SEEN_STORY_URL, $params); + } + + /** + * @param int $storyId + * + * @return string + * + * @throws InstagramFetchException + */ + public function like(int $storyId): string + { + $params['media_id'] = $storyId; + return $this->postData(Endpoints::LIKE_STORY_URL, $params); + } + + /** + * @param int $storyId + * + * @return string + * + * @throws InstagramFetchException + */ + public function unlike(int $storyId): string + { + $params['media_id'] = $storyId; + return $this->postData(Endpoints::UNLIKE_STORY_URL, $params); + } + + /** + * @param string $endpoint + * @param string $formParameters + * + * @return string + * + * @throws InstagramFetchException + */ + public function postData(string $endpoint, array $formParameters = []): string + { + $csrfToken = ''; + + if (!empty($this->session->getCookies()->getCookieByName("csrftoken"))) { + $csrfToken = $this->session->getCookies()->getCookieByName("csrftoken")->getValue(); + } + + $options = [ + 'headers' => [ + 'user-agent' => OptionHelper::$USER_AGENT, + 'accept-language' => OptionHelper::$LOCALE, + 'x-csrftoken' => $csrfToken, + 'x-ig-app-id' => 1217981644879628, + ], + 'cookies' => $this->session->getCookies(), + ]; + + if (count($formParameters) > 0) { + $options = array_merge($options, [ + 'form_params' => $formParameters, + ]); + } + + try { + $res = $this->client->request('POST', $endpoint, $options); + } catch (ClientException $exception) { + throw new InstagramFetchException("StoryInteraction error, {$exception->getMessage()}"); + } + + $data = (string) $res->getBody(); + $data = json_decode($data); - if (!$data->status) { - throw new InstagramFetchException('Whoops, looks like something went wrong!'); + if ($data === null) { + throw new InstagramAuthException('StoryInteraction error, Unable to get JSON data!'); } return $data->status; diff --git a/src/Instagram/Utils/Endpoints.php b/src/Instagram/Utils/Endpoints.php index d33eb4a..75ccb7a 100644 --- a/src/Instagram/Utils/Endpoints.php +++ b/src/Instagram/Utils/Endpoints.php @@ -26,6 +26,10 @@ class Endpoints const SEEN_STORY_URL = 'https://i.instagram.com/api/v1/stories/reel/seen/'; + const LIKE_STORY_URL = 'https://i.instagram.com/api/v1/story_interactions/send_story_like'; + + const UNLIKE_STORY_URL = 'https://i.instagram.com/api/v1/story_interactions/unsend_story_like'; + /** * @param int $accountId * From 0c5f33607594d8003cad4ed24680ab32647a2899 Mon Sep 17 00:00:00 2001 From: nsmle Date: Tue, 23 Aug 2022 16:56:01 +0700 Subject: [PATCH 3/6] Fix bug login with cookie --- examples/login-with-cookies.php | 33 ++++++++++++++++++++++++++------- src/Instagram/Api.php | 14 +++++++++++++- 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/examples/login-with-cookies.php b/examples/login-with-cookies.php index c9ff343..6d0941f 100644 --- a/examples/login-with-cookies.php +++ b/examples/login-with-cookies.php @@ -39,25 +39,44 @@ "Discard" => false, "HttpOnly" => true, ]); - // Generate CookieJar from instagram cookie 'sessionid' $cookieJar = new CookieJar(false, [$sessionId]); */ try { - $api = new Api(); - + $api = new Api($cachePool); + // Optionals for set user agent and language $api->setUserAgent('Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.57 Safari/537.36'); $api->setLanguage('id-ID'); - - $api->loginWithCookies($cookieJar); - + + $api->loginWithCookies($cookieJar, $credentials->getLogin()); + $profile = $api->getProfile('robertdowneyjr'); - + dd($profile); } catch (InstagramAuthException $e) { print_r($e->getMessage()); } catch (InstagramException $e) { print_r($e->getMessage()); } + + +/** Note : + * If you want to save your own cookies manually + * you can use the method below + */ + +/** login with method loginWithCookies */ +// $newCookieJar = $api->loginWithCookies($cookieJar); + +/** Save cookieJar into file */ +// $unixStringForCookieIdentification = $credentials->getLogin(); // can be replaced with any string just for cookie identification +// $sessionData = $cachePool +// ->getItem(Session::SESSION_KEY . '.' . CacheHelper::sanitizeUsername($unixStringForCookieIdentification)); +// ->set($newCookieJar); +// $cachePool->save($sessionData); + +/** use of cookies in subsequent requests after login with cookies */ +// $api->login($unixStringForCookieIdentification, ''); +// dd($api->getProfile('robertdowneyjr')); diff --git a/src/Instagram/Api.php b/src/Instagram/Api.php index 554e64a..6c86020 100644 --- a/src/Instagram/Api.php +++ b/src/Instagram/Api.php @@ -118,9 +118,11 @@ public function setLanguage(string $language): void /** * @param \GuzzleHttp\Cookie\CookieJar $cookies * + * return \GuzzleHttp\Cookie\CookieJar + * * @throws Exception\InstagramAuthException */ - public function loginWithCookies(CookieJar $cookies): void + public function loginWithCookies(CookieJar $cookies, string $username = null): CookieJar { $login = new Login($this->client, '', '', null, $this->challengeDelay); @@ -135,7 +137,17 @@ public function loginWithCookies(CookieJar $cookies): void // Get New Cookies $cookies = $login->withCookies($session->toArray()); + // Save cookies to cachePool if username/identifier cookies is not empty + if (!empty($username)) { + $sessionData = $this->cachePool + ->getItem(Session::SESSION_KEY . '.' . CacheHelper::sanitizeUsername($username)) + ->set($cookies); + $this->cachePool->save($sessionData); + } + $this->session = new Session($cookies); + + return $cookies; } /** From 42edc3a434ea7846a8abf386607a934a5c255898 Mon Sep 17 00:00:00 2001 From: Fiki Pratama Date: Fri, 10 Feb 2023 04:38:28 +0700 Subject: [PATCH 4/6] Update login with cookies regex * Update login with cookies regex --- examples/login-with-cookies.php | 12 ++++++++---- src/Instagram/Api.php | 34 ++++++++++++++++++--------------- src/Instagram/Auth/Login.php | 9 ++++++--- 3 files changed, 33 insertions(+), 22 deletions(-) diff --git a/examples/login-with-cookies.php b/examples/login-with-cookies.php index 6d0941f..e12f541 100644 --- a/examples/login-with-cookies.php +++ b/examples/login-with-cookies.php @@ -21,8 +21,8 @@ /** 1. Get cookies from file */ $sessionId = $cachePool->getItem(Session::SESSION_KEY . '.' . CacheHelper::sanitizeUsername($credentials->getLogin())) - ->get() - ->getCookieByName('sessionId'); + ->get() + ->getCookieByName('sessionId'); // Generate CookieJar from instagram cookie 'sessionid' $cookieJar = new CookieJar(false, [$sessionId]); @@ -41,7 +41,7 @@ ]); // Generate CookieJar from instagram cookie 'sessionid' $cookieJar = new CookieJar(false, [$sessionId]); -*/ + */ try { $api = new Api($cachePool); @@ -50,7 +50,11 @@ $api->setUserAgent('Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.57 Safari/537.36'); $api->setLanguage('id-ID'); - $api->loginWithCookies($cookieJar, $credentials->getLogin()); + $api->loginWithCookies($cookieJar); + + /** You can use below code to auto save session + $api->loginWithCookies($cookieJar, true, $credentials->getLogin()); + */ $profile = $api->getProfile('robertdowneyjr'); diff --git a/src/Instagram/Api.php b/src/Instagram/Api.php index 6c86020..5f61a62 100644 --- a/src/Instagram/Api.php +++ b/src/Instagram/Api.php @@ -9,7 +9,8 @@ use GuzzleHttp\Cookie\{SetCookie, CookieJar}; use Instagram\Auth\{Checkpoint\ImapClient, Login, Session}; use Instagram\Exception\{InstagramException, InstagramAuthException}; -use Instagram\Hydrator\{LocationHydrator, +use Instagram\Hydrator\{ + LocationHydrator, MediaHydrator, MediaCommentsHydrator, ProfileAlternativeHydrator, @@ -23,7 +24,8 @@ LiveHydrator, TimelineFeedHydrator }; -use Instagram\Model\{Location, +use Instagram\Model\{ + Location, Media, MediaDetailed, MediaComments, @@ -39,7 +41,8 @@ TaggedMediasFeed, TimelineFeed }; -use Instagram\Transport\{CommentPost, +use Instagram\Transport\{ + CommentPost, JsonMediaDetailedDataFeed, JsonMediasDataFeed, JsonMediaCommentsFeed, @@ -122,7 +125,8 @@ public function setLanguage(string $language): void * * @throws Exception\InstagramAuthException */ - public function loginWithCookies(CookieJar $cookies, string $username = null): CookieJar + + public function loginWithCookies(CookieJar $cookies, bool $saveCookies = false, string $sessionKey = null): void { $login = new Login($this->client, '', '', null, $this->challengeDelay); @@ -137,17 +141,18 @@ public function loginWithCookies(CookieJar $cookies, string $username = null): C // Get New Cookies $cookies = $login->withCookies($session->toArray()); - // Save cookies to cachePool if username/identifier cookies is not empty - if (!empty($username)) { - $sessionData = $this->cachePool - ->getItem(Session::SESSION_KEY . '.' . CacheHelper::sanitizeUsername($username)) - ->set($cookies); - $this->cachePool->save($sessionData); + if ($saveCookies) { + if (!($this->cachePool instanceof CacheItemPoolInterface)) + throw new InstagramAuthException('You must set cachePool to save this session, example: \n$cachePool = new \Symfony\Component\Cache\Adapter\FilesystemAdapter("Instagram", 0, __DIR__ . "/../cache"); \n$api = new \Instagram\Api($cachePool);'); + if (empty($sessionKey)) + throw new InstagramAuthException('You must set sessionKey, Example like your instagram username. \nE.g: (new Instagram\Api())->loginWithCookies($cookies, true, $credentials->getLogin());'); + + $sessionData = $this->cachePool->getItem(Session::SESSION_KEY . '.' . CacheHelper::sanitizeUsername($sessionKey)); + $sessionData->set($cookies); + $this->cachePool->save($sessionData); } $this->session = new Session($cookies); - - return $cookies; } /** @@ -163,7 +168,7 @@ public function login(string $username, string $password, ?ImapClient $imapClien { $login = new Login($this->client, $username, $password, $imapClient, $this->challengeDelay); - if ( !($this->cachePool instanceof CacheItemPoolInterface) ) { + if (!($this->cachePool instanceof CacheItemPoolInterface)) { throw new InstagramAuthException('You must set cachePool / login with cookies, example: \n$cachePool = new \Symfony\Component\Cache\Adapter\FilesystemAdapter("Instagram", 0, __DIR__ . "/../cache"); \n$api = new \Instagram\Api($cachePool);'); } @@ -180,7 +185,6 @@ public function login(string $username, string $password, ?ImapClient $imapClien $this->logout($username); $this->login($username, $password, $imapClient); } - } else { $cookies = $login->process(); $sessionData->set($cookies); @@ -833,7 +837,7 @@ public function getTimeline(string $maxId = null): TimelineFeed return $hydrator->getTimelineFeed(); } - + /** * @param string $user * diff --git a/src/Instagram/Auth/Login.php b/src/Instagram/Auth/Login.php index 28916e1..2301ffd 100644 --- a/src/Instagram/Auth/Login.php +++ b/src/Instagram/Auth/Login.php @@ -145,10 +145,13 @@ public function withCookies(array $session): CookieJar $html = (string) $baseRequest->getBody(); - preg_match('/\\\"csrf_token\\\":\\\"(.*?)\\\"/', $html, $matches); + preg_match('/"raw":"{\\\\"(.*?)\\\\"}"/', $html, $matches); + + if (isset($matches[0])) { + if (!property_exists(json_decode("{{$matches[0]}}"), 'raw')) + throw new InstagramAuthException('Login With Cookies Failed, Please login with instagram credentials.'); - if (isset($matches[1])) { - $data = $matches[1]; + $data = json_decode(json_decode("{{$matches[0]}}")->raw); if (!isset($data->config->viewer) && !isset($data->config->viewerId)) { throw new InstagramAuthException('Please login with instagram credentials.'); From eb2d5826fcc4b564cf12964ac1141c94dfdd4e2e Mon Sep 17 00:00:00 2001 From: nsmle Date: Sun, 12 Feb 2023 08:27:31 +0700 Subject: [PATCH 5/6] Fix get all cookies --- src/Instagram/Auth/Login.php | 8 ++++++++ tests/LoginWithCookiesTest.php | 7 ++++--- tests/fixtures/manifest.json | 1 + 3 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 tests/fixtures/manifest.json diff --git a/src/Instagram/Auth/Login.php b/src/Instagram/Auth/Login.php index 2301ffd..2d527dc 100644 --- a/src/Instagram/Auth/Login.php +++ b/src/Instagram/Auth/Login.php @@ -158,6 +158,14 @@ public function withCookies(array $session): CookieJar } } + // get all instagram cookies + $manifestRequest = $this->client->request('GET', InstagramHelper::URL_BASE . "data/manifest.json", [ + 'headers' => [ + 'user-agent' => OptionHelper::$USER_AGENT, + ], + 'cookies' => $cookies + ]); + return $cookies; } diff --git a/tests/LoginWithCookiesTest.php b/tests/LoginWithCookiesTest.php index d587a49..7590f22 100644 --- a/tests/LoginWithCookiesTest.php +++ b/tests/LoginWithCookiesTest.php @@ -5,7 +5,7 @@ use GuzzleHttp\{Client, Cookie\CookieJar, Cookie\SetCookie, Handler\MockHandler, HandlerStack, Psr7\Response}; use Instagram\Api; -use Instagram\Auth\{ Login, Session }; +use Instagram\Auth\{Login, Session}; use Instagram\Exception\InstagramAuthException; use PHPUnit\Framework\TestCase; use Symfony\Component\Cache\Adapter\FilesystemAdapter; @@ -26,6 +26,7 @@ public function testSucceededLoginWithCookie() $mock = new MockHandler([ new Response(200, [], file_get_contents(__DIR__ . '/fixtures/login-success.json')), + new Response(200, [], file_get_contents(__DIR__ . '/fixtures/manifest.json')), new Response(200, [], file_get_contents(__DIR__ . '/fixtures/profile.json')), ]); @@ -58,7 +59,7 @@ public function testLoginWithCookiesWithExpiredSession() $api = new Api(); $api->loginWithCookies($cookiesJar); } - + public function testLoginWithCookiesInvalid() { $this->expectException(InstagramAuthException::class); @@ -84,4 +85,4 @@ public function testLoginWithCookiesInvalid() $api = new Api(null, $client); $api->loginWithCookies($cookiesJar); } -} \ No newline at end of file +} diff --git a/tests/fixtures/manifest.json b/tests/fixtures/manifest.json new file mode 100644 index 0000000..b15a3dd --- /dev/null +++ b/tests/fixtures/manifest.json @@ -0,0 +1 @@ +{"name":"Instagram","short_name":"Instagram","description":"Instagram is a simple way to capture and share the world's moments.","start_url":"/?utm_source=pwa_homescreen","orientation":"portrait","display":"standalone","background_color":"#ffffff","theme_color":"#ffffff","prompt_message":"Add a Home screen icon for easy access to Instagram","icons":[{"src":"/static/images/ico/xxhdpi_launcher.png/99cf3909d459.png","sizes":"144x144","type":"image/png"},{"src":"/static/images/ico/xxxhdpi_launcher.png/9fc4bab7565b.png","sizes":"192x192","type":"image/png"}],"gcm_sender_id":"524223308106","gcm_user_visible_only":true,"related_applications":[{"platform":"play","id":"com.instagram.lite"},{"platform":"play","id":"com.instagram.android"}],"status":"ok"} \ No newline at end of file From 6c3dae4a03307814a13bc087f961b52f681ff056 Mon Sep 17 00:00:00 2001 From: nsmle Date: Sat, 20 Apr 2024 09:52:17 +0700 Subject: [PATCH 6/6] Fix merge 'pgrimaud:master into master' conflict --- src/Instagram/Auth/Login.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Instagram/Auth/Login.php b/src/Instagram/Auth/Login.php index a9610e5..00d5929 100644 --- a/src/Instagram/Auth/Login.php +++ b/src/Instagram/Auth/Login.php @@ -148,7 +148,7 @@ public function withCookies(array $session): CookieJar preg_match('/\"csrf_token\":\"(.*?)\"/', $html, $matches); if (isset($matches[1])) { - $data = json_decode(json_decode("{{$matches[0]}}")->raw); + $data = $matches[1]; if (!isset($data->config->viewer) && !isset($data->config->viewerId)) { throw new InstagramAuthException('Please login with instagram credentials.');