Something went wrong. Try again.
Monorepo for Aesthetic.Computer aesthetic.computer
Something went wrong. Try again.
JavaScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181#!/usr/bin/env node
// Interactive Instagram login script.// Performs the same login flow as instagram-cli (preLoginSync, challenge handling,// session persistence) and saves the resulting session to MongoDB for use by// the insta-api serverless function.//// Usage:// source ../aesthetic-computer-vault/.env (or set MONGODB_CONNECTION_STRING)// node scripts/insta-login.mjs//// If INSTA_USER / INSTA_PASS are not set, it prompts interactively.
import { MongoClient } from "mongodb";import { IgApiClient, IgCheckpointError, IgLoginTwoFactorRequiredError, IgLoginBadPasswordError,} from "instagram-private-api";import { createInterface } from "readline";
const rl = createInterface({ input: process.stdin, output: process.stdout });const ask = (q) => new Promise((res) => rl.question(q, res));
const MONGODB_CONNECTION_STRING = process.env.MONGODB_CONNECTION_STRING;const MONGODB_NAME = process.env.MONGODB_NAME || "aesthetic";
if (!MONGODB_CONNECTION_STRING) { console.error("MONGODB_CONNECTION_STRING not set."); console.error("Run: source aesthetic-computer-vault/.env"); process.exit(1);}
async function main() { // Get credentials let username = process.env.INSTA_USER; let password = process.env.INSTA_PASS;
if (!username) username = await ask("Instagram username: "); if (!password) password = await ask("Instagram password: ");
console.log(`\nLogging in as @${username}...`);
const ig = new IgApiClient(); ig.state.generateDevice(username);
// Pre-login flow (instagram-cli pattern — reduces challenge risk) console.log(" Running preLoginSync..."); try { await ig.launcher.preLoginSync(); console.log(" preLoginSync OK"); } catch (e) { console.warn(" preLoginSync failed (continuing):", e.message); }
// Attempt login let loggedIn = false; try { await ig.account.login(username, password); loggedIn = true; console.log(" Login successful!"); } catch (err) { if (err instanceof IgCheckpointError) { console.log("\n Instagram checkpoint triggered."); console.log(" Requesting verification code...");
try { await ig.challenge.auto(true); console.log(" Verification code sent (check email/SMS).");
const code = await ask("\n Enter verification code: "); await ig.challenge.sendSecurityCode(code.trim()); loggedIn = true; console.log(" Challenge completed!"); } catch (challengeErr) { console.error(" Challenge failed:", challengeErr.message); rl.close(); process.exit(1); } } else if (err instanceof IgLoginTwoFactorRequiredError) { console.log("\n Two-factor authentication required."); const twoFactorInfo = err.response.body.two_factor_info; const totp = twoFactorInfo.totp_two_factor_on; const method = totp ? "authenticator app" : "SMS"; console.log(` Method: ${method}`);
const code = await ask(`\n Enter 2FA code from ${method}: `); try { await ig.account.twoFactorLogin({ username, verificationCode: code.trim(), twoFactorIdentifier: twoFactorInfo.two_factor_identifier, verificationMethod: totp ? "0" : "1", }); loggedIn = true; console.log(" 2FA login successful!"); } catch (tfaErr) { console.error(" 2FA failed:", tfaErr.message); rl.close(); process.exit(1); } } else if (err instanceof IgLoginBadPasswordError) { console.error(" Bad password. Check credentials."); rl.close(); process.exit(1); } else { console.error(" Login error:", err.message); rl.close(); process.exit(1); } }
if (!loggedIn) { console.error("Login failed."); rl.close(); process.exit(1); }
// Post-login flow (instagram-cli pattern) console.log(" Running postLoginFlow..."); try { await ig.feed.reelsTray("cold_start").request(); await ig.feed.timeline("cold_start_fetch").request(); console.log(" postLoginFlow OK"); } catch (e) { console.warn(" postLoginFlow failed (continuing):", e.message); }
// Verify login const currentUser = await ig.account.currentUser(); console.log(`\n Logged in as: @${currentUser.username} (pk: ${currentUser.pk})`);
// Serialize and save session to MongoDB console.log("\n Saving session to MongoDB..."); const serialized = await ig.state.serialize(); delete serialized.constants; delete serialized.supportedCapabilities;
const client = new MongoClient(MONGODB_CONNECTION_STRING); try { await client.connect(); const db = client.db(MONGODB_NAME);
await db.collection("insta-sessions").updateOne( { _id: username }, { $set: { _id: username, state: serialized, updatedAt: new Date(), loginMethod: "insta-login.mjs", verifiedUser: currentUser.username, }, }, { upsert: true }, ); console.log(" Session saved to MongoDB (insta-sessions collection)");
// Verify by reading it back const doc = await db .collection("insta-sessions") .findOne({ _id: username }); console.log(` Session document size: ~${JSON.stringify(doc.state).length} bytes`); console.log(` Updated at: ${doc.updatedAt}`); } finally { await client.close(); }
console.log("\n Done! The insta-api function will now reuse this session."); console.log(" Try: /api/insta?action=profile&username=whistlegraph\n");
rl.close();}
main().catch((e) => { console.error("Fatal:", e.message); rl.close(); process.exit(1);});