Advertisement
Guest User

Untitled

a guest
Sep 20th, 2017
2,064
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 30.27 KB | None | 0 0
  1. <?php
  2.  
  3. namespace InstagramAPI;
  4.  
  5. /**
  6. * Instagram's Private API v3.
  7. *
  8. * TERMS OF USE:
  9. * - This code is in no way affiliated with, authorized, maintained, sponsored
  10. * or endorsed by Instagram or any of its affiliates or subsidiaries. This is
  11. * an independent and unofficial API. Use at your own risk.
  12. * - We do NOT support or tolerate anyone who wants to use this API to send spam
  13. * or commit other online crimes.
  14. * - You will NOT use this API for marketing or other abusive purposes (spam,
  15. * botting, harassment, massive bulk messaging...).
  16. *
  17. * @author mgp25: Founder, Reversing, Project Leader (https://github.com/mgp25)
  18. * @author SteveJobzniak (https://github.com/SteveJobzniak)
  19. */
  20. class Instagram
  21. {
  22. /**
  23. * Experiments refresh interval in sec.
  24. *
  25. * @var int
  26. */
  27. const EXPERIMENTS_REFRESH = 7200;
  28.  
  29. /**
  30. * Currently active Instagram username.
  31. *
  32. * @var string
  33. */
  34. public $username;
  35.  
  36. /**
  37. * Currently active Instagram password.
  38. *
  39. * @var string
  40. */
  41. public $password;
  42.  
  43. /**
  44. * The Android Device for the currently active user.
  45. *
  46. * @var \InstagramAPI\Devices\Device
  47. */
  48. public $device;
  49.  
  50. /**
  51. * Toggles API query/response debug output.
  52. *
  53. * @var bool
  54. */
  55. public $debug;
  56.  
  57. /**
  58. * Toggles truncating long responses when debugging.
  59. *
  60. * @var bool
  61. */
  62. public $truncatedDebug;
  63.  
  64. /**
  65. * For internal use by Instagram-API developers!
  66. *
  67. * Toggles the throwing of exceptions whenever Instagram-API's "Response"
  68. * classes lack fields that were provided by the server. Useful for
  69. * discovering that our library classes need updating.
  70. *
  71. * This is only settable via this public property and is NOT meant for
  72. * end-users of this library. It is for contributing developers!
  73. *
  74. * @var bool
  75. */
  76. public $apiDeveloperDebug = false;
  77.  
  78. /**
  79. * UUID.
  80. *
  81. * @var string
  82. */
  83. public $uuid;
  84.  
  85. /**
  86. * Google Play Advertising ID.
  87. *
  88. * The advertising ID is a unique ID for advertising, provided by Google
  89. * Play services for use in Google Play apps. Used by Instagram.
  90. *
  91. * @var string
  92. *
  93. * @see https://support.google.com/googleplay/android-developer/answer/6048248?hl=en
  94. */
  95. public $advertising_id;
  96.  
  97. /**
  98. * Device ID.
  99. *
  100. * @var string
  101. */
  102. public $device_id;
  103.  
  104. /**
  105. * Phone ID.
  106. *
  107. * @var string
  108. */
  109. public $phone_id;
  110.  
  111. /**
  112. * Numerical UserPK ID of the active user account.
  113. *
  114. * @var string
  115. */
  116. public $account_id;
  117.  
  118. /**
  119. * Session status.
  120. *
  121. * @var bool
  122. */
  123. public $isLoggedIn = false;
  124.  
  125. /**
  126. * Rank token.
  127. *
  128. * @var string
  129. */
  130. public $rank_token;
  131.  
  132. /**
  133. * Raw API communication/networking class.
  134. *
  135. * @var Client
  136. */
  137. public $client;
  138.  
  139. /**
  140. * The account settings storage.
  141. *
  142. * @var \InstagramAPI\Settings\StorageHandler|null
  143. */
  144. public $settings;
  145.  
  146. /**
  147. * The current application session ID.
  148. *
  149. * This is a temporary ID which changes in the official app every time the
  150. * user closes and re-opens the Instagram application or switches account.
  151. *
  152. * @var string
  153. */
  154. public $session_id;
  155.  
  156. /**
  157. * A list of experiments enabled on per-account basis.
  158. *
  159. * @var array
  160. */
  161. public $experiments;
  162.  
  163. /** @var Request\Account Collection of Account related functions. */
  164. public $account;
  165. /** @var Request\Business Collection of Business related functions. */
  166. public $business;
  167. /** @var Request\Collection Collection of Collections related functions. */
  168. public $collection;
  169. /** @var Request\Creative Collection of Creative related functions. */
  170. public $creative;
  171. /** @var Request\Direct Collection of Direct related functions. */
  172. public $direct;
  173. /** @var Request\Discover Collection of Discover related functions. */
  174. public $discover;
  175. /** @var Request\Hashtag Collection of Hashtag related functions. */
  176. public $hashtag;
  177. /** @var Request\Internal Collection of Internal (non-public) functions. */
  178. public $internal;
  179. /** @var Request\Live Collection of Live related functions. */
  180. public $live;
  181. /** @var Request\Location Collection of Location related functions. */
  182. public $location;
  183. /** @var Request\Media Collection of Media related functions. */
  184. public $media;
  185. /** @var Request\People Collection of People related functions. */
  186. public $people;
  187. /** @var Request\Push Collection of Push related functions. */
  188. public $push;
  189. /** @var Request\Story Collection of Story related functions. */
  190. public $story;
  191. /** @var Request\Timeline Collection of Timeline related functions. */
  192. public $timeline;
  193. /** @var Request\Usertag Collection of Usertag related functions. */
  194. public $usertag;
  195.  
  196. /**
  197. * Constructor.
  198. *
  199. * @param bool $debug Show API queries and responses.
  200. * @param bool $truncatedDebug Truncate long responses in debug.
  201. * @param array $storageConfig Configuration for the desired
  202. * user settings storage backend.
  203. *
  204. * @throws \InstagramAPI\Exception\InstagramException
  205. */
  206. public function __construct(
  207. $debug = false,
  208. $truncatedDebug = false,
  209. $storageConfig = [])
  210. {
  211. // Prevent people from running this library on ancient PHP versions.
  212. if (!defined('PHP_VERSION_ID')) { // Emulate version value if missing.
  213. $version = explode('.', PHP_VERSION);
  214. define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2]));
  215. }
  216. if (PHP_VERSION_ID < 50600) {
  217. throw new \InstagramAPI\Exception\InternalException('You must have PHP 5.6 or higher to use the Instagram API library.');
  218. }
  219.  
  220. // Debugging options.
  221. $this->debug = $debug;
  222. $this->truncatedDebug = $truncatedDebug;
  223.  
  224. // Load all function collections.
  225. $this->account = new Request\Account($this);
  226. $this->business = new Request\Business($this);
  227. $this->collection = new Request\Collection($this);
  228. $this->creative = new Request\Creative($this);
  229. $this->direct = new Request\Direct($this);
  230. $this->discover = new Request\Discover($this);
  231. $this->hashtag = new Request\Hashtag($this);
  232. $this->internal = new Request\Internal($this);
  233. $this->live = new Request\Live($this);
  234. $this->location = new Request\Location($this);
  235. $this->media = new Request\Media($this);
  236. $this->people = new Request\People($this);
  237. $this->push = new Request\Push($this);
  238. $this->story = new Request\Story($this);
  239. $this->timeline = new Request\Timeline($this);
  240. $this->usertag = new Request\Usertag($this);
  241.  
  242. // Configure the settings storage and network client.
  243. $self = $this;
  244. $this->settings = Settings\Factory::createHandler(
  245. $storageConfig,
  246. [
  247. // This saves all user session cookies "in bulk" at script exit
  248. // or when switching to a different user, so that it only needs
  249. // to write cookies to storage a few times per user session:
  250. 'onCloseUser' => function ($storage) use ($self) {
  251. if ($self->client instanceof Client) {
  252. $self->client->saveCookieJar();
  253. }
  254. },
  255. ]
  256. );
  257. $this->client = new Client($this);
  258. $this->experiments = [];
  259. }
  260.  
  261. /**
  262. * Controls the SSL verification behavior of the Client.
  263. *
  264. * @see http://docs.guzzlephp.org/en/latest/request-options.html#verify
  265. *
  266. * @param bool|string $state TRUE to verify using PHP's default CA bundle,
  267. * FALSE to disable SSL verification (this is
  268. * insecure!), String to verify using this path to
  269. * a custom CA bundle file.
  270. */
  271. public function setVerifySSL(
  272. $state)
  273. {
  274. $this->client->setVerifySSL($state);
  275. }
  276.  
  277. /**
  278. * Gets the current SSL verification behavior of the Client.
  279. *
  280. * @return bool|string
  281. */
  282. public function getVerifySSL()
  283. {
  284. return $this->client->getVerifySSL();
  285. }
  286.  
  287. /**
  288. * Set the proxy to use for requests.
  289. *
  290. * @see http://docs.guzzlephp.org/en/latest/request-options.html#proxy
  291. *
  292. * @param string|array|null $value String or Array specifying a proxy in
  293. * Guzzle format, or NULL to disable proxying.
  294. */
  295. public function setProxy(
  296. $value)
  297. {
  298. $this->client->setProxy($value);
  299. }
  300.  
  301. /**
  302. * Gets the current proxy used for requests.
  303. *
  304. * @return string|array|null
  305. */
  306. public function getProxy()
  307. {
  308. return $this->client->getProxy();
  309. }
  310.  
  311. /**
  312. * Sets the network interface override to use.
  313. *
  314. * Only works if Guzzle is using the cURL backend. But that's
  315. * almost always the case, on most PHP installations.
  316. *
  317. * @see http://php.net/curl_setopt CURLOPT_INTERFACE
  318. *
  319. * @param string|null $value Interface name, IP address or hostname, or NULL to
  320. * disable override and let Guzzle use any interface.
  321. */
  322. public function setOutputInterface(
  323. $value)
  324. {
  325. $this->client->setOutputInterface($value);
  326. }
  327.  
  328. /**
  329. * Gets the current network interface override used for requests.
  330. *
  331. * @return string|null
  332. */
  333. public function getOutputInterface()
  334. {
  335. return $this->client->getOutputInterface();
  336. }
  337.  
  338. /**
  339. * Login to Instagram or automatically resume and refresh previous session.
  340. *
  341. * Sets the active account for the class instance. You can call this multiple times to switch
  342. * between multiple Instagram accounts.
  343. *
  344. * WARNING: You MUST run this function EVERY time your script runs! It handles automatic session
  345. * resume and relogin and app session state refresh and other absolutely *vital* things that are
  346. * important if you don't want to be banned from Instagram!
  347. *
  348. * WARNING: This function MAY return a CHALLENGE telling you that the account needs two-factor
  349. * login before letting you log in! Read the two-factor login example to see how to handle that.
  350. *
  351. * @param string $username Your Instagram username.
  352. * @param string $password Your Instagram password.
  353. * @param bool $forceLogin Force login to Instagram instead of resuming previous session.
  354. * @param int $appRefreshInterval How frequently login() should act like an Instagram app
  355. * that's been closed and reopened and needs to "refresh its
  356. * state", by asking for extended account state details.
  357. * Default: After 1800 seconds, meaning 30 minutes since the
  358. * last state-refreshing login() call.
  359. * This CANNOT be longer than 6 hours. Read _sendLoginFlow()!
  360. * The shorter your delay is the BETTER. You may even want to
  361. * set it to an even LOWER value than the default 30 minutes!
  362. *
  363. * @throws \InvalidArgumentException
  364. * @throws \InstagramAPI\Exception\InstagramException
  365. *
  366. * @return \InstagramAPI\Response\LoginResponse|null A login response if a full (re-)login happens,
  367. * otherwise NULL if an existing session is resumed.
  368. */
  369. public function login(
  370. $username,
  371. $password,
  372. $forceLogin = false,
  373. $appRefreshInterval = 1800)
  374. {
  375. if (empty($username) || empty($password)) {
  376. throw new \InvalidArgumentException('You must provide a username and password to login().');
  377. }
  378.  
  379. // Switch the currently active user/pass if the details are different.
  380. if ($this->username !== $username || $this->password !== $password) {
  381. $this->_setUser($username, $password);
  382. }
  383.  
  384. // Perform a full relogin if necessary.
  385. if (!$this->isLoggedIn || $forceLogin) {
  386. $this->_sendPreLoginFlow();
  387.  
  388. try {
  389. $response = $this->request('accounts/login/')
  390. ->setNeedsAuth(false)
  391. ->addPost('phone_id', $this->phone_id)
  392. ->addPost('_csrftoken', $this->client->getToken())
  393. ->addPost('username', $this->username)
  394. ->addPost('adid', $this->advertising_id)
  395. ->addPost('guid', $this->uuid)
  396. ->addPost('device_id', $this->device_id)
  397. ->addPost('password', $this->password)
  398. ->addPost('login_attempt_count', 0)
  399. ->getResponse(new Response\LoginResponse());
  400. } catch (\InstagramAPI\Exception\InstagramException $e) {
  401. if ($e->hasResponse() && $e->getResponse()->isTwoFactorRequired()) {
  402. // Login failed because two-factor login is required.
  403. // Return server response to tell user they need 2-factor.
  404. return $e->getResponse();
  405. } else {
  406. // Login failed for some other reason... Re-throw error.
  407. throw $e;
  408. }
  409. }
  410.  
  411. $this->_updateLoginState($response);
  412.  
  413. $this->_sendLoginFlow(true, $appRefreshInterval);
  414.  
  415. // Full (re-)login successfully completed. Return server response.
  416. return $response;
  417. }
  418.  
  419. // Attempt to resume an existing session, or full re-login if necessary.
  420. // NOTE: The "return" here gives a LoginResponse in case of re-login.
  421. return $this->_sendLoginFlow(false, $appRefreshInterval);
  422. }
  423.  
  424. /**
  425. * Finish a two-factor authenticated login.
  426. *
  427. * This function finishes a two-factor challenge that was provided by the
  428. * regular login() function. If you successfully answer their challenge,
  429. * you will be logged in after this function call.
  430. *
  431. * @param string $verificationCode Verification code you have received via SMS.
  432. * @param string $twoFactorIdentifier Two factor identifier, obtained in login() response. Format: "123456".
  433. * @param int $appRefreshInterval See login() for description of this parameter.
  434. *
  435. * @throws \InstagramAPI\Exception\InstagramException
  436. *
  437. * @return \InstagramAPI\Response\LoginResponse
  438. */
  439. public function finishTwoFactorLogin(
  440. $verificationCode,
  441. $twoFactorIdentifier,
  442. $appRefreshInterval = 1800)
  443. {
  444. if (empty($this->username) || empty($this->password)) {
  445. throw new \InstagramAPI\Exception\LoginRequiredException(
  446. 'You must provide a username and password to login() before attempting to finish the two-factor login process.'
  447. );
  448. }
  449.  
  450. $verificationCode = trim(str_replace(' ', '', $verificationCode));
  451.  
  452. $response = $this->request('accounts/two_factor_login/')
  453. ->setNeedsAuth(false)
  454. ->addPost('verification_code', $verificationCode)
  455. ->addPost('two_factor_identifier', $twoFactorIdentifier)
  456. ->addPost('_csrftoken', $this->client->getToken())
  457. ->addPost('username', $this->username)
  458. ->addPost('device_id', $this->device_id)
  459. ->addPost('password', $this->password)
  460. ->getResponse(new Response\LoginResponse());
  461.  
  462. $this->_updateLoginState($response);
  463.  
  464. $this->_sendLoginFlow(true, $appRefreshInterval);
  465.  
  466. return $response;
  467. }
  468.  
  469. /**
  470. * Set the active account for the class instance.
  471. *
  472. * We can call this multiple times to switch between multiple accounts.
  473. *
  474. * @param string $username Your Instagram username.
  475. * @param string $password Your Instagram password.
  476. *
  477. * @throws \InvalidArgumentException
  478. * @throws \InstagramAPI\Exception\InstagramException
  479. */
  480. protected function _setUser(
  481. $username,
  482. $password)
  483. {
  484. if (empty($username) || empty($password)) {
  485. throw new \InvalidArgumentException('You must provide a username and password to _setUser().');
  486. }
  487.  
  488. // Load all settings from the storage and mark as current user.
  489. $this->settings->setActiveUser($username);
  490.  
  491. // Generate the user's Device instance, which will be created from the
  492. // user's last-used device IF they've got a valid, good one stored.
  493. // But if they've got a BAD/none, this will create a brand-new device.
  494. $savedDeviceString = $this->settings->get('devicestring');
  495. $this->device = new Devices\Device(Constants::IG_VERSION, Constants::VERSION_CODE, Constants::USER_AGENT_LOCALE, $savedDeviceString);
  496.  
  497. // Get active device string so that we can compare it to any saved one.
  498. $deviceString = $this->device->getDeviceString();
  499.  
  500. // Generate a brand-new device fingerprint if the Device wasn't reused
  501. // from settings, OR if any of the stored fingerprints are missing.
  502. // NOTE: The regeneration when our device model changes is to avoid
  503. // dangerously reusing the "previous phone's" unique hardware IDs.
  504. // WARNING TO CONTRIBUTORS: Only add new parameter-checks here if they
  505. // are CRITICALLY important to the particular device. We don't want to
  506. // frivolously force the users to generate new device IDs constantly.
  507. $resetCookieJar = false;
  508.  
  509. print_r($this->settings);
  510. exit;
  511. /*if ($deviceString !== $savedDeviceString || empty($this->settings->get('uuid')) || empty($this->settings->get('phone_id')) // ...important device...
  512. || empty($this->settings->get('device_id'))) { // ...parameters.
  513. // Erase all previously stored device-specific settings.
  514. $this->settings->eraseDeviceSettings();
  515.  
  516. // Save the chosen device string to settings.
  517. $this->settings->set('devicestring', $deviceString);
  518.  
  519. // Generate hardware fingerprints for the new device.
  520. $this->settings->set('device_id', Signatures::generateDeviceId());
  521. $this->settings->set('phone_id', Signatures::generateUUID(true));
  522. $this->settings->set('uuid', Signatures::generateUUID(true));
  523.  
  524. // Erase any stored account ID, to ensure that we detect ourselves
  525. // as logged-out. This will force a new relogin from the new device.
  526. $this->settings->set('account_id', '');
  527.  
  528. // We'll also need to throw out all previous cookies.
  529. $resetCookieJar = true;
  530. }*/
  531.  
  532. // Generate other missing values. These are for less critical parameters
  533. // that don't need to trigger a complete device reset like above. For
  534. // example, this is good for new parameters that Instagram introduces
  535. // over time, since those can be added one-by-one over time here without
  536. // needing to wipe/reset the whole device.
  537. if (empty($this->settings->get('advertising_id'))) {
  538. $this->settings->set('advertising_id', Signatures::generateUUID(true));
  539. }
  540. if (empty($this->settings->get('session_id'))) {
  541. $this->settings->set('session_id', Signatures::generateUUID(true));
  542. }
  543.  
  544. // Store various important parameters for easy access.
  545. $this->username = $username;
  546. $this->password = $password;
  547. $this->uuid = $this->settings->get('uuid');
  548. $this->advertising_id = $this->settings->get('advertising_id');
  549. $this->device_id = $this->settings->get('device_id');
  550. $this->phone_id = $this->settings->get('phone_id');
  551. $this->session_id = $this->settings->get('session_id');
  552. $this->experiments = $this->settings->getExperiments();
  553.  
  554. // Load the previous session details if we're possibly logged in.
  555. if (!$resetCookieJar && $this->settings->isMaybeLoggedIn()) {
  556. $this->isLoggedIn = true;
  557. $this->account_id = $this->settings->get('account_id');
  558. $this->rank_token = $this->account_id.'_'.$this->uuid;
  559. } else {
  560. $this->isLoggedIn = false;
  561. $this->account_id = null;
  562. $this->rank_token = null;
  563. }
  564.  
  565. // Configures Client for current user AND updates isLoggedIn state
  566. // if it fails to load the expected cookies from the user's jar.
  567. // Must be done last here, so that isLoggedIn is properly updated!
  568. // NOTE: If we generated a new device we start a new cookie jar.
  569. $this->client->updateFromCurrentSettings($resetCookieJar);
  570. }
  571.  
  572. /**
  573. * Updates the internal state after a successful login.
  574. *
  575. * @param Response\LoginResponse $response The login response.
  576. *
  577. * @throws \InvalidArgumentException
  578. * @throws \InstagramAPI\Exception\InstagramException
  579. */
  580. protected function _updateLoginState(
  581. Response\LoginResponse $response)
  582. {
  583. // This check is just protection against accidental bugs. It makes sure
  584. // that we always call this function with a *successful* login response!
  585. if (!$response instanceof Response\LoginResponse
  586. || !$response->isOk()) {
  587. throw new \InvalidArgumentException('Invalid login response provided to _updateLoginState().');
  588. }
  589.  
  590. $this->isLoggedIn = true;
  591. $this->account_id = $response->getLoggedInUser()->getPk();
  592. $this->settings->set('account_id', $this->account_id);
  593. $this->rank_token = $this->account_id.'_'.$this->uuid;
  594. $this->settings->set('last_login', time());
  595. }
  596.  
  597. /**
  598. * Sends pre-login flow. This is required to emulate real device behavior.
  599. *
  600. * @throws \InstagramAPI\Exception\InstagramException
  601. */
  602. protected function _sendPreLoginFlow()
  603. {
  604. // Calling this non-token API will put a csrftoken in our cookie
  605. // jar. We must do this before any functions that require a token.
  606. $this->internal->syncDeviceFeatures(true);
  607. $this->internal->readMsisdnHeader();
  608. $this->internal->logAttribution();
  609. }
  610.  
  611. /**
  612. * Sends login flow. This is required to emulate real device behavior.
  613. *
  614. * @param bool $justLoggedIn
  615. * @param int $appRefreshInterval
  616. *
  617. * @throws \InvalidArgumentException
  618. * @throws \InstagramAPI\Exception\InstagramException
  619. *
  620. * @return \InstagramAPI\Response\LoginResponse|null A login response if a full (re-)login is needed
  621. * during the login flow attempt, otherwise NULL.
  622. */
  623. protected function _sendLoginFlow(
  624. $justLoggedIn,
  625. $appRefreshInterval = 1800)
  626. {
  627. if ($appRefreshInterval > 21600) {
  628. throw new \InvalidArgumentException("Instagram's app state refresh interval is NOT allowed to be higher than 6 hours, and the lower the better!");
  629. }
  630.  
  631. // SUPER IMPORTANT:
  632. //
  633. // STOP trying to ask us to remove this code section!
  634. //
  635. // EVERY time the user presses their device's home button to leave the
  636. // app and then comes back to the app, Instagram does ALL of these things
  637. // to refresh its internal app state. We MUST emulate that perfectly,
  638. // otherwise Instagram will silently detect you as a "fake" client
  639. // after a while!
  640. //
  641. // You can configure the login's $appRefreshInterval in the function
  642. // parameter above, but you should keep it VERY frequent (definitely
  643. // NEVER longer than 6 hours), so that Instagram sees you as a real
  644. // client that keeps quitting and opening their app like a REAL user!
  645. //
  646. // Otherwise they WILL detect you as a bot and silently BLOCK features
  647. // or even ban you.
  648. //
  649. // You have been warned.
  650. if ($justLoggedIn) {
  651. // Perform the "user has just done a full login" API flow.
  652. $this->people->getAutoCompleteUserList();
  653. $this->story->getReelsTrayFeed();
  654. $this->timeline->getTimelineFeed();
  655. $this->direct->getRecentRecipients();
  656. $this->internal->syncUserFeatures();
  657. //$this->push->register();
  658. $this->direct->getRankedRecipients('reshare', true);
  659. $this->direct->getRankedRecipients('raven', true);
  660. $this->direct->getInbox();
  661. $this->direct->getVisualInbox();
  662. // bootstrap users
  663. $this->internal->getProfileNotice();
  664. //$this->internal->getMegaphoneLog();
  665. $this->people->getRecentActivityInbox();
  666. $this->internal->getQPFetch();
  667. $this->media->getBlockedMedia();
  668. $this->discover->getExploreFeed(null, true);
  669. //$this->internal->getFacebookOTA();
  670. } else {
  671. // Act like a real logged in app client refreshing its news timeline.
  672. // This also lets us detect if we're still logged in with a valid session.
  673. try {
  674. $this->timeline->getTimelineFeed(null, [
  675. 'is_pull_to_refresh' => mt_rand(1, 3) < 3,
  676. ]);
  677. } catch (\InstagramAPI\Exception\LoginRequiredException $e) {
  678. // If our session cookies are expired, we were now told to login,
  679. // so handle that by running a forced relogin in that case!
  680. return $this->login($this->username, $this->password, true, $appRefreshInterval);
  681. }
  682.  
  683. // Perform the "user has returned to their already-logged in app,
  684. // so refresh all feeds to check for news" API flow.
  685. $lastLoginTime = $this->settings->get('last_login');
  686. if (is_null($lastLoginTime) || (time() - $lastLoginTime) > $appRefreshInterval) {
  687. $this->settings->set('last_login', time());
  688.  
  689. // Generate and save a new application session ID.
  690. $this->session_id = Signatures::generateUUID(true);
  691. $this->settings->set('session_id', $this->session_id);
  692.  
  693. // Do the rest of the "user is re-opening the app" API flow...
  694. $this->people->getAutoCompleteUserList();
  695. $this->story->getReelsTrayFeed();
  696. $this->direct->getRankedRecipients('reshare', true);
  697. $this->direct->getRankedRecipients('raven', true);
  698. //push register
  699. $this->direct->getRecentRecipients();
  700. //push register
  701. //$this->internal->getMegaphoneLog();
  702. $this->direct->getInbox();
  703. $this->people->getRecentActivityInbox();
  704. $this->internal->getProfileNotice();
  705. $this->discover->getExploreFeed();
  706. }
  707.  
  708. // Users normally resume their sessions, meaning that their
  709. // experiments never get synced and updated. So sync periodically.
  710. $lastExperimentsTime = $this->settings->get('last_experiments');
  711. if (is_null($lastExperimentsTime) || (time() - $lastExperimentsTime) > self::EXPERIMENTS_REFRESH) {
  712. $this->internal->syncUserFeatures();
  713. $this->internal->syncDeviceFeatures();
  714. }
  715. }
  716.  
  717. // We've now performed a login or resumed a session. Forcibly write our
  718. // cookies to the storage, to ensure that the storage doesn't miss them
  719. // in case something bad happens to PHP after this moment.
  720. $this->client->saveCookieJar();
  721. }
  722.  
  723. /**
  724. * Log out of Instagram.
  725. *
  726. * WARNING: Most people should NEVER call logout()! Our library emulates
  727. * the Instagram app for Android, where you are supposed to stay logged in
  728. * forever. By calling this function, you will tell Instagram that you are
  729. * logging out of the APP. But you SHOULDN'T do that! In almost 100% of all
  730. * cases you want to *stay logged in* so that LOGIN() resumes your session!
  731. *
  732. * @throws \InstagramAPI\Exception\InstagramException
  733. *
  734. * @return \InstagramAPI\Response\LogoutResponse
  735. *
  736. * @see Instagram::login()
  737. */
  738. public function logout()
  739. {
  740. $response = $this->request('accounts/logout/')
  741. ->addPost('phone_id', $this->phone_id)
  742. ->addPost('_csrftoken', $this->client->getToken())
  743. ->addPost('guid', $this->uuid)
  744. ->addPost('device_id', $this->device_id)
  745. ->addPost('_uuid', $this->uuid)
  746. ->getResponse(new Response\LogoutResponse());
  747.  
  748. // We've now logged out. Forcibly write our cookies to the storage, to
  749. // ensure that the storage doesn't miss them in case something bad
  750. // happens to PHP after this moment.
  751. $this->client->saveCookieJar();
  752.  
  753. return $response;
  754. }
  755.  
  756. /**
  757. * Checks if a parameter is enabled in the given experiment.
  758. *
  759. * @param string $experiment
  760. * @param string $param
  761. *
  762. * @return bool
  763. */
  764. public function isExperimentEnabled(
  765. $experiment,
  766. $param)
  767. {
  768. return isset($this->experiments[$experiment][$param])
  769. && in_array($this->experiments[$experiment][$param], ['enabled', 'true', '1']);
  770. }
  771.  
  772. /**
  773. * Create a custom API request.
  774. *
  775. * Used internally, but can also be used by end-users if they want
  776. * to create completely custom API queries without modifying this library.
  777. *
  778. * @param string $url
  779. *
  780. * @return \InstagramAPI\Request
  781. */
  782. public function request(
  783. $url)
  784. {
  785. return new Request($this, $url);
  786. }
  787. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement