Refactor Instagram login process to handle session data and improve error handling

This commit is contained in:
암냥 2025-11-28 22:08:42 +09:00
commit 48f66773c7
4 changed files with 79 additions and 88 deletions

View file

@ -10,7 +10,9 @@ async function main() {
try { try {
const data = await Login(); const data = await Login();
console.log("✨ | Instagram login successful"); console.log("✨ | Instagram login successful");
console.log(`🤔 | Login as ${data.currentUser.full_name}`); if (data) {
console.log(`🤔 | Login as ${data.currentUser.full_name}`);
}
} catch (error) { } catch (error) {
console.error("❌ | Instagram login failed:", error); console.error("❌ | Instagram login failed:", error);
} finally { } finally {

View file

@ -7,38 +7,59 @@ export async function Login() {
ig.state.generateDevice(process.env.IG_USERNAME!); ig.state.generateDevice(process.env.IG_USERNAME!);
ig.state.appUserAgent ig.state.appUserAgent
ig.request.end$.subscribe(async () => {
const serialized = await ig.state.serialize();
delete serialized.constants; // this deletes the version info, so you'll always use the version provided by the library
await Bun.write('./temp/session.json', JSON.stringify(serialized));
});
try { try {
await ig.simulate.preLoginFlow(); let loggedInUser;
const loggedInUser = await ig.account.login( try {
process.env.IG_USERNAME!,
process.env.IG_PASSWORD!
);
process.nextTick(async () => await ig.simulate.postLoginFlow());
const currentUser = await ig.account.currentUser();
return { loggedInUser, currentUser }; if (await Bun.file('./temp/session.json').exists()) {
const sessionData = await Bun.file('./temp/session.json').json();
await ig.state.deserialize(sessionData);
loggedInUser = await ig.account.login(
process.env.IG_USERNAME!,
process.env.IG_PASSWORD!
);
} else {
loggedInUser = await ig.account.login(
process.env.IG_USERNAME!,
process.env.IG_PASSWORD!
);
await ig.simulate.preLoginFlow();
} catch (error: any) { process.nextTick(async () => await ig.simulate.postLoginFlow());
if (error.name === "IgCheckpointError") { }
console.error( } catch (error: any) {
"Instagram checkpoint required. Please verify your account in the Instagram app or handle the challenge." if (error.name === "IgCheckpointError") {
); console.error(
// Optionally, you can trigger challenge handling here "Instagram checkpoint required. Please verify your account in the Instagram app or handle the challenge."
// await ig.challenge.auto(true); // Requesting sms-code or click "It was me" button );
} else { // Optionally, you can trigger challenge handling here
console.error("🔒 | Login failed:", error); // await ig.challenge.auto(true); // Requesting sms-code or click "It was me" button
} else {
console.error("🔒 | Login failed:", error);
}
throw error;
} }
throw error;
const currentUser = await ig.account.currentUser();
return { loggedInUser, currentUser };
} catch (error) {
console.warn("⚠️ | Failed to load session data:", error);
} }
} }
export class Upload { export class Upload {
static async Post(filePath: string, caption: string) { static async Post(filePath: string, caption: string) {
try { try {
const ImagePath = path.resolve(`${filePath}`); const ImagePath = path.resolve(`${filePath}`);
const bunFile = Bun.file(ImagePath); const bunFile = Bun.file(ImagePath);
const ImageBuffer = Buffer.from(await bunFile.arrayBuffer()); const ImageBuffer = Buffer.from(await bunFile.arrayBuffer());
await ig.publish.photo({ await ig.publish.photo({
file: ImageBuffer, file: ImageBuffer,
caption: caption, caption: caption,
@ -47,13 +68,13 @@ export class Upload {
console.error("Error uploading post:", error); console.error("Error uploading post:", error);
} }
} }
static async Story(filePath: string, MLSV_YMD: string) { static async Story(filePath: string, MLSV_YMD: string) {
try { try {
const ImagePath = path.resolve(`${filePath}`); const ImagePath = path.resolve(`${filePath}`);
const bunFile = Bun.file(ImagePath); const bunFile = Bun.file(ImagePath);
const ImageBuffer = Buffer.from(await bunFile.arrayBuffer()); const ImageBuffer = Buffer.from(await bunFile.arrayBuffer());
await ig.publish.story({ await ig.publish.story({
file: ImageBuffer, file: ImageBuffer,
caption: `#인천상정중학교 #상정중학교 #급식 \n${MLSV_YMD}일자 급식`, caption: `#인천상정중학교 #상정중학교 #급식 \n${MLSV_YMD}일자 급식`,

View file

@ -1,63 +1,22 @@
//import { Discord } from "./lib/discord"; // //import { Discord } from "./lib/discord";
import { CreateImage } from "./lib/image"; // import {getAllSchedules} from "./lib/schedules";
// import { CreateImage } from "./lib/image";
// await CreateImage.PostSchedule();
//const YYMMDD = new Date().toISOString().slice(0, 10).replace(/-/g, "").toString(); // import { Login, Upload } from "./lib/instagram";
const YYMMDD = "20250530" // try {
//console.log(YYMMDD); // const data = await Login();
// console.log("✨ | Instagram login successful");
// console.log(`🤔 | Login as ${data.currentUser.full_name}`);
// } catch (error) {
// console.error("❌ | Instagram login failed:", error);
// } finally {
// console.timeEnd("🔓 | Instagram login");
// }
//Discord("20250509") // await Upload.Post(
async function run() { // `/home/neko/today.isangjeong/app/temp/schedule-2025-06.png`,
console.time("Post"); // `#인천상정중학교 #상정중학교 #학사일정 \n${new Date().getFullYear()}년도 ${
const post = await CreateImage.PostMeal(YYMMDD); // new Date().getMonth() + 1
console.timeEnd("Post"); // }월 학사 일정`
console.log("Post created:", post); // );
let NutritionInfoText = "";
const entries = Object.entries(post ?? {}).filter(([_, value]) => value.toString().length > 0);
entries.forEach(([name, value], idx) => {
NutritionInfoText += `${name} : ${value.toString().replace(",", ", ")}`;
if (idx !== entries.length - 1) {
NutritionInfoText += "\n";
}
});
console.log("Nutrition Info Text:", NutritionInfoText);
console.time("Story");
await CreateImage.ConvertToStory(`./temp/${YYMMDD}.png`);
console.timeEnd("Story");
}
run();
import { getAllSchedules } from "./lib/schedule";
//import { CreateImage } from "./lib/image";
//CreateImage.PostSchedule()
//const tomorrow = new Date();
//tomorrow.setDate(tomorrow.getDate() + 1);
// 내일이 1일이면
//console.log(tomorrow.getDate());
/*import { VTSList } from "./lib/vts";
VTSList().then(results => {
if (results.length > 0) {
console.log("\n5번째 행의 노란색 셀 내용 리스트:");
results.forEach(value => console.log(value));
} else {
console.log("\n5번째 행에서 노란색 배경의 셀을 찾지 못했거나, 'V.T.S.' 조건 불충족.");
}
});*/
/*
getAllSchedules()
.then((schedules) => {
console.log("학사 일정:", schedules);
})
.catch((error) => {
console.error("Error fetching schedules:", error);
});
*/

View file

@ -1,6 +1,15 @@
services: services:
app: app:
build: . build: .
restart: always restart: unless-stopped
volumes: volumes:
- ./logs:/code/app/temp/logs - ./logs:/code/app/temp/logs
networks:
hikari:
networks:
hikari:
ipam:
driver: default
config:
- subnet: 172.30.0.0/16