Integrate full instagram oauth

This commit is contained in:
2025-11-09 11:59:36 +01:00
parent d6ba7c595a
commit 8ca2bc9909
6 changed files with 79 additions and 73 deletions

26
app.js
View File

@@ -1,14 +1,34 @@
import { data } from "./wwwroot/core/appData.js"; import { data } from "./wwwroot/core/appData.js";
import express from "express"; import express from "express";
import {Logger} from "./wwwroot/core/logging/logger.js";
import {launch} from "./bot.js";
//await launch();
console.log(data.instagramTokenManager.getOauthUrl());
const app = express(); const app = express();
app.use(express.json()); app.use(express.json());
app.get("/oauth/", async (req, res) => { app.get("/oauth/", async (req, res) => {
const code = req.query.code; const code = req.query.code;
console.log("Received OAuth code:", code); let resMsg = "";
await data.instagramTokenManager.generate(code); try{
const shortLived = await data.instagramTokenManager.generateShortLivedToken(code);
const longLived = await data.instagramTokenManager.generateLongLivedToken(shortLived);
console.log(longLived);
resMsg = "Authentication successful. You can close this tab";
} catch(err){
console.log(err);
await Logger.error(`Unable to generate token from code ${code}`, err);
resMsg = "An error occurred. Try again in few minutes.";
} finally {
res.send(`
<html lang="en">
<head><title>Authentication</title></head>
<body>${resMsg}</body>
</html>
`);
}
}); });
app.get("/api/health", (req, res) => { app.get("/api/health", (req, res) => {

76
bot.js
View File

@@ -2,50 +2,54 @@ import {data} from "./wwwroot/core/appData.js";
import JsonManager from "./wwwroot/core/utils/jsonManager.js"; import JsonManager from "./wwwroot/core/utils/jsonManager.js";
import {Logger} from "./wwwroot/core/logging/logger.js"; import {Logger} from "./wwwroot/core/logging/logger.js";
try{ const launch = async () => {
try{
data.instagramTokenManager.startWatching(); data.instagramTokenManager.startWatching();
//data.tiktokTokenManager.startWatching(); //data.tiktokTokenManager.startWatching();
data.instagramPoller.on("newPost", async ({permalink, userId}) => { data.instagramPoller.on("newPost", async ({permalink, userId}) => {
const modified = JsonManager.upsertPost("./posts.json", {permalink, userId}) const modified = JsonManager.upsertPost("./posts.json", {permalink, userId})
if(!modified) return; if(!modified) return;
const message = `Behold ! Some new awesome content has been posted ! \n\n${permalink}`; const message = `Behold ! Some new awesome content has been posted ! \n\n${permalink}`;
await data.sender.send(data.socialChannelID, message) await data.sender.send(data.socialChannelID, message)
}); });
data.client.once('clientReady', async () => { data.client.once('clientReady', async () => {
await data.sender.send(data.updateChannelID, "I'm now online ! ✅") await data.sender.send(data.updateChannelID, "I'm now online ! ✅")
console.log(`✅ Logged in as ${data.client.user.tag}`); console.log(`✅ Logged in as ${data.client.user.tag}`);
}); });
data.client.on('messageCreate', (message) => { data.client.on('messageCreate', (message) => {
const isGuildOwner = message.guild && message.author.id === message.guild.ownerId; const isGuildOwner = message.guild && message.author.id === message.guild.ownerId;
if (message.content === '/login' && isGuildOwner) { if (message.content === '/login' && isGuildOwner) {
message.reply(data.instagramTokenManager.getOauthUrl()); message.reply(data.instagramTokenManager.getOauthUrl());
} }
}); });
data.client.on('guildMemberAdd', member => { data.client.on('guildMemberAdd', member => {
const avatar = member.user.avatarURL(); const avatar = member.user.avatarURL();
}); });
process.on('SIGINT', async () => { process.on('SIGINT', async () => {
try { try {
await data.sender.send(data.updateChannelID, "I'm shutting down, now. Bye! 👋") await data.sender.send(data.updateChannelID, "I'm shutting down, now. Bye! 👋")
} catch (error) { } catch (error) {
await Logger.error("Error while shutting down", error); await Logger.error("Error while shutting down", error);
} finally { } finally {
await data.client.destroy(); await data.client.destroy();
process.exit(0); process.exit(0);
} }
}); });
await data.client.login(process.env.DISCORD_TOKEN); await data.client.login(process.env.DISCORD_TOKEN);
data.instagramPoller.start(600000); data.instagramPoller.start(600000);
} catch(err){ } catch(err){
await Logger.error("Unexpected error", err) await Logger.error("Unexpected error", err)
}
} }
export {launch}

View File

@@ -24,8 +24,7 @@ export class InstagramTokenManager extends BaseTokenManager {
+ "&response_type=code"; + "&response_type=code";
} }
async generate(code) { async generateShortLivedToken(code){
let headers = { let headers = {
"Content-Type": "application/x-www-form-urlencoded" "Content-Type": "application/x-www-form-urlencoded"
}; };
@@ -40,11 +39,14 @@ export class InstagramTokenManager extends BaseTokenManager {
let encodedBody = new URLSearchParams(body); let encodedBody = new URLSearchParams(body);
let shortLiveAccessTokenData = await Requester.doPostRequest( return await Requester.doPostRequest(
"https://api.instagram.com/oauth/access_token", headers, encodedBody); "https://api.instagram.com/oauth/access_token", headers, encodedBody);
}
let userId = shortLiveAccessTokenData.user_id; async generateLongLivedToken(shortLivedToken) {
let shortLiveAccessToken = shortLiveAccessTokenData.access_token;
let userId = shortLivedToken.user_id;
let shortLiveAccessToken = shortLivedToken.access_token;
let longLiveAccessTokenData = await Requester.doGetRequest( let longLiveAccessTokenData = await Requester.doGetRequest(
"https://graph.instagram.com/access_token?grant_type=ig_exchange_token" + "https://graph.instagram.com/access_token?grant_type=ig_exchange_token" +

View File

@@ -29,7 +29,7 @@ export class Logger{
await mkdir(logsDir, { recursive: true }); await mkdir(logsDir, { recursive: true });
await appendFile(fullPath, `${time} - ${message} -> ${JSON.stringify(error)} \n`); await appendFile(fullPath, `${time} - ${message} -> ${error.message} \n`);
console.error(`An error occured. The incident has been logged in ${fullPath}`) console.error(`An error occured. The incident has been logged in ${fullPath}`)
} catch (err) { } catch (err) {
console.error("Error writing log:", err); console.error("Error writing log:", err);

View File

@@ -24,12 +24,18 @@ export class Requester {
headers: headers, headers: headers,
body: body body: body
}) })
.then(response => response.json()) .then(async response => {
if (!response.ok) {
throw new Error(`HTTP ${response.status} ${response.statusText} : ${await response.text()}`);
}
return response.json()
})
.then(data => { .then(data => {
return data; return data;
}) })
.catch(error => { .catch(error => {
Logger.error(`Unable to fetch`, error); Logger.error(`Unable to fetch`, error);
throw error;
}); });
} }
} }

View File

@@ -1,26 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>The Jailor auth</title>
</head>
<body>
<div id="result-text"></div>
</body>
</html>
<script type="module">
import {data} from "../core/appData.js";
try{
const urlParams = new URLSearchParams(window.location.search);
const code = urlParams.get("code");
await data.instagramTokenManager.generate(code)
document.querySelector("#code").innerText = "Authentication successful. You can close this tab";
} catch(err){
document.querySelector("#code").innerText = "Authentication failed.";
}
</script>