Skylar-Tech / node-red-contrib-matrix-chat

Matrix chat server support for Node-RED
GNU General Public License v3.0
31 stars 10 forks source link

Support for messages in threads #104

Open justyns opened 7 months ago

justyns commented 7 months ago

Hello! Thanks for working on this package, it's been super useful for me. One feature request I have is for native support of matrix threads.

As an example, this is something I hacked together with a function node:

let matrixClient = global.get("matrixClient['@botid']"),
    matrixOnline = global.get("matrixClientOnline['@botid']");

// TODO: For some reason, I can't normally access matrixEvent.decrypted
let parsedEvent = JSON.parse(JSON.stringify(msg.event));

// Determine if the message is part of an existing thread
msg.isPartOfThread = parsedEvent.decrypted?.content['m.relates_to']?.['rel_type'] === 'm.thread';

// Determine the thread ID if part of a thread
const threadEventId = msg.isPartOfThread ? parsedEvent.decrypted?.content['m.relates_to']?.event_id : null;

// Initialize the content object
const content = {
    "body": msg.payload,
    "formatted_body": msg.payload,
    "format": "org.matrix.custom.html",
    "msgtype": "m.text"
};

// Handle thread replies
if (msg.isPartOfThread) {
    // Use the original thread's event_id for the reply
    const threadEventId2 = parsedEvent.decrypted.content['m.relates_to'].event_id;
    content["m.relates_to"] = {
        "rel_type": "m.thread",
        "event_id": threadEventId2,
        "is_falling_back": false,
    };
} else {
    // Start a new thread if not part of an existing thread
    content["m.relates_to"] = {
        "rel_type": "m.thread",
        "event_id": msg.eventId,
        "is_falling_back": false,
    };
}

// Send the message
matrixClient.sendEvent(msg.topic, "m.room.message", content, "").then((res) => {
    msg.response = res;
    return [null, msg];
}).catch((error) => {
    msg.error = error;
    return [null, msg];
});

It basically always either starts a new thread or replies to an existing thread if one already exists. The input is always from a receive node. When I don't need threads, I just use the normal matrix send node.

I'm not actually sure what the best way to handle this would be, but maybe simply a config checkbox on the send node that is something like "reply in thread"?

skylord123 commented 7 months ago

One feature request I have is for native support of matrix threads.

Ah yeah it looks like the MSC for thread support was finally approved. Last time I looked into this it was still a proposal/in beta and wasn't official. Looks like we can now implement it.

I'm not actually sure what the best way to handle this would be, but maybe simply a config checkbox on the send node that is something like "reply in thread"?

Yeah that is most likely the best way to handle this. I'll probably make it so you can either set it directly to true/false inside the node config or point it to a property on a msg so that you have options to do it either way. For the next release I have already updated a few existing nodes so that their options can be determined by a property on the msg so it makes sense to do it for this as well. That way you don't need two send message nodes (one for sending a regular message and one for replying).

It may be good to update the receive node to set an is_reply boolean property that tells us if the message we just received is a reply to another message. You can determine this based on the full message object but if we set it to a property directly we could default to reading this property on the send message node to determine if we should reply back to the reply. Not sure on this though, I will have to do some testing to see if it makes sense. I would also have to make it backwards compatible so that we don't just default to replying to replies for people's existing flows. Maybe if the node already exists we default to setting it to false and if the node was newly created we default to it replying to replies.

skylord123 commented 7 months ago

@justyns I just pushed up some changes to the dev branch with this feature. Want to try it out and give me feedback? Thanks.