release 0.1.0
This commit is contained in:
parent
4b3ba6b516
commit
35b4509238
18 changed files with 399 additions and 1 deletions
|
@ -1,2 +1,2 @@
|
||||||
# spellbinder
|
# plerama
|
||||||
A Matrix(https://matrix.org/docs/spec/) client for the fediverse.
|
A Matrix(https://matrix.org/docs/spec/) client for the fediverse.
|
||||||
|
|
18
commands/boo.js
Normal file
18
commands/boo.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
const axios = require('axios');
|
||||||
|
|
||||||
|
exports.runQuery = function (matrixClient, room, userInput, registrar) {
|
||||||
|
axios({
|
||||||
|
method: 'POST',
|
||||||
|
url: `${registrar.config.fediverse}/api/v1/statuses/${userInput}/unfavourite`,
|
||||||
|
headers: { Authorization: `Bearer ${registrar.config.fediverseToken}` },
|
||||||
|
}).then((response) => {
|
||||||
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
|
'',
|
||||||
|
`You have boo'd: <a href="${response.data.url}">${response.data.account.acct}</a>
|
||||||
|
<blockquote>${response.data.content}`);
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
|
'', `${e}`);
|
||||||
|
});
|
||||||
|
};
|
18
commands/clap.js
Normal file
18
commands/clap.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
const axios = require('axios');
|
||||||
|
|
||||||
|
exports.runQuery = function (matrixClient, room, userInput, registrar) {
|
||||||
|
axios({
|
||||||
|
method: 'POST',
|
||||||
|
url: `${registrar.config.fediverse}/api/v1/statuses/${userInput}/favourite`,
|
||||||
|
headers: { Authorization: `Bearer ${registrar.config.fediverseToken}` },
|
||||||
|
}).then((response) => {
|
||||||
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
|
'',
|
||||||
|
`You have clapped: <a href="${response.data.url}">${response.data.account.acct}</a>:
|
||||||
|
<blockquote>${response.data.content}`);
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
|
'', `${e}`);
|
||||||
|
});
|
||||||
|
};
|
18
commands/copy.js
Normal file
18
commands/copy.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
const axios = require('axios');
|
||||||
|
|
||||||
|
exports.runQuery = function (matrixClient, room, userInput, registrar) {
|
||||||
|
axios({
|
||||||
|
method: 'POST',
|
||||||
|
url: `${registrar.config.fediverse}/api/v1/statuses/${userInput}/reblog`,
|
||||||
|
headers: { Authorization: `Bearer ${registrar.config.fediverseToken}` },
|
||||||
|
}).then((response) => {
|
||||||
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
|
'',
|
||||||
|
`You have repeated:
|
||||||
|
<blockquote>${response.data.content}`);
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
|
'', `${e}`);
|
||||||
|
});
|
||||||
|
};
|
35
commands/flood.js
Normal file
35
commands/flood.js
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
const axios = require('axios');
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
exports.runQuery = function (matrixClient, room, registrar) {
|
||||||
|
setInterval(() => {
|
||||||
|
axios({
|
||||||
|
method: 'GET',
|
||||||
|
url: `${registrar.config.fediverse}/api/v1/timelines/home`,
|
||||||
|
headers: { Authorization: `Bearer ${registrar.config.fediverseToken}` },
|
||||||
|
}).then((events) => {
|
||||||
|
const event = fs.readFileSync('timeline.json', 'utf8');
|
||||||
|
fs.writeFileSync('timeline.json', events.data[0].created_at, 'utf8');
|
||||||
|
if (event !== events.data[0].created_at) {
|
||||||
|
if (events.data[0].reblog === null) {
|
||||||
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
|
'',
|
||||||
|
`<b><a href="${registrar.config.fediverse}/notice/${events.data[0].id}">${events.data[0].account.acct}</a>
|
||||||
|
<blockquote><i>${events.data[0].content}<br>
|
||||||
|
(id: ${events.data[0].id}</a>)
|
||||||
|
</blockquote><br>`);
|
||||||
|
} else {
|
||||||
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
|
'',
|
||||||
|
`<b><a href="${registrar.config.fediverse}/${events.data[0].account.id}">
|
||||||
|
${events.data[0].account.acct}</a>
|
||||||
|
<font color="#7886D7">has <a href="${registrar.config.fediverse}/notice/${events.data[0].id}">repeated</a>:
|
||||||
|
<blockquote><a href="${events.data[0].reblog.account.url}">${events.data[0].reblog.account.acct}</a></blockquote>
|
||||||
|
<blockquote>${events.data[0].content}<br>
|
||||||
|
(id: ${events.data[0].id})
|
||||||
|
</blockquote><br>`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 8000);
|
||||||
|
};
|
20
commands/fren.js
Normal file
20
commands/fren.js
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
const axios = require('axios');
|
||||||
|
|
||||||
|
exports.runQuery = function (matrixClient, room, userInput, registrar) {
|
||||||
|
axios.get(`${registrar.config.fediverse}/api/v1/accounts/${userInput}`).then((findUID) => {
|
||||||
|
axios({
|
||||||
|
method: 'POST',
|
||||||
|
url: `${registrar.config.fediverse}/api/v1/accounts/${findUID.data.id}/follow`,
|
||||||
|
headers: { Authorization: `Bearer ${registrar.config.fediverseToken}` },
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
|
'',
|
||||||
|
`Subscribed:
|
||||||
|
<blockquote>${registrar.config.fediverse}}/${response.data.id}`);
|
||||||
|
});
|
||||||
|
}).catch((e) => {
|
||||||
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
|
'', `${e}`);
|
||||||
|
});
|
||||||
|
};
|
15
commands/help.js
Normal file
15
commands/help.js
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
exports.runQuery = function (matrixClient, room) {
|
||||||
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
|
'',
|
||||||
|
'<blockquote><b>+plemara [your message] : post<br>'
|
||||||
|
+ '+fren [user id] : follow<br>'
|
||||||
|
+ '+unfren [user id] : unfollow<br>'
|
||||||
|
+ '+copy [post id] : repeat/repost/retweet<br>'
|
||||||
|
+ '+reply [post id] : reply to post<br>'
|
||||||
|
+ '+clap [post id] : favorite<br>'
|
||||||
|
+ '+boo [post id] : unfavorite</blockquote>'
|
||||||
|
+ '<blockquote><b>channel commands<br>'
|
||||||
|
+ '+flood : turn on timeline<br>'
|
||||||
|
+ '+notify : show notifications</b></blockquote>'
|
||||||
|
+ '<blockquote><b>--- <i>docs by lint</i> ---</b></blockquote>');
|
||||||
|
};
|
51
commands/notify.js
Normal file
51
commands/notify.js
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
const axios = require('axios');
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
exports.runQuery = function (matrixClient, room, registrar) {
|
||||||
|
setInterval(() => {
|
||||||
|
axios({
|
||||||
|
method: 'GET',
|
||||||
|
url: `${registrar.config.fediverse}/api/v1/notifications`,
|
||||||
|
headers: { Authorization: `Bearer ${registrar.config.fediverseToken}` },
|
||||||
|
}).then((notifications) => {
|
||||||
|
const event = fs.readFileSync('notification.json', 'utf8');
|
||||||
|
fs.writeFileSync('notification.json', notifications.data[0].created_at, 'utf8');
|
||||||
|
|
||||||
|
if (event !== notifications.data[0].created_at) {
|
||||||
|
if (notifications.data[0].type === 'follow') {
|
||||||
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
|
'',
|
||||||
|
`<hr><b><a href="${registrar.config.fediverse}/${notifications.data[0].account.id}">
|
||||||
|
${notifications.data[0].account.acct}</a></b>
|
||||||
|
<font color="#03b381"><b>has followed you.</b></font>
|
||||||
|
<br><i>${notifications.data[0].account.note}</i><hr>`);
|
||||||
|
} else if (notifications.data[0].type === 'favourite') {
|
||||||
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
|
'',
|
||||||
|
`<hr><b><a href="${registrar.config.fediverse}/${notifications.data[0].account.id}">
|
||||||
|
${notifications.data[0].account.acct}</a></b>
|
||||||
|
<font color="#03b381"><b>has <a href="${notifications.data[0].status.uri}">favorited</a>
|
||||||
|
your post:</b></font>
|
||||||
|
<br><i><b>${notifications.data[0].status.content}</i></b><hr>`);
|
||||||
|
} else if (notifications.data[0].type === 'mention') {
|
||||||
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
|
'',
|
||||||
|
`<hr><b><a href="${registrar.config.fediverse}/${notifications.data[0].account.id}">
|
||||||
|
${notifications.data[0].account.acct}</a></b>
|
||||||
|
<font color="#03b381"><b>has <a href="${notifications.data[0].status.uri}">mentioned</a>
|
||||||
|
you:</b></font><br>
|
||||||
|
<i><b>${notifications.data[0].status.content}</i></b>
|
||||||
|
<br>[id: ${notifications.data[0].status.id}]</i></b><hr>`);
|
||||||
|
} else if (notifications.data[0].type === 'reblog') {
|
||||||
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
|
'',
|
||||||
|
`<hr><b><a href="${registrar.config.fediverse}/${notifications.data[0].account.id}">
|
||||||
|
${notifications.data[0].account.acct}</a></b>
|
||||||
|
<font color="#03b381"><b>has <a href="${notifications.data[0].status.uri}">repeated</a>
|
||||||
|
your post:</b></font><br>
|
||||||
|
<i><b>${notifications.data[0].status.content}</i></b><hr>`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 8000);
|
||||||
|
};
|
21
commands/plemara.js
Normal file
21
commands/plemara.js
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
const axios = require('axios');
|
||||||
|
|
||||||
|
exports.runQuery = function (matrixClient, room, userInput, registrar) {
|
||||||
|
axios({
|
||||||
|
method: 'POST',
|
||||||
|
url: `${registrar.config.fediverse}/api/v1/statuses`,
|
||||||
|
headers: { Authorization: `Bearer ${registrar.config.fediverseToken}` },
|
||||||
|
data: { status: userInput },
|
||||||
|
}).then((response) => {
|
||||||
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
|
'',
|
||||||
|
`<b>
|
||||||
|
<blockquote><i>${response.data.content}<br>
|
||||||
|
(id: ${response.data.id}</a>)
|
||||||
|
</blockquote><br>`);
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
|
'', `${e}`);
|
||||||
|
});
|
||||||
|
};
|
17
commands/redact.js
Normal file
17
commands/redact.js
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
const axios = require('axios');
|
||||||
|
|
||||||
|
exports.runQuery = function (matrixClient, room, userInput, registrar) {
|
||||||
|
axios({
|
||||||
|
method: 'DELETE',
|
||||||
|
url: `${registrar.config.fediverse}/api/v1/statuses/${userInput}`,
|
||||||
|
headers: { Authorization: `Bearer ${registrar.config.fediverseToken}` },
|
||||||
|
}).then((response) => {
|
||||||
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
|
'',
|
||||||
|
'<blockquote>Redacted.</blockquote');
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
|
'', `${e}`);
|
||||||
|
});
|
||||||
|
};
|
18
commands/reply.js
Normal file
18
commands/reply.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
const axios = require('axios');
|
||||||
|
|
||||||
|
exports.runQuery = function (matrixClient, room, address, flaggedInput, registrar) {
|
||||||
|
axios({
|
||||||
|
method: 'POST',
|
||||||
|
url: `${registrar.config.fediverse}/api/v1/statuses`,
|
||||||
|
headers: { Authorization: `Bearer ${registrar.config.fediverseToken}` },
|
||||||
|
data: { status: flaggedInput, in_reply_to_id: address },
|
||||||
|
}).then((response) => {
|
||||||
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
|
'',
|
||||||
|
`${response.data.content} ${response.data.url}`);
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
|
'', `${e}`);
|
||||||
|
});
|
||||||
|
};
|
20
commands/unfren.js
Normal file
20
commands/unfren.js
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
const axios = require('axios');
|
||||||
|
|
||||||
|
exports.runQuery = function (matrixClient, room, userInput, registrar) {
|
||||||
|
axios.get(`${registrar.config.fediverse}/api/v1/accounts/${userInput}`).then((findUID) => {
|
||||||
|
axios({
|
||||||
|
method: 'POST',
|
||||||
|
url: `${registrar.config.fediverse}/api/v1/accounts/${findUID.data.id}/unfollow`,
|
||||||
|
headers: { Authorization: `Bearer ${registrar.config.fediverseToken}` },
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
|
'',
|
||||||
|
`Unsubscribed:
|
||||||
|
<blockquote>${registrar.config.fediverse}/${response.data.id}`);
|
||||||
|
});
|
||||||
|
}).catch((e) => {
|
||||||
|
matrixClient.sendHtmlNotice(room.roomId,
|
||||||
|
'', `${e}`);
|
||||||
|
});
|
||||||
|
};
|
8
config.js
Normal file
8
config.js
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
module.exports = {
|
||||||
|
matrixServer: 'https://server.com',
|
||||||
|
userId: '@matrixUser:server.com',
|
||||||
|
matrixUser: 'hello',
|
||||||
|
matrixPass: 'password',
|
||||||
|
fediverse: 'https://server.com',
|
||||||
|
fediverseToken: 'access_token',
|
||||||
|
};
|
95
main.js
Normal file
95
main.js
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
const sdk = require('matrix-js-sdk');
|
||||||
|
const axios = require('axios');
|
||||||
|
const registrar = require('./registrar.js');
|
||||||
|
|
||||||
|
const homeServer = 'https://civseed.com/_matrix/client/r0/login';
|
||||||
|
const auth = {
|
||||||
|
type: 'm.login.password',
|
||||||
|
user: registrar.config.matrixUser,
|
||||||
|
password: registrar.config.matrixPass,
|
||||||
|
};
|
||||||
|
|
||||||
|
axios.post(homeServer, auth).then((response) => {
|
||||||
|
CreateClient(response.data.access_token);
|
||||||
|
}).catch((e) => {
|
||||||
|
console.log(e);
|
||||||
|
});
|
||||||
|
|
||||||
|
let CreateClient = (token) => {
|
||||||
|
const matrixClient = sdk.createClient({
|
||||||
|
baseUrl: registrar.config.matrixServer,
|
||||||
|
accessToken: token,
|
||||||
|
userId: registrar.config.userId,
|
||||||
|
timelineSupport: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
matrixClient.on('RoomMember.membership', (event, member) => {
|
||||||
|
if (member.membership === 'invite' && member.userId === registrar.config.userId) {
|
||||||
|
matrixClient.joinRoom(member.roomId).done(() => {
|
||||||
|
console.log('Auto-joined %s', member.roomId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
matrixClient.on('Room.timeline', (event, room, toStartOfTimeline) => {
|
||||||
|
if (toStartOfTimeline) return;
|
||||||
|
if (event.getType() !== 'm.room.message') return;
|
||||||
|
if (event.getSender() === registrar.config.userId) return;
|
||||||
|
if (event.event.unsigned.age > 10000) return;
|
||||||
|
if (event.event.content.body.charAt(0) === '+') {
|
||||||
|
console.log(`Logs: ${event.event.sender} - ${event.event.content.body}`);
|
||||||
|
const args = event.event.content.body.slice(1).trim().split(/ +/g);
|
||||||
|
const command = args.shift().toLowerCase();
|
||||||
|
const userInput = args.join(' ');
|
||||||
|
const flaggedInput = userInput.substr(userInput.indexOf(' ') + 1);
|
||||||
|
const address = args.slice(0, 1).join(' ').replace(/"/g, '');
|
||||||
|
|
||||||
|
if (command === 'boo') {
|
||||||
|
registrar.boo.runQuery(matrixClient, room, userInput, registrar);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command === 'clap') {
|
||||||
|
registrar.clap.runQuery(matrixClient, room, userInput, registrar);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command === 'copy') {
|
||||||
|
registrar.copy.runQuery(matrixClient, room, userInput, registrar);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command === 'flood') {
|
||||||
|
registrar.flood.runQuery(matrixClient, room, registrar);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command === 'fren') {
|
||||||
|
registrar.fren.runQuery(matrixClient, room, registrar);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command === 'help') {
|
||||||
|
registrar.help.runQuery(matrixClient, room);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command === 'plemara') {
|
||||||
|
registrar.plemara.runQuery(matrixClient, room, userInput, registrar);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command === 'notify') {
|
||||||
|
registrar.notify.runQuery(matrixClient, room, registrar);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command === 'redact') {
|
||||||
|
registrar.redact.runQuery(matrixClient, room, userInput, registrar);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command === 'reply') {
|
||||||
|
registrar.reply.runQuery(matrixClient, room, address, flaggedInput, registrar);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command === 'unfren') {
|
||||||
|
registrar.unfren.runQuery(matrixClient, room, userInput, registrar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
matrixClient.startClient();
|
||||||
|
module.exports = matrixClient;
|
||||||
|
};
|
0
notification.json
Normal file
0
notification.json
Normal file
30
package.json
Normal file
30
package.json
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
{
|
||||||
|
"name": "spellbinder",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"description": "A Matrix to Fediverse client",
|
||||||
|
"main": "main.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"run": "node main.js"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/vulet/spellbinder.git"
|
||||||
|
},
|
||||||
|
"author": "vul",
|
||||||
|
"license": "AGPL-3.0-only",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/vulet/spellbinder/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/vulet/spellbinder#readme",
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^0.19.0",
|
||||||
|
"file-system": "^2.2.2",
|
||||||
|
"matrix-js-sdk": "^2.0.1-rc.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"eslint": "^5.16.0",
|
||||||
|
"eslint-config-airbnb-base": "^13.1.0",
|
||||||
|
"eslint-plugin-import": "^2.17.3"
|
||||||
|
}
|
||||||
|
}
|
14
registrar.js
Normal file
14
registrar.js
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
module.exports = {
|
||||||
|
config: require('./config.js'),
|
||||||
|
boo: require('./commands/boo.js'),
|
||||||
|
clap: require('./commands/clap.js'),
|
||||||
|
copy: require('./commands/copy.js'),
|
||||||
|
flood: require('./commands/flood.js'),
|
||||||
|
fren: require('./commands/fren.js'),
|
||||||
|
help: require('./commands/help.js'),
|
||||||
|
plemara: require('./commands/plemara.js'),
|
||||||
|
redact: require('./commands/redact.js'),
|
||||||
|
notify: require('./commands/notify.js'),
|
||||||
|
reply: require('./commands/reply.js'),
|
||||||
|
unfren: require('./commands/unfren.js'),
|
||||||
|
};
|
0
timeline.json
Normal file
0
timeline.json
Normal file
Loading…
Reference in a new issue