diff --git a/src/bot.ts b/src/bot.ts
index b0eff028f22b8ade91b144516a9a88af8f6cd2b3..8ddcf134cc2f83e7401d34c98f50a44d73b8fe1d 100644
--- a/src/bot.ts
+++ b/src/bot.ts
@@ -5,7 +5,7 @@ import { DbEmoji } from "./db/dbdataemoji";
 import { DbEvent } from "./db/dbdataevent";
 import { MatrixUser, RemoteUser, Bridge, Entry } from "matrix-appservice-bridge";
 import { Util } from "./util";
-import { MessageProcessor, MessageProcessorOpts } from "./messageprocessor";
+import { MessageProcessor, MessageProcessorOpts, MessageProcessorMatrixResult } from "./messageprocessor";
 import { MatrixEventProcessor, MatrixEventProcessorOpts } from "./matrixeventprocessor";
 import { PresenceHandler } from "./presencehandler";
 import * as Discord from "discord.js";
@@ -80,7 +80,8 @@ export class DiscordBot {
       client.on("guildMemberAdd", (newMember) => { this.AddGuildMember(newMember); });
       client.on("guildMemberRemove", (oldMember) => { this.RemoveGuildMember(oldMember); });
       client.on("guildMemberUpdate", (_, newMember) => { this.UpdateGuildMember(newMember); });
-      client.on("messageDelete", (msg) => {this.DeleteDiscordMessage(msg); });
+      client.on("messageUpdate", (oldMessage, newMessage) => { this.OnMessageUpdate(oldMessage, newMessage); });
+      client.on("messageDelete", (msg) => { this.DeleteDiscordMessage(msg); });
       client.on("message", (msg) => { Bluebird.delay(MSG_PROCESS_DELAY).then(() => {
           this.OnMessage(msg);
         });
@@ -434,6 +435,32 @@ export class DiscordBot {
     });
   }
 
+  private async SendMatrixMessage(matrixMsg: MessageProcessorMatrixResult, chan: Discord.Channel,
+                                  guild: Discord.Guild, author: Discord.User,
+                                  msgID: string): Promise<boolean> {
+    const rooms = await this.GetRoomIdsFromChannel(chan);
+    const intent = this.GetIntentFromDiscordMember(author);
+
+    rooms.forEach((room) => {
+      intent.sendMessage(room, {
+        body: matrixMsg.body,
+        msgtype: "m.text",
+        formatted_body: matrixMsg.formattedBody,
+        format: "org.matrix.custom.html",
+      }).then((res) => {
+        const evt = new DbEvent();
+        evt.MatrixId = res.event_id + ";" + room;
+        evt.DiscordId = msgID;
+        evt.ChannelId = chan.id;
+        evt.GuildId = guild.id;
+        this.store.Insert(evt);
+      });
+    });
+
+    // Sending was a success
+    return true;
+  }
+
   private AddGuildMember(guildMember: Discord.GuildMember) {
     return this.GetRoomIdsFromGuild(guildMember.guild.id).then((roomIds) => {
       return this.InitJoinUser(guildMember, roomIds);
@@ -586,6 +613,21 @@ export class DiscordBot {
     });
   }
 
+  private async OnMessageUpdate(oldMsg: Discord.Message, newMsg: Discord.Message) {
+    // Check if an edit was actually made
+    if (oldMsg.content === newMsg.content) {
+      return;
+    }
+
+    // Create a new edit message using the old and new message contents
+    const editedMsg = await this.msgProcessor.FormatEdit(oldMsg, newMsg);
+
+    // Send the message to all bridged matrix rooms
+    if (!await this.SendMatrixMessage(editedMsg, newMsg.channel, newMsg.guild, newMsg.author, newMsg.id)) {
+      log.error("DiscordBot", "Unable to announce message edit for msg id:", newMsg.id);
+    }
+  }
+
     private async DeleteDiscordMessage(msg: Discord.Message) {
         log.info("DiscordBot", `Got delete event for ${msg.id}`);
         const storeEvent = await this.store.Get(DbEvent, {discord_id: msg.id});
diff --git a/src/messageprocessor.ts b/src/messageprocessor.ts
index 6dac01a2fc0eb803ce06111fb6144c835c6f1c51..f02893357d4fd442546ed0a3beb85fae02053163 100644
--- a/src/messageprocessor.ts
+++ b/src/messageprocessor.ts
@@ -71,6 +71,12 @@ export class MessageProcessor {
         return result;
     }
 
+    public async FormatEdit(oldMsg: Discord.Message, newMsg: Discord.Message): Promise<MessageProcessorMatrixResult> {
+        // TODO: Produce a nice, colored diff between the old and new message content
+        oldMsg.content = "*edit:* ~~" + oldMsg.content + "~~ -> " + newMsg.content;
+        return this.FormatDiscordMessage(oldMsg);
+    }
+
     public InsertEmbeds(content: string, msg: Discord.Message): string {
         for (const embed of msg.embeds) {
             let embedContent = "\n\n----"; // Horizontal rule. Two to make sure the content doesn't become a title.
diff --git a/test/test_discordbot.ts b/test/test_discordbot.ts
index 95855e72dd60790d02f1a5682af28348c05351e9..45f820d8383fda07abc9167208c491d6bfda78ff 100644
--- a/test/test_discordbot.ts
+++ b/test/test_discordbot.ts
@@ -1,8 +1,13 @@
 import * as Chai from "chai";
 import * as ChaiAsPromised from "chai-as-promised";
 import * as Proxyquire from "proxyquire";
+import * as Discord from "discord.js";
 import * as log from "npmlog";
 
+import { MessageProcessorMatrixResult } from "../src/messageprocessor";
+import { MockGuild } from "./mocks/guild";
+import { MockMember } from "./mocks/member";
+
 Chai.use(ChaiAsPromised);
 log.level = "silent";
 
@@ -76,6 +81,62 @@ describe("DiscordBot", () => {
       return assert.isFulfilled(discordBot.LookupRoom("123", "321"));
     });
   });
+  describe("OnMessageUpdate()", () => {
+    it("should return on an unchanged message", () => {
+      discordBot = new modDiscordBot.DiscordBot(
+        config,
+        mockBridge,
+      );
+
+      const guild: any = new MockGuild("123", []);
+      guild._mockAddMember(new MockMember("12345", "TestUsername"));
+      const channel = new Discord.TextChannel(guild, null);
+      const oldMsg = new Discord.Message(channel, null, null);
+      const newMsg = new Discord.Message(channel, null, null);
+      oldMsg.embeds = [];
+      newMsg.embeds = [];
+
+      // Content updated but not changed
+      oldMsg.content = "a";
+      newMsg.content = "a";
+
+      // Mock the SendMatrixMessage method to check if it is called
+      let checkMsgSent = false;
+      discordBot.SendMatrixMessage = (...args) => checkMsgSent = true;
+
+      discordBot.OnMessageUpdate(oldMsg, newMsg).then(() => {
+        Chai.assert.equal(checkMsgSent, false);
+      });
+    });
+
+    it("should send a matrix message on an edited discord message", () => {
+      discordBot = new modDiscordBot.DiscordBot(
+        config,
+        mockBridge,
+      );
+
+      const guild: any = new MockGuild("123", []);
+      guild._mockAddMember(new MockMember("12345", "TestUsername"));
+      const channel = new Discord.TextChannel(guild, null);
+      const oldMsg = new Discord.Message(channel, null, null);
+      const newMsg = new Discord.Message(channel, null, null);
+      oldMsg.embeds = [];
+      newMsg.embeds = [];
+
+      // Content updated and edited
+      oldMsg.content = "a";
+      newMsg.content = "b";
+
+      // Mock the SendMatrixMessage method to check if it is called
+      let checkMsgSent = false;
+      discordBot.SendMatrixMessage = (...args) => checkMsgSent = true;
+
+      discordBot.OnMessageUpdate(oldMsg, newMsg).then(() => {
+        Chai.assert.equal(checkMsgSent, true);
+      });
+    });
+  });
+
   // describe("ProcessMatrixMsgEvent()", () => {
   //
   // });
diff --git a/test/test_messageprocessor.ts b/test/test_messageprocessor.ts
index 063a29d80d226e4ca9dde2557ebc5ced1c0c87c4..d054b1e5d4f9dac0751dc8a7787a0873d6d12f96 100644
--- a/test/test_messageprocessor.ts
+++ b/test/test_messageprocessor.ts
@@ -51,6 +51,42 @@ describe("MessageProcessor", () => {
         Chai.assert.equal(result.formattedBody, "<p>Hello <em>World</em>!</p>\n");
       });
     });
+    describe("FormatEdit", () => {
+      it("should format basic edits appropriately", async () => {
+        const processor = new MessageProcessor(new MessageProcessorOpts("localhost"), <DiscordBot> bot);
+        const oldMsg = new Discord.Message(null, null, null);
+        const newMsg = new Discord.Message(null, null, null);
+        oldMsg.embeds = [];
+        newMsg.embeds = [];
+       
+        // Content updated but not changed
+        oldMsg.content = "a";
+        newMsg.content = "b";
+
+        const result = await processor.FormatEdit(oldMsg, newMsg);
+        Chai.assert.equal(result.body, "*edit:* ~~a~~ -> b");
+        Chai.assert.equal(result.formattedBody, "<p><em>edit:</em> <del>a</del> -&gt; b</p>\n");
+      });
+
+      it("should format markdown heavy edits apropriately", async () => {
+        const processor = new MessageProcessor(new MessageProcessorOpts("localhost"), <DiscordBot> bot);
+        const oldMsg = new Discord.Message(null, null, null);
+        const newMsg = new Discord.Message(null, null, null);
+        oldMsg.embeds = [];
+        newMsg.embeds = [];
+       
+        // Content updated but not changed
+        oldMsg.content = "a slice of **cake**";
+        newMsg.content = "*a* slice of cake";
+
+        const result = await processor.FormatEdit(oldMsg, newMsg);
+        Chai.assert.equal(result.body, "*edit:* ~~a slice of **cake**~~ -> *a* slice of cake");
+        Chai.assert.equal(result.formattedBody, "<p><em>edit:</em> <del>a slice of <strong>" +
+          "cake</strong></del> -&gt; <em>a</em> slice of cake</p>\n");
+      });
+
+    });
+        
     describe("ReplaceMembers", () => {
         it("processes members missing from the guild correctly", () => {
             const processor = new MessageProcessor(new MessageProcessorOpts("localhost"), <DiscordBot> bot);