Nerixyz / instagram_mqtt

Realtime and Push Notification (FBNS) support for the instagram-private-api
MIT License
252 stars 50 forks source link

using an existing object of ig #114

Closed ra7bi closed 6 months ago

ra7bi commented 7 months ago

I have made modifications to the Instagram private API, expanding its header options to prevent blocking. These modifications have been effective in operation. However, I encountered an issue when attempting to integrate this modified API with the instagram_mqtt package.

Upon integration, I encountered the following error: GET /api/v1/direct_v2/inbox/?visual_message_return_type=unseen&thread_message_limit=10&persistentBadging=true&limit=20 - 401 Unauthorized; Please wait a few minutes befor

Interestingly, removing const mqttClient: IgApiClientRealtime = withRealtime(ig); and using instagram-private-api without mqtt package resolves the issue, allowing the code to function correctly and retrieve the desired data.

However, when utilizing IgApiClientRealtime, I consistently encounter the 401 Unauthorized error.

I'm seeking guidance on any additional configurations or adjustments required to effectively integrate the MQTT package. Any assistance or insights would be greatly appreciated.

Below is the relevant section of my code:

import 'dotenv/config';

/* NOTE ,  This is Modified Version of Instagram Private API */
import {  IgApiClient, IgCheckpointError, IgNetworkError  } from '../instagram-private-api';
import { DirectCommands, GraphQLSubscriptions, IgApiClientExt, IgApiClientFbns, IgApiClientRealtime, SkywalkerSubscriptions, withFbns, withRealtime } from 'instagram_mqtt';

import * as fs from 'fs';
import { exit } from 'process';
const {IG_USERNAME = '', IG_PASSWORD = '', IG_SESSIONFILE =''} = process.env;
console.log(IG_SESSIONFILE)

async function fakeSave(data: object) {
    return fs.writeFileSync(IG_SESSIONFILE, JSON.stringify(data), { encoding: 'utf8' });
}

async function fakeExists(){
    if (!await fs.existsSync(IG_SESSIONFILE))
        return false;
    return true;
}

async function fakeLoad() {
  console.log('FakeSession Found');
  return await fs.readFileSync(IG_SESSIONFILE, {encoding: 'utf8'});
}

(async () => {

      //ig.state.bloksVersionId = Fixed from const file in core/const
      ig.state.igWWWClaim = 'hmac.xxxxx'
      ig.state.uuid = '9af1xxxx42';
      ig.state.familyDeviceId = '83361xxxxc74bda'
      ig.state.deviceId = 'anxxxxc'
      ig.state.altLoggerIdsS = '251xxxx400'
      ig.state.connectionTypeHeader = 'WIFI'
      ig.state.contentType = 'WIFI';
      ig.state.capabilitiesHeader = 'xxx'
      ig.state.priority ='u=3'
      ig.state.deviceString = '25/7.1.2; 320dpi; 1080x1920; samsung; SM-G977N; beyond1q; qcom'
      ig.state.language = 'en-US';
      ig.state.authorization = 'Bearer IGT:2:xxxXR0FPQmQ1Oxxx'
      ig.state.xMID = 'xxNAABx'
      ig.state.directRegionHint ='xxxx'
      ig.state.shbid = 'xxxxxxxxx'
      ig.state.shbts = 'xxxxxxx'
      ig.state.dsUserId = 'xxxxxxxxx'
      ig.state.rur = 'xxxxxxxxxx'
      ig.state.intendedUserId = 'xxx'
      ig.state.contentType = 'application/x-www-form-urlencoded; charset=UTF-8'
      ig.state.acceptEncoding = 'gzip, deflate, br';
      ig.state.fbHttpEngine = 'Liger'
      ig.state.fbClientIp = 'True'
      ig.state.fbServerCluster = 'True'

      const cookieJar = await ig.state.serializeCookieJar()

      console.log('----------------- serializeCookie Jar --------------')
      console.log(cookieJar)
      await ig.state.deserializeCookieJar(cookieJar);
      console.log('-----------------END deserializeCookie Jar --------------')

    ig.request.end$.subscribe(async () => {
      const serialized = await ig.state.serialize();
      fakeSave(serialized);
    });

    if (await fakeExists()) {
      console.log(fakeLoad())
      await ig.state.deserialize(fakeLoad());
    }

    let pk = await ig.user.getIdByUsername('xxxx')

    const followersFeed = ig.feed.accountFollowers(pk);
    const wholeResponse = await followersFeed.request();

    console.log('------------------ > USER ID FOR \n \r '+pk);

    console.log(' \n \r------------- MQTT CLIENT ------------------------');

    const mqttClient: IgApiClientRealtime = withRealtime(ig);

        // whenever something gets sent and has no event, this is called
      mqttClient.realtime.on('receive', (topic, messages) => console.log('receive', topic, messages));

      // this is called with a wrapper use {message} to only get the "actual" message from the wrapper
      mqttClient.realtime.on('message', logEvent('messageWrapper'));

      await mqttClient.realtime.connect({
        // optional
        graphQlSubs: [
            // these are some subscriptions
            GraphQLSubscriptions.getAppPresenceSubscription(),
            GraphQLSubscriptions.getZeroProvisionSubscription(ig.state.deviceId),
            GraphQLSubscriptions.getDirectStatusSubscription(),
            GraphQLSubscriptions.getDirectTypingSubscription(ig.state.dsUserId,true),
            GraphQLSubscriptions.getAsyncAdSubscription(ig.state.dsUserId),
        ],
        // // optional
        // skywalkerSubs: [
        //     SkywalkerSubscriptions.directSub(mqttClient.state.cookieUserId),
        //     SkywalkerSubscriptions.liveSub(mqttClient.state.cookieUserId),
        // ],
        // optional
        // this enables you to get direct messages
        irisData: await mqttClient.feed.directInbox().request(),
        // optional
        // in here you can change connect options
        // available are all properties defined in MQTToTConnectionClientInfo
        connectOverrides: {},

        // optional
        // use this proxy
        // socksOptions: {
        //     type: 5,
        //     port: 12345,
        //     host: '...'
        // }
    });

    // simulate turning the device off after 2s and turning it back on after another 2s
    setTimeout(() => {
        console.log('Device off');
        // from now on, you won't receive any realtime-data as you "aren't in the app"
        // the keepAliveTimeout is somehow a 'constant' by instagram
        mqttClient.realtime.direct.sendForegroundState({
            inForegroundApp: false,
            inForegroundDevice: false,
            keepAliveTimeout: 900,
        });
    }, 2000);
    setTimeout(() => {
        console.log('In App');
        mqttClient.realtime.direct.sendForegroundState({
            inForegroundApp: true,
            inForegroundDevice: true,
            keepAliveTimeout: 60,
        });
    }, 4000);

    // an example on how to subscribe to live comments
    // you can add other GraphQL subs using .subscribe
   // await mqttClient.realtime.graphQlSubscribe(GraphQLSubscriptions.getLiveRealtimeCommentsSubscription('<broadcast-id>'));

})();

function logEvent(name: string) {
  return (data: any) => console.log(name, data);
}

the idea here is to use existing token from my phone , i also tried many ig private api function and it works

ra7bi commented 7 months ago

My console logs

------------------ > USER ID FOR
 111111111111

 ------------- MQTT CLIENT ------------------------
C:\Users\nodejs\Desktop\nodeEngine\engine\node_modules\instagram-private-api\dist\core\request.js:126
        return new errors_1.IgResponseError(response);
               ^

IgResponseError: GET /api/v1/direct_v2/inbox/?visual_message_return_type=unseen&thread_message_limit=10&persistentBadging=true&limit=20 - 401 Unauthorized; Please wait a few minutes before you try again.
    at Request.handleResponseError (C:\Users\nodejs\Desktop\nodeEngine\engine\node_modules\instagram-private-api\dist\core\request.js:126:16)
    at Request.send (C:\Users\nodejs\Desktop\nodeEngine\engine\node_modules\instagram-private-api\dist\core\request.js:54:28)
    at async DirectInboxFeed.request (C:\Users\nodejs\Desktop\nodeEngine\engine\node_modules\instagram-private-api\dist\feeds\direct-inbox.feed.js:22:26)
Nerixyz commented 7 months ago

I suppose you'd need to rewrite extend.ts by using the import from your modified library instead of instagram-private-api.

ra7bi commented 6 months ago

I suppose you'd need to rewrite extend.ts by using the import from your modified library instead of instagram-private-api.

Thank you