Initial reply implementation

This commit is contained in:
Inex Code 2020-11-03 16:38:06 +00:00
parent f09e898503
commit 5510dc059b
3 changed files with 66 additions and 25 deletions

View file

@ -18,10 +18,10 @@ Register that one with synapse and start the bridge with `npm run start`.
- [ ] Image content - [ ] Image content
- [ ] Audio/Video content - [ ] Audio/Video content
- [ ] Other files - [ ] Other files
- [ ] Replies - [x] Replies
- [ ] Typing notifs - [ ] Typing notifs - not possible yet
- [ ] Presence - [ ] Presence - not possible yet
- [ ] Read notifications - [ ] Read notifications - not possible yet
- [ ] Message edits - [ ] Message edits
- [ ] Message redacts - [ ] Message redacts
- VK -> Matrix - VK -> Matrix
@ -30,7 +30,7 @@ Register that one with synapse and start the bridge with `npm run start`.
- [ ] Audio/Video content - [ ] Audio/Video content
- [ ] Stickers - [ ] Stickers
- [ ] Other files - [ ] Other files
- [ ] Presence - [ ] Presence - not effective to track
- [x] Typing notifs - [x] Typing notifs
- [x] User profiles - [x] User profiles
- [ ] Read notifications - [ ] Read notifications

View file

@ -82,12 +82,12 @@ async function run() {
// create our own protocol class // create our own protocol class
const vk = new VkPuppet(puppet); const vk = new VkPuppet(puppet);
// required: listen to when a new puppet is created
puppet.on("puppetNew", vk.newPuppet.bind(vk)); puppet.on("puppetNew", vk.newPuppet.bind(vk));
// required: listen to when a puppet is deleted
puppet.on("puppetDelete", vk.deletePuppet.bind(vk)); puppet.on("puppetDelete", vk.deletePuppet.bind(vk));
// required: listen to when a message is received from matrix
puppet.on("message", vk.handleMatrixMessage.bind(vk)); puppet.on("message", vk.handleMatrixMessage.bind(vk));
puppet.on("reply", vk.handleMatrixReply.bind(vk));
puppet.setCreateRoomHook(vk.createRoom.bind(vk)); puppet.setCreateRoomHook(vk.createRoom.bind(vk));
// required: get description hook // required: get description hook
puppet.setGetDescHook(async (puppetId: number, data: any): Promise<string> => { puppet.setGetDescHook(async (puppetId: number, data: any): Promise<string> => {

View file

@ -159,6 +159,10 @@ export class VkPuppet {
delete this.puppets[puppetId]; // and finally delete our local copy delete this.puppets[puppetId]; // and finally delete our local copy
} }
//////////////////////////
// Matrix -> VK section //
//////////////////////////
public async handleMatrixMessage(room: IRemoteRoom, data: IMessageEvent, event: any) { public async handleMatrixMessage(room: IRemoteRoom, data: IMessageEvent, event: any) {
// this is called every time we receive a message from matrix and need to // this is called every time we receive a message from matrix and need to
// forward it to the remote protocol. // forward it to the remote protocol.
@ -169,7 +173,6 @@ export class VkPuppet {
return; return;
} }
// usually you'd send it here to the remote protocol via the client object // usually you'd send it here to the remote protocol via the client object
const dedupeKey = `${room.puppetId};${room.roomId}`;
try { try {
const response = await p.client.api.messages.send({ const response = await p.client.api.messages.send({
peer_id: Number(room.roomId), peer_id: Number(room.roomId),
@ -180,7 +183,29 @@ export class VkPuppet {
} catch (err) { } catch (err) {
log.error("Error sending to vk", err.error || err.body || err); log.error("Error sending to vk", err.error || err.body || err);
} }
}
public async handleMatrixReply(
room: IRemoteRoom,
eventId: string,
data: IMessageEvent,
event: any,
) {
const p = this.puppets[room.puppetId];
if (!p) {
return;
}
try {
const response = await p.client.api.messages.send({
peer_id: Number(room.roomId),
message: data.body,
random_id: new Date().getTime(),
reply_to: Number(eventId),
});
await this.puppet.eventSync.insert(room, data.eventId!, response.toString());
} catch (err) {
log.error("Error sending to vk", err.error || err.body || err);
}
} }
public async createRoom(room: IRemoteRoom): Promise<IRemoteRoom | null> { public async createRoom(room: IRemoteRoom): Promise<IRemoteRoom | null> {
@ -193,19 +218,9 @@ export class VkPuppet {
return await this.getRemoteRoom(room.puppetId, Number(room.roomId)); return await this.getRemoteRoom(room.puppetId, Number(room.roomId));
} }
public async getDmRoomId(user: IRemoteUser): Promise<string | null> { //////////////////////////
// this is called whenever someone invites a ghost on the matrix side // VK -> Matrix section //
// from the user ID we need to return the room ID of the DM room, or null if none is present //////////////////////////
// first we check if the puppet exists
const p = this.puppets[user.puppetId];
if (!p) {
return null;
}
// now we just return the userId of the ghost
return user.userId;
}
public async handleVkMessage(puppetId: number, context: MessageContext) { public async handleVkMessage(puppetId: number, context: MessageContext) {
const p = this.puppets[puppetId]; const p = this.puppets[puppetId];
@ -213,14 +228,40 @@ export class VkPuppet {
return; return;
} }
log.info("Received new message!", context); log.info("Received new message!", context);
if (context.isOutbox) {
return; // Deduping
}
const params = await this.getSendParams(puppetId, context.peerId, context.senderId, context.id.toString()); const params = await this.getSendParams(puppetId, context.peerId, context.senderId, context.id.toString());
if (context.hasText && !context.isOutbox) { if (context.hasText) {
const opts = { const opts: IMessageEvent = {
body: context.text || "Attachment", body: context.text || "Attachment",
}; };
if (context.hasReplyMessage) {
if (this.puppet.eventSync.getMatrix(params.room, context.replyMessage!.id.toString())) {
// We got referenced message in room, using matrix reply
await this.puppet.sendReply(params, context.replyMessage!.id.toString(), opts);
} else {
// Using a fallback
}
}
await this.puppet.sendMessage(params, opts); await this.puppet.sendMessage(params, opts);
} }
} }
////////////////
// Formatters //
////////////////
public async prependReply(puppetId: number, body: string, reply: string, userid: string) {
const user = await this.getRemoteUser(puppetId, Number(userid));
const replySplitted = reply.split("\n");
let formatted: string = `> <${user.name}>\n`;
replySplitted.forEach((element) => {
formatted += `> ${element}`;
});
formatted += `\n\n${body}`;
return formatted;
}
} }