Initial reply implementation
This commit is contained in:
parent
f09e898503
commit
5510dc059b
10
README.md
10
README.md
|
@ -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
|
||||||
|
|
|
@ -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> => {
|
||||||
|
|
75
src/vk.ts
75
src/vk.ts
|
@ -37,7 +37,7 @@ export class VkPuppet {
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
public async getSendParams(puppetId: number, peerId: number, senderId: number, eventId?: string | undefined):
|
public async getSendParams(puppetId: number, peerId: number, senderId: number, eventId?: string | undefined):
|
||||||
Promise<IReceiveParams> {
|
Promise<IReceiveParams> {
|
||||||
// we will use this function internally to create the send parameters
|
// we will use this function internally to create the send parameters
|
||||||
// needed to send a message, a file, reactions, ... to matrix
|
// needed to send a message, a file, reactions, ... to matrix
|
||||||
log.info(`Creating send params for ${peerId}...`);
|
log.info(`Creating send params for ${peerId}...`);
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue