diff --git a/package.json b/package.json
index 5566300968bf18cd7cef48723e7aad801484f95e..5b7c30c2662ba06aa283958bb291ef33682f8dce 100644
--- a/package.json
+++ b/package.json
@@ -29,7 +29,9 @@
   },
   "homepage": "https://github.com/Half-Shot/matrix-appservice-discord#readme",
   "dependencies": {
+    "@types/bluebird": "^3.0.37",
     "@types/node": "^7.0.5",
+    "@types/sqlite3": "^2.2.32",
     "bluebird": "^3.4.7",
     "discord.js": "^11.0.0",
     "js-yaml": "^3.8.1",
@@ -37,6 +39,7 @@
     "matrix-appservice-bridge": "^1.3.5",
     "mime": "^1.3.4",
     "npmlog": "^4.0.2",
+    "sqlite3": "^3.1.8",
     "tslint": "^4.4.2",
     "typescript": "^2.1.6"
   },
diff --git a/src/dbschema/dbschema.ts b/src/dbschema/dbschema.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e8b7cfdc625be7662f5e0cad1a910c78efd9025c
--- /dev/null
+++ b/src/dbschema/dbschema.ts
@@ -0,0 +1,5 @@
+import { DiscordStore } from "../discordstore";
+export interface IDbSchema {
+  description: string,
+  run(store: DiscordStore): Promise<null>;
+}
diff --git a/src/dbschema/v1.ts b/src/dbschema/v1.ts
new file mode 100644
index 0000000000000000000000000000000000000000..474544f7cfa27b50984e0711a479046c81c731bc
--- /dev/null
+++ b/src/dbschema/v1.ts
@@ -0,0 +1,19 @@
+import {IDbSchema} from "./dbschema";
+import {DiscordStore} from "../discordstore";
+export class Schema implements IDbSchema {
+  public description = "Schema, Client Auth Table";
+  public run(store: DiscordStore): Promise<null> {
+    return store.create_table(`
+    CREATE TABLE schema (
+      version	INTEGER UNIQUE NOT NULL
+    );`, "schema").then(() => {
+      return store.db.runAsync("INSERT INTO schema VALUES (0);");
+    }).then(() => {
+      return store.create_table(`
+      CREATE TABLE user_tokens (
+        userId TEXT UNIQUE NOT NULL,
+        token TEXT UNIQUE NOT NULL
+      );`, "user_tokens");
+    })
+  }
+}
diff --git a/src/discordas.ts b/src/discordas.ts
index 1b5807922f2be99e8333ae361d5b6d772e7a6267..7d913fcb1f6cf94f9c3b1f8cedacada77a437fa4 100644
--- a/src/discordas.ts
+++ b/src/discordas.ts
@@ -5,6 +5,7 @@ import * as fs from "fs";
 import { DiscordBridgeConfig } from "./config";
 import { DiscordBot } from "./discordbot";
 import { MatrixRoomHandler } from "./matrixroomhandler";
+import { DiscordStore } from "./discordstore";
 
 const cli = new Cli({
   bridgeConfig: {
@@ -47,26 +48,21 @@ function run (port: number, config: DiscordBridgeConfig) {
     token: registration.as_token,
     url: config.bridge.homeserverUrl,
   });
-  const discordbot = new DiscordBot(config);
+  const discordstore = new DiscordStore("discord.db");
+  const discordbot = new DiscordBot(config, discordstore);
   const roomhandler = new MatrixRoomHandler(discordbot, config, botUserId);
 
   const bridge = new Bridge({
     clientFactory,
     controller: {
       // onUserQuery: userQuery,
-      onAliasQuery: (alias, aliasLocalpart) => {
-        return roomhandler.OnAliasQuery(alias, aliasLocalpart);
-      },
+      onAliasQuery: roomhandler.OnAliasQuery.bind(roomhandler),
       onEvent: roomhandler.OnEvent.bind(roomhandler),
       onAliasQueried: roomhandler.OnAliasQueried.bind(roomhandler),
       thirdPartyLookup: roomhandler.ThirdPartyLookup,
-      // onLog: function (line, isError) {
-      //   if(isError) {
-      //     if(line.indexOf("M_USER_IN_USE") === -1) {//QUIET!
-      //       log.warn("matrix-appservice-bridge", line);
-      //     }
-      //   }
-      // }
+      onLog: (line, isError) => {
+        log.verbose("matrix-appservice-bridge", line);
+      }
     },
     domain: config.bridge.domain,
     homeserverUrl: config.bridge.homeserverUrl,
@@ -74,9 +70,12 @@ function run (port: number, config: DiscordBridgeConfig) {
   });
   roomhandler.setBridge(bridge);
   discordbot.setBridge(bridge);
-
+  log.info("discordas", "Initing bridge.");
   log.info("AppServ", "Started listening on port %s at %s", port, new Date().toUTCString() );
   bridge.run(port, config);
-  discordbot.run();
-
+  log.info("discordas", "Initing store.");
+  discordstore.init().then(() => {
+    log.info("discordas", "Initing bot.");
+    return discordbot.run();
+  });
 }
diff --git a/src/discordstore.ts b/src/discordstore.ts
new file mode 100644
index 0000000000000000000000000000000000000000..83d981799427fccf16ef07326016789f5b114f4a
--- /dev/null
+++ b/src/discordstore.ts
@@ -0,0 +1,121 @@
+import * as SQLite3 from "sqlite3";
+import * as log from "npmlog";
+import * as Bluebird from "bluebird";
+import { IDbSchema } from "./dbschema/dbschema";
+
+const CURRENT_SCHEMA = 1;
+/**
+ * Stores data for specific users and data not specific to rooms.
+ */
+export class DiscordStore {
+  /**
+   * @param  {string} filepath Location of the SQLite database file.
+   */
+  public db: any;
+  private version: number;
+  constructor (filepath) {
+    this.db = new SQLite3.Database(filepath, (err) => {
+      if (err) {
+        log.error("DiscordStore", "Error opening database, %s");
+        throw new Error("Couldn't open database. The appservice won't be able to continue.");
+      }
+    });
+    this.db = Bluebird.promisifyAll(this.db);
+    this.version = null;
+  }
+
+  /**
+   * Checks the database has all the tables needed.
+   */
+  public init () {
+    log.info("DiscordStore", "Starting DB Init");
+    let oldVersion;
+    let version;
+    return this.getSchemaVersion().then( (v) => {
+      oldVersion = v;
+      version = v;
+      let promises = [];
+      while (version < CURRENT_SCHEMA) {
+        version++;
+        const schemaClass = require(`./dbschema/v${version}.js`).Schema;
+        const schema = (new schemaClass() as IDbSchema);
+        log.info("DiscordStore", `Updating database to v${version}, ${schema.description}`);
+        promises.push(schema.run(this).then(() => {
+          log.info("DiscordStore", "Updated database v%s", version);
+        }));
+        this.version = version;
+      }
+      return Promise.all(promises);
+    }).then( () => {
+      return this.setSchemaVersion(oldVersion, version).then( () => {
+        log.info("DiscordStore", "Updated database to the latest schema");
+      });
+    }).catch( (err) => {
+      log.error("DiscordStore", "Couldn't update database to the latest version! Bailing");
+      throw err;
+    });
+  }
+
+  public create_table (statement, tablename) {
+    return this.db.runAsync(statement).then(() => {
+      log.info("DiscordStore", "Created table ", tablename);
+    }).catch((err) => {
+      throw new Error(`Error creating '${tablename}': ${err}`);
+    });
+  }
+
+  public close () {
+    this.db.close();
+  }
+
+  public set_user_token(userId: string, token: string) {
+    log.silly("SQL", "set_user_token => %s", userId);
+    return this.db.runAsync(
+      `REPLACE INTO user_tokens (userId,token) VALUES ($id,$token);`
+    , {
+      $id: userId,
+      $token: token
+    }).catch(err => {
+      log.error("TwitDB", "Error storing user token %s", err);
+      throw err;
+    });
+  }
+
+  public get_user_token(userId: string): Promise<string> {
+    log.silly("SQL", "get_user_token => %s", userId);
+    return this.db.getAsync(
+      `
+      SELECT token
+      FROM user_tokens
+      WHERE user_tokens.userId = $id;
+      `
+    , {
+      $id: userId
+    }).then(row => {
+      return row !== undefined ? row.token : null;
+    }).catch( err => {
+      log.error("TwitDB", "Error getting user token  %s", err.Error);
+      throw err;
+    });
+  }
+
+  private getSchemaVersion ( ) {
+    log.silly("DiscordStore", "_get_schema_version");
+    return this.db.getAsync(`SELECT version FROM schema`).then((row) => {
+      return row === undefined ? 0 : row.version;
+    }).catch( ()  => {
+      return 0;
+    });
+  }
+
+  private setSchemaVersion (oldVer: number, ver: number) {
+    log.silly("DiscordStore", "_set_schema_version => %s", ver);
+    return this.db.getAsync(
+      `
+      UPDATE schema
+      SET version = $ver
+      WHERE version = $old_ver
+      `, {$ver: ver, $old_ver: oldVer},
+    );
+  }
+}