123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319 |
- require('dotenv').config();
- var fs = require('fs');
- var express = require('express');
- var bodyParser = require('body-parser');
- var app = express();
- var http = require('http').Server(app);
- var ref = require('instagram-id-to-url-segment');
- let date = require('date-and-time');
- var urlSegmentToInstagramId = ref.urlSegmentToInstagramId;
- var Client = require('instagram-private-api').V1;
- var device = new Client.Device('anonbot.wl');
- var storage = new Client.CookieFileStorage(__dirname + '/cookies/anonbot.json');
- const pngToJpeg = require('png-to-jpeg');
- var wrap = require('word-wrap');
- const { createCanvas, loadImage, registerFont } = require('canvas');
- registerFont('./fonts/SourceCodePro-Regular.ttf', {family: 'SourceCodePro'});
- const canvas = createCanvas(1080, 1080);
- const ctx = canvas.getContext('2d');
- var Airtable = require('airtable');
- var logs = new Airtable({apiKey: process.env.AIRTABLE_API_KEY}).base('appDowHJJVQTHNJfk');
- var blacklist = new Airtable({apiKey: process.env.AIRTABLE_API_KEY}).base('applZHoMDx5uF9h1Z');
- var sha256 = require('crypto-js/sha256');
- function createSubmission(text, fillStyle, ip, isResponse, responseText, color) {
- ctx.clearRect(0, 0, canvas.width, canvas.height);
- var formatted = wrap(text, {indent: '', width: 28});
- var truncated = formatted.length > 355 ? formatted.substr(0, 356) + "\u2026" : formatted;
- ctx.fillStyle = fillStyle;
- ctx.fillRect(0, 0, 1080, 1080);
- ctx.font = '62px "SourceCodePro"';
- ctx.fillStyle = '#FFF';
- ctx.fillText(truncated, 17, 65);
- var buf = canvas.toBuffer();
- fs.writeFileSync("submission.png", buf);
- //convert to jpeg because currently api only supports jpeg
- let buffer = fs.readFileSync("./submission.png");
- pngToJpeg()(buffer)
- .then(output => fs.writeFile("./submission.jpeg", output, function(err) {
- if (err) console.log(err);
- fs.exists("./submission.jpeg", function(exists) {
- if (exists && isResponse) publish(responseText, ip, isResponse, color);
- else if (exists && !isResponse) publish(text, ip, isResponse, color);
- })
- }));
- fs.unlinkSync('./submission.png');
- }
- function createResponse(text, originalText, ip, color) {
- ctx.clearRect(0, 0, canvas.width, canvas.height);
- var formatted = wrap(text, {indent: '', width: 28});
- var truncated = formatted.length > 355 ? formatted.substr(0, 356) + "\u2026" : formatted;
- if (color === "red") ctx.fillStyle = "#b20000";
- else ctx.fillStyle = "#404040";
- //ctx.fillStyle = "#c6c6c6";
- ctx.fillRect(0, 0, 1080, 1080);
- ctx.font = '62px "SourceCodePro"';
- ctx.fillStyle = '#FFF';
- ctx.fillText(truncated, 17, 65);
- var buf = canvas.toBuffer();
- fs.writeFileSync("response.png", buf);
- let buffer = fs.readFileSync("./response.png");
- pngToJpeg()(buffer)
- .then(output => fs.writeFile("./response.jpeg", output, function(err) {
- if (err) console.log(err);
- fs.exists("./response.jpeg", function(exists) {
- if (exists) {
- console.log(color);
- if (color === "gray") createSubmission(originalText, '#b20000', ip, true, text + "\n---\n" + originalText, "red");
- else createSubmission(originalText, '#404040', ip, true, text + "\n---\n" + originalText, "gray");
- }
- })
- }));
- fs.unlinkSync('./response.png');
- }
- function publish(caption, ip, isResponse, color) {
- if (isResponse) {
- var photos = [
- {
- type: 'photo',
- size: [1000,1000],
- data: './response.jpeg'
- },
- {
- type: 'photo',
- size: [1000,1000],
- data: './submission.jpeg'
- }
- ], disabledComments = false;
- Client.Session.create(device, storage, 'anonbot.wl', process.env.ANON_PASSWORD)
- .then(function(session) {
- Client.Upload.album(session, photos)
- .then(function(payload) {
- console.log("Uploaded new response!");
- Client.Media.configureAlbum(session, payload, caption, disabledComments)
- })
- })
- }
- else {
- Client.Session.create(device, storage, 'anonbot.wl', process.env.ANON_PASSWORD)
- .then(function(session) {
- Client.Upload.photo(session, './submission.jpeg')
- .then(function(upload) {
- console.log("uploading...");
- return Client.Media.configurePhoto(session, upload.params.uploadId, caption);
- })
- .then(function(medium) {
- console.log("photo uploaded at " + medium.params.webLink);
- })
- });
- }
- log(caption, ip);
- }
- function postComment(id, comment) {
- Client.Session.create(device, storage, 'anonbot.wl', process.env.ANON_PASSWORD)
- .then(function(session) {
- console.log("posted comment " + comment);
- return Client.Comment.create(session, ''+id, comment);
- })
- }
- function postReponse(url, comment, ip) {
- Client.Session.create(device, storage, 'anonbot.wl', process.env.ANON_PASSWORD)
- .then(function(session) {
- return Client.Media.getByUrl(session, url)
- .then(function(data) {
- getWhichColor().then(function(color) {
- createResponse(comment, data._params.caption, ip, color);
- })
- })
- })
- }
- function delPost(id) {
- Client.Session.create(device, storage, 'anonbot.wl', process.env.ANON_PASSWORD)
- .then(function(session) {
- return Client.Media.delete(session, ''+id);
- })
- }
- function log(caption, ip, color) {
- var now = new Date();
- // set to eastern time
- now.setTime(now.getTime()+now.getTimezoneOffset()*60*1000);
- var estDate = new Date(now.getTime() + -240*60*1000);
- let formattedDate = date.format(estDate, 'YYYY/MM/DD HH:mm:ss');
- logs('Anonbot Logs').create({
- "Time": formattedDate,
- "Post": caption,
- "IP Hash": ""+sha256(ip)
- }, function(err, record) {
- if (err) { console.error(err); return; }
- console.log("new log created! " + record.getId());
- })
- }
- function getClientIP(req){ // Anonbot logs IPs for safety & moderation
- var ip = (req.headers['x-forwarded-for'] || req.connection.remoteAddress).split(',');
- return ip[0];
- }
- function determineIfBanned(address) {
- var banned = false;
- return new Promise(function(resolve, reject) {
- blacklist('Blacklist').select({
- view: "Grid view"
- }).eachPage(function page(records, fetchNextPage) {
- records.forEach(function(record) {
- if (record.get('IP Hash') === ""+sha256(address)) {
- console.log("A banned user tried to access the site!");
- banned = true;
- }
- })
- fetchNextPage();
- }, function done(err) {
- if (err) reject(err);
- resolve(banned);
- })
- })
- }
- function getWhichColor() {
- return new Promise(function(resolve, reject) {
- Client.Session.create(device, storage, 'anonbot.wl', process.env.ANON_PASSWORD)
- .then(function(session) {
- session.getAccount()
- .then(function(account) {
- if (account.params.mediaCount % 2 === 0) resolve("gray");
- else resolve("red");
- })
- })
- })
- }
- function getShortcode(url) {
- var parts = url.split('/');
- return parts[4];
- }
- app.use('/public', express.static('public'));
- app.use(bodyParser.urlencoded({ extended: false }));
- app.use(bodyParser.json());
- app.post("/submission", function(req, res) {
- console.log("received submission " + req.body.anon);
- if (req.body.anon === "") return res.redirect('/');
- getWhichColor().then(function(color) {
- if (color === "red") createSubmission(req.body.anon, '#b20000', getClientIP(req), false, "", "gray");
- else createSubmission(req.body.anon, '#404040', getClientIP(req), false, "", "red");
- })
- //createSubmission(req.body.anon, '#404040', getClientIP(req), false);
- return res.redirect('/submitted');
- });
- app.post("/postcomment", function(req, res) {
- var commentString = req.body.comment.split('::');
- var comment = commentString[0];
- var commentType = commentString[1];
- console.log("received comment " + comment + " type " + commentType + " on " + req.body.url);
- var shortcode = getShortcode(req.body.url);
- Client.Session.create(device, storage, 'anonbot.wl', process.env.ANON_PASSWORD)
- .then(function(session) {
- return Client.Media.getByUrl(session, ''+req.body.url)
- .then(function(data) {
- if (data._params.user.username === "anonbot.wl") {
- if (commentType === "comm") postComment(urlSegmentToInstagramId(shortcode), comment);
- else postReponse(req.body.url, comment, getClientIP(req));
- return res.redirect('/commented');
- } else {
- console.log("comment not posted: post is not an Anonbot post");
- return res.redirect('/');
- }
- })
- .catch(function(err) {
- if (err) {
- console.log("commment not posted: url is invalid");
- return res.redirect('/');
- }
- })
- })
- });
- app.post("/delpost", function(req, res) {
- console.log("received deletion request for " + req.body.link);
- if (req.body.key === process.env.MOD_KEY) {
- var shortcode = getShortcode(req.body.url);
- delPost(urlSegmentToInstagramId(shortcode));
- console.log("deletion successful");
- return res.redirect(req.body.url);
- } else {
- console.log("request denied: incorrect mod key");
- return res.redirect('/');
- }
- });
- app.post("/modpost", function(req, res) {
- console.log("received mod post request " + req.body.mod);
- if (req.body.key === process.env.MOD_KEY) {
- createSubmission(req.body.mod, '#e59d0b', false); // prev. #b20000
- return res.redirect('/submitted');
- } else {
- console.log("request denied: incorrect mod key");
- return res.redirect('/');
- }
- })
- app.post("/banip", function(req, res) {
- console.log("received ban request for IP " + req.body.ip);
- if (req. body.key === process.env.MOD_KEY) {
- blacklist('Blacklist').create({
- "IP": req.body.ip,
- "Reason": req.body.reason
- }, function(err) {
- if (err) { console.error(err); return; }
- console.log("banned " + req.body.ip);
- res.redirect('/banned');
- })
- } else {
- console.log("request denied: incorrect mod key");
- return res.redirect('/');
- }
- })
- app.get("/", function(request, response) {
- determineIfBanned(getClientIP(request)).then(function(banned) {
- if (banned) return response.sendFile(__dirname + '/views/banned.html');
- else return response.sendFile(__dirname + '/views/index.html');
- })
- });
- app.get("/submitted", function(request, response) {
- response.sendFile(__dirname + '/views/submitted.html');
- });
- app.get("/delete", function(request, response) {
- response.sendFile(__dirname + '/views/delete.html');
- });
- app.get("/modpost", function(request, response) {
- response.sendFile(__dirname + '/views/modpost.html');
- });
- app.get("/respond", function(request, response) {
- determineIfBanned(getClientIP(request)).then(function(banned) {
- if (banned) return response.sendFile(__dirname + '/views/banned.html');
- else return response.sendFile(__dirname + '/views/respond.html');
- })
- });
- app.get("/commented", function(request, response) {
- response.sendFile(__dirname + '/views/commented.html');
- });
- app.get("/ban", function(request, response) {
- response.sendFile(__dirname + '/views/ban.html');
- })
- app.get("/banned", function(request, response) {
- response.sendFile(__dirname + '/views/banned.html');
- });
- http.listen(3000);
|