diff --git a/src/bot.ts b/src/bot.ts
index 30a0455e35a17b7c80ae3c021365b1b60fbe00e2..563cc31b98defdb2741267c453bcf800ad5c2c79 100644
--- a/src/bot.ts
+++ b/src/bot.ts
@@ -687,31 +687,6 @@ export class DiscordBot {
             }
         }
 
-        // Check if there's an ongoing bridge request
-        if ((msg.content === "!approve" || msg.content === "!deny") && this.provisioner.HasPendingRequest(chan)) {
-            try {
-                const isApproved = msg.content === "!approve";
-                const successfullyBridged = await this.provisioner.MarkApproved(chan, msg.member, isApproved);
-                if (successfullyBridged && isApproved) {
-                    await msg.channel.sendMessage("Thanks for your response! The matrix bridge has been approved");
-                } else if (successfullyBridged && !isApproved) {
-                    await msg.channel.sendMessage("Thanks for your response! The matrix bridge has been declined");
-                } else {
-                    await msg.channel.sendMessage("Thanks for your response, however" +
-                        "the time for responses has expired - sorry!");
-                }
-            } catch (err) {
-                if (err.message === "You do not have permission to manage webhooks in this channel") {
-                    await msg.channel.sendMessage(err.message);
-                } else {
-                    log.error("Error processing room approval");
-                    log.error(err);
-                }
-            }
-
-            return; // stop processing - we're approving/declining the bridge request
-        }
-
         // check if it is a command to process by the bot itself
         if (msg.content.startsWith("!matrix")) {
             await this.discordCommandHandler.Process(msg);
diff --git a/src/discordcommandhandler.ts b/src/discordcommandhandler.ts
index 042ec66ca8a5d4604c8add86cc13fbd02c96b4c6..29d8e92f3193506acf7bec2ad2e1727b830c8a21 100644
--- a/src/discordcommandhandler.ts
+++ b/src/discordcommandhandler.ts
@@ -25,7 +25,8 @@ export class DiscordCommandHandler {
     ) { }
 
     public async Process(msg: Discord.Message) {
-        if (!(msg.channel as Discord.TextChannel).guild) {
+        const chan = msg.channel as Discord.TextChannel;
+        if (!chan.guild) {
             await msg.channel.send("**ERROR:** only available for guild channels");
             return;
         }
@@ -33,23 +34,49 @@ export class DiscordCommandHandler {
         const intent = this.bridge.getIntent();
 
         const actions: ICommandActions = {
+            approve: {
+                description: "Approve a pending bridge request",
+                params: [],
+                permission: "MANAGE_WEBHOOKS",
+                run: async () => {
+                    if (await this.discord.Provisioner.MarkApproved(chan, msg.member, true)) {
+                        return "Thanks for your response! The matrix bridge has been approved";
+                    } else {
+                        return "Thanks for your response, however" +
+                            "the time for responses has expired - sorry!";
+                    }
+                },
+            },
             ban: {
                 description: "Bans a user on the matrix side",
                 params: ["name"],
                 permission: "BAN_MEMBERS",
-                run: this.ModerationActionGenerator(msg.channel as Discord.TextChannel, "ban", "Banned"),
+                run: this.ModerationActionGenerator(chan, "ban", "Banned"),
+            },
+            deny: {
+                description: "Deny a pending bridge request",
+                params: [],
+                permission: "MANAGE_WEBHOOKS",
+                run: async () => {
+                    if (await this.discord.Provisioner.MarkApproved(chan, msg.member, false)) {
+                        return "Thanks for your response! The matrix bridge has been declined";
+                    } else {
+                        return "Thanks for your response, however" +
+                            "the time for responses has expired - sorry!";
+                    }
+                },
             },
             kick: {
                 description: "Kicks a user on the matrix side",
                 params: ["name"],
                 permission: "KICK_MEMBERS",
-                run: this.ModerationActionGenerator(msg.channel as Discord.TextChannel, "kick", "Kicked"),
+                run: this.ModerationActionGenerator(chan, "kick", "Kicked"),
             },
             unban: {
                 description: "Unbans a user on the matrix side",
                 params: ["name"],
                 permission: "BAN_MEMBERS",
-                run: this.ModerationActionGenerator(msg.channel as Discord.TextChannel, "unban", "Unbanned"),
+                run: this.ModerationActionGenerator(chan, "unban", "Unbanned"),
             },
         };
 
diff --git a/src/provisioner.ts b/src/provisioner.ts
index 9a871a1750fae09eb2f3592b24d1ba1488ccc55d..c5b53068274d89b3e6644dce70104cfb4bd4e98b 100644
--- a/src/provisioner.ts
+++ b/src/provisioner.ts
@@ -78,7 +78,7 @@ export class Provisioner {
         setTimeout(() => approveFn(false, true), timeout);
 
         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");
+            " to manage webhooks please reply with `!matrix approve` or `!matrix deny` in the next 5 minutes");
         return await deferP;
 
     }
diff --git a/src/util.ts b/src/util.ts
index 80dc32ca65eeae9bd19dd62ae667e1e511c2f815..ff0fe9e7ac4e6edb0cbb45c9f64111cef31c8f68 100644
--- a/src/util.ts
+++ b/src/util.ts
@@ -337,6 +337,8 @@ export class Util {
             return retStr;
         } catch (e) {
             return `**ERROR:** ${e.message}`;
+            log.error("Error processing command");
+            log.error(e);
         }
     }
 
diff --git a/test/test_discordbot.ts b/test/test_discordbot.ts
index 09088f4ceaa59f9ba5af3472b0aa73dfff3efe6e..2eeccfc065c3506ed596029794b071f94654f6af 100644
--- a/test/test_discordbot.ts
+++ b/test/test_discordbot.ts
@@ -133,13 +133,11 @@ describe("DiscordBot", () => {
     });
     describe("OnMessage()", () => {
         let SENT_MESSAGE = false;
-        let MARKED = -1;
         let HANDLE_COMMAND = false;
         let ATTACHMENT = {} as any;
         let MSGTYPE = "";
         function getDiscordBot() {
             SENT_MESSAGE = false;
-            MARKED = -1;
             HANDLE_COMMAND = false;
             ATTACHMENT = {};
             MSGTYPE = "";
@@ -150,13 +148,6 @@ describe("DiscordBot", () => {
                 {},
             );
             discord.bot = { user: { id: "654" } };
-            discord.provisioner = {
-                HasPendingRequest: (chan) => true,
-                MarkApproved: async (chan, member, approved) => {
-                    MARKED = approved ? 1 : 0;
-                    return approved;
-                },
-            };
             discord.GetIntentFromDiscordMember = (_) => {return {
                 sendMessage: async (room, msg) => {
                     SENT_MESSAGE = true;
@@ -195,22 +186,6 @@ describe("DiscordBot", () => {
             await discordBot.OnMessage(msg);
             Chai.assert.equal(SENT_MESSAGE, false);
         });
-        it("accepts !approve", async () => {
-            discordBot = getDiscordBot();
-            const channel = new Discord.TextChannel({} as any, {} as any);
-            const msg = new MockMessage(channel) as any;
-            msg.content = "!approve";
-            await discordBot.OnMessage(msg);
-            Chai.assert.equal(MARKED, 1);
-        });
-        it("denies !deny", async () => {
-            discordBot = getDiscordBot();
-            const channel = new Discord.TextChannel({} as any, {} as any);
-            const msg = new MockMessage(channel) as any;
-            msg.content = "!deny";
-            await discordBot.OnMessage(msg);
-            Chai.assert.equal(MARKED, 0);
-        });
         it("Passes on !matrix commands", async () => {
             discordBot = getDiscordBot();
             const channel = new Discord.TextChannel({} as any, {} as any);
diff --git a/test/test_discordcommandhandler.ts b/test/test_discordcommandhandler.ts
index eb4b725130353a170934152abd2a0a60eca986f6..f5851f4f4e1a5fb5bbdaa1f2632f61475ee3c89f 100644
--- a/test/test_discordcommandhandler.ts
+++ b/test/test_discordcommandhandler.ts
@@ -32,12 +32,14 @@ let USERSKICKED = 0;
 let USERSBANNED = 0;
 let USERSUNBANNED = 0;
 let MESSAGESENT: any = {};
+let MARKED = -1;
 function createCH(opts: any = {}) {
     USERSJOINED = 0;
     USERSKICKED = 0;
     USERSBANNED = 0;
     USERSUNBANNED = 0;
     MESSAGESENT = {};
+    MARKED = -1;
     const bridge = {
         getIntent: () => {
             return {
@@ -58,6 +60,13 @@ function createCH(opts: any = {}) {
     };
     const discord = {
         ChannelSyncroniser: cs,
+        Provisioner: {
+            HasPendingRequest: (chan) => true,
+            MarkApproved: async (chan, member, approved) => {
+                MARKED = approved ? 1 : 0;
+                return approved;
+            },
+        },
     };
     const discordCommandHndlr = (Proxyquire("../src/discordcommandhandler", {
         "./util": {
@@ -159,4 +168,38 @@ describe("DiscordCommandHandler", () => {
         await handler.Process(message);
         expect(USERSUNBANNED).equals(1);
     });
+    it("handles !matrix approve", async () => {
+        const handler: any = createCH();
+        const channel = new MockChannel("123");
+        const guild = new MockGuild("456", [channel]);
+        channel.guild = guild;
+        const member: any = new MockMember("123456", "blah");
+        member.hasPermission = () => {
+            return true;
+        };
+        const message = {
+            channel,
+            content: "!matrix approve",
+            member,
+        };
+        await handler.Process(message);
+        expect(MARKED).equals(1);
+    });
+    it("handles !matrix deny", async () => {
+        const handler: any = createCH();
+        const channel = new MockChannel("123");
+        const guild = new MockGuild("456", [channel]);
+        channel.guild = guild;
+        const member: any = new MockMember("123456", "blah");
+        member.hasPermission = () => {
+            return true;
+        };
+        const message = {
+            channel,
+            content: "!matrix deny",
+            member,
+        };
+        await handler.Process(message);
+        expect(MARKED).equals(0);
+    });
 });