var express = require('express'); var router = express.Router(); var sqlite3 = require('sqlite3'); var Masto = require('mastodon'); // import accounts_to_select from '../src/configs.js' const accounts_to_select = [ { label: "tykayn", value: "tykayn", src : "https://mastodon.cipherbliss.com/system/accounts/avatars/000/000/001/original/6388tykayn.gif" }, { label: "modominem", value: "modominem", src : "https://mastodon.cipherbliss.com/system/accounts/avatars/000/152/770/original/c62bb94381dc1f75.png" }, { label: "qzine", value: "qzine", src :"https://mastodon.cipherbliss.com/system/accounts/avatars/000/003/032/original/2bb8b90d21d3fdca.jpg" }, { label: "curator", value: "curator", src : "https://mastodon.cipherbliss.com/system/accounts/avatars/000/002/974/original/8e48623291e49afe.jpg" }, { label: "kurator", value: "kurator", src : "https://mastodon.cipherbliss.com/system/accounts/avatars/000/162/067/original/bb374d2c6a361b6d.jpg" }, { label: "voix du nucléaire", value: "voixdunucleaire", src : "https://mastodon.cipherbliss.com/system/accounts/avatars/000/107/055/original/7dac1a35f1423b94.jpg" }, { label: "The greatest Meme", value: "meme", src : "https://mastodon.cipherbliss.com/system/accounts/avatars/000/002/978/original/b2f2e817572c93e9.png" }, { label: "cil de gometz", value: "cil_gometz", src : "https://mastodon.cipherbliss.com/system/accounts/avatars/000/107/055/original/7dac1a35f1423b94.jpg" }, ] // change this object to fit your multi accounts const default_times = ['08:02:00', '08:42:00', '09:10:00', '09:15:00', '10:22:00', '12:22:00'] const database_masto = "mastodon_multi_accounts.db" /* GET home page. */ let schedule_time = ''; router.get('/', function (req, res, next) { if (!req.body.schedule_time) { schedule_time = default_times[Math.floor(Math.random() * default_times.length)]; } res.render('index', {accounts_to_select, reqBody: req.body, schedule_time}); }); // publier un message avec un certain compte router.get('/publish', function (req, res, next) { res.render('index', {title: 'Express'}); }); const connect = require('@databases/sqlite'); const {sql} = require('@databases/sqlite'); const {runOnChangeOnly} = require("nodemon/lib/config/defaults"); const fs = require("fs"); const db = connect(database_masto); function createDatabase() { var newdb = new sqlite3.Database(database_masto, sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE, (err) => { createTables(newdb); }) } function createTables(newdb) { async function prepare() { await db.query(sql` create table posts_scheduled ( action_id integer constraint posts_scheduled_pk primary key autoincrement, post_username varchar not null, content varchar not null, medias varchar, datetime datetime ); create unique index posts_scheduled_action_id_uindex on posts_scheduled (action_id); insert into posts_scheduled values (NULL, "modominem", "un message d'example", NULL); `); console.log('requête de création faite') } const prepared = prepare(); } // ajouter un message à la file d'attente avec un certain compte router.post('/add-to-queue', function (req, res, next) { // get account // get content* // add to sql DB // insert into posts_scheduled // values (NULL, "modominem", "un message d'example", NULL); var db = new sqlite3.Database(database_masto, sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE, (err) => { } ) db.serialize(() => { db.run('INSERT INTO posts_scheduled VALUES(?,?,?,?,?)', [null, req.body.author, req.body.message, req.body.fichier, null], function (err) { if (err) { return console.log(err.message); res.render('index', {message: 'erreur ' + err.message}); } console.log("nouveau post ajouté", req.body.author, req.body.message); res.render('index', {message: 'message ajouté OK'}); }); }); }); function getAllPosts(db) { return db.query(sql`SELECT * FROM posts_scheduled ORDER BY action_id DESC LIMIT 15;`) } router.get('/init-db', function (req, res, next) { var db = new sqlite3.Database(database_masto, sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE, (err) => { console.log('got to create db') createDatabase() } ) res.render('created_db', {}); }); router.get('/list', function (req, res, next) { // let posts_list = [{ // action_id: 1, // post_username: "modominem", // content: "demo post list", // medias: "media file name from assets folder", // date_schedule: "2022-07-07 " // }] getAllPosts(db).then( (results) => { console.log("liste de posts ", results) res.render('database', {posts_list: results}); }, (err) => console.error(err), ); }); router.get('/add-example', function (req, res, next) { // let db = connect(database_masto); async function prepare() { await db.query(sql` insert into posts_scheduled values (NULL, "modominem", "un message d'example", "image.jpg", NULL) ; `).then(resp => { console.log(resp) let posts_list = [] res.redirect('/list') }, err => { console.log(err) }); } const prepared = prepare(); } ); require('dotenv').config(); // publier le message en db dans la file router.get('/publish-last-entry', function (req, res, next) { var OAuth2 = require('oauth').OAuth2; // console.log('process.env' , process.env) var oauth = new OAuth2(process.env.APP_ID, process.env.SECRET, process.env.INSTANCE_MASTODON, null, '/oauth/token'); var url = oauth.getAuthorizeUrl({ redirect_uri: 'urn:ietf:wg:oauth:2.0:oob', response_type: 'code', scope: 'read write follow' }); console.log('url ', url) let status = "#mastoart of @tykayn" let visibility = "unlisted" // public, unlisted, private, direct. let media_filename = "colline.JPG" let file_path = "assets/not_published/" + media_filename let accessToken = process.env.TOKEN let sensitive = false; let scheduled_at = "2022-07-07T21:36:29.100Z"; let account_id = "2974"; // curator bliss let language = "fr"; let enable_post = false; // Get the user to open up the url in their browser and get the code // oauth.getOAuthAccessToken('code from the authorization page that user should paste into your app', // {grant_type: 'authorization_code', redirect_uri: 'urn:ietf:wg:oauth:2.0:oob'}, // function (err, accessToken, refreshToken, res) { // // console.log(err, accessToken, refreshToken , res); const masto = new Masto({ access_token: accessToken, api_url: process.env.INSTANCE_MASTODON + '/api/v1/', }); if (enable_post) { masto.post('media', {file: fs.createReadStream(file_path)}).then(resp => { id = resp.data.id; // doc https://docs.joinmastodon.org/methods/statuses/ console.log('media id ', resp.data.id) console.log(resp.data) masto.post('statuses', { status: status, media_ids: [id], account_id, visibility, language, sensitive }).then(resp => { // succès, marquer le post comme fait en BDD console.log(resp) var oldPath = file_path var newPath = 'assets/published/' + media_filename fs.rename(oldPath, newPath, function (err) { if (err) throw err console.log('Successfully renamed - AKA moved!') }) }, err => { console.error(err) }) }) } // // if (!file) { // return masto.post('statuses', { // status, // visibility, // }); // } // const response = await masto.post('media', { // file: { // value: file, // options: { // filename: 'assets/test.png', // contentType: 'image/png', // }, // }, // }); // // return masto.post('statuses', { // status, // visibility, // media_ids: [response.data.id], // }); // }) res.render('index', {}); // // getAllPosts(db).then( // (results) => { // console.log( "publier le premier message de la file d'attente" ,results[0]) // res.render('publish', {p: results[0]}); // }, // (err) => console.error(err), // ); }); // répartir les publications dans le temps // TODO const limit_posts_per_day = 10 router.get('/dispatch-publication-in-time', function (req, res, next) { getAllPosts(db).then( (results) => { console.log("répartir", results[0]) // on compte les posts et quel intervalle de temps mettre entre chaque pour tenir le rythme de X posts par jour res.render('index', {p: results[0]}); }, (err) => console.error(err), ); }); router.post('/direct-post', function (req, res, next) { if (process.env['TOKEN_' + req.body.author]) { let visibility = 'public'; let language = 'fr'; let sensitive = false; let accessToken = process.env['TOKEN_' + req.body.author] console.log('accessToken', accessToken) const masto = new Masto({ access_token: accessToken, api_url: process.env.INSTANCE_MASTODON + '/api/v1/', }); let params = { status: req.body.message, visibility, language, sensitive } if (req.body.cw) { params['spoiler_text'] = req.body.cw } if (req.body.scheduled_at && req.body.scheduled_at_bool) { let dateschedule = new Date(req.body.scheduled_at) params['scheduled_at'] = dateschedule.toISOString() } console.log(req.body) if (!req.body.fichier) { masto.post('statuses', params).then(rep => { console.log('rep', rep) }, err => { console.error(err) }) res.render('index', {bodyReq: req.body}) } // if (req.body.fichier) { // // masto.post('statuses', params).then(rep => { // console.log('rep', rep) // }, err => { // console.error(err) // }) // res.render('index', {bodyReq: req.body}) // } } else { console.error('pas de token pour ' + req.body.author) } }) module.exports = router;