diff --git a/src/bot.ts b/src/bot.ts
index c30495f014b24c0b4046dcfe03f4df9c612bcf57..8810553f19cc72d0c51fed1ad4509f8f61e3b0e9 100644
--- a/src/bot.ts
+++ b/src/bot.ts
@@ -4,7 +4,7 @@ import { DiscordStore } from "./store";
 import { DbEmoji } from "./db/dbdataemoji";
 import { DbEvent } from "./db/dbdataevent";
 import { MatrixUser, RemoteUser, Bridge, Entry, Intent } from "matrix-appservice-bridge";
-import { Util } from "./util";
+import { Util, IMatrixEvent } from "./util";
 import { MessageProcessor, MessageProcessorOpts, MessageProcessorMatrixResult } from "./messageprocessor";
 import { MatrixEventProcessor, MatrixEventProcessorOpts } from "./matrixeventprocessor";
 import { PresenceHandler } from "./presencehandler";
@@ -28,6 +28,18 @@ class ChannelLookupResult {
     public botUser: boolean;
 }
 
+interface IThirdPartyLookupField {
+    channel_id: string;
+    channel_name: string;
+    guild_id: string;
+}
+
+interface IThirdPartyLookup {
+    alias: string;
+    fields: IThirdPartyLookupField;
+    protocol: string;
+}
+
 export class DiscordBot {
     private config: DiscordBridgeConfig;
     private clientFactory: DiscordClientFactory;
@@ -170,7 +182,7 @@ export class DiscordBot {
         return this.bot.guilds.array();
     }
 
-    public ThirdpartySearchForChannels(guildId: string, channelName: string): any[] {
+    public ThirdpartySearchForChannels(guildId: string, channelName: string): IThirdPartyLookup[] {
         if (channelName.startsWith("#")) {
             channelName = channelName.substr(1);
         }
@@ -187,7 +199,7 @@ export class DiscordBot {
                         guild_id: guild.id,
                     },
                     protocol: "discord",
-                };
+                } as IThirdPartyLookup;
             });
         } else {
             log.info("Tried to do a third party lookup for a channel, but the guild did not exist");
@@ -221,7 +233,7 @@ export class DiscordBot {
         }
     }
 
-    public async ProcessMatrixStateEvent(event: any): Promise<void> {
+    public async ProcessMatrixStateEvent(event: IMatrixEvent): Promise<void> {
         log.verbose(`Got state event from ${event.room_id} ${event.type}`);
         const channel = await this.GetChannelFromRoomId(event.room_id) as Discord.TextChannel;
         const msg = this.mxEventProcessor.StateEventToMessage(event, channel);
@@ -244,7 +256,7 @@ export class DiscordBot {
         });
     }
 
-    public async ProcessMatrixMsgEvent(event: any, guildId: string, channelId: string): Promise<null> {
+    public async ProcessMatrixMsgEvent(event: IMatrixEvent, guildId: string, channelId: string): Promise<null> {
         const mxClient = this.bridge.getClientFactory().getClientAs();
         log.verbose(`Looking up ${guildId}_${channelId}`);
         const result = await this.LookupRoom(guildId, channelId, event.sender);
@@ -295,7 +307,7 @@ export class DiscordBot {
                     embeds: embedSet.replyEmbed ? [embedSet.replyEmbed] : undefined,
                     files: opts.file ? [opts.file] : undefined,
                     username: embed.author.name,
-                } as any);
+                } as Discord.WebhookMessageOptions);
             } else {
                 if (embedSet.replyEmbed) {
                     embed.addField("Replying to", embedSet.replyEmbed.author.name);
@@ -324,7 +336,7 @@ export class DiscordBot {
         return;
     }
 
-    public async ProcessMatrixRedact(event: any) {
+    public async ProcessMatrixRedact(event: IMatrixEvent) {
         if (this.config.bridge.disableDeletionForwarding) {
             return;
         }
diff --git a/src/clientfactory.ts b/src/clientfactory.ts
index b29d7c83b22b92014be64e1666b74507ea433fcf..adb3bb8eb17eee1368464617239f4dc84c10be49 100644
--- a/src/clientfactory.ts
+++ b/src/clientfactory.ts
@@ -1,8 +1,9 @@
 import { DiscordBridgeConfigAuth } from "./config";
 import { DiscordStore } from "./store";
-import { Client } from "discord.js";
+import * as Discord from "discord.js";
 import * as Bluebird from "bluebird";
 import { Log } from "./log";
+import * as Matrix from "matrix-js-sdk";
 
 const log = new Log("ClientFactory");
 
@@ -11,8 +12,8 @@ const READY_TIMEOUT = 5000;
 export class DiscordClientFactory {
     private config: DiscordBridgeConfigAuth;
     private store: DiscordStore;
-    private botClient: any;
-    private clients: Map<string, any>;
+    private botClient: Matrix.Client;
+    private clients: Map<string, Matrix.Client>;
     constructor(store: DiscordStore, config?: DiscordBridgeConfigAuth) {
         this.config = config;
         this.clients = new Map();
@@ -25,7 +26,7 @@ export class DiscordClientFactory {
         }
         // We just need to make sure we have a bearer token.
         // Create a new Bot client.
-        this.botClient = Bluebird.promisifyAll(new Client({
+        this.botClient = Bluebird.promisifyAll(new Discord.Client({
             fetchAllMembers: true,
             messageCacheLifetime: 5,
             sync: true,
@@ -40,7 +41,7 @@ export class DiscordClientFactory {
     }
 
     public async getDiscordId(token: string): Promise<string> {
-        const client = new Client({
+        const client = new Discord.Client({
             fetchAllMembers: false,
             messageCacheLifetime: 5,
             sync: false,
@@ -58,7 +59,7 @@ export class DiscordClientFactory {
         });
     }
 
-    public async getClient(userId: string = null): Promise<any> {
+    public async getClient(userId: string = null): Promise<Matrix.Client> {
         if (userId == null) {
             return this.botClient;
         }
@@ -72,7 +73,7 @@ export class DiscordClientFactory {
         }
         // TODO: Select a profile based on preference, not the first one.
         const token = await this.store.get_token(discordIds[0]);
-        const client = Bluebird.promisifyAll(new Client({
+        const client = Bluebird.promisifyAll(new Discord.Client({
             fetchAllMembers: true,
             messageCacheLifetime: 5,
             sync: true,
diff --git a/src/config.ts b/src/config.ts
index e6ec2628cf2673e8fe18e5d10cf15cf7abefa488..031a7ee69c7eaedffb049678ae9eb0629a2573ad 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -13,6 +13,7 @@ export class DiscordBridgeConfig {
      * @param _config Config keys
      * @param configLayer Private parameter
      */
+    // tslint:disable-next-line no-any
     public ApplyConfig(newConfig: {[key: string]: any}, configLayer: any = this) {
           Object.keys(newConfig).forEach((key) => {
             if ( typeof(configLayer[key]) === "object" &&
diff --git a/src/log.ts b/src/log.ts
index 410fb5bf98413020b4587b2def61e4044416e2a6..8a895ded8caaf20c9af707bddc8cd9598c47c6a6 100644
--- a/src/log.ts
+++ b/src/log.ts
@@ -81,6 +81,7 @@ export class Log {
             maxSize: config.maxSize,
         };
 
+        // tslint:disable-next-line no-any
         return new (transports as any).DailyRotateFile(opts);
     }
 
@@ -88,26 +89,32 @@ export class Log {
 
     constructor(private module: string) { }
 
+    // tslint:disable-next-line no-any
     public error(...msg: any[]) {
         this.log("error", msg);
     }
 
+    // tslint:disable-next-line no-any
     public warn(...msg: any[]) {
         this.log("warn", msg);
     }
 
+    // tslint:disable-next-line no-any
     public info(...msg: any[]) {
         this.log("info", msg);
     }
 
+    // tslint:disable-next-line no-any
     public verbose(...msg: any[]) {
         this.log("verbose", msg);
     }
 
+    // tslint:disable-next-line no-any
     public silly(...msg: any[]) {
         this.log("silly", msg);
     }
 
+    // tslint:disable-next-line no-any
     private log(level: string, msg: any[]) {
         if (Log.logger === null) {
             // We've not configured the logger yet, so create a basic one.
diff --git a/src/matrixeventprocessor.ts b/src/matrixeventprocessor.ts
index 9d42108cb73f8b623b7f23812230c12417113622..8991490ad175a48bc343c7e6f73db1236e6be645 100644
--- a/src/matrixeventprocessor.ts
+++ b/src/matrixeventprocessor.ts
@@ -3,10 +3,11 @@ import { MessageProcessorOpts, MessageProcessor } from "./messageprocessor";
 import { DiscordBot } from "./bot";
 import { DiscordBridgeConfig } from "./config";
 import * as escapeStringRegexp from "escape-string-regexp";
-import { Util } from "./util";
+import { Util, IMatrixEvent, IMatrixEventContent } from "./util";
 import * as path from "path";
 import * as mime from "mime";
-import { MatrixUser } from "matrix-appservice-bridge";
+import { MatrixUser, Bridge } from "matrix-appservice-bridge";
+import * as Matrix from "matrix-js-sdk";
 
 import { Log } from "./log";
 const log = new Log("MatrixEventProcessor");
@@ -21,7 +22,7 @@ const DISCORD_AVATAR_HEIGHT = 128;
 export class MatrixEventProcessorOpts {
     constructor(
         readonly config: DiscordBridgeConfig,
-        readonly bridge: any,
+        readonly bridge: Bridge,
         readonly discord: DiscordBot,
         ) {
 
@@ -35,7 +36,7 @@ export interface IMatrixEventProcessorResult {
 
 export class MatrixEventProcessor {
     private config: DiscordBridgeConfig;
-    private bridge: any;
+    private bridge: Bridge;
     private discord: DiscordBot;
 
     constructor(opts: MatrixEventProcessorOpts) {
@@ -44,7 +45,7 @@ export class MatrixEventProcessor {
         this.discord = opts.discord;
     }
 
-    public StateEventToMessage(event: any, channel: Discord.TextChannel): string {
+    public StateEventToMessage(event: IMatrixEvent, channel: Discord.TextChannel): string {
         const SUPPORTED_EVENTS = ["m.room.member", "m.room.name", "m.room.topic"];
         if (!SUPPORTED_EVENTS.includes(event.type)) {
             log.verbose(`${event.event_id} ${event.type} is not displayable.`);
@@ -83,7 +84,7 @@ export class MatrixEventProcessor {
     }
 
     public async EventToEmbed(
-        event: any, profile: any|null, channel: Discord.TextChannel,
+        event: IMatrixEvent, profile: IMatrixEvent|null, channel: Discord.TextChannel,
     ): Promise<IMatrixEventProcessorResult> {
         let body = this.config.bridge.disableDiscordMentions ? event.content.body :
             this.FindMentionsInPlainBody(
@@ -170,7 +171,7 @@ export class MatrixEventProcessor {
         return content;
     }
 
-    public async HandleAttachment(event: any, mxClient: any): Promise<string|Discord.FileOptions> {
+    public async HandleAttachment(event: IMatrixEvent, mxClient: Matrix.Client): Promise<string|Discord.FileOptions> {
         const hasAttachment = [
             "m.image",
             "m.audio",
@@ -211,7 +212,7 @@ export class MatrixEventProcessor {
         return `[${name}](${url})`;
     }
 
-    public async GetEmbedForReply(event: any): Promise<[Discord.RichEmbed, string]|undefined> {
+    public async GetEmbedForReply(event: IMatrixEvent): Promise<[Discord.RichEmbed, string]|undefined> {
         const relatesTo = event.content["m.relates_to"];
         let eventId = null;
         if (relatesTo && relatesTo["m.in_reply_to"]) {
@@ -249,7 +250,7 @@ export class MatrixEventProcessor {
         return [embed, reponseText];
     }
 
-    private async SetEmbedAuthor(embed: Discord.RichEmbed, sender: string, profile?: any) {
+    private async SetEmbedAuthor(embed: Discord.RichEmbed, sender: string, profile?: IMatrixEvent) {
         const intent = this.bridge.getIntent();
         let displayName = sender;
         let avatarUrl;
@@ -300,7 +301,7 @@ export class MatrixEventProcessor {
         );
     }
 
-    private GetFilenameForMediaEvent(content: any): string {
+    private GetFilenameForMediaEvent(content: IMatrixEventContent): string {
         if (content.body) {
             if (path.extname(content.body) !== "") {
                 return content.body;
diff --git a/src/matrixroomhandler.ts b/src/matrixroomhandler.ts
index c0defadd6ca44b704df67dcb4d45baa612f800b8..265cba163435c074677ad9ca310b0a2b1be9c759 100644
--- a/src/matrixroomhandler.ts
+++ b/src/matrixroomhandler.ts
@@ -6,12 +6,15 @@ import {
     thirdPartyProtocolResult,
     thirdPartyUserResult,
     thirdPartyLocationResult,
+    BridgeContext,
+    ProvisionedRoom,
+    Intent,
 } from "matrix-appservice-bridge";
 import { DiscordBridgeConfig } from "./config";
 
 import * as Discord from "discord.js";
 import * as Bluebird from "bluebird";
-import { Util, ICommandActions, ICommandParameters } from "./util";
+import { Util, ICommandActions, ICommandParameters, IMatrixEvent } from "./util";
 import { Provisioner } from "./provisioner";
 import { Log } from "./log";
 const log = new Log("MatrixRoomHandler");
@@ -103,35 +106,41 @@ export class MatrixRoomHandler {
         await Promise.all(promiseList);
     }
 
-    public async OnEvent(request, context): Promise<any> {
+    public async OnEvent(request, context): Promise<void> {
         const event = request.getData();
         if (event.unsigned.age > AGE_LIMIT) {
             log.warn(`Skipping event due to age ${event.unsigned.age} > ${AGE_LIMIT}`);
             throw new Error("Event too old");
         }
         if (event.type === "m.room.member" && event.content.membership === "invite") {
-            return this.HandleInvite(event);
+            await this.HandleInvite(event);
+            return;
         } else if (event.type === "m.room.member" && event.content.membership === "join") {
             if (this.bridge.getBot().isRemoteUser(event.state_key)) {
-                return this.discord.UserSyncroniser.OnMemberState(event, USERSYNC_STATE_DELAY_MS);
+                await this.discord.UserSyncroniser.OnMemberState(event, USERSYNC_STATE_DELAY_MS);
             } else {
-                return this.discord.ProcessMatrixStateEvent(event);
+                await this.discord.ProcessMatrixStateEvent(event);
             }
+            return;
         } else if (["m.room.member", "m.room.name", "m.room.topic"].includes(event.type)) {
-            return this.discord.ProcessMatrixStateEvent(event);
+            await this.discord.ProcessMatrixStateEvent(event);
+            return;
         } else if (event.type === "m.room.redaction" && context.rooms.remote) {
-            return this.discord.ProcessMatrixRedact(event);
+            await this.discord.ProcessMatrixRedact(event);
+            return;
         } else if (event.type === "m.room.message" || event.type === "m.sticker") {
             log.verbose(`Got ${event.type} event`);
             const isBotCommand = event.type === "m.room.message" &&
                 event.content.body &&
                 event.content.body.startsWith("!discord");
             if (isBotCommand) {
-                return this.ProcessCommand(event, context);
+                await this.ProcessCommand(event, context);
+                return;
             } else if (context.rooms.remote) {
                 const srvChanPair = context.rooms.remote.roomId.substr("_discord".length).split("_", ROOM_NAME_PARTS);
                 try {
-                    return this.discord.ProcessMatrixMsgEvent(event, srvChanPair[0], srvChanPair[1]);
+                    await this.discord.ProcessMatrixMsgEvent(event, srvChanPair[0], srvChanPair[1]);
+                    return;
                 } catch (err) {
                     log.warn("There was an error sending a matrix event", err);
                     return;
@@ -139,7 +148,8 @@ export class MatrixRoomHandler {
             }
         } else if (event.type === "m.room.encryption" && context.rooms.remote) {
             try {
-                return this.HandleEncryptionWarning(event.room_id);
+                await this.HandleEncryptionWarning(event.room_id);
+                return;
             } catch (err) {
                 throw new Error(`Failed to handle encrypted room, ${err}`);
             }
@@ -168,7 +178,7 @@ export class MatrixRoomHandler {
         await this.bridge.getRoomStore().removeEntriesByMatrixRoomId(roomId);
     }
 
-    public async HandleInvite(event: any) {
+    public async HandleInvite(event: IMatrixEvent) {
         log.info("Received invite for " + event.state_key + " in room " + event.room_id);
         if (event.state_key === this.botUserId) {
             log.info("Accepting invite for bridge bot");
@@ -179,7 +189,7 @@ export class MatrixRoomHandler {
         }
     }
 
-    public async ProcessCommand(event: any, context: any) {
+    public async ProcessCommand(event: IMatrixEvent, context: BridgeContext) {
         const intent = this.bridge.getIntent();
         if (!(await this.isBotInRoom(event.room_id))) {
             log.warn(`Bot is not in ${event.room_id}. Ignoring command`);
@@ -328,7 +338,7 @@ export class MatrixRoomHandler {
         }
     }
 
-    public async OnAliasQuery(alias: string, aliasLocalpart: string): Promise<any> {
+    public async OnAliasQuery(alias: string, aliasLocalpart: string): Promise<ProvisionedRoom> {
         log.info("Got request for #", aliasLocalpart);
         const srvChanPair = aliasLocalpart.substr("_discord_".length).split("_", ROOM_NAME_PARTS);
         if (srvChanPair.length < ROOM_NAME_PARTS || srvChanPair[0] === "" || srvChanPair[1] === "") {
@@ -389,6 +399,7 @@ export class MatrixRoomHandler {
         };
     }
 
+    // tslint:disable-next-line no-any
     public async tpGetLocation(protocol: string, fields: any): Promise<thirdPartyLocationResult[]> {
         log.info("Got location request ", protocol, fields);
         const chans = this.discord.ThirdpartySearchForChannels(fields.guild_id, fields.channel_name);
@@ -399,6 +410,7 @@ export class MatrixRoomHandler {
         throw {err: "Unsupported", code: HTTP_UNSUPPORTED};
     }
 
+    // tslint:disable-next-line no-any
     public async tpGetUser(protocol: string, fields: any): Promise<thirdPartyUserResult[]> {
         log.info("Got user request ", protocol, fields);
         throw {err: "Unsupported", code: HTTP_UNSUPPORTED};
@@ -453,7 +465,7 @@ export class MatrixRoomHandler {
             let replyHelpMessage = "Available Commands:\n";
             for (const actionKey of Object.keys(actions)) {
                 const action = actions[actionKey];
-                if (!msg.member.hasPermission(action.permission as any)) {
+                if (!msg.member.hasPermission(action.permission as Discord.PermissionResolvable)) {
                     continue;
                 }
                 replyHelpMessage += " - `!matrix " + actionKey;
@@ -476,7 +488,7 @@ export class MatrixRoomHandler {
             return;
         }
 
-        if (!msg.member.hasPermission(actions[command].permission as any)) {
+        if (!msg.member.hasPermission(actions[command].permission as Discord.PermissionResolvable)) {
             await msg.channel.send("**ERROR:** insufficiant permissions to use this matrix command");
             return;
         }
@@ -519,7 +531,7 @@ export class MatrixRoomHandler {
         };
     }
 
-    private async joinRoom(intent: any, roomIdOrAlias: string): Promise<void> {
+    private async joinRoom(intent: Intent, roomIdOrAlias: string): Promise<void> {
         let currentSchedule = JOIN_ROOM_SCHEDULE[0];
         const doJoin = async () => {
             await Util.DelayedPromise(currentSchedule);
@@ -549,7 +561,7 @@ export class MatrixRoomHandler {
         }
     }
 
-    private createMatrixRoom(channel: Discord.TextChannel, alias: string) {
+    private createMatrixRoom(channel: Discord.TextChannel, alias: string): ProvisionedRoom {
         const remote = new RemoteRoom(`discord_${channel.guild.id}_${channel.id}`);
         remote.set("discord_type", "text");
         remote.set("discord_guild", channel.guild.id);
@@ -573,7 +585,7 @@ export class MatrixRoomHandler {
         return {
             creationOpts,
             remote,
-        };
+        } as ProvisionedRoom;
     }
 
     private async isBotInRoom(roomId: string): Promise<boolean> {
diff --git a/src/presencehandler.ts b/src/presencehandler.ts
index aa77d962e9091e45f309b95a7946aac6e22c9d33..9c6d94657ea2947997cf2353b74a0ac44c657798 100644
--- a/src/presencehandler.ts
+++ b/src/presencehandler.ts
@@ -10,6 +10,11 @@ export class PresenceHandlerStatus {
     public ShouldDrop: boolean = false;
 }
 
+interface IMatrixPresence {
+    presence?: string;
+    status_msg?: string;
+}
+
 export class PresenceHandler {
     private readonly bot: DiscordBot;
     private presenceQueue: User[];
@@ -106,7 +111,7 @@ export class PresenceHandler {
 
     private async setMatrixPresence(user: User, status: PresenceHandlerStatus) {
         const intent = this.bot.GetIntentFromDiscordMember(user);
-        const statusObj: any = {presence: status.Presence};
+        const statusObj: IMatrixPresence = {presence: status.Presence};
         if (status.StatusMsg) {
             statusObj.status_msg = status.StatusMsg;
         }
diff --git a/src/provisioner.ts b/src/provisioner.ts
index 0e20175e686a01434aaa439e690ae7c7efe62ad9..1a43db0940894338df80aabdc0da0a0ab398fe31 100644
--- a/src/provisioner.ts
+++ b/src/provisioner.ts
@@ -32,7 +32,7 @@ export class Provisioner {
         return this.bridge.getRoomStore().removeEntriesByRemoteRoomId(remoteRoom.getId());
     }
 
-    public async AskBridgePermission(channel: Discord.TextChannel, requestor: string): Promise<any> {
+    public async AskBridgePermission(channel: Discord.TextChannel, requestor: string): Promise<void> {
         const channelId = channel.guild.id + "/" + channel.id;
 
         let responded = false;
diff --git a/src/usersyncroniser.ts b/src/usersyncroniser.ts
index af3d7c781b6745d6e6b704318b14dd2b71d0b59f..89ff6ab6c7bf6f5d55778d6c2219d52539e55b80 100644
--- a/src/usersyncroniser.ts
+++ b/src/usersyncroniser.ts
@@ -1,6 +1,6 @@
 import { User, GuildMember, GuildChannel } from "discord.js";
 import { DiscordBot } from "./bot";
-import { Util } from "./util";
+import { Util, IMatrixEvent } from "./util";
 import { MatrixUser, RemoteUser, Bridge, Entry, UserBridgeStore } from "matrix-appservice-bridge";
 import { DiscordBridgeConfig } from "./config";
 import * as Bluebird from "bluebird";
@@ -59,14 +59,14 @@ export class UserSyncroniser {
     public static readonly ERR_NEWER_EVENT = "newer_state_event_arrived";
 
     // roomId+userId => ev
-    public userStateHold: Map<string, any>;
+    public userStateHold: Map<string, IMatrixEvent>;
     private userStore: UserBridgeStore;
     constructor(
         private bridge: Bridge,
         private config: DiscordBridgeConfig,
         private discord: DiscordBot) {
         this.userStore = this.bridge.getUserStore();
-        this.userStateHold = new Map<string, any>();
+        this.userStateHold = new Map<string, IMatrixEvent>();
     }
 
     /**
@@ -276,7 +276,7 @@ export class UserSyncroniser {
         );
     }
 
-    public async UpdateStateForGuilds(remoteUser: any) {
+    public async UpdateStateForGuilds(remoteUser: RemoteUser) {
         const id = remoteUser.getId();
         log.info(`Got update for ${id}.`);
 
@@ -295,7 +295,7 @@ export class UserSyncroniser {
         });
     }
 
-    public async OnMemberState(ev: any, delayMs: number = 0): Promise<string> {
+    public async OnMemberState(ev: IMatrixEvent, delayMs: number = 0): Promise<string> {
         // Avoid tripping over multiple state events.
         if (await this.memberStateLock(ev, delayMs) === false) {
             // We're igorning this update because we have a newer one.
@@ -328,7 +328,7 @@ export class UserSyncroniser {
         return this.ApplyStateToRoom(state, roomId, member.guild.id);
     }
 
-    private async memberStateLock(ev: any, delayMs: number = -1): Promise<boolean> {
+    private async memberStateLock(ev: IMatrixEvent, delayMs: number = -1): Promise<boolean> {
         const userStateKey = `${ev.room_id}${ev.state_key}`;
         if (this.userStateHold.has(userStateKey)) {
             const oldEv = this.userStateHold.get(userStateKey);
diff --git a/src/util.ts b/src/util.ts
index 43050c846d130d3d5aca7cc65e12e0d74c071f53..09afd905e946514e02828c2f2be5742537d82699 100644
--- a/src/util.ts
+++ b/src/util.ts
@@ -4,6 +4,7 @@ import { Intent } from "matrix-appservice-bridge";
 import { Buffer } from "buffer";
 import * as mime from "mime";
 import { Permissions } from "discord.js";
+import { DiscordBridgeConfig } from "./config";
 
 const HTTP_OK = 200;
 
@@ -14,7 +15,7 @@ export interface ICommandAction {
     params: string[];
     description?: string;
     permission?: string;
-    run(params: any): Promise<any>;
+    run(params: any): Promise<any>; // tslint:disable-line no-any
 }
 
 export interface ICommandActions {
@@ -23,13 +24,40 @@ export interface ICommandActions {
 
 export interface ICommandParameter {
     description?: string;
-    get(param: string): Promise<any>;
+    get(param: string): Promise<any>; // tslint:disable-line no-any
 }
 
 export interface ICommandParameters {
     [index: string]: ICommandParameter;
 }
 
+export interface IMatrixEventContent {
+    body?: string;
+    info?: any; // tslint:disable-line no-any
+    name?: string;
+    topic?: string;
+    membership?: string;
+    msgtype?: string;
+    url?: string;
+    displayname?: string;
+    "m.relates_to"?: any; // tslint:disable-line no-any
+}
+
+export interface IMatrixEvent {
+    event_id: string;
+    state_key: string;
+    type: string;
+    sender: string;
+    room_id: string;
+    membership?: string;
+    avatar_url?: string;
+    displayname?: string;
+    redacts?: string;
+    content?: IMatrixEventContent;
+    unsigned?: any; // tslint:disable-line no-any
+    origin_server_ts?: number;
+}
+
 export class Util {
     /**
      * downloadFile - This function will take a URL and store the resulting data into
@@ -128,13 +156,13 @@ export class Util {
      * @param {number} duration The number of milliseconds to wait
      * @returns {Promise<any>} The promise
      */
-    public static async DelayedPromise(duration: number): Promise<any> {
-        return new Promise<any>((resolve, reject) => {
+    public static async DelayedPromise(duration: number): Promise<void> {
+        return new Promise<void>((resolve, reject) => {
             setTimeout(resolve, duration);
         });
     }
 
-    public static GetBotLink(config: any): string {
+    public static GetBotLink(config: DiscordBridgeConfig): string {
         /* tslint:disable:no-bitwise */
         const perms = Permissions.FLAGS.READ_MESSAGES |
             Permissions.FLAGS.SEND_MESSAGES |
diff --git a/test/test_matrixeventprocessor.ts b/test/test_matrixeventprocessor.ts
index 861e164b77862a5a7c966191454da9cb96d30aa9..fd030fccc64ef971a9eb44d710df497f39dfc8bd 100644
--- a/test/test_matrixeventprocessor.ts
+++ b/test/test_matrixeventprocessor.ts
@@ -9,10 +9,11 @@ import { MockGuild } from "./mocks/guild";
 import { MockCollection } from "./mocks/collection";
 import { MockMember } from "./mocks/member";
 import { MockEmoji } from "./mocks/emoji";
-import {MatrixEventProcessor, MatrixEventProcessorOpts} from "../src/matrixeventprocessor";
-import {DiscordBridgeConfig} from "../src/config";
-import {MessageProcessor, MessageProcessorOpts} from "../src/messageprocessor";
-import {MockChannel} from "./mocks/channel";
+import { MatrixEventProcessor, MatrixEventProcessorOpts } from "../src/matrixeventprocessor";
+import { DiscordBridgeConfig } from "../src/config";
+import { MessageProcessor, MessageProcessorOpts } from "../src/messageprocessor";
+import { MockChannel } from "./mocks/channel";
+import { IMatrixEvent } from "../src/util";
 
 // we are a test file and thus need those
 /* tslint:disable:no-unused-expression max-file-line-count no-any */
@@ -142,7 +143,7 @@ describe("MatrixEventProcessor", () => {
             const event = {
                 sender: "@user:localhost",
                 type: "m.room.nonexistant",
-            };
+            } as IMatrixEvent;
             const channel = new MockChannel("123456");
             const msg = processor.StateEventToMessage(event, channel as any);
             Chai.assert.equal(msg, undefined);
@@ -152,7 +153,7 @@ describe("MatrixEventProcessor", () => {
             const event = {
                 sender: "@botuser:localhost",
                 type: "m.room.member",
-            };
+            } as IMatrixEvent;
             const channel = new MockChannel("123456");
             const msg = processor.StateEventToMessage(event, channel as any);
             Chai.assert.equal(msg, undefined);
@@ -165,7 +166,7 @@ describe("MatrixEventProcessor", () => {
                 },
                 sender: "@user:localhost",
                 type: "m.room.name",
-            };
+            } as IMatrixEvent;
             const channel = new MockChannel("123456");
             const msg = processor.StateEventToMessage(event, channel as any);
             Chai.assert.equal(msg, "`@user:localhost` set the name to `Test Name` on Matrix.");
@@ -178,7 +179,7 @@ describe("MatrixEventProcessor", () => {
                 },
                 sender: "@user:localhost",
                 type: "m.room.topic",
-            };
+            } as IMatrixEvent;
             const channel = new MockChannel("123456");
             const msg = processor.StateEventToMessage(event, channel as any);
             Chai.assert.equal(msg, "`@user:localhost` set the topic to `Test Topic` on Matrix.");
@@ -192,7 +193,7 @@ describe("MatrixEventProcessor", () => {
                 sender: "@user:localhost",
                 type: "m.room.member",
                 unsigned: {},
-            };
+            } as IMatrixEvent;
             const channel = new MockChannel("123456");
             const msg = processor.StateEventToMessage(event, channel as any);
             Chai.assert.equal(msg, "`@user:localhost` joined the room on Matrix.");
@@ -207,7 +208,7 @@ describe("MatrixEventProcessor", () => {
                 state_key: "@user2:localhost",
                 type: "m.room.member",
                 unsigned: {},
-            };
+            } as IMatrixEvent;
             const channel = new MockChannel("123456");
             const msg = processor.StateEventToMessage(event, channel as any);
             Chai.assert.equal(msg, "`@user:localhost` invited `@user2:localhost` to the room on Matrix.");
@@ -222,7 +223,7 @@ describe("MatrixEventProcessor", () => {
                 state_key: "@user2:localhost",
                 type: "m.room.member",
                 unsigned: {},
-            };
+            } as IMatrixEvent;
             const channel = new MockChannel("123456");
             const msg = processor.StateEventToMessage(event, channel as any);
             Chai.assert.equal(msg, "`@user:localhost` kicked `@user2:localhost` from the room on Matrix.");
@@ -237,7 +238,7 @@ describe("MatrixEventProcessor", () => {
                 state_key: "@user:localhost",
                 type: "m.room.member",
                 unsigned: {},
-            };
+            } as IMatrixEvent;
             const channel = new MockChannel("123456");
             const msg = processor.StateEventToMessage(event, channel as any);
             Chai.assert.equal(msg, "`@user:localhost` left the room on Matrix.");
@@ -252,7 +253,7 @@ describe("MatrixEventProcessor", () => {
                 state_key: "@user2:localhost",
                 type: "m.room.member",
                 unsigned: {},
-            };
+            } as IMatrixEvent;
             const channel = new MockChannel("123456");
             const msg = processor.StateEventToMessage(event, channel as any);
             Chai.assert.equal(msg, "`@user:localhost` banned `@user2:localhost` from the room on Matrix.");
@@ -266,11 +267,11 @@ describe("MatrixEventProcessor", () => {
                     body: "testcontent",
                 },
                 sender: "@test:localhost",
-            },
+            } as IMatrixEvent,
             {
                 avatar_url: "mxc://localhost/avatarurl",
                 displayname: "Test User",
-            }, mockChannel as any);
+            } as IMatrixEvent, mockChannel as any);
             const author = embeds.messageEmbed.author;
             Chai.assert.equal(author.name, "Test User");
             Chai.assert.equal(author.icon_url, "https://localhost/avatarurl");
@@ -284,8 +285,9 @@ describe("MatrixEventProcessor", () => {
                     body: "testcontent",
                 },
                 sender: "@test:localhost",
-            }, {
-                displayname: "Test User"}, mockChannel as any);
+            } as IMatrixEvent, {
+                displayname: "Test User",
+            } as IMatrixEvent, mockChannel as any);
             const author = embeds.messageEmbed.author;
             Chai.assert.equal(author.name, "Test User");
             Chai.assert.isUndefined(author.icon_url);
@@ -299,7 +301,7 @@ describe("MatrixEventProcessor", () => {
                     body: "testcontent",
                 },
                 sender: "@test:localhost",
-            }, null, mockChannel as any);
+            } as IMatrixEvent, null, mockChannel as any);
             const author = embeds.messageEmbed.author;
             Chai.assert.equal(author.name, "@test:localhost");
             Chai.assert.isUndefined(author.icon_url);
@@ -313,8 +315,9 @@ describe("MatrixEventProcessor", () => {
                     body: "testcontent",
                 },
                 sender: "@test:localhost",
-            }, {
-                displayname: "t"}, mockChannel as any);
+            } as IMatrixEvent, {
+                displayname: "t",
+            } as IMatrixEvent, mockChannel as any);
             const author = embeds.messageEmbed.author;
             Chai.assert.equal(author.name, "@test:localhost");
         });
@@ -326,9 +329,9 @@ describe("MatrixEventProcessor", () => {
                     body: "testcontent",
                 },
                 sender: "@test:localhost",
-            }, {
+            } as IMatrixEvent, {
                 displayname: "this is a very very long displayname that should be capped",
-            }, mockChannel as any);
+            } as IMatrixEvent, mockChannel as any);
             const author = embeds.messageEmbed.author;
             Chai.assert.equal(author.name, "@test:localhost");
         });
@@ -340,7 +343,7 @@ describe("MatrixEventProcessor", () => {
                     body: "testcontent",
                 },
                 sender: "@testwithalottosayaboutitselfthatwillgoonandonandonandon:localhost",
-            }, null, mockChannel as any);
+            } as IMatrixEvent, null, mockChannel as any);
             const author = embeds.messageEmbed.author;
             Chai.assert.equal(author.name, "@testwithalottosayaboutitselftha");
         });
@@ -352,7 +355,9 @@ describe("MatrixEventProcessor", () => {
                     body: "testcontent",
                 },
                 sender: "@test:localhost",
-            }, {avatar_url: "mxc://localhost/test"}, mockChannel as any);
+            } as IMatrixEvent, {
+                avatar_url: "mxc://localhost/test",
+            } as IMatrixEvent, mockChannel as any);
             const author = embeds.messageEmbed.author;
             Chai.assert.equal(author.name, "@test:localhost");
             Chai.assert.equal(author.icon_url, "https://localhost/test");
@@ -366,7 +371,9 @@ describe("MatrixEventProcessor", () => {
                     body: "@testuser2 Hello!",
                 },
                 sender: "@test:localhost",
-            }, {avatar_url: "test"}, mockChannel as any);
+            } as IMatrixEvent, {
+                avatar_url: "test",
+            } as IMatrixEvent, mockChannel as any);
             Chai.assert.equal(embeds.messageEmbed.description, "<@!12345> Hello!");
         });
 
@@ -377,7 +384,9 @@ describe("MatrixEventProcessor", () => {
                     body: "@testuser2 Hello!",
                 },
                 sender: "@test:localhost",
-            }, {avatar_url: "test"}, mockChannel as any);
+            } as IMatrixEvent, {
+                avatar_url: "test",
+            } as IMatrixEvent, mockChannel as any);
             Chai.assert.equal(embeds.messageEmbed.description, "@testuser2 Hello!");
         });
 
@@ -388,7 +397,9 @@ describe("MatrixEventProcessor", () => {
                     body: "@everyone Hello!",
                 },
                 sender: "@test:localhost",
-            }, {avatar_url: "test"}, mockChannel as any);
+            } as IMatrixEvent, {
+                avatar_url: "test",
+            } as IMatrixEvent, mockChannel as any);
             Chai.assert.equal(embeds.messageEmbed.description, "@ everyone Hello!");
         });
 
@@ -399,7 +410,9 @@ describe("MatrixEventProcessor", () => {
                     body: "@here Hello!",
                 },
                 sender: "@test:localhost",
-            }, {avatar_url: "test"}, mockChannel as any);
+            } as IMatrixEvent, {
+                avatar_url: "test",
+            } as IMatrixEvent, mockChannel as any);
             Chai.assert.equal(embeds.messageEmbed.description, "@ here Hello!");
         });
 
@@ -417,7 +430,9 @@ describe("MatrixEventProcessor", () => {
                     body: "I like :supercake:",
                 },
                 sender: "@test:localhost",
-            }, {avatar_url: "test"}, mockChannelEmojis as any);
+            } as IMatrixEvent, {
+                avatar_url: "test",
+            } as IMatrixEvent, mockChannelEmojis as any);
             Chai.assert.equal(
                 embeds.messageEmbed.description,
                 "I like <:supercake:123>",
@@ -438,7 +453,9 @@ describe("MatrixEventProcessor", () => {
                     body: "I like :lamecake:",
                 },
                 sender: "@test:localhost",
-            }, {avatar_url: "test"}, mockChannelEmojis as any);
+            } as IMatrixEvent, {
+                avatar_url: "test",
+            } as IMatrixEvent, mockChannelEmojis as any);
             Chai.assert.equal(
                 embeds.messageEmbed.description,
                 "I like :lamecake:",
@@ -452,9 +469,9 @@ describe("MatrixEventProcessor", () => {
                     msgtype: "m.emote",
                 },
                 sender: "@test:localhost",
-            }, {
+            } as IMatrixEvent, {
                 displayname: "displayname",
-            }, mockChannel as any);
+            } as IMatrixEvent, mockChannel as any);
             Chai.assert.equal(
                 embeds.messageEmbed.description,
                 "*displayname likes puppies*",
@@ -469,7 +486,9 @@ describe("MatrixEventProcessor", () => {
                 },
                 sender: "@test:localhost",
                 type: "m.sticker",
-            }, {avatar_url: "test"}, mockChannel as any);
+            } as IMatrixEvent, {
+                avatar_url: "test",
+            } as IMatrixEvent, mockChannel as any);
             Chai.assert.equal(embeds.messageEmbed.description, "");
         });
     });
@@ -587,7 +606,7 @@ describe("MatrixEventProcessor", () => {
                 content: {
                     msgtype: "m.text",
                 },
-            }, mxClient)).to.eventually.eq("");
+            } as IMatrixEvent, mxClient)).to.eventually.eq("");
         });
         it("message without an info", () => {
             const processor = createMatrixEventProcessor();
@@ -597,7 +616,7 @@ describe("MatrixEventProcessor", () => {
                     msgtype: "m.video",
                     url: "mxc://localhost/200",
                 },
-            }, mxClient)).to.eventually.satisfy((attachment) => {
+            } as IMatrixEvent, mxClient)).to.eventually.satisfy((attachment) => {
                 expect(attachment.name).to.eq("filename.webm");
                 expect(attachment.attachment.length).to.eq(SMALL_FILE);
                 return true;
@@ -612,7 +631,7 @@ describe("MatrixEventProcessor", () => {
                     },
                     msgtype: "m.video",
                 },
-            }, mxClient)).to.eventually.eq("");
+            } as IMatrixEvent, mxClient)).to.eventually.eq("");
         });
         it("message with a large info.size", () => {
             const LARGE_FILE = 8000000;
@@ -626,7 +645,8 @@ describe("MatrixEventProcessor", () => {
                     msgtype: "m.video",
                     url: "mxc://localhost/8000000",
                 },
-            }, mxClient)).to.eventually.eq("[filename.webm](https://localhost/8000000)");
+            } as IMatrixEvent, mxClient))
+                .to.eventually.eq("[filename.webm](https://localhost/8000000)");
         });
         it("message with a small info.size", () => {
             const processor = createMatrixEventProcessor();
@@ -639,7 +659,7 @@ describe("MatrixEventProcessor", () => {
                     msgtype: "m.video",
                     url: "mxc://localhost/200",
                 },
-            }, mxClient)).to.eventually.satisfy((attachment) => {
+            } as IMatrixEvent, mxClient)).to.eventually.satisfy((attachment) => {
                 expect(attachment.name).to.eq("filename.webm");
                 expect(attachment.attachment.length).to.eq(SMALL_FILE);
                 return true;
@@ -656,7 +676,7 @@ describe("MatrixEventProcessor", () => {
                     msgtype: "m.video",
                     url: "mxc://localhost/8000000",
                 },
-            }, mxClient)).to.eventually.eq("[filename.webm](https://localhost/8000000)");
+            } as IMatrixEvent, mxClient)).to.eventually.eq("[filename.webm](https://localhost/8000000)");
         });
         it("Should handle stickers.", () => {
             const processor = createMatrixEventProcessor();
@@ -670,7 +690,7 @@ describe("MatrixEventProcessor", () => {
                 },
                 sender: "@test:localhost",
                 type: "m.sticker",
-            }, mxClient)).to.eventually.satisfy((attachment) => {
+            } as IMatrixEvent, mxClient)).to.eventually.satisfy((attachment) => {
                 expect(attachment.name).to.eq("Bunnies.png");
                 return true;
             });
@@ -685,7 +705,7 @@ describe("MatrixEventProcessor", () => {
                 },
                 sender: "@test:localhost",
                 type: "m.room.message",
-            });
+            } as IMatrixEvent);
             expect(result).to.be.undefined;
         });
         it("should handle replies without a fallback", async () => {
@@ -701,7 +721,7 @@ describe("MatrixEventProcessor", () => {
                 },
                 sender: "@test:localhost",
                 type: "m.room.message",
-            });
+            } as IMatrixEvent);
             expect(result[0].description).to.be.equal("Hello!");
             expect(result[0].author.name).to.be.equal("Doggo!");
             expect(result[0].author.icon_url).to.be.equal("https://fakeurl.com");
@@ -723,7 +743,7 @@ This is where the reply goes`,
                 },
                 sender: "@test:localhost",
                 type: "m.room.message",
-            });
+            } as IMatrixEvent);
             expect(result[0].description).to.be.equal("Reply with unknown content");
             expect(result[0].author.name).to.be.equal("Unknown");
             expect(result[0].author.icon_url).to.be.undefined;
@@ -745,7 +765,7 @@ This is where the reply goes`,
                 },
                 sender: "@test:localhost",
                 type: "m.room.message",
-            });
+            } as IMatrixEvent);
             expect(result[0].description).to.be.equal("Hello!");
             expect(result[0].author.name).to.be.equal("Doggo!");
             expect(result[0].author.icon_url).to.be.equal("https://fakeurl.com");
@@ -767,7 +787,7 @@ This is the second reply`,
                 },
                 sender: "@test:localhost",
                 type: "m.room.message",
-            });
+            } as IMatrixEvent);
             expect(result[0].description).to.be.equal("This is the first reply");
             expect(result[0].author.name).to.be.equal("Doggo!");
             expect(result[0].author.icon_url).to.be.equal("https://fakeurl.com");
@@ -789,7 +809,7 @@ This is the reply`,
                 },
                 sender: "@test:localhost",
                 type: "m.room.message",
-            });
+            } as IMatrixEvent);
             expect(result[0].description).to.be.equal("Reply with unknown content");
             expect(result[0].author.name).to.be.equal("Doggo!");
             expect(result[0].author.icon_url).to.be.equal("https://fakeurl.com");
diff --git a/test/test_matrixroomhandler.ts b/test/test_matrixroomhandler.ts
index f96baa87c6a59d4c1a88d5aee4b5765ef951e88e..789b58943a992f146e8af2126ef9422027c27036 100644
--- a/test/test_matrixroomhandler.ts
+++ b/test/test_matrixroomhandler.ts
@@ -41,6 +41,8 @@ let USERSKICKED = 0;
 let USERSBANNED = 0;
 let USERSUNBANNED = 0;
 let MESSAGESENT: any = {};
+let USERSYNC_HANDLED = false;
+let MESSAGE_PROCCESS = "";
 
 function buildRequest(eventData) {
     if (eventData.unsigned === undefined) {
@@ -56,6 +58,8 @@ function createRH(opts: any = {}) {
     USERSKICKED = 0;
     USERSBANNED = 0;
     USERSUNBANNED = 0;
+    USERSYNC_HANDLED = false;
+    MESSAGE_PROCCESS = "";
     const bridge = {
         getBot: () => {
             return {
@@ -86,7 +90,9 @@ function createRH(opts: any = {}) {
     };
     const us = {
         EnsureJoin: async () => { },
-        OnMemberState: async () => "user_sync_handled",
+        OnMemberState: async () => {
+            USERSYNC_HANDLED = true;
+        },
         OnUpdateUser: async () => { },
     };
     const cs = {
@@ -126,9 +132,15 @@ function createRH(opts: any = {}) {
             const channel = new MockChannel();
             return {channel, botUser: true };
         },
-        ProcessMatrixMsgEvent: async () => "processed",
-        ProcessMatrixRedact: async () => "redacted",
-        ProcessMatrixStateEvent: async () => "stateevent",
+        ProcessMatrixMsgEvent: async () => {
+            MESSAGE_PROCCESS = "processed";
+        },
+        ProcessMatrixRedact: async () => {
+            MESSAGE_PROCCESS = "redacted";
+        },
+        ProcessMatrixStateEvent: async () => {
+            MESSAGE_PROCCESS = "stateevent";
+        },
         ThirdpartySearchForChannels: () => {
             return [];
         },
@@ -206,37 +218,48 @@ describe("MatrixRoomHandler", () => {
                 type: "m.potato",
                 unsigned: {age: AGE}}), null)).to.be.rejectedWith("Event not processed by bridge");
         });
-        it("should handle invites", () => {
+        it("should handle invites", async () => {
             const handler = createRH();
-            handler.HandleInvite = async (ev) => "invited";
-            return expect(handler.OnEvent(buildRequest({
+            let invited = false;
+            handler.HandleInvite = async (ev) => {
+                invited = true;
+            };
+            await handler.OnEvent(buildRequest({
                 content: {membership: "invite"},
-                type: "m.room.member"}), null)).to.eventually.equal("invited");
+                type: "m.room.member"}), null);
+            expect(invited).to.be.true;
         });
-        it("should handle own state updates", () => {
+        it("should handle own state updates", async () => {
             const handler = createRH();
-            return expect(handler.OnEvent(buildRequest({
+            await handler.OnEvent(buildRequest({
                 content: {membership: "join"},
                 state_key: "@_discord_12345:localhost",
-                type: "m.room.member"}), null)).to.eventually.equal("user_sync_handled");
+                type: "m.room.member"}), null);
+            expect(USERSYNC_HANDLED).to.be.true;
         });
-        it("should pass other member types to state event", () => {
+        it("should pass other member types to state event", async () => {
             const handler = createRH();
-            handler.HandleInvite = async (ev) => "invited";
-            return expect(handler.OnEvent(buildRequest({
+            let invited = false;
+            handler.HandleInvite = async (ev) => {
+                invited = true;
+            };
+            handler.OnEvent(buildRequest({
                 content: {membership: "join"},
                 state_key: "@bacon:localhost",
-                type: "m.room.member"}), null)).to.eventually.equal("stateevent");
+                type: "m.room.member"}), null);
+            expect(invited).to.be.false;
+            expect(MESSAGE_PROCCESS).equals("stateevent");
         });
-        it("should handle redactions with existing rooms", () => {
+        it("should handle redactions with existing rooms", async () => {
             const handler = createRH();
             const context = {
                 rooms: {
                     remote: true,
                 },
             };
-            return expect(handler.OnEvent(buildRequest({
-                type: "m.room.redaction"}), context)).to.eventually.equal("redacted");
+            await handler.OnEvent(buildRequest({
+                type: "m.room.redaction"}), context);
+            expect(MESSAGE_PROCCESS).equals("redacted");
         });
         it("should ignore redactions with no linked room", () => {
             const handler = createRH();
@@ -248,7 +271,7 @@ describe("MatrixRoomHandler", () => {
             return expect(handler.OnEvent(buildRequest({
                 type: "m.room.redaction"}), context)).to.be.rejectedWith("Event not processed by bridge");
         });
-        it("should process regular messages", () => {
+        it("should process regular messages", async () => {
             const handler = createRH();
             const context = {
                 rooms: {
@@ -257,10 +280,11 @@ describe("MatrixRoomHandler", () => {
                     },
                 },
             };
-            return expect(handler.OnEvent(buildRequest({
+            await handler.OnEvent(buildRequest({
                 content: {body: "abc"},
                 type: "m.room.message",
-            }), context)).to.eventually.equal("processed");
+            }), context);
+            expect(MESSAGE_PROCCESS).equals("processed");
         });
         it("should alert if encryption is turned on", () => {
             const handler = createRH();
@@ -276,13 +300,17 @@ describe("MatrixRoomHandler", () => {
                 type: "m.room.encryption",
             }), context)).to.eventually.be.fulfilled;
         });
-        it("should process !discord commands", () => {
+        it("should process !discord commands", async () => {
             const handler = createRH();
-            handler.ProcessCommand = async (ev) => "processedcmd";
-            return expect(handler.OnEvent(buildRequest({
+            let processedcmd = false;
+            handler.ProcessCommand = async (ev) => {
+                processedcmd = true;
+            };
+            await handler.OnEvent(buildRequest({
                 content: {body: "!discord cmd"},
                 type: "m.room.message",
-            }), null)).to.eventually.equal("processedcmd");
+            }), null);
+            expect(processedcmd).to.be.true;
         });
         it("should ignore regular messages with no linked room", () => {
             const handler = createRH();
@@ -296,7 +324,7 @@ describe("MatrixRoomHandler", () => {
                 type: "m.room.message",
             }), context)).to.be.rejectedWith("Event not processed by bridge");
         });
-        it("should process stickers", () => {
+        it("should process stickers", async () => {
             const handler = createRH();
             const context = {
                 rooms: {
@@ -305,13 +333,14 @@ describe("MatrixRoomHandler", () => {
                     },
                 },
             };
-            return expect(handler.OnEvent(buildRequest({
+            await handler.OnEvent(buildRequest({
                 content: {
                     body: "abc",
                     url: "mxc://abc",
                 },
                 type: "m.sticker",
-            }), context)).to.eventually.equal("processed");
+            }), context);
+            expect(MESSAGE_PROCCESS).equals("processed");
         });
     });
     describe("HandleInvite", () => {
diff --git a/test/test_usersyncroniser.ts b/test/test_usersyncroniser.ts
index b349475152d1aab8d9738ecc1421f2a80f95eab3..b8febd30713183283daa2656a0aedc0549d6f9a2 100644
--- a/test/test_usersyncroniser.ts
+++ b/test/test_usersyncroniser.ts
@@ -8,6 +8,7 @@ import * as Proxyquire from "proxyquire";
 import {MockMember} from "./mocks/member";
 import {MockGuild} from "./mocks/guild";
 import { MockChannel } from "./mocks/channel";
+import { IMatrixEvent } from "../src/util";
 
 // we are a test file and thus need those
 /* tslint:disable:no-unused-expression max-file-line-count no-any */
@@ -511,46 +512,46 @@ describe("UserSyncroniser", () => {
    });
    describe("OnMemberState", () => {
        it("will update state for rooms", async () => {
-           const userSync = CreateUserSync([new RemoteUser("123456")]);
-           return userSync.OnMemberState({
-               content: {
+            const userSync = CreateUserSync([new RemoteUser("123456")]);
+            return userSync.OnMemberState({
+                content: {
 
-               },
-               room_id: "!found:localhost",
-               state_key: "123456",
-           }, 0).then(() => {
-                expect(SEV_COUNT).to.equal(1);
-           });
+                },
+                room_id: "!found:localhost",
+                state_key: "123456",
+            } as IMatrixEvent, 0).then(() => {
+                 expect(SEV_COUNT).to.equal(1);
+            });
        });
        it("will not update state for a unknown user", async () => {
-           const userSync = CreateUserSync([]);
-           return expect(userSync.OnMemberState({
-               content: {
+            const userSync = CreateUserSync([]);
+            return expect(userSync.OnMemberState({
+                content: {
 
-               },
-               room_id: "!abcdef:localhost",
-               state_key: "123456",
-            }, 0)).to.eventually.equal(UserSyncroniser.ERR_USER_NOT_FOUND);
+                },
+                room_id: "!abcdef:localhost",
+                state_key: "123456",
+            } as IMatrixEvent, 0)).to.eventually.equal(UserSyncroniser.ERR_USER_NOT_FOUND);
        });
        it("will not update state for a unknown room", async () => {
             const userSync = CreateUserSync([new RemoteUser("123456")]);
             return expect(userSync.OnMemberState({
-               content: {
+                content: {
 
-               },
-               room_id: "!notfound:localhost",
-               state_key: "123456",
-            }, 0)).to.eventually.equal(UserSyncroniser.ERR_CHANNEL_MEMBER_NOT_FOUND);
+                },
+                room_id: "!notfound:localhost",
+                state_key: "123456",
+            } as IMatrixEvent, 0)).to.eventually.equal(UserSyncroniser.ERR_CHANNEL_MEMBER_NOT_FOUND);
        });
        it("will not update state for a member not found in the channel", async () => {
             const userSync = CreateUserSync([new RemoteUser("111222")]);
             return expect(userSync.OnMemberState({
-               content: {
+                content: {
 
-               },
-               room_id: "!found:localhost",
-               state_key: "111222",
-            }, 0)).to.eventually.equal(UserSyncroniser.ERR_CHANNEL_MEMBER_NOT_FOUND);
+                },
+                room_id: "!found:localhost",
+                state_key: "111222",
+            } as IMatrixEvent, 0)).to.eventually.equal(UserSyncroniser.ERR_CHANNEL_MEMBER_NOT_FOUND);
        });
        it("will not process old events", async () => {
             const DELAY_MS = 250;
@@ -562,35 +563,36 @@ describe("UserSyncroniser", () => {
                     origin_server_ts: 10000,
                     room_id: "!found:localhost",
                     state_key: "123456",
-                }, DELAY_MS)).to.eventually.equal(UserSyncroniser.ERR_NEWER_EVENT, "State 1 Failed"),
+                } as IMatrixEvent, DELAY_MS))
+                    .to.eventually.equal(UserSyncroniser.ERR_NEWER_EVENT, "State 1 Failed"),
                 expect(userSync.OnMemberState({
                     content: { },
                     event_id: "QuiteOld:localhost",
                     origin_server_ts: 7000,
                     room_id: "!found:localhost",
                     state_key: "123456",
-                }, DELAY_MS)).to.eventually.equal(UserSyncroniser.ERR_NEWER_EVENT, "State 2 Failed"),
+                } as IMatrixEvent, DELAY_MS)).to.eventually.equal(UserSyncroniser.ERR_NEWER_EVENT, "State 2 Failed"),
                 expect(userSync.OnMemberState({
                     content: { },
                     event_id: "FreshEnough:localhost",
                     origin_server_ts: 3000,
                     room_id: "!found:localhost",
                     state_key: "123456",
-                }, DELAY_MS)).to.eventually.equal(UserSyncroniser.ERR_NEWER_EVENT, "State 3 Failed"),
+                } as IMatrixEvent, DELAY_MS)).to.eventually.equal(UserSyncroniser.ERR_NEWER_EVENT, "State 3 Failed"),
                 expect(userSync.OnMemberState({
                     content: { },
                     event_id: "GettingOnABit:localhost",
                     origin_server_ts: 4000,
                     room_id: "!found:localhost",
                     state_key: "123456",
-                }, DELAY_MS)).to.eventually.equal(UserSyncroniser.ERR_NEWER_EVENT, "State 4 Failed"),
+                } as IMatrixEvent, DELAY_MS)).to.eventually.equal(UserSyncroniser.ERR_NEWER_EVENT, "State 4 Failed"),
                 expect(userSync.OnMemberState({
                     content: { },
                     event_id: "FreshOutTheOven:localhost",
                     origin_server_ts: 100,
                     room_id: "!found:localhost",
                     state_key: "123456",
-                }, DELAY_MS)).to.eventually.be.fulfilled,
+                } as IMatrixEvent, DELAY_MS)).to.eventually.be.fulfilled,
             ]);
        });
    });