Implement message deletion

This commit is contained in:
emerson 2022-02-02 18:55:09 -05:00
parent 0c805ba3fb
commit 0e1117e796
4 changed files with 55 additions and 5 deletions

View file

@ -29,9 +29,9 @@ Servers and clients implementing this spec MUST also implement the `message-tags
To edit a message, clients send the edited message with a tag of `edit-message`. This tag has a required value of the `msgid` from the original message. The edited message MUST have the same command and first parameter as the original message, unless it is being changed into a multiline message (see below)
Servers MUST support editing `PRIVMSG`, `NOTICE`, `TAGMSG`, and `PART` messages, and MAY support editing any other type of message. Servers SHOULD enforce all checks that they normally would for that specific type of message (line length, color stripping, censoring, etc.) and return appropriate numerics if the message fails a check.
Servers MUST support editing `PRIVMSG`, `NOTICE`, and `TAGMSG` messages, and MAY support editing any other type of message. Servers SHOULD enforce all checks that they normally would for that specific type of message (line length, color stripping, censoring, etc.) and return appropriate numerics if the message fails a check.
Client tags attached to the original message MUST be attached to the edited message to preserve or edit their value. If a client tag in the original message is not included in the edited message,
Client tags attached to the original message MUST be attached to the edited message to preserve or edit their value. If a client tag in the original message is not included in the edited message, clients must consider it removed and no longer a part of the message.
If the server has any persistent history store for the type of message that is edited,
@ -41,7 +41,7 @@ To delete a message, clients send a `DELETEMSG` message to the channel or user t
Clients who receive a `DELETEMSG` with the `draft/delete-message` tag MUST remove all displayed content from the specified `msgid`. If the original message is ephemeral, clients SHOULD remove it entirely; otherwise they MUST replace the content with the deletion reason or a generic substitute.
Servers MUST ensure that the user requesting deletion has sufficient privileges to delete the specified message. Servers MUST remove the content of the original message from all persistent history stores, and MAY replace the content with a generic deletion message if needed.
Servers MUST ensure that the user requesting deletion has sufficient privileges to delete the specified message. Servers MUST remove the content of the original message from all persistent history stores, and MAY replace the content with the deletion reason or a generic deletion message if needed.
## Examples

View file

@ -115,6 +115,9 @@ export class Client {
case 'CAP':
this.doCAP(message);
break;
case 'DELETEMSG':
this.doDELETEMSG(message);
break;
case 'INVITE':
this.doINVITE(message);
break;
@ -251,6 +254,29 @@ export class Client {
}
}
doDELETEMSG(message: IRCMessage) {
if (!this.checkIfRegistered() || !this.checkMinParams(message, 1))
return;
const targetChannel = this.getChannel(message.params[0]);
const eventId = message.tags.get("draft/delete-message");
if (!this.user || !targetChannel || !eventId) return;
if (!this.checkIfInChannel(targetChannel)) return;
const data = {
"reason": (message.params.length === 2) ? message.params[1] : ""
}
const newTxnid = randomUUID();
axios.put(`https://${this.user.homeserver}/_matrix/client/v3/rooms/${targetChannel.roomId}/redact/${eventId}/${newTxnid}?access_token=${this.user.accessToken}`, data).catch(function (error) {
if (error.response) {
console.log(error.response.data);
} else if (error.request) {
console.log(error.request);
} else {
console.log('Error', error.message);
console.log(error.config);
}
})
}
doINVITE(message: IRCMessage) {
if (!this.checkIfRegistered() || !this.checkMinParams(message, 2))
return;
@ -566,8 +592,8 @@ export class Client {
['account', 'account-tag'],
['label', 'labeled-response'],
['msgid', 'message-tags'],
['reflectionircd.chat/delete-message', 'reflectionircd.chat/delete-message'],
['reflectionircd.chat/edit-message', 'reflectionircd.chat/edit-message'],
['draft/delete-message', 'draft/delete-message'],
['draft/edit-message', 'draft/edit-message'],
['time', 'server-time'],
])
const ourTags: Map<string, string> = new Map();

View file

@ -210,6 +210,9 @@ export class IRCUser {
case 'm.room.power_levels':
this.handleMatrixPL(nextEvent, targetChannel);
break;
case 'm.room.redaction':
this.handleMatrixRedaction(nextEvent, targetChannel);
break;
case 'm.room.topic':
this.handleMatrixTopic(nextEvent, targetChannel);
break;
@ -479,6 +482,25 @@ export class IRCUser {
}
}
handleMatrixRedaction(event: any, targetChannel: Channel) {
const sourceUser = this.getOrCreateMatrixUser(event["sender"]);
if (!targetChannel.matrixUsers.has(sourceUser.nick)) {
targetChannel.matrixUsers.set(sourceUser.nick, sourceUser);
const prefix = sourceUser.getMask();
const joinTags = new Map([["account", sourceUser.accountName], ['time', new Date(event["origin_server_ts"]).toISOString()]])
this.sendToAllWithCap('extended-join', prefix, "JOIN", [targetChannel.name, sourceUser.accountName, sourceUser.realname], joinTags);
this.sendToAllWithoutCap('extended-join', prefix, "JOIN", [targetChannel.name], joinTags);
}
const reason = event["content"]?.["reason"] || "";
const tags: Map<string, string> = new Map();
tags.set('draft/delete-message', event["redacts"]);
tags.set('account', sourceUser.accountName);
tags.set('time', new Date(event["origin_server_ts"]).toISOString())
this.clients.forEach((client) => {
client.sendMessage(sourceUser.getMask(), 'DELETEMSG', [targetChannel.name, reason], tags);
});
}
handleMatrixTopic(event: any, targetChannel: Channel) {
const topicText = event["content"]?.["topic"];
if (!topicText)

View file

@ -66,6 +66,8 @@ function encodeTag(value: string): string {
function addToTags(key: string): boolean {
const tagsToPass = [
'batch',
'draft/delete-message',
'draft/edit-message',
'label',
]
return (tagsToPass.includes(key) || key.startsWith('+'));