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',
|
domain: 'https://your_homeserver.com',
|
||||||
user: 'your_user',
|
user: 'your_user',
|
||||||
password: 'your_password',
|
password: 'your_password',
|
||||||
|
domains: [ 'your_homeserver.com' ],
|
||||||
|
mimetypes: [ 'image/png', 'image/jpeg' ]
|
||||||
},
|
},
|
||||||
fediverse: {
|
fediverse: {
|
||||||
domain: 'https://your_federation.com',
|
domain: 'https://your_federation.com',
|
||||||
|
@ -22,4 +24,4 @@ module.exports = {
|
||||||
userAgent: 'Mozilla/4.0 (compatible; Beep Boop)',
|
userAgent: 'Mozilla/4.0 (compatible; Beep Boop)',
|
||||||
domains: [ 'invidio.us', 'www.invidio.us', 'youtube.com', 'www.youtube.com' ]
|
domains: [ 'invidio.us', 'www.invidio.us', 'youtube.com', 'www.youtube.com' ]
|
||||||
}
|
}
|
||||||
};
|
};
|
4
main.js
4
main.js
|
@ -127,6 +127,10 @@ let CreateClient = (token, user_id) => {
|
||||||
if (command === 'invidious') {
|
if (command === 'invidious') {
|
||||||
registrar.invidious.runQuery(matrixClient, room, userInput, registrar);
|
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",
|
"axios": "^0.19.2",
|
||||||
"file-system": "^2.2.2",
|
"file-system": "^2.2.2",
|
||||||
"matrix-js-sdk": "^2.4.6",
|
"matrix-js-sdk": "^2.4.6",
|
||||||
"jsdom": "^16.2.2"
|
"jsdom": "^16.2.2",
|
||||||
|
"form-data": "^3.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint": "^5.16.0",
|
"eslint": "^5.16.0",
|
||||||
|
|
|
@ -19,4 +19,5 @@ module.exports = {
|
||||||
archive: require('./commands/archive.js'),
|
archive: require('./commands/archive.js'),
|
||||||
nitter: require('./commands/nitter.js'),
|
nitter: require('./commands/nitter.js'),
|
||||||
invidious: require('./commands/invidious.js'),
|
invidious: require('./commands/invidious.js'),
|
||||||
|
media: require('./commands/media.js')
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue