can publish pictures
This commit is contained in:
parent
7ab74aa7b1
commit
68f1059e7d
34
README.md
34
README.md
@ -1,2 +1,36 @@
|
|||||||
# Mastodon Multi account posting
|
# Mastodon Multi account posting
|
||||||
|
|
||||||
Permet de poster sur mastodon selon le compte que l'on souhaite
|
Permet de poster sur mastodon selon le compte que l'on souhaite
|
||||||
|
|
||||||
|
# curl auth
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST \
|
||||||
|
-F 'client_name=Test Application' \
|
||||||
|
-F 'redirect_uris=urn:ietf:wg:oauth:2.0:oob' \
|
||||||
|
-F 'scopes=read write follow push' \
|
||||||
|
-F 'website=https://mastodon.cipherbliss.com' \
|
||||||
|
https://mastodon.cipherbliss.com/api/v1/apps
|
||||||
|
|
||||||
|
curl -X POST \
|
||||||
|
-F 'client_id=PuZ8Eg_2WWutiK4Cafs7mx3FIL4_SugQPSFgdC7Qq1I' \
|
||||||
|
-F 'client_secret=GXlQI_DQAgLR7TgdVXifmpq7zITa7ye4V7Wj2gzaxiU' \
|
||||||
|
-F 'redirect_uri=urn:ietf:wg:oauth:2.0:oob' \
|
||||||
|
-F 'grant_type=client_credentials' \
|
||||||
|
https://mastodon.cipherbliss.com/oauth/token
|
||||||
|
|
||||||
|
|
||||||
|
curl \
|
||||||
|
-H 'Authorization: Bearer 7Z8EJZCWvzyybl_L5BCRP3PGDTtH4Jd_-jDUQEYmYDc' \
|
||||||
|
https://mastodon.cipherbliss.com/api/v1/apps/verify_credentials
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
{"id":"1054","name":"Test Application","website":"https://mastodon.cipherbliss.com","redirect_uri":"urn:ietf:wg:oauth:
|
||||||
|
2.0:oob","client_id":"SgVTsRjDTbORQnk2iYXbZ8csIFsKJXR8Aahz_h1y44A","client_secret":"
|
||||||
|
IeeLHtBsyR97i8wGoL6TP2O0Go7KixfBZ350ks71hIQ","vapid_key":"
|
||||||
|
BEceqzZx0tYD_rY4PyN8Py9cmhsrcSlF7a3Hr26PqL1FPZuWQSN-29-EyWSx0A3mdR22ETgUkHOYIuEtDUcQvMw="}
|
||||||
|
|
||||||
|
{"access_token":"7Z8EJZCWvzyybl_L5BCRP3PGDTtH4Jd_-jDUQEYmYDc","token_type":"Bearer","scope":"read","created_at":1657227222}
|
||||||
|
|
||||||
|
{"name":"greeting bot","website":null,"vapid_key":"BEceqzZx0tYD_rY4PyN8Py9cmhsrcSlF7a3Hr26PqL1FPZuWQSN-29-EyWSx0A3mdR22ETgUkHOYIuEtDUcQvMw="}
|
BIN
assets/not_published/DSC02080.JPG
Executable file
BIN
assets/not_published/DSC02080.JPG
Executable file
Binary file not shown.
After Width: | Height: | Size: 38 KiB |
BIN
assets/not_published/colline.JPG
Executable file
BIN
assets/not_published/colline.JPG
Executable file
Binary file not shown.
After Width: | Height: | Size: 99 KiB |
BIN
assets/not_published/musee_histoire_naturelle_bruxelles (1).JPG
Executable file
BIN
assets/not_published/musee_histoire_naturelle_bruxelles (1).JPG
Executable file
Binary file not shown.
After Width: | Height: | Size: 135 KiB |
BIN
assets/not_published/musee_histoire_naturelle_bruxelles (3).JPG
Executable file
BIN
assets/not_published/musee_histoire_naturelle_bruxelles (3).JPG
Executable file
Binary file not shown.
After Width: | Height: | Size: 130 KiB |
BIN
assets/test.png
Normal file
BIN
assets/test.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 81 KiB |
Binary file not shown.
@ -9,12 +9,15 @@
|
|||||||
"@databases/sqlite": "^4.0.0",
|
"@databases/sqlite": "^4.0.0",
|
||||||
"cookie-parser": "~1.4.4",
|
"cookie-parser": "~1.4.4",
|
||||||
"debug": "~2.6.9",
|
"debug": "~2.6.9",
|
||||||
|
"dotenv": "^16.0.1",
|
||||||
"express": "~4.16.1",
|
"express": "~4.16.1",
|
||||||
"http-errors": "~1.6.3",
|
"http-errors": "~1.6.3",
|
||||||
"jade": "~1.11.0",
|
"jade": "~1.11.0",
|
||||||
"mastodon": "^1.2.2",
|
"mastodon": "^1.2.2",
|
||||||
"morgan": "~1.9.1",
|
"morgan": "~1.9.1",
|
||||||
|
"node-fs": "^0.1.7",
|
||||||
"nodemon": "^2.0.19",
|
"nodemon": "^2.0.19",
|
||||||
|
"oauth": "^0.9.15",
|
||||||
"sqlite3": "^5.0.8"
|
"sqlite3": "^5.0.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
137
routes/index.js
137
routes/index.js
@ -1,6 +1,14 @@
|
|||||||
var express = require('express');
|
var express = require('express');
|
||||||
var router = express.Router();
|
var router = express.Router();
|
||||||
var sqlite3 = require('sqlite3');
|
var sqlite3 = require('sqlite3');
|
||||||
|
var Masto = require('mastodon')
|
||||||
|
|
||||||
|
var M = new Masto({
|
||||||
|
access_token: '...',
|
||||||
|
timeout_ms: 60 * 1000, // optional HTTP request timeout to apply to all requests.
|
||||||
|
api_url: 'https://gay.crime.team/api/v1/', // optional, defaults to https://mastodon.social/api/v1/
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
const database_masto = "mastodon_multi_accounts.db"
|
const database_masto = "mastodon_multi_accounts.db"
|
||||||
/* GET home page. */
|
/* GET home page. */
|
||||||
@ -16,6 +24,8 @@ router.get('/publish', function (req, res, next) {
|
|||||||
|
|
||||||
const connect = require('@databases/sqlite');
|
const connect = require('@databases/sqlite');
|
||||||
const {sql} = require('@databases/sqlite');
|
const {sql} = require('@databases/sqlite');
|
||||||
|
const {runOnChangeOnly} = require("nodemon/lib/config/defaults");
|
||||||
|
const fs = require("fs");
|
||||||
|
|
||||||
const db = connect(database_masto);
|
const db = connect(database_masto);
|
||||||
|
|
||||||
@ -56,7 +66,8 @@ function createTables(newdb) {
|
|||||||
|
|
||||||
function getAllPosts(db) {
|
function getAllPosts(db) {
|
||||||
return db.query(sql`SELECT *
|
return db.query(sql`SELECT *
|
||||||
FROM posts_scheduled;`)
|
FROM posts_scheduled
|
||||||
|
ORDER BY action_id ASC LIMIT 15;`)
|
||||||
}
|
}
|
||||||
|
|
||||||
router.get('/init-db', function (req, res, next) {
|
router.get('/init-db', function (req, res, next) {
|
||||||
@ -80,7 +91,7 @@ router.get('/list', function (req, res, next) {
|
|||||||
|
|
||||||
getAllPosts(db).then(
|
getAllPosts(db).then(
|
||||||
(results) => {
|
(results) => {
|
||||||
console.log( "liste de posts " ,results)
|
console.log("liste de posts ", results)
|
||||||
res.render('database', {posts_list: results});
|
res.render('database', {posts_list: results});
|
||||||
},
|
},
|
||||||
(err) => console.error(err),
|
(err) => console.error(err),
|
||||||
@ -94,7 +105,7 @@ router.get('/add-example', function (req, res, next) {
|
|||||||
async function prepare() {
|
async function prepare() {
|
||||||
await db.query(sql`
|
await db.query(sql`
|
||||||
insert into posts_scheduled
|
insert into posts_scheduled
|
||||||
values (NULL, "modominem", "un message d'example", "image.jpg",NULL)
|
values (NULL, "modominem", "un message d'example", "image.jpg", NULL)
|
||||||
;
|
;
|
||||||
`).then(resp => {
|
`).then(resp => {
|
||||||
console.log(resp)
|
console.log(resp)
|
||||||
@ -112,33 +123,131 @@ router.get('/add-example', function (req, res, next) {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
require('dotenv').config();
|
||||||
|
|
||||||
// publier le message en db dans la file
|
// publier le message en db dans la file
|
||||||
router.get('/publish-last-entry', function (req, res, next) {
|
router.get('/publish-last-entry', function (req, res, next) {
|
||||||
res.render('index', {title: 'Express'});
|
|
||||||
getAllPosts(db).then(
|
var OAuth2 = require('oauth').OAuth2;
|
||||||
(results) => {
|
|
||||||
console.log( "publier le premier message de la file d'attente" ,results[0])
|
// console.log('process.env' , process.env)
|
||||||
res.render('publish', {posts_list: results[0]});
|
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),
|
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
|
// répartir les publications dans le temps
|
||||||
// TODO
|
// TODO
|
||||||
const limit_posts_per_day=10
|
const limit_posts_per_day = 10
|
||||||
|
|
||||||
router.get('/dispatch-publication-in-time', function (req, res, next) {
|
router.get('/dispatch-publication-in-time', function (req, res, next) {
|
||||||
res.render('index', {title: 'Express'});
|
|
||||||
getAllPosts(db).then(
|
getAllPosts(db).then(
|
||||||
(results) => {
|
(results) => {
|
||||||
console.log( "répartir" ,results[0])
|
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
|
// on compte les posts et quel intervalle de temps mettre entre chaque pour tenir le rythme de X posts par jour
|
||||||
|
|
||||||
res.render('index', {posts_list: results[0]});
|
res.render('index', {p: results[0]});
|
||||||
},
|
},
|
||||||
(err) => console.error(err),
|
(err) => console.error(err),
|
||||||
);
|
);
|
||||||
|
@ -3,6 +3,7 @@ extends layout
|
|||||||
block content
|
block content
|
||||||
h1 Publié
|
h1 Publié
|
||||||
div.post-message
|
div.post-message
|
||||||
|
strong.author= p.datetime
|
||||||
strong.author= p.post_username
|
strong.author= p.post_username
|
||||||
div.content= p.content
|
div.content= p.content
|
||||||
img(src=p.medias)
|
img(src=p.medias)
|
15
yarn.lock
15
yarn.lock
@ -541,6 +541,11 @@ detect-libc@^2.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.1.tgz#e1897aa88fa6ad197862937fbc0441ef352ee0cd"
|
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.1.tgz#e1897aa88fa6ad197862937fbc0441ef352ee0cd"
|
||||||
integrity sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==
|
integrity sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==
|
||||||
|
|
||||||
|
dotenv@^16.0.1:
|
||||||
|
version "16.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.1.tgz#8f8f9d94876c35dac989876a5d3a82a267fdce1d"
|
||||||
|
integrity sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ==
|
||||||
|
|
||||||
ecc-jsbn@~0.1.1:
|
ecc-jsbn@~0.1.1:
|
||||||
version "0.1.2"
|
version "0.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
|
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
|
||||||
@ -1249,6 +1254,11 @@ node-fetch@^2.6.7:
|
|||||||
dependencies:
|
dependencies:
|
||||||
whatwg-url "^5.0.0"
|
whatwg-url "^5.0.0"
|
||||||
|
|
||||||
|
node-fs@^0.1.7:
|
||||||
|
version "0.1.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/node-fs/-/node-fs-0.1.7.tgz#32323cccb46c9fbf0fc11812d45021cc31d325bb"
|
||||||
|
integrity sha512-XqDBlmUKgDGe76+lZ/0sRBF3XW2vVcK07+ZPvdpUTK8jrvtPahUd0aBqJ9+ZjB01ANjZLuvK3O/eoMVmz62rpA==
|
||||||
|
|
||||||
node-gyp@8.x:
|
node-gyp@8.x:
|
||||||
version "8.4.1"
|
version "8.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-8.4.1.tgz#3d49308fc31f768180957d6b5746845fbd429937"
|
resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-8.4.1.tgz#3d49308fc31f768180957d6b5746845fbd429937"
|
||||||
@ -1325,6 +1335,11 @@ oauth-sign@~0.9.0:
|
|||||||
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
|
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
|
||||||
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
|
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
|
||||||
|
|
||||||
|
oauth@^0.9.15:
|
||||||
|
version "0.9.15"
|
||||||
|
resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1"
|
||||||
|
integrity sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==
|
||||||
|
|
||||||
object-assign@^4.1.1:
|
object-assign@^4.1.1:
|
||||||
version "4.1.1"
|
version "4.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||||
|
Loading…
Reference in New Issue
Block a user