feat(fedi): allow media uploads
This commit is contained in:
parent
402594f109
commit
2d714943e7
5 changed files with 71 additions and 2 deletions
61
commands/media.js
Normal file
61
commands/media.js
Normal file
|
@ -0,0 +1,61 @@
|
|||
const qs = require('qs');
|
||||
const axios = require('axios');
|
||||
const FormData = require('form-data');
|
||||
|
||||
const mediaDownload = async (url, types) => {
|
||||
const media = await axios({ method: 'GET', url, responseType: 'arraybuffer' });
|
||||
if (media.statusText !== 'OK' || !types.includes(media.headers['content-type'])) throw media;
|
||||
return {
|
||||
data: media.data,
|
||||
//filename: //TODO,
|
||||
mimetype: media.headers['content-type']
|
||||
};
|
||||
};
|
||||
|
||||
const mediaUpload = async ({ domain, token }, { data, mimetype }) => {
|
||||
const form = new FormData();
|
||||
form.append('file', data, {
|
||||
filename: 'upload',
|
||||
contentType: mimetype,
|
||||
});
|
||||
const upload = await axios({
|
||||
method: 'POST',
|
||||
url: `${domain}/api/v1/media`,
|
||||
headers: form.getHeaders({ Authorization: `Bearer ${token}` }),
|
||||
data: form,
|
||||
});
|
||||
if(upload.statusText !== 'OK') throw upload;
|
||||
return upload.data.id;
|
||||
};
|
||||
|
||||
const run = async (matrixClient, { roomId }, mediaURL, content, registrar) => {
|
||||
const fediverse = registrar.config.fediverse;
|
||||
const media = await mediaDownload(mediaURL, registrar.config.matrix.mimetypes);
|
||||
const mediaId = await mediaUpload(fediverse, media);
|
||||
const response = await axios({
|
||||
method: 'POST',
|
||||
url: `${fediverse.domain}/api/v1/statuses`,
|
||||
headers: { Authorization: `Bearer ${fediverse.token}`, 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
data : qs.stringify({
|
||||
status: content,
|
||||
content_type: `text/markdown`,
|
||||
media_ids: [ mediaId ],
|
||||
}, { arrayFormat: 'brackets' })
|
||||
});
|
||||
return matrixClient.sendHtmlNotice(roomId, '', `<a href="${response.data.url}">${response.data.id}</a>`);
|
||||
}
|
||||
|
||||
exports.runQuery = async (client, room, userInput, registrar) => {
|
||||
try {
|
||||
let chunks = userInput.trim().split(' ');
|
||||
if(chunks.length < 2) throw '';
|
||||
const url = new URL(chunks[0]);
|
||||
chunks.shift();
|
||||
if(url.protocol !== 'https:') throw '';
|
||||
if(!registrar.config.matrix.domains.includes(url.hostname)) throw '';
|
||||
if(!/^\/_matrix\/media\/r0\/download\/[^/]+\/[^/]+\/?$/.test(url.pathname)) throw '';
|
||||
return await run(client, room, url.toString(), chunks.join(' '), registrar);
|
||||
} catch(e) {
|
||||
return client.sendHtmlNotice(room.roomId, 'Sad!', `<strong>Sad!</strong>`).catch(()=>{});
|
||||
}
|
||||
};
|
|
@ -3,6 +3,8 @@ module.exports = {
|
|||
domain: 'https://your_homeserver.com',
|
||||
user: 'your_user',
|
||||
password: 'your_password',
|
||||
domains: [ 'your_homeserver.com' ],
|
||||
mimetypes: [ 'image/png', 'image/jpeg' ]
|
||||
},
|
||||
fediverse: {
|
||||
domain: 'https://your_federation.com',
|
||||
|
|
4
main.js
4
main.js
|
@ -127,6 +127,10 @@ let CreateClient = (token, user_id) => {
|
|||
if (command === 'invidious') {
|
||||
registrar.invidious.runQuery(matrixClient, room, userInput, registrar);
|
||||
}
|
||||
|
||||
if (command === 'media') {
|
||||
registrar.media.runQuery(matrixClient, room, userInput, registrar);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -21,7 +21,8 @@
|
|||
"axios": "^0.19.2",
|
||||
"file-system": "^2.2.2",
|
||||
"matrix-js-sdk": "^2.4.6",
|
||||
"jsdom": "^16.2.2"
|
||||
"jsdom": "^16.2.2",
|
||||
"form-data": "^3.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^5.16.0",
|
||||
|
|
|
@ -19,4 +19,5 @@ module.exports = {
|
|||
archive: require('./commands/archive.js'),
|
||||
nitter: require('./commands/nitter.js'),
|
||||
invidious: require('./commands/invidious.js'),
|
||||
media: require('./commands/media.js')
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue