mx-puppet-bridge
Advanced tools
Comparing version 0.0.11 to 0.0.12
@@ -46,3 +46,25 @@ "use strict"; | ||
switch (fnCollect ? "link" : arg) { | ||
case "relink": | ||
case "link": { | ||
let puppetId = -1; | ||
let parseParam = param; | ||
if (fnCollect) { | ||
puppetId = fnCollect.puppetId; | ||
parseParam = event.content.body; | ||
} | ||
else if (arg === "relink") { | ||
const [__, pidStr, p] = param.split(/([^ ]*)(?: (.*))?/); | ||
const pid = parseInt(pidStr, 10); | ||
// now we need to check if that pid is ours | ||
const d = yield this.provisioner.get(pid); | ||
if (!d || d.puppetMxid !== sender) { | ||
yield this.sendMessage(roomId, "ERROR: PuppetID not found"); | ||
break; | ||
} | ||
puppetId = pid; | ||
parseParam = p; | ||
} | ||
if (!parseParam) { | ||
parseParam = ""; | ||
} | ||
if (!this.provisioner.canCreate(sender)) { | ||
@@ -58,7 +80,7 @@ yield this.sendMessage(roomId, "ERROR: You don't have permission to use this bridge"); | ||
if (fnCollect) { | ||
retData = yield fnCollect(event.content.body); | ||
retData = yield fnCollect.fn(event.content.body); | ||
this.fnCollectListeners.delete(sender); | ||
} | ||
else { | ||
retData = yield this.bridge.hooks.getDataFromStr(param); | ||
retData = yield this.bridge.hooks.getDataFromStr(parseParam); | ||
} | ||
@@ -68,3 +90,6 @@ if (!retData.success) { | ||
yield this.sendMessage(roomId, `${retData.error}`); | ||
this.fnCollectListeners.set(sender, retData.fn); | ||
this.fnCollectListeners.set(sender, { | ||
fn: retData.fn, | ||
puppetId: -1, | ||
}); | ||
break; | ||
@@ -75,4 +100,12 @@ } | ||
} | ||
const puppetId = yield this.provisioner.new(sender, retData.data, retData.userId); | ||
yield this.sendMessage(roomId, `Created new link with ID ${puppetId}`); | ||
if (puppetId === -1) { | ||
// we need to create a new link | ||
puppetId = yield this.provisioner.new(sender, retData.data, retData.userId); | ||
yield this.sendMessage(roomId, `Created new link with ID ${puppetId}`); | ||
} | ||
else { | ||
// we need to update an existing link | ||
yield this.provisioner.update(sender, puppetId, retData.data, retData.userId); | ||
yield this.sendMessage(roomId, `Updated link with ID ${puppetId}`); | ||
} | ||
break; | ||
@@ -206,3 +239,3 @@ } | ||
yield this.sendMessage(roomId, "Available commands: help, list, link, " + | ||
"unlink, setmatrixtoken, listusers, listchannels"); | ||
"unlink, relink, setmatrixtoken, listusers, listchannels"); | ||
} | ||
@@ -227,4 +260,4 @@ }); | ||
} | ||
const sendStr = `[Status] ${desc.desc}: ${msg}`; | ||
const sendStrHtml = `[Status] ${desc.html}: ${md.render(msg)}`; | ||
const sendStr = `[Status] ${puppetId}: ${desc.desc}: ${msg}`; | ||
const sendStrHtml = `[Status] ${puppetId}: ${desc.html}: ${md.render(msg)}`; | ||
yield this.sendMessage(info.statusRoom, sendStr, sendStrHtml); | ||
@@ -231,0 +264,0 @@ }); |
@@ -27,2 +27,3 @@ import { PuppetBridge } from "./puppetbridge"; | ||
new(puppetMxid: string, data: any, userId?: string): Promise<number>; | ||
update(puppetMxid: string, puppetId: number, data: any, userId?: string): Promise<void>; | ||
delete(puppetMxid: string, puppetId: number): Promise<void>; | ||
@@ -29,0 +30,0 @@ getDesc(puppetMxid: string, puppetId: number): Promise<IProvisionerDesc | null>; |
@@ -116,2 +116,19 @@ "use strict"; | ||
} | ||
update(puppetMxid, puppetId, data, userId) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (!this.canCreate(puppetMxid)) { | ||
return; | ||
} | ||
const d = yield this.get(puppetId); | ||
if (!d || d.puppetMxid !== puppetMxid) { | ||
return; | ||
} | ||
yield this.setData(puppetId, data); | ||
if (userId) { | ||
yield this.setUserId(puppetId, userId); | ||
} | ||
log.info(`Updating puppet with id ${puppetId}`); | ||
this.bridge.emit("puppetNew", puppetId, data); | ||
}); | ||
} | ||
delete(puppetMxid, puppetId) { | ||
@@ -118,0 +135,0 @@ return __awaiter(this, void 0, void 0, function* () { |
@@ -129,2 +129,3 @@ /// <reference types="node" /> | ||
setUserTyping(params: IReceiveParams, typing: boolean): Promise<void>; | ||
sendReadReceipt(params: IReceiveParams): Promise<void>; | ||
getMxidForUser(user: IRemoteUser, doublePuppetCheck?: boolean): Promise<string>; | ||
@@ -131,0 +132,0 @@ getMxidForChan(chan: IRemoteChan): Promise<string>; |
@@ -242,6 +242,11 @@ "use strict"; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
log.verbose(`Setting user presence for userId=${user.userId} to ${presence}`); | ||
const client = yield this.userSync.getClient(user); | ||
const userId = yield client.getUserId(); | ||
this.presenceHandler.set(userId, presence); | ||
if (this.features.presence && this.config.presence.enabled) { | ||
log.verbose(`Setting user presence for userId=${user.userId} to ${presence}`); | ||
const client = yield this.userSync.maybeGetClient(user); | ||
if (!client) { | ||
return; | ||
} | ||
const userId = yield client.getUserId(); | ||
this.presenceHandler.set(userId, presence); | ||
} | ||
}); | ||
@@ -251,6 +256,11 @@ } | ||
return __awaiter(this, void 0, void 0, function* () { | ||
log.verbose(`Setting user status for userId=${user.userId} to ${status}`); | ||
const client = yield this.userSync.getClient(user); | ||
const userId = yield client.getUserId(); | ||
this.presenceHandler.setStatus(userId, status); | ||
if (this.features.presence && this.config.presence.enabled) { | ||
log.verbose(`Setting user status for userId=${user.userId} to ${status}`); | ||
const client = yield this.userSync.maybeGetClient(user); | ||
if (!client) { | ||
return; | ||
} | ||
const userId = yield client.getUserId(); | ||
this.presenceHandler.setStatus(userId, status); | ||
} | ||
}); | ||
@@ -268,2 +278,15 @@ } | ||
} | ||
sendReadReceipt(params) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
log.verbose(`Got request to send read indicators for userId=${params.user.userId} in roomId=${params.chan.roomId}`); | ||
const ret = yield this.maybePrepareSend(params); | ||
if (!ret || !params.eventId) { | ||
return; | ||
} | ||
const origEvents = yield this.eventStore.getMatrix(params.chan.puppetId, params.eventId); | ||
for (const origEvent of origEvents) { | ||
yield ret.client.sendReadReceipt(ret.mxid, origEvent); | ||
} | ||
}); | ||
} | ||
getMxidForUser(user, doublePuppetCheck = true) { | ||
@@ -552,3 +575,6 @@ return __awaiter(this, void 0, void 0, function* () { | ||
} | ||
const client = yield this.userSync.getClient(params.user); | ||
const client = yield this.userSync.maybeGetClient(params.user); | ||
if (!client) { | ||
return null; | ||
} | ||
return { client, mxid }; | ||
@@ -555,0 +581,0 @@ }); |
@@ -18,2 +18,3 @@ /// <reference types="node" /> | ||
getClientFromTokenCallback(token: ITokenResponse | null): Promise<MatrixClient | null>; | ||
maybeGetClient(data: IRemoteUser): Promise<MatrixClient | null>; | ||
getClient(data: IRemoteUser): Promise<MatrixClient>; | ||
@@ -20,0 +21,0 @@ getPartsFromMxid(mxid: string): IRemoteUser | null; |
@@ -40,2 +40,23 @@ "use strict"; | ||
} | ||
maybeGetClient(data) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
log.silly("Maybe getting the client"); | ||
const puppetData = yield this.bridge.provisioner.get(data.puppetId); | ||
if (puppetData && puppetData.userId === data.userId) { | ||
const token = yield this.bridge.provisioner.getToken(data.puppetId); | ||
const puppetClient = yield this.getClientFromTokenCallback(token); | ||
if (puppetClient) { | ||
return puppetClient; | ||
} | ||
} | ||
const user = yield this.userStore.get(data.puppetId, data.userId); | ||
if (!user) { | ||
return null; | ||
} | ||
const intent = this.bridge.AS.getIntentForSuffix(`${data.puppetId}_${util_1.Util.str2mxid(data.userId)}`); | ||
yield intent.ensureRegistered(); | ||
const client = intent.underlyingClient; | ||
return client; | ||
}); | ||
} | ||
getClient(data) { | ||
@@ -42,0 +63,0 @@ return __awaiter(this, void 0, void 0, function* () { |
{ | ||
"name": "mx-puppet-bridge", | ||
"version": "0.0.11", | ||
"version": "0.0.12", | ||
"description": "Matrix Puppeting Bridge library", | ||
@@ -5,0 +5,0 @@ "repository": { |
@@ -12,1 +12,3 @@ [Support Chat](https://matrix.to/#/#mx-puppet-bridge:sorunome.de) [![donate](https://liberapay.com/assets/widgets/donate.svg)](https://liberapay.com/Sorunome/donate) | ||
- [Discord](https://github.com/matrix-discord/mx-puppet-discord) | ||
- [Instagram](https://github.com/Sorunome/mx-puppet-instagram) | ||
- [Twitter](https://github.com/Sorunome/mx-puppet-twitter) |
@@ -15,5 +15,10 @@ import { PuppetBridge, RetDataFn, IRetData } from "./puppetbridge"; | ||
interface IFnCollect { | ||
fn: RetDataFn; | ||
puppetId: number; | ||
} | ||
export class BotProvisioner { | ||
private provisioner: Provisioner; | ||
private fnCollectListeners: TimedCache<string, RetDataFn>; | ||
private fnCollectListeners: TimedCache<string, IFnCollect>; | ||
constructor( | ||
@@ -46,3 +51,24 @@ private bridge: PuppetBridge, | ||
switch (fnCollect ? "link" : arg) { | ||
case "relink": | ||
case "link": { | ||
let puppetId = -1; | ||
let parseParam = param; | ||
if (fnCollect) { | ||
puppetId = fnCollect.puppetId; | ||
parseParam = event.content.body; | ||
} else if (arg === "relink") { | ||
const [__, pidStr, p] = param.split(/([^ ]*)(?: (.*))?/); | ||
const pid = parseInt(pidStr, 10); | ||
// now we need to check if that pid is ours | ||
const d = await this.provisioner.get(pid); | ||
if (!d || d.puppetMxid !== sender) { | ||
await this.sendMessage(roomId, "ERROR: PuppetID not found"); | ||
break; | ||
} | ||
puppetId = pid; | ||
parseParam = p; | ||
} | ||
if (!parseParam) { | ||
parseParam = ""; | ||
} | ||
if (!this.provisioner.canCreate(sender)) { | ||
@@ -58,6 +84,6 @@ await this.sendMessage(roomId, "ERROR: You don't have permission to use this bridge"); | ||
if (fnCollect) { | ||
retData = await fnCollect(event.content.body); | ||
retData = await fnCollect.fn(event.content.body); | ||
this.fnCollectListeners.delete(sender); | ||
} else { | ||
retData = await this.bridge.hooks.getDataFromStr(param); | ||
retData = await this.bridge.hooks.getDataFromStr(parseParam); | ||
} | ||
@@ -67,3 +93,6 @@ if (!retData.success) { | ||
await this.sendMessage(roomId, `${retData.error}`); | ||
this.fnCollectListeners.set(sender, retData.fn); | ||
this.fnCollectListeners.set(sender, { | ||
fn: retData.fn, | ||
puppetId: -1, | ||
}); | ||
break; | ||
@@ -74,4 +103,11 @@ } | ||
} | ||
const puppetId = await this.provisioner.new(sender, retData.data, retData.userId); | ||
await this.sendMessage(roomId, `Created new link with ID ${puppetId}`); | ||
if (puppetId === -1) { | ||
// we need to create a new link | ||
puppetId = await this.provisioner.new(sender, retData.data, retData.userId); | ||
await this.sendMessage(roomId, `Created new link with ID ${puppetId}`); | ||
} else { | ||
// we need to update an existing link | ||
await this.provisioner.update(sender, puppetId, retData.data, retData.userId); | ||
await this.sendMessage(roomId, `Updated link with ID ${puppetId}`); | ||
} | ||
break; | ||
@@ -205,3 +241,3 @@ } | ||
await this.sendMessage(roomId, "Available commands: help, list, link, " + | ||
"unlink, setmatrixtoken, listusers, listchannels"); | ||
"unlink, relink, setmatrixtoken, listusers, listchannels"); | ||
} | ||
@@ -214,3 +250,3 @@ } | ||
const info = await this.bridge.puppetStore.getOrCreateMxidInfo(mxid); | ||
if (!info.statusRoom){ | ||
if (!info.statusRoom) { | ||
// no status room present, nothing to do | ||
@@ -226,4 +262,4 @@ log.info("No status room found"); | ||
} | ||
const sendStr = `[Status] ${desc.desc}: ${msg}`; | ||
const sendStrHtml = `[Status] ${desc.html}: ${md.render(msg)}`; | ||
const sendStr = `[Status] ${puppetId}: ${desc.desc}: ${msg}`; | ||
const sendStrHtml = `[Status] ${puppetId}: ${desc.html}: ${md.render(msg)}`; | ||
await this.sendMessage(info.statusRoom, sendStr, sendStrHtml); | ||
@@ -230,0 +266,0 @@ } |
@@ -112,2 +112,18 @@ import { PuppetBridge } from "./puppetbridge"; | ||
public async update(puppetMxid: string, puppetId: number, data: any, userId?: string) { | ||
if (!this.canCreate(puppetMxid)) { | ||
return; | ||
} | ||
const d = await this.get(puppetId); | ||
if (!d || d.puppetMxid !== puppetMxid) { | ||
return; | ||
} | ||
await this.setData(puppetId, data); | ||
if (userId) { | ||
await this.setUserId(puppetId, userId); | ||
} | ||
log.info(`Updating puppet with id ${puppetId}`); | ||
this.bridge.emit("puppetNew", puppetId, data); | ||
} | ||
public async delete(puppetMxid: string, puppetId: number) { | ||
@@ -114,0 +130,0 @@ log.info(`Deleting puppet with id ${puppetId}`); |
@@ -365,13 +365,23 @@ import * as fs from "fs"; | ||
public async setUserPresence(user: IRemoteUser, presence: MatrixPresence) { | ||
log.verbose(`Setting user presence for userId=${user.userId} to ${presence}`); | ||
const client = await this.userSync.getClient(user); | ||
const userId = await client.getUserId(); | ||
this.presenceHandler.set(userId, presence); | ||
if (this.features.presence && this.config.presence.enabled) { | ||
log.verbose(`Setting user presence for userId=${user.userId} to ${presence}`); | ||
const client = await this.userSync.maybeGetClient(user); | ||
if (!client) { | ||
return; | ||
} | ||
const userId = await client.getUserId(); | ||
this.presenceHandler.set(userId, presence); | ||
} | ||
} | ||
public async setUserStatus(user: IRemoteUser, status: string) { | ||
log.verbose(`Setting user status for userId=${user.userId} to ${status}`); | ||
const client = await this.userSync.getClient(user); | ||
const userId = await client.getUserId(); | ||
this.presenceHandler.setStatus(userId, status); | ||
if (this.features.presence && this.config.presence.enabled) { | ||
log.verbose(`Setting user status for userId=${user.userId} to ${status}`); | ||
const client = await this.userSync.maybeGetClient(user); | ||
if (!client) { | ||
return; | ||
} | ||
const userId = await client.getUserId(); | ||
this.presenceHandler.setStatus(userId, status); | ||
} | ||
} | ||
@@ -388,2 +398,14 @@ | ||
public async sendReadReceipt(params: IReceiveParams) { | ||
log.verbose(`Got request to send read indicators for userId=${params.user.userId} in roomId=${params.chan.roomId}`); | ||
const ret = await this.maybePrepareSend(params); | ||
if (!ret || !params.eventId) { | ||
return; | ||
} | ||
const origEvents = await this.eventStore.getMatrix(params.chan.puppetId, params.eventId); | ||
for (const origEvent of origEvents) { | ||
await ret.client.sendReadReceipt(ret.mxid, origEvent); | ||
} | ||
} | ||
public async getMxidForUser(user: IRemoteUser, doublePuppetCheck: boolean = true): Promise<string> { | ||
@@ -652,3 +674,6 @@ if (doublePuppetCheck) { | ||
} | ||
const client = await this.userSync.getClient(params.user); | ||
const client = await this.userSync.maybeGetClient(params.user); | ||
if (!client) { | ||
return null; | ||
} | ||
return { client, mxid }; | ||
@@ -655,0 +680,0 @@ } |
@@ -47,2 +47,22 @@ import { PuppetBridge } from "./puppetbridge"; | ||
public async maybeGetClient(data: IRemoteUser): Promise<MatrixClient | null> { | ||
log.silly("Maybe getting the client"); | ||
const puppetData = await this.bridge.provisioner.get(data.puppetId); | ||
if (puppetData && puppetData.userId === data.userId) { | ||
const token = await this.bridge.provisioner.getToken(data.puppetId); | ||
const puppetClient = await this.getClientFromTokenCallback(token); | ||
if (puppetClient) { | ||
return puppetClient; | ||
} | ||
} | ||
const user = await this.userStore.get(data.puppetId, data.userId); | ||
if (!user) { | ||
return null; | ||
} | ||
const intent = this.bridge.AS.getIntentForSuffix(`${data.puppetId}_${Util.str2mxid(data.userId)}`); | ||
await intent.ensureRegistered(); | ||
const client = intent.underlyingClient; | ||
return client; | ||
} | ||
public async getClient(data: IRemoteUser): Promise<MatrixClient> { | ||
@@ -49,0 +69,0 @@ // first we look if we can puppet this user to the matrix side |
298832
7885
14