diff --git a/src/provisioner.ts b/src/provisioner.ts
index 478e81e6a343ce83b34eed06d0c33862120167b2..6d863ced8a35ac198b1a5609c7659ac331607c05 100644
--- a/src/provisioner.ts
+++ b/src/provisioner.ts
@@ -10,7 +10,7 @@ const PERMISSION_REQUEST_TIMEOUT = 300000; // 5 minutes
 export class Provisioner {
 
     private bridge: Bridge;
-    private pendingRequests: { [channelId: string]: (approved: boolean) => void } = {}; // [channelId]: resolver fn
+    private pendingRequests: Map<string, (approved: boolean) => void> = new Map(); // [channelId]: resolver fn
 
     public SetBridge(bridge: Bridge): void {
         this.bridge = bridge;
@@ -32,38 +32,47 @@ export class Provisioner {
         return this.bridge.getRoomStore().removeEntriesByRemoteRoomId(remoteRoom.getId());
     }
 
-    public async AskBridgePermission(channel: Discord.TextChannel, requestor: string): Promise<void> {
+    public async AskBridgePermission(
+        channel: Discord.TextChannel,
+        requestor: string,
+        timeout: number = PERMISSION_REQUEST_TIMEOUT): Promise<string> {
         const channelId = `${channel.guild.id}/${channel.id}`;
 
         let responded = false;
+        let resolve: (msg: string) => void;
+        let reject: (err: string) => void;
+        const deferP: Promise<string> = new Promise((res, rej) => {resolve = res; reject = rej;});
+
         const approveFn = (approved: boolean, expired = false) => {
             if (responded) {
                 return;
             }
 
             responded = true;
-            delete this.pendingRequests[channelId];
+            this.pendingRequests.delete(channelId);
             if (approved) {
-                return;
+                resolve("Approved");
             } else {
                 if (expired) {
-                    throw new Error("Timed out waiting for a response from the Discord owners");
+                    reject("Timed out waiting for a response from the Discord owners");
                 } else {
-                    throw new Error("The bridge has been declined by the Discord guild");
+                    reject("The bridge has been declined by the Discord guild");
                 }
             }
         };
 
-        this.pendingRequests[channelId] = approveFn;
-        setTimeout(() => approveFn(false, true), PERMISSION_REQUEST_TIMEOUT);
+        this.pendingRequests.set(channelId, approveFn);
+        setTimeout(() => approveFn(false, true), timeout);
 
-        await channel.sendMessage(`${requestor} on matrix would like to bridge this channel. Someone with permission` +
+        await channel.send(`${requestor} on matrix would like to bridge this channel. Someone with permission` +
             " to manage webhooks please reply with !approve or !deny in the next 5 minutes");
+        return await deferP;
+
     }
 
     public HasPendingRequest(channel: Discord.TextChannel): boolean {
         const channelId = `${channel.guild.id}/${channel.id}`;
-        return !!this.pendingRequests[channelId];
+        return this.pendingRequests.has(channelId);
     }
 
     public async MarkApproved(
@@ -72,17 +81,17 @@ export class Provisioner {
         allow: boolean,
     ): Promise<boolean> {
         const channelId = `${channel.guild.id}/${channel.id}`;
-        if (!this.pendingRequests[channelId]) {
+        if (!this.pendingRequests.has(channelId)) {
             return false; // no change, so false
         }
 
         const perms = channel.permissionsFor(member);
-        if (!perms || !perms.hasPermission(Discord.Permissions.FLAGS.MANAGE_WEBHOOKS as Discord.PermissionResolvable)) {
+        if (!perms || !perms.has(Discord.Permissions.FLAGS.MANAGE_WEBHOOKS as Discord.PermissionResolvable)) {
             // Missing permissions, so just reject it
             throw new Error("You do not have permission to manage webhooks in this channel");
         }
 
-        this.pendingRequests[channelId](allow);
+        this.pendingRequests.get(channelId)!(allow);
         return true; // replied, so true
     }
 }