diff --git a/backend/package-lock.json b/backend/package-lock.json
index 932f7973..1903f9f8 100644
--- a/backend/package-lock.json
+++ b/backend/package-lock.json
@@ -1010,6 +1010,7 @@
       "requires": {
         "anymatch": "~3.1.1",
         "braces": "~3.0.2",
+        "fsevents": "~2.1.2",
         "glob-parent": "~5.1.0",
         "is-binary-path": "~2.1.0",
         "is-glob": "~4.0.1",
@@ -1841,6 +1842,13 @@
       "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
       "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
     },
+    "fsevents": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
+      "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
+      "dev": true,
+      "optional": true
+    },
     "function-bind": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
@@ -2364,19 +2372,12 @@
       }
     },
     "knub": {
-      "version": "30.0.0-beta.21",
-      "resolved": "https://registry.npmjs.org/knub/-/knub-30.0.0-beta.21.tgz",
-      "integrity": "sha512-BkMLgqqw7AroarZpsQ0wK93Yk2cFBRJa8GmFPYogiXEDTA/47oQ+A21SpbRCfZ2sCxFdjdZPUZIPqgjG38H7YQ==",
+      "version": "30.0.0-beta.23",
+      "resolved": "https://registry.npmjs.org/knub/-/knub-30.0.0-beta.23.tgz",
+      "integrity": "sha512-kBlQQAc6IPqyVA832wR567qUdE2EZIJUGTgUQE8NGmx7MxQrqZ7yvK1+Mkzh3HlNBgnrAgMorRimQHeO+xEXxw==",
       "requires": {
         "knub-command-manager": "^8.1.2",
         "ts-essentials": "^6.0.7"
-      },
-      "dependencies": {
-        "escape-string-regexp": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
-          "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w=="
-        }
       }
     },
     "knub-command-manager": {
diff --git a/backend/package.json b/backend/package.json
index 2c3ba2ac..2f49ee42 100644
--- a/backend/package.json
+++ b/backend/package.json
@@ -38,7 +38,7 @@
     "humanize-duration": "^3.15.0",
     "io-ts": "^2.0.0",
     "js-yaml": "^3.13.1",
-    "knub": "^30.0.0-beta.21",
+    "knub": "^30.0.0-beta.23",
     "knub-command-manager": "^8.1.2",
     "last-commit-log": "^2.1.0",
     "lodash.chunk": "^4.2.0",
diff --git a/backend/src/pluginUtils.ts b/backend/src/pluginUtils.ts
index 8125ca68..849eb53b 100644
--- a/backend/src/pluginUtils.ts
+++ b/backend/src/pluginUtils.ts
@@ -3,27 +3,20 @@
  */
 
 import { Member } from "eris";
-import {
-  CommandContext,
-  configUtils,
-  ConfigValidationError,
-  helpers,
-  PluginBlueprint,
-  PluginData,
-  PluginOptions,
-} from "knub";
+import { CommandContext, configUtils, ConfigValidationError, GuildPluginData, helpers, PluginOptions } from "knub";
 import { decodeAndValidateStrict, StrictValidationError, validate } from "./validatorUtils";
 import { deepKeyIntersect, errorMessage, successMessage, tDeepPartial, tNullable } from "./utils";
-import { ZeppelinPluginBlueprint } from "./plugins/ZeppelinPluginBlueprint";
 import { TZeppelinKnub } from "./types";
 import { ExtendedMatchParams } from "knub/dist/config/PluginConfigManager"; // TODO: Export from Knub index
 import * as t from "io-ts";
 import { PluginOverrideCriteria } from "knub/dist/config/configTypes";
 import { Tail } from "./utils/typeUtils";
+import { AnyPluginData } from "knub/dist/plugins/PluginData";
+import { ZeppelinPlugin } from "./plugins/ZeppelinPlugin";
 
 const { getMemberLevel } = helpers;
 
-export function canActOn(pluginData: PluginData<any>, member1: Member, member2: Member, allowSameLevel = false) {
+export function canActOn(pluginData: GuildPluginData<any>, member1: Member, member2: Member, allowSameLevel = false) {
   if (member2.id === pluginData.client.user.id) {
     return false;
   }
@@ -33,7 +26,7 @@ export function canActOn(pluginData: PluginData<any>, member1: Member, member2:
   return allowSameLevel ? ourLevel >= memberLevel : ourLevel > memberLevel;
 }
 
-export function hasPermission(pluginData: PluginData<any>, permission: string, matchParams: ExtendedMatchParams) {
+export function hasPermission(pluginData: AnyPluginData<any>, permission: string, matchParams: ExtendedMatchParams) {
   const config = pluginData.config.getMatchingConfig(matchParams);
   return helpers.hasPermission(config, permission);
 }
@@ -71,8 +64,8 @@ export function strictValidationErrorToConfigValidationError(err: StrictValidati
 }
 
 export function getPluginConfigPreprocessor(
-  blueprint: ZeppelinPluginBlueprint,
-  customPreprocessor?: PluginBlueprint<any>["configPreprocessor"],
+  blueprint: ZeppelinPlugin,
+  customPreprocessor?: ZeppelinPlugin["configPreprocessor"],
 ) {
   return async (options: PluginOptions<any>) => {
     // 1. Validate the basic structure of plugin config
@@ -141,22 +134,22 @@ export function getPluginConfigPreprocessor(
   };
 }
 
-export function sendSuccessMessage(pluginData: PluginData<any>, channel, body) {
-  const emoji = pluginData.guildConfig.success_emoji || undefined;
+export function sendSuccessMessage(pluginData: AnyPluginData<any>, channel, body) {
+  const emoji = pluginData.fullConfig.success_emoji || undefined;
   return channel.createMessage(successMessage(body, emoji));
 }
 
-export function sendErrorMessage(pluginData: PluginData<any>, channel, body) {
-  const emoji = pluginData.guildConfig.error_emoji || undefined;
+export function sendErrorMessage(pluginData: AnyPluginData<any>, channel, body) {
+  const emoji = pluginData.fullConfig.error_emoji || undefined;
   return channel.createMessage(errorMessage(body, emoji));
 }
 
-export function getBaseUrl(pluginData: PluginData<any>) {
+export function getBaseUrl(pluginData: AnyPluginData<any>) {
   const knub = pluginData.getKnubInstance() as TZeppelinKnub;
   return knub.getGlobalConfig().url;
 }
 
-export function isOwner(pluginData: PluginData<any>, userId: string) {
+export function isOwner(pluginData: AnyPluginData<any>, userId: string) {
   const knub = pluginData.getKnubInstance() as TZeppelinKnub;
   const owners = knub.getGlobalConfig().owners;
   if (!owners) {
diff --git a/backend/src/plugins/AutoDelete/AutoDeletePlugin.ts b/backend/src/plugins/AutoDelete/AutoDeletePlugin.ts
index 7b5d47aa..ed8aa590 100644
--- a/backend/src/plugins/AutoDelete/AutoDeletePlugin.ts
+++ b/backend/src/plugins/AutoDelete/AutoDeletePlugin.ts
@@ -1,8 +1,8 @@
 import { PluginOptions } from "knub";
 import { AutoDeletePluginType, ConfigSchema } from "./types";
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
-import { GuildSavedMessages } from "src/data/GuildSavedMessages";
-import { GuildLogs } from "src/data/GuildLogs";
+import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
+import { GuildSavedMessages } from "../../data/GuildSavedMessages";
+import { GuildLogs } from "../../data/GuildLogs";
 import { onMessageCreate } from "./util/onMessageCreate";
 import { onMessageDelete } from "./util/onMessageDelete";
 import { onMessageDeleteBulk } from "./util/onMessageDeleteBulk";
@@ -15,7 +15,7 @@ const defaultOptions: PluginOptions<AutoDeletePluginType> = {
   },
 };
 
-export const AutoDeletePlugin = zeppelinPlugin<AutoDeletePluginType>()("auto_delete", {
+export const AutoDeletePlugin = zeppelinGuildPlugin<AutoDeletePluginType>()("auto_delete", {
   showInDocs: true,
   info: {
     prettyName: "Auto-delete",
diff --git a/backend/src/plugins/AutoDelete/types.ts b/backend/src/plugins/AutoDelete/types.ts
index 1eb9342d..bcb285b5 100644
--- a/backend/src/plugins/AutoDelete/types.ts
+++ b/backend/src/plugins/AutoDelete/types.ts
@@ -1,9 +1,9 @@
 import * as t from "io-ts";
-import { BasePluginType } from "knub";
-import { tDelayString, MINUTES } from "src/utils";
-import { GuildLogs } from "src/data/GuildLogs";
-import { GuildSavedMessages } from "src/data/GuildSavedMessages";
-import { SavedMessage } from "src/data/entities/SavedMessage";
+import { BasePluginType, guildCommand, guildEventListener } from "knub";
+import { tDelayString, MINUTES } from "../../utils";
+import { GuildLogs } from "../../data/GuildLogs";
+import { GuildSavedMessages } from "../../data/GuildSavedMessages";
+import { SavedMessage } from "../../data/entities/SavedMessage";
 
 export const MAX_DELAY = 5 * MINUTES;
 
diff --git a/backend/src/plugins/AutoDelete/util/addMessageToDeletionQueue.ts b/backend/src/plugins/AutoDelete/util/addMessageToDeletionQueue.ts
index b727a3bc..21788d58 100644
--- a/backend/src/plugins/AutoDelete/util/addMessageToDeletionQueue.ts
+++ b/backend/src/plugins/AutoDelete/util/addMessageToDeletionQueue.ts
@@ -1,11 +1,11 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { AutoDeletePluginType } from "../types";
-import { SavedMessage } from "src/data/entities/SavedMessage";
+import { SavedMessage } from "../../../data/entities/SavedMessage";
 import { scheduleNextDeletion } from "./scheduleNextDeletion";
-import { sorter } from "src/utils";
+import { sorter } from "../../../utils";
 
 export function addMessageToDeletionQueue(
-  pluginData: PluginData<AutoDeletePluginType>,
+  pluginData: GuildPluginData<AutoDeletePluginType>,
   msg: SavedMessage,
   delay: number,
 ) {
diff --git a/backend/src/plugins/AutoDelete/util/deleteNextItem.ts b/backend/src/plugins/AutoDelete/util/deleteNextItem.ts
index 68a10eb0..5bd7a790 100644
--- a/backend/src/plugins/AutoDelete/util/deleteNextItem.ts
+++ b/backend/src/plugins/AutoDelete/util/deleteNextItem.ts
@@ -1,13 +1,13 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { AutoDeletePluginType } from "../types";
 import moment from "moment-timezone";
-import { LogType } from "src/data/LogType";
-import { stripObjectToScalars, resolveUser } from "src/utils";
-import { logger } from "src/logger";
+import { LogType } from "../../../data/LogType";
+import { stripObjectToScalars, resolveUser } from "../../../utils";
+import { logger } from "../../../logger";
 import { scheduleNextDeletion } from "./scheduleNextDeletion";
 import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin";
 
-export async function deleteNextItem(pluginData: PluginData<AutoDeletePluginType>) {
+export async function deleteNextItem(pluginData: GuildPluginData<AutoDeletePluginType>) {
   const [itemToDelete] = pluginData.state.deletionQueue.splice(0, 1);
   if (!itemToDelete) return;
 
diff --git a/backend/src/plugins/AutoDelete/util/onMessageCreate.ts b/backend/src/plugins/AutoDelete/util/onMessageCreate.ts
index 11dad95d..20773ed8 100644
--- a/backend/src/plugins/AutoDelete/util/onMessageCreate.ts
+++ b/backend/src/plugins/AutoDelete/util/onMessageCreate.ts
@@ -1,11 +1,11 @@
 import { AutoDeletePluginType, MAX_DELAY } from "../types";
-import { PluginData } from "knub";
-import { SavedMessage } from "src/data/entities/SavedMessage";
-import { convertDelayStringToMS, resolveMember } from "src/utils";
-import { LogType } from "src/data/LogType";
+import { GuildPluginData } from "knub";
+import { SavedMessage } from "../../../data/entities/SavedMessage";
+import { convertDelayStringToMS, resolveMember } from "../../../utils";
+import { LogType } from "../../../data/LogType";
 import { addMessageToDeletionQueue } from "./addMessageToDeletionQueue";
 
-export async function onMessageCreate(pluginData: PluginData<AutoDeletePluginType>, msg: SavedMessage) {
+export async function onMessageCreate(pluginData: GuildPluginData<AutoDeletePluginType>, msg: SavedMessage) {
   const member = await resolveMember(pluginData.client, pluginData.guild, msg.user_id);
   const config = pluginData.config.getMatchingConfig({ member, channelId: msg.channel_id });
   if (config.enabled) {
diff --git a/backend/src/plugins/AutoDelete/util/onMessageDelete.ts b/backend/src/plugins/AutoDelete/util/onMessageDelete.ts
index e0e96382..98eb2816 100644
--- a/backend/src/plugins/AutoDelete/util/onMessageDelete.ts
+++ b/backend/src/plugins/AutoDelete/util/onMessageDelete.ts
@@ -1,9 +1,9 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { AutoDeletePluginType } from "../types";
-import { SavedMessage } from "src/data/entities/SavedMessage";
+import { SavedMessage } from "../../../data/entities/SavedMessage";
 import { scheduleNextDeletion } from "./scheduleNextDeletion";
 
-export function onMessageDelete(pluginData: PluginData<AutoDeletePluginType>, msg: SavedMessage) {
+export function onMessageDelete(pluginData: GuildPluginData<AutoDeletePluginType>, msg: SavedMessage) {
   const indexToDelete = pluginData.state.deletionQueue.findIndex(item => item.message.id === msg.id);
   if (indexToDelete > -1) {
     pluginData.state.deletionQueue.splice(indexToDelete, 1);
diff --git a/backend/src/plugins/AutoDelete/util/onMessageDeleteBulk.ts b/backend/src/plugins/AutoDelete/util/onMessageDeleteBulk.ts
index 9993254c..b48f8f89 100644
--- a/backend/src/plugins/AutoDelete/util/onMessageDeleteBulk.ts
+++ b/backend/src/plugins/AutoDelete/util/onMessageDeleteBulk.ts
@@ -1,9 +1,9 @@
 import { AutoDeletePluginType } from "../types";
-import { PluginData } from "knub";
-import { SavedMessage } from "src/data/entities/SavedMessage";
+import { GuildPluginData } from "knub";
+import { SavedMessage } from "../../../data/entities/SavedMessage";
 import { onMessageDelete } from "./onMessageDelete";
 
-export function onMessageDeleteBulk(pluginData: PluginData<AutoDeletePluginType>, messages: SavedMessage[]) {
+export function onMessageDeleteBulk(pluginData: GuildPluginData<AutoDeletePluginType>, messages: SavedMessage[]) {
   for (const msg of messages) {
     onMessageDelete(pluginData, msg);
   }
diff --git a/backend/src/plugins/AutoDelete/util/scheduleNextDeletion.ts b/backend/src/plugins/AutoDelete/util/scheduleNextDeletion.ts
index 5a9f2797..60c47088 100644
--- a/backend/src/plugins/AutoDelete/util/scheduleNextDeletion.ts
+++ b/backend/src/plugins/AutoDelete/util/scheduleNextDeletion.ts
@@ -1,8 +1,8 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { AutoDeletePluginType } from "../types";
 import { deleteNextItem } from "./deleteNextItem";
 
-export function scheduleNextDeletion(pluginData: PluginData<AutoDeletePluginType>) {
+export function scheduleNextDeletion(pluginData: GuildPluginData<AutoDeletePluginType>) {
   if (pluginData.state.deletionQueue.length === 0) {
     clearTimeout(pluginData.state.nextDeletionTimeout);
     return;
diff --git a/backend/src/plugins/AutoReactions/AutoReactionsPlugin.ts b/backend/src/plugins/AutoReactions/AutoReactionsPlugin.ts
index 573bd1e6..c779b46e 100644
--- a/backend/src/plugins/AutoReactions/AutoReactionsPlugin.ts
+++ b/backend/src/plugins/AutoReactions/AutoReactionsPlugin.ts
@@ -1,10 +1,10 @@
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
+import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
 import { AutoReactionsPluginType, ConfigSchema } from "./types";
 import { PluginOptions } from "knub";
 import { NewAutoReactionsCmd } from "./commands/NewAutoReactionsCmd";
 import { DisableAutoReactionsCmd } from "./commands/DisableAutoReactionsCmd";
-import { GuildSavedMessages } from "src/data/GuildSavedMessages";
-import { GuildAutoReactions } from "src/data/GuildAutoReactions";
+import { GuildSavedMessages } from "../../data/GuildSavedMessages";
+import { GuildAutoReactions } from "../../data/GuildAutoReactions";
 import { AddReactionsEvt } from "./events/AddReactionsEvt";
 import { trimPluginDescription } from "../../utils";
 import { LogsPlugin } from "../Logs/LogsPlugin";
@@ -23,7 +23,7 @@ const defaultOptions: PluginOptions<AutoReactionsPluginType> = {
   ],
 };
 
-export const AutoReactionsPlugin = zeppelinPlugin<AutoReactionsPluginType>()("auto_reactions", {
+export const AutoReactionsPlugin = zeppelinGuildPlugin<AutoReactionsPluginType>()("auto_reactions", {
   showInDocs: true,
   info: {
     prettyName: "Auto-reactions",
diff --git a/backend/src/plugins/AutoReactions/commands/DisableAutoReactionsCmd.ts b/backend/src/plugins/AutoReactions/commands/DisableAutoReactionsCmd.ts
index 1d95e9ba..5f2d82cf 100644
--- a/backend/src/plugins/AutoReactions/commands/DisableAutoReactionsCmd.ts
+++ b/backend/src/plugins/AutoReactions/commands/DisableAutoReactionsCmd.ts
@@ -1,6 +1,6 @@
 import { autoReactionsCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
-import { sendErrorMessage, sendSuccessMessage } from "src/pluginUtils";
+import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
 
 export const DisableAutoReactionsCmd = autoReactionsCmd({
   trigger: "auto_reactions disable",
diff --git a/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts b/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts
index 18c05f9f..fc742868 100644
--- a/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts
+++ b/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts
@@ -1,7 +1,7 @@
 import { autoReactionsCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
-import { canUseEmoji, customEmojiRegex, isEmoji } from "src/utils";
-import { sendErrorMessage, sendSuccessMessage } from "src/pluginUtils";
+import { canUseEmoji, customEmojiRegex, isEmoji } from "../../../utils";
+import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
 import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions";
 import { Constants, GuildChannel } from "eris";
 import { readChannelPermissions } from "../../../utils/readChannelPermissions";
diff --git a/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts b/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts
index 7e47a53f..281f48eb 100644
--- a/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts
+++ b/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts
@@ -1,6 +1,6 @@
 import { autoReactionsEvt } from "../types";
-import { isDiscordRESTError } from "src/utils";
-import { LogType } from "src/data/LogType";
+import { isDiscordRESTError } from "../../../utils";
+import { LogType } from "../../../data/LogType";
 import { logger } from "../../../logger";
 import { LogsPlugin } from "../../Logs/LogsPlugin";
 import { Constants, GuildChannel } from "eris";
diff --git a/backend/src/plugins/AutoReactions/types.ts b/backend/src/plugins/AutoReactions/types.ts
index 0f50993e..a7e6f3ab 100644
--- a/backend/src/plugins/AutoReactions/types.ts
+++ b/backend/src/plugins/AutoReactions/types.ts
@@ -1,8 +1,8 @@
 import * as t from "io-ts";
-import { BasePluginType, command, eventListener } from "knub";
-import { GuildLogs } from "src/data/GuildLogs";
-import { GuildSavedMessages } from "src/data/GuildSavedMessages";
-import { GuildAutoReactions } from "src/data/GuildAutoReactions";
+import { BasePluginType, guildCommand, guildEventListener } from "knub";
+import { GuildLogs } from "../../data/GuildLogs";
+import { GuildSavedMessages } from "../../data/GuildSavedMessages";
+import { GuildAutoReactions } from "../../data/GuildAutoReactions";
 
 export const ConfigSchema = t.type({
   can_manage: t.boolean,
@@ -18,5 +18,5 @@ export interface AutoReactionsPluginType extends BasePluginType {
   };
 }
 
-export const autoReactionsCmd = command<AutoReactionsPluginType>();
-export const autoReactionsEvt = eventListener<AutoReactionsPluginType>();
+export const autoReactionsCmd = guildCommand<AutoReactionsPluginType>();
+export const autoReactionsEvt = guildEventListener<AutoReactionsPluginType>();
diff --git a/backend/src/plugins/Automod/AutomodPlugin.ts b/backend/src/plugins/Automod/AutomodPlugin.ts
index 17beba3e..c93b884b 100644
--- a/backend/src/plugins/Automod/AutomodPlugin.ts
+++ b/backend/src/plugins/Automod/AutomodPlugin.ts
@@ -1,4 +1,4 @@
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
+import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
 import { AutomodPluginType, ConfigSchema } from "./types";
 import { RunAutomodOnJoinEvt } from "./events/RunAutomodOnJoinEvt";
 import { GuildLogs } from "../../data/GuildLogs";
@@ -147,7 +147,7 @@ const configPreprocessor: ConfigPreprocessorFn<AutomodPluginType> = options => {
   return options;
 };
 
-export const AutomodPlugin = zeppelinPlugin<AutomodPluginType>()("automod", {
+export const AutomodPlugin = zeppelinGuildPlugin<AutomodPluginType>()("automod", {
   showInDocs: true,
   info: pluginInfo,
 
diff --git a/backend/src/plugins/Automod/commands/AntiraidClearCmd.ts b/backend/src/plugins/Automod/commands/AntiraidClearCmd.ts
index 4ac60488..32434322 100644
--- a/backend/src/plugins/Automod/commands/AntiraidClearCmd.ts
+++ b/backend/src/plugins/Automod/commands/AntiraidClearCmd.ts
@@ -1,9 +1,9 @@
-import { command } from "knub";
+import { guildCommand, GuildPluginData } from "knub";
 import { AutomodPluginType } from "../types";
 import { setAntiraidLevel } from "../functions/setAntiraidLevel";
 import { sendSuccessMessage } from "../../../pluginUtils";
 
-export const AntiraidClearCmd = command<AutomodPluginType>()({
+export const AntiraidClearCmd = guildCommand<AutomodPluginType>()({
   trigger: ["antiraid clear", "antiraid reset", "antiraid none", "antiraid off"],
   permission: "can_set_antiraid",
 
diff --git a/backend/src/plugins/Automod/commands/SetAntiraidCmd.ts b/backend/src/plugins/Automod/commands/SetAntiraidCmd.ts
index 7b2f003c..fd0ec7a5 100644
--- a/backend/src/plugins/Automod/commands/SetAntiraidCmd.ts
+++ b/backend/src/plugins/Automod/commands/SetAntiraidCmd.ts
@@ -1,10 +1,10 @@
-import { command } from "knub";
+import { guildCommand, GuildPluginData } from "knub";
 import { AutomodPluginType } from "../types";
 import { setAntiraidLevel } from "../functions/setAntiraidLevel";
 import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 
-export const SetAntiraidCmd = command<AutomodPluginType>()({
+export const SetAntiraidCmd = guildCommand<AutomodPluginType>()({
   trigger: "antiraid",
   permission: "can_set_antiraid",
 
diff --git a/backend/src/plugins/Automod/commands/ViewAntiraidCmd.ts b/backend/src/plugins/Automod/commands/ViewAntiraidCmd.ts
index 77597ca7..14864612 100644
--- a/backend/src/plugins/Automod/commands/ViewAntiraidCmd.ts
+++ b/backend/src/plugins/Automod/commands/ViewAntiraidCmd.ts
@@ -1,14 +1,14 @@
-import { command } from "knub";
+import { guildCommand, GuildPluginData } from "knub";
 import { AutomodPluginType } from "../types";
 import { setAntiraidLevel } from "../functions/setAntiraidLevel";
 import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 
-export const ViewAntiraidCmd = command<AutomodPluginType>()({
+export const ViewAntiraidCmd = guildCommand<AutomodPluginType>()({
   trigger: "antiraid",
   permission: "can_view_antiraid",
 
-  async run({ pluginData, message, args }) {
+  async run({ pluginData, message }) {
     if (pluginData.state.cachedAntiraidLevel) {
       message.channel.createMessage(`Anti-raid is set to **${pluginData.state.cachedAntiraidLevel}**`);
     } else {
diff --git a/backend/src/plugins/Automod/events/RunAutomodOnJoinEvt.ts b/backend/src/plugins/Automod/events/RunAutomodOnJoinEvt.ts
index 596feda6..ec5ff8d9 100644
--- a/backend/src/plugins/Automod/events/RunAutomodOnJoinEvt.ts
+++ b/backend/src/plugins/Automod/events/RunAutomodOnJoinEvt.ts
@@ -1,9 +1,9 @@
-import { eventListener } from "knub";
+import { guildEventListener } from "knub";
 import { AutomodContext, AutomodPluginType } from "../types";
 import { runAutomod } from "../functions/runAutomod";
 import { RecentActionType } from "../constants";
 
-export const RunAutomodOnJoinEvt = eventListener<AutomodPluginType>()(
+export const RunAutomodOnJoinEvt = guildEventListener<AutomodPluginType>()(
   "guildMemberAdd",
   ({ pluginData, args: { member } }) => {
     const context: AutomodContext = {
diff --git a/backend/src/plugins/Automod/events/RunAutomodOnMemberUpdate.ts b/backend/src/plugins/Automod/events/RunAutomodOnMemberUpdate.ts
index d850ec1d..6d3e2e5a 100644
--- a/backend/src/plugins/Automod/events/RunAutomodOnMemberUpdate.ts
+++ b/backend/src/plugins/Automod/events/RunAutomodOnMemberUpdate.ts
@@ -1,11 +1,11 @@
-import { eventListener } from "knub";
+import { guildEventListener } from "knub";
 import { AutomodContext, AutomodPluginType } from "../types";
 import { RecentActionType } from "../constants";
 import { runAutomod } from "../functions/runAutomod";
 import isEqual from "lodash.isequal";
 import diff from "lodash.difference";
 
-export const RunAutomodOnMemberUpdate = eventListener<AutomodPluginType>()(
+export const RunAutomodOnMemberUpdate = guildEventListener<AutomodPluginType>()(
   "guildMemberUpdate",
   ({ pluginData, args: { member, oldMember } }) => {
     if (!oldMember) return;
diff --git a/backend/src/plugins/Automod/events/runAutomodOnMessage.ts b/backend/src/plugins/Automod/events/runAutomodOnMessage.ts
index 18b13a79..0ae87a6f 100644
--- a/backend/src/plugins/Automod/events/runAutomodOnMessage.ts
+++ b/backend/src/plugins/Automod/events/runAutomodOnMessage.ts
@@ -1,12 +1,16 @@
 import { SavedMessage } from "../../../data/entities/SavedMessage";
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { AutomodContext, AutomodPluginType } from "../types";
 import { runAutomod } from "../functions/runAutomod";
 import { addRecentActionsFromMessage } from "../functions/addRecentActionsFromMessage";
 import moment from "moment-timezone";
 import { clearRecentActionsForMessage } from "../functions/clearRecentActionsForMessage";
 
-export function runAutomodOnMessage(pluginData: PluginData<AutomodPluginType>, message: SavedMessage, isEdit: boolean) {
+export function runAutomodOnMessage(
+  pluginData: GuildPluginData<AutomodPluginType>,
+  message: SavedMessage,
+  isEdit: boolean,
+) {
   const user = pluginData.client.users.get(message.user_id);
   const member = pluginData.guild.members.get(message.user_id);
 
diff --git a/backend/src/plugins/Automod/functions/addRecentActionsFromMessage.ts b/backend/src/plugins/Automod/functions/addRecentActionsFromMessage.ts
index 91f4ada5..289c6f5c 100644
--- a/backend/src/plugins/Automod/functions/addRecentActionsFromMessage.ts
+++ b/backend/src/plugins/Automod/functions/addRecentActionsFromMessage.ts
@@ -1,9 +1,9 @@
 import { AutomodContext, AutomodPluginType } from "../types";
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { RECENT_ACTION_EXPIRY_TIME, RecentActionType } from "../constants";
 import { getEmojiInString, getRoleMentions, getUrlsInString, getUserMentions } from "../../../utils";
 
-export function addRecentActionsFromMessage(pluginData: PluginData<AutomodPluginType>, context: AutomodContext) {
+export function addRecentActionsFromMessage(pluginData: GuildPluginData<AutomodPluginType>, context: AutomodContext) {
   const globalIdentifier = context.message.user_id;
   const perChannelIdentifier = `${context.message.channel_id}-${context.message.user_id}`;
   const expiresAt = Date.now() + RECENT_ACTION_EXPIRY_TIME;
diff --git a/backend/src/plugins/Automod/functions/checkAndUpdateCooldown.ts b/backend/src/plugins/Automod/functions/checkAndUpdateCooldown.ts
index 7e40a0e2..4dfc1abe 100644
--- a/backend/src/plugins/Automod/functions/checkAndUpdateCooldown.ts
+++ b/backend/src/plugins/Automod/functions/checkAndUpdateCooldown.ts
@@ -1,10 +1,10 @@
 import { AutomodContext, AutomodPluginType, TRule } from "../types";
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { AutomodTriggerMatchResult } from "../helpers";
 import { convertDelayStringToMS } from "../../../utils";
 
 export function checkAndUpdateCooldown(
-  pluginData: PluginData<AutomodPluginType>,
+  pluginData: GuildPluginData<AutomodPluginType>,
   rule: TRule,
   context: AutomodContext,
 ) {
diff --git a/backend/src/plugins/Automod/functions/clearOldNicknameChanges.ts b/backend/src/plugins/Automod/functions/clearOldNicknameChanges.ts
index 2f503cf8..8d668ba7 100644
--- a/backend/src/plugins/Automod/functions/clearOldNicknameChanges.ts
+++ b/backend/src/plugins/Automod/functions/clearOldNicknameChanges.ts
@@ -1,8 +1,8 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { AutomodPluginType } from "../types";
 import { RECENT_NICKNAME_CHANGE_EXPIRY_TIME, RECENT_SPAM_EXPIRY_TIME } from "../constants";
 
-export function clearOldRecentNicknameChanges(pluginData: PluginData<AutomodPluginType>) {
+export function clearOldRecentNicknameChanges(pluginData: GuildPluginData<AutomodPluginType>) {
   const now = Date.now();
   for (const [userId, { timestamp }] of pluginData.state.recentNicknameChanges) {
     if (timestamp + RECENT_NICKNAME_CHANGE_EXPIRY_TIME <= now) {
diff --git a/backend/src/plugins/Automod/functions/clearOldRecentActions.ts b/backend/src/plugins/Automod/functions/clearOldRecentActions.ts
index 7f933be9..e1ee2fe5 100644
--- a/backend/src/plugins/Automod/functions/clearOldRecentActions.ts
+++ b/backend/src/plugins/Automod/functions/clearOldRecentActions.ts
@@ -1,8 +1,8 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { AutomodPluginType } from "../types";
 import { RECENT_ACTION_EXPIRY_TIME } from "../constants";
 
-export function clearOldRecentActions(pluginData: PluginData<AutomodPluginType>) {
+export function clearOldRecentActions(pluginData: GuildPluginData<AutomodPluginType>) {
   const now = Date.now();
   pluginData.state.recentActions = pluginData.state.recentActions.filter(info => {
     return info.context.timestamp + RECENT_ACTION_EXPIRY_TIME > now;
diff --git a/backend/src/plugins/Automod/functions/clearOldRecentSpam.ts b/backend/src/plugins/Automod/functions/clearOldRecentSpam.ts
index a05c699d..7fcec63e 100644
--- a/backend/src/plugins/Automod/functions/clearOldRecentSpam.ts
+++ b/backend/src/plugins/Automod/functions/clearOldRecentSpam.ts
@@ -1,8 +1,8 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { AutomodPluginType } from "../types";
 import { RECENT_SPAM_EXPIRY_TIME } from "../constants";
 
-export function clearOldRecentSpam(pluginData: PluginData<AutomodPluginType>) {
+export function clearOldRecentSpam(pluginData: GuildPluginData<AutomodPluginType>) {
   const now = Date.now();
   pluginData.state.recentSpam = pluginData.state.recentSpam.filter(spam => {
     return spam.timestamp + RECENT_SPAM_EXPIRY_TIME > now;
diff --git a/backend/src/plugins/Automod/functions/clearRecentActionsForMessage.ts b/backend/src/plugins/Automod/functions/clearRecentActionsForMessage.ts
index 424a80c5..0d1fb4c6 100644
--- a/backend/src/plugins/Automod/functions/clearRecentActionsForMessage.ts
+++ b/backend/src/plugins/Automod/functions/clearRecentActionsForMessage.ts
@@ -1,9 +1,9 @@
 import { AutomodContext, AutomodPluginType } from "../types";
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { RECENT_ACTION_EXPIRY_TIME, RecentActionType } from "../constants";
 import { getEmojiInString, getRoleMentions, getUrlsInString, getUserMentions } from "../../../utils";
 
-export function clearRecentActionsForMessage(pluginData: PluginData<AutomodPluginType>, context: AutomodContext) {
+export function clearRecentActionsForMessage(pluginData: GuildPluginData<AutomodPluginType>, context: AutomodContext) {
   const globalIdentifier = context.message.user_id;
   const perChannelIdentifier = `${context.message.channel_id}-${context.message.user_id}`;
 
diff --git a/backend/src/plugins/Automod/functions/findRecentSpam.ts b/backend/src/plugins/Automod/functions/findRecentSpam.ts
index 8a4b4979..6ec8a59f 100644
--- a/backend/src/plugins/Automod/functions/findRecentSpam.ts
+++ b/backend/src/plugins/Automod/functions/findRecentSpam.ts
@@ -1,8 +1,12 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { AutomodPluginType } from "../types";
 import { RecentActionType } from "../constants";
 
-export function findRecentSpam(pluginData: PluginData<AutomodPluginType>, type: RecentActionType, identifier?: string) {
+export function findRecentSpam(
+  pluginData: GuildPluginData<AutomodPluginType>,
+  type: RecentActionType,
+  identifier?: string,
+) {
   return pluginData.state.recentSpam.find(spam => {
     return spam.type === type && (!identifier || spam.identifiers.includes(identifier));
   });
diff --git a/backend/src/plugins/Automod/functions/getMatchingMessageRecentActions.ts b/backend/src/plugins/Automod/functions/getMatchingMessageRecentActions.ts
index 3fbac2a6..7e7299bc 100644
--- a/backend/src/plugins/Automod/functions/getMatchingMessageRecentActions.ts
+++ b/backend/src/plugins/Automod/functions/getMatchingMessageRecentActions.ts
@@ -1,4 +1,4 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { AutomodPluginType } from "../types";
 import { SavedMessage } from "../../../data/entities/SavedMessage";
 import moment from "moment-timezone";
@@ -6,7 +6,7 @@ import { getMatchingRecentActions } from "./getMatchingRecentActions";
 import { RecentActionType } from "../constants";
 
 export function getMatchingMessageRecentActions(
-  pluginData: PluginData<AutomodPluginType>,
+  pluginData: GuildPluginData<AutomodPluginType>,
   message: SavedMessage,
   type: RecentActionType,
   identifier: string,
diff --git a/backend/src/plugins/Automod/functions/getMatchingRecentActions.ts b/backend/src/plugins/Automod/functions/getMatchingRecentActions.ts
index b5638d04..c25cd5cc 100644
--- a/backend/src/plugins/Automod/functions/getMatchingRecentActions.ts
+++ b/backend/src/plugins/Automod/functions/getMatchingRecentActions.ts
@@ -1,9 +1,9 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { AutomodPluginType } from "../types";
 import { RecentActionType } from "../constants";
 
 export function getMatchingRecentActions(
-  pluginData: PluginData<AutomodPluginType>,
+  pluginData: GuildPluginData<AutomodPluginType>,
   type: RecentActionType,
   identifier: string | null,
   since: number,
diff --git a/backend/src/plugins/Automod/functions/getTextMatchPartialSummary.ts b/backend/src/plugins/Automod/functions/getTextMatchPartialSummary.ts
index 425baa15..8983bbd3 100644
--- a/backend/src/plugins/Automod/functions/getTextMatchPartialSummary.ts
+++ b/backend/src/plugins/Automod/functions/getTextMatchPartialSummary.ts
@@ -1,11 +1,11 @@
 import { MatchableTextType } from "./matchMultipleTextTypesOnMessage";
 import { AutomodContext, AutomodPluginType } from "../types";
 import { messageSummary, verboseChannelMention } from "../../../utils";
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { User } from "eris";
 
 export function getTextMatchPartialSummary(
-  pluginData: PluginData<AutomodPluginType>,
+  pluginData: GuildPluginData<AutomodPluginType>,
   type: MatchableTextType,
   context: AutomodContext,
 ) {
diff --git a/backend/src/plugins/Automod/functions/ignoredRoleChanges.ts b/backend/src/plugins/Automod/functions/ignoredRoleChanges.ts
index d9a296b2..a3c881a6 100644
--- a/backend/src/plugins/Automod/functions/ignoredRoleChanges.ts
+++ b/backend/src/plugins/Automod/functions/ignoredRoleChanges.ts
@@ -1,10 +1,10 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { AutomodPluginType } from "../types";
 import { MINUTES } from "../../../utils";
 
 const IGNORED_ROLE_CHANGE_LIFETIME = 5 * MINUTES;
 
-function cleanupIgnoredRoleChanges(pluginData: PluginData<AutomodPluginType>) {
+function cleanupIgnoredRoleChanges(pluginData: GuildPluginData<AutomodPluginType>) {
   const cutoff = Date.now() - IGNORED_ROLE_CHANGE_LIFETIME;
   for (const ignoredChange of pluginData.state.ignoredRoleChanges.values()) {
     if (ignoredChange.timestamp < cutoff) {
@@ -13,7 +13,7 @@ function cleanupIgnoredRoleChanges(pluginData: PluginData<AutomodPluginType>) {
   }
 }
 
-export function ignoreRoleChange(pluginData: PluginData<AutomodPluginType>, memberId: string, roleId: string) {
+export function ignoreRoleChange(pluginData: GuildPluginData<AutomodPluginType>, memberId: string, roleId: string) {
   pluginData.state.ignoredRoleChanges.add({
     memberId,
     roleId,
@@ -26,7 +26,11 @@ export function ignoreRoleChange(pluginData: PluginData<AutomodPluginType>, memb
 /**
  * @return Whether the role change should be ignored
  */
-export function consumeIgnoredRoleChange(pluginData: PluginData<AutomodPluginType>, memberId: string, roleId: string) {
+export function consumeIgnoredRoleChange(
+  pluginData: GuildPluginData<AutomodPluginType>,
+  memberId: string,
+  roleId: string,
+) {
   for (const ignoredChange of pluginData.state.ignoredRoleChanges.values()) {
     if (ignoredChange.memberId === memberId && ignoredChange.roleId === roleId) {
       pluginData.state.ignoredRoleChanges.delete(ignoredChange);
diff --git a/backend/src/plugins/Automod/functions/matchMultipleTextTypesOnMessage.ts b/backend/src/plugins/Automod/functions/matchMultipleTextTypesOnMessage.ts
index 16fb72d9..a51ad74d 100644
--- a/backend/src/plugins/Automod/functions/matchMultipleTextTypesOnMessage.ts
+++ b/backend/src/plugins/Automod/functions/matchMultipleTextTypesOnMessage.ts
@@ -1,6 +1,6 @@
 import { SavedMessage } from "../../../data/entities/SavedMessage";
 import { resolveMember } from "../../../utils";
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { AutomodPluginType } from "../types";
 
 type TextTriggerWithMultipleMatchTypes = {
@@ -20,7 +20,7 @@ type YieldedContent = [MatchableTextType, string];
  * Generator function that allows iterating through matchable pieces of text of a SavedMessage
  */
 export async function* matchMultipleTextTypesOnMessage(
-  pluginData: PluginData<AutomodPluginType>,
+  pluginData: GuildPluginData<AutomodPluginType>,
   trigger: TextTriggerWithMultipleMatchTypes,
   msg: SavedMessage,
 ): AsyncIterableIterator<YieldedContent> {
diff --git a/backend/src/plugins/Automod/functions/resolveActionContactMethods.ts b/backend/src/plugins/Automod/functions/resolveActionContactMethods.ts
index 6ae3fca0..5ce5e799 100644
--- a/backend/src/plugins/Automod/functions/resolveActionContactMethods.ts
+++ b/backend/src/plugins/Automod/functions/resolveActionContactMethods.ts
@@ -1,11 +1,11 @@
 import { disableUserNotificationStrings, UserNotificationMethod } from "../../../utils";
 import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError";
 import { TextChannel } from "eris";
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { AutomodPluginType } from "../types";
 
 export function resolveActionContactMethods(
-  pluginData: PluginData<AutomodPluginType>,
+  pluginData: GuildPluginData<AutomodPluginType>,
   actionConfig: {
     notify?: string;
     notifyChannel?: string;
diff --git a/backend/src/plugins/Automod/functions/runAutomod.ts b/backend/src/plugins/Automod/functions/runAutomod.ts
index d80a1d88..c8fe9318 100644
--- a/backend/src/plugins/Automod/functions/runAutomod.ts
+++ b/backend/src/plugins/Automod/functions/runAutomod.ts
@@ -1,4 +1,4 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { AutomodContext, AutomodPluginType } from "../types";
 import { availableTriggers } from "../triggers/availableTriggers";
 import { availableActions } from "../actions/availableActions";
@@ -6,7 +6,7 @@ import { AutomodTriggerMatchResult } from "../helpers";
 import { CleanAction } from "../actions/clean";
 import { checkAndUpdateCooldown } from "./checkAndUpdateCooldown";
 
-export async function runAutomod(pluginData: PluginData<AutomodPluginType>, context: AutomodContext) {
+export async function runAutomod(pluginData: GuildPluginData<AutomodPluginType>, context: AutomodContext) {
   const userId = context.user?.id || context.member?.id || context.message?.user_id;
   const user = context.user || (userId && pluginData.client.users.get(userId));
   const member = context.member || (userId && pluginData.guild.members.get(userId));
diff --git a/backend/src/plugins/Automod/functions/setAntiraidLevel.ts b/backend/src/plugins/Automod/functions/setAntiraidLevel.ts
index 87031471..2d446bf8 100644
--- a/backend/src/plugins/Automod/functions/setAntiraidLevel.ts
+++ b/backend/src/plugins/Automod/functions/setAntiraidLevel.ts
@@ -1,12 +1,12 @@
 import { User } from "eris";
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { AutomodPluginType } from "../types";
 import { LogsPlugin } from "../../Logs/LogsPlugin";
 import { LogType } from "../../../data/LogType";
 import { stripObjectToScalars } from "../../../utils";
 
 export async function setAntiraidLevel(
-  pluginData: PluginData<AutomodPluginType>,
+  pluginData: GuildPluginData<AutomodPluginType>,
   newLevel: string | null,
   user?: User,
 ) {
diff --git a/backend/src/plugins/Automod/helpers.ts b/backend/src/plugins/Automod/helpers.ts
index 4bb8154d..3bda6370 100644
--- a/backend/src/plugins/Automod/helpers.ts
+++ b/backend/src/plugins/Automod/helpers.ts
@@ -1,4 +1,4 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { Awaitable } from "knub/dist/utils";
 import * as t from "io-ts";
 import { AutomodContext, AutomodPluginType } from "./types";
@@ -15,14 +15,14 @@ export interface AutomodTriggerMatchResult<TExtra extends any = unknown> {
 
 type AutomodTriggerMatchFn<TConfigType, TMatchResultExtra> = (meta: {
   ruleName: string;
-  pluginData: PluginData<AutomodPluginType>;
+  pluginData: GuildPluginData<AutomodPluginType>;
   context: AutomodContext;
   triggerConfig: TConfigType;
 }) => Awaitable<null | AutomodTriggerMatchResult<TMatchResultExtra>>;
 
 type AutomodTriggerRenderMatchInformationFn<TConfigType, TMatchResultExtra> = (meta: {
   ruleName: string;
-  pluginData: PluginData<AutomodPluginType>;
+  pluginData: GuildPluginData<AutomodPluginType>;
   contexts: AutomodContext[];
   triggerConfig: TConfigType;
   matchResult: AutomodTriggerMatchResult<TMatchResultExtra>;
@@ -54,7 +54,7 @@ export function automodTrigger(...args) {
 
 type AutomodActionApplyFn<TConfigType> = (meta: {
   ruleName: string;
-  pluginData: PluginData<AutomodPluginType>;
+  pluginData: GuildPluginData<AutomodPluginType>;
   contexts: AutomodContext[];
   actionConfig: TConfigType;
   matchResult: AutomodTriggerMatchResult;
diff --git a/backend/src/plugins/Automod/info.ts b/backend/src/plugins/Automod/info.ts
index a69eaff9..c2c87dbf 100644
--- a/backend/src/plugins/Automod/info.ts
+++ b/backend/src/plugins/Automod/info.ts
@@ -1,7 +1,7 @@
-import { ZeppelinPluginBlueprint } from "../ZeppelinPluginBlueprint";
+import { ZeppelinGuildPluginBlueprint } from "../ZeppelinPluginBlueprint";
 import { trimPluginDescription } from "../../utils";
 
-export const pluginInfo: ZeppelinPluginBlueprint["info"] = {
+export const pluginInfo: ZeppelinGuildPluginBlueprint["info"] = {
   prettyName: "Automod",
   description: trimPluginDescription(`
       Allows specifying automated actions in response to triggers. Example use cases include word filtering and spam prevention.
diff --git a/backend/src/plugins/BotControl/BotControlPlugin.ts b/backend/src/plugins/BotControl/BotControlPlugin.ts
index f4c6edd4..904dc618 100644
--- a/backend/src/plugins/BotControl/BotControlPlugin.ts
+++ b/backend/src/plugins/BotControl/BotControlPlugin.ts
@@ -1,4 +1,4 @@
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
+import { zeppelinGlobalPlugin } from "../ZeppelinPluginBlueprint";
 import { BotControlPluginType, ConfigSchema } from "./types";
 import { GuildArchives } from "../../data/GuildArchives";
 import { TextChannel } from "eris";
@@ -16,7 +16,7 @@ const defaultOptions = {
   },
 };
 
-export const BotControlPlugin = zeppelinPlugin<BotControlPluginType>()("bot_control", {
+export const BotControlPlugin = zeppelinGlobalPlugin<BotControlPluginType>()("bot_control", {
   configSchema: ConfigSchema,
   defaultOptions,
 
diff --git a/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts b/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts
index 0e74b22a..26035147 100644
--- a/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts
+++ b/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts
@@ -1,9 +1,8 @@
-import { command } from "knub";
-import { BotControlPluginType } from "../types";
+import { botControlCmd } from "../types";
 import { isOwnerPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 
-export const LeaveServerCmd = command<BotControlPluginType>()({
+export const LeaveServerCmd = botControlCmd({
   trigger: ["leave_server", "leave_guild"],
   permission: null,
   config: {
diff --git a/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts b/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts
index ca4a801a..4ffcd90a 100644
--- a/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts
+++ b/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts
@@ -1,10 +1,9 @@
-import { command } from "knub";
-import { BotControlPluginType } from "../types";
+import { botControlCmd } from "../types";
 import { isOwnerPreFilter } from "../../../pluginUtils";
 import { getActiveReload, setActiveReload } from "../activeReload";
 import { TextChannel } from "eris";
 
-export const ReloadGlobalPluginsCmd = command<BotControlPluginType>()({
+export const ReloadGlobalPluginsCmd = botControlCmd({
   trigger: "bot_reload_global_plugins",
   permission: null,
   config: {
diff --git a/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts b/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts
index e455c369..7c725e11 100644
--- a/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts
+++ b/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts
@@ -1,9 +1,8 @@
-import { command } from "knub";
-import { BotControlPluginType } from "../types";
+import { botControlCmd } from "../types";
 import { isOwnerPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 
-export const ReloadServerCmd = command<BotControlPluginType>()({
+export const ReloadServerCmd = botControlCmd({
   trigger: ["reload_server", "reload_guild"],
   permission: null,
   config: {
diff --git a/backend/src/plugins/BotControl/commands/ServersCmd.ts b/backend/src/plugins/BotControl/commands/ServersCmd.ts
index ff9020ef..6ec71343 100644
--- a/backend/src/plugins/BotControl/commands/ServersCmd.ts
+++ b/backend/src/plugins/BotControl/commands/ServersCmd.ts
@@ -1,11 +1,10 @@
-import { command } from "knub";
-import { BotControlPluginType } from "../types";
+import { botControlCmd } from "../types";
 import { isOwnerPreFilter } from "../../../pluginUtils";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import escapeStringRegexp from "escape-string-regexp";
 import { createChunkedMessage, getUser, sorter } from "../../../utils";
 
-export const ServersCmd = command<BotControlPluginType>()({
+export const ServersCmd = botControlCmd({
   trigger: ["servers", "guilds"],
   permission: null,
   config: {
diff --git a/backend/src/plugins/BotControl/types.ts b/backend/src/plugins/BotControl/types.ts
index 50e1847a..a59a4d17 100644
--- a/backend/src/plugins/BotControl/types.ts
+++ b/backend/src/plugins/BotControl/types.ts
@@ -1,6 +1,6 @@
 import * as t from "io-ts";
 import { tNullable } from "../../utils";
-import { BasePluginType } from "knub";
+import { BasePluginType, globalCommand, globalEventListener } from "knub";
 import { GuildArchives } from "../../data/GuildArchives";
 
 export const ConfigSchema = t.type({
@@ -15,3 +15,6 @@ export interface BotControlPluginType extends BasePluginType {
     archives: GuildArchives;
   };
 }
+
+export const botControlCmd = globalCommand<BotControlPluginType>();
+export const botControlEvt = globalEventListener<BotControlPluginType>();
diff --git a/backend/src/plugins/Cases/CasesPlugin.ts b/backend/src/plugins/Cases/CasesPlugin.ts
index 239d5298..b4ce8e7f 100644
--- a/backend/src/plugins/Cases/CasesPlugin.ts
+++ b/backend/src/plugins/Cases/CasesPlugin.ts
@@ -1,4 +1,4 @@
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
+import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
 import { CaseArgs, CaseNoteArgs, CasesPluginType, ConfigSchema } from "./types";
 import { createCase } from "./functions/createCase";
 import { GuildLogs } from "../../data/GuildLogs";
@@ -26,7 +26,7 @@ const defaultOptions = {
   },
 };
 
-export const CasesPlugin = zeppelinPlugin<CasesPluginType>()("cases", {
+export const CasesPlugin = zeppelinGuildPlugin<CasesPluginType>()("cases", {
   showInDocs: true,
   info: {
     prettyName: "Cases",
diff --git a/backend/src/plugins/Cases/functions/createCase.ts b/backend/src/plugins/Cases/functions/createCase.ts
index 447dca85..ff61c6d2 100644
--- a/backend/src/plugins/Cases/functions/createCase.ts
+++ b/backend/src/plugins/Cases/functions/createCase.ts
@@ -1,11 +1,11 @@
 import { CaseArgs, CasesPluginType } from "../types";
 import { resolveUser } from "../../../utils";
-import { plugin, PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { createCaseNote } from "./createCaseNote";
 import { postCaseToCaseLogChannel } from "./postToCaseLogChannel";
 import { logger } from "../../../logger";
 
-export async function createCase(pluginData: PluginData<CasesPluginType>, args: CaseArgs) {
+export async function createCase(pluginData: GuildPluginData<CasesPluginType>, args: CaseArgs) {
   const user = await resolveUser(pluginData.client, args.userId);
   const userName = `${user.username}#${user.discriminator}`;
 
diff --git a/backend/src/plugins/Cases/functions/createCaseNote.ts b/backend/src/plugins/Cases/functions/createCaseNote.ts
index e62f3d05..1eae08f9 100644
--- a/backend/src/plugins/Cases/functions/createCaseNote.ts
+++ b/backend/src/plugins/Cases/functions/createCaseNote.ts
@@ -1,11 +1,11 @@
 import { CaseNoteArgs, CasesPluginType } from "../types";
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError";
 import { resolveCaseId } from "./resolveCaseId";
 import { postCaseToCaseLogChannel } from "./postToCaseLogChannel";
 import { resolveUser } from "../../../utils";
 
-export async function createCaseNote(pluginData: PluginData<CasesPluginType>, args: CaseNoteArgs): Promise<void> {
+export async function createCaseNote(pluginData: GuildPluginData<CasesPluginType>, args: CaseNoteArgs): Promise<void> {
   const theCase = await pluginData.state.cases.find(resolveCaseId(args.caseId));
   if (!theCase) {
     throw new RecoverablePluginError(ERRORS.UNKNOWN_NOTE_CASE);
diff --git a/backend/src/plugins/Cases/functions/getCaseColor.ts b/backend/src/plugins/Cases/functions/getCaseColor.ts
index 9e574cb6..1cf6ce77 100644
--- a/backend/src/plugins/Cases/functions/getCaseColor.ts
+++ b/backend/src/plugins/Cases/functions/getCaseColor.ts
@@ -1,8 +1,8 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { CasesPluginType } from "../types";
 import { CaseTypes, CaseTypeToName } from "../../../data/CaseTypes";
 import { caseColors } from "../caseColors";
 
-export function getCaseColor(pluginData: PluginData<CasesPluginType>, caseType: CaseTypes) {
+export function getCaseColor(pluginData: GuildPluginData<CasesPluginType>, caseType: CaseTypes) {
   return pluginData.config.get().case_colors?.[CaseTypeToName[caseType]] ?? caseColors[caseType];
 }
diff --git a/backend/src/plugins/Cases/functions/getCaseEmbed.ts b/backend/src/plugins/Cases/functions/getCaseEmbed.ts
index 4e7ea817..21be1035 100644
--- a/backend/src/plugins/Cases/functions/getCaseEmbed.ts
+++ b/backend/src/plugins/Cases/functions/getCaseEmbed.ts
@@ -2,7 +2,7 @@ import { Case } from "../../../data/entities/Case";
 import { AdvancedMessageContent, MessageContent } from "eris";
 import moment from "moment-timezone";
 import { CaseTypes } from "../../../data/CaseTypes";
-import { PluginData, helpers } from "knub";
+import { GuildPluginData, helpers } from "knub";
 import { CasesPluginType } from "../types";
 import { resolveCaseId } from "./resolveCaseId";
 import { chunkLines, chunkMessageLines, emptyEmbedValue, messageLink } from "../../../utils";
@@ -10,7 +10,7 @@ import { getCaseColor } from "./getCaseColor";
 import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin";
 
 export async function getCaseEmbed(
-  pluginData: PluginData<CasesPluginType>,
+  pluginData: GuildPluginData<CasesPluginType>,
   caseOrCaseId: Case | number,
   requestMemberId?: string,
 ): Promise<AdvancedMessageContent> {
diff --git a/backend/src/plugins/Cases/functions/getCaseIcon.ts b/backend/src/plugins/Cases/functions/getCaseIcon.ts
index 0cf0758f..eb8fc3d5 100644
--- a/backend/src/plugins/Cases/functions/getCaseIcon.ts
+++ b/backend/src/plugins/Cases/functions/getCaseIcon.ts
@@ -1,8 +1,8 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { CasesPluginType } from "../types";
 import { CaseTypes, CaseTypeToName } from "../../../data/CaseTypes";
 import { caseIcons } from "../caseIcons";
 
-export function getCaseIcon(pluginData: PluginData<CasesPluginType>, caseType: CaseTypes) {
+export function getCaseIcon(pluginData: GuildPluginData<CasesPluginType>, caseType: CaseTypes) {
   return pluginData.config.get().case_icons?.[CaseTypeToName[caseType]] ?? caseIcons[caseType];
 }
diff --git a/backend/src/plugins/Cases/functions/getCaseSummary.ts b/backend/src/plugins/Cases/functions/getCaseSummary.ts
index 18034e8e..887b3f9e 100644
--- a/backend/src/plugins/Cases/functions/getCaseSummary.ts
+++ b/backend/src/plugins/Cases/functions/getCaseSummary.ts
@@ -1,4 +1,4 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { CasesPluginType } from "../types";
 import {
   convertDelayStringToMS,
@@ -24,7 +24,7 @@ const UPDATE_STR = "**[Update]**";
 const RELATIVE_TIME_THRESHOLD = 7 * DAYS;
 
 export async function getCaseSummary(
-  pluginData: PluginData<CasesPluginType>,
+  pluginData: GuildPluginData<CasesPluginType>,
   caseOrCaseId: Case | number,
   withLinks = false,
   requestMemberId?: string,
diff --git a/backend/src/plugins/Cases/functions/getCaseTypeAmountForUserId.ts b/backend/src/plugins/Cases/functions/getCaseTypeAmountForUserId.ts
index f5f1319e..60752242 100644
--- a/backend/src/plugins/Cases/functions/getCaseTypeAmountForUserId.ts
+++ b/backend/src/plugins/Cases/functions/getCaseTypeAmountForUserId.ts
@@ -1,9 +1,9 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { CasesPluginType } from "../types";
 import { CaseTypes } from "../../../data/CaseTypes";
 
 export async function getCaseTypeAmountForUserId(
-  pluginData: PluginData<CasesPluginType>,
+  pluginData: GuildPluginData<CasesPluginType>,
   userID: string,
   type: CaseTypes,
 ): Promise<number> {
diff --git a/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts b/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts
index 3d464adc..c311ec1b 100644
--- a/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts
+++ b/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts
@@ -1,4 +1,4 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { CasesPluginType } from "../types";
 import { Message, MessageContent, MessageFile, TextChannel } from "eris";
 import { isDiscordRESTError } from "../../../utils";
@@ -9,7 +9,7 @@ import { resolveCaseId } from "./resolveCaseId";
 import { logger } from "../../../logger";
 
 export async function postToCaseLogChannel(
-  pluginData: PluginData<CasesPluginType>,
+  pluginData: GuildPluginData<CasesPluginType>,
   content: MessageContent,
   file: MessageFile = null,
 ): Promise<Message | null> {
@@ -40,7 +40,7 @@ export async function postToCaseLogChannel(
 }
 
 export async function postCaseToCaseLogChannel(
-  pluginData: PluginData<CasesPluginType>,
+  pluginData: GuildPluginData<CasesPluginType>,
   caseOrCaseId: Case | number,
 ): Promise<Message | null> {
   const theCase = await pluginData.state.cases.find(resolveCaseId(caseOrCaseId));
diff --git a/backend/src/plugins/Cases/types.ts b/backend/src/plugins/Cases/types.ts
index c5b44981..1a00a814 100644
--- a/backend/src/plugins/Cases/types.ts
+++ b/backend/src/plugins/Cases/types.ts
@@ -1,7 +1,7 @@
 import * as t from "io-ts";
 import { tDelayString, tPartialDictionary, tNullable } from "../../utils";
 import { CaseNameToType, CaseTypes } from "../../data/CaseTypes";
-import { BasePluginType } from "knub";
+import { BasePluginType, guildCommand, guildEventListener } from "knub";
 import { GuildLogs } from "../../data/GuildLogs";
 import { GuildCases } from "../../data/GuildCases";
 import { GuildArchives } from "../../data/GuildArchives";
diff --git a/backend/src/plugins/Censor/CensorPlugin.ts b/backend/src/plugins/Censor/CensorPlugin.ts
index 2f8454d9..b7fd5575 100644
--- a/backend/src/plugins/Censor/CensorPlugin.ts
+++ b/backend/src/plugins/Censor/CensorPlugin.ts
@@ -1,8 +1,8 @@
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
+import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
 import { PluginOptions } from "knub";
 import { ConfigSchema, CensorPluginType } from "./types";
-import { GuildLogs } from "src/data/GuildLogs";
-import { GuildSavedMessages } from "src/data/GuildSavedMessages";
+import { GuildLogs } from "../../data/GuildLogs";
+import { GuildSavedMessages } from "../../data/GuildSavedMessages";
 import { onMessageCreate } from "./util/onMessageCreate";
 import { onMessageUpdate } from "./util/onMessageUpdate";
 import { trimPluginDescription } from "../../utils";
@@ -43,7 +43,7 @@ const defaultOptions: PluginOptions<CensorPluginType> = {
   ],
 };
 
-export const CensorPlugin = zeppelinPlugin<CensorPluginType>()("censor", {
+export const CensorPlugin = zeppelinGuildPlugin<CensorPluginType>()("censor", {
   showInDocs: true,
   info: {
     prettyName: "Censor",
diff --git a/backend/src/plugins/Censor/types.ts b/backend/src/plugins/Censor/types.ts
index 921aecd8..5cc64f5d 100644
--- a/backend/src/plugins/Censor/types.ts
+++ b/backend/src/plugins/Censor/types.ts
@@ -1,9 +1,9 @@
 import * as t from "io-ts";
-import { BasePluginType, eventListener } from "knub";
-import { tNullable } from "src/utils";
-import { TRegex } from "src/validatorUtils";
-import { GuildLogs } from "src/data/GuildLogs";
-import { GuildSavedMessages } from "src/data/GuildSavedMessages";
+import { BasePluginType } from "knub";
+import { tNullable } from "../../utils";
+import { TRegex } from "../../validatorUtils";
+import { GuildLogs } from "../../data/GuildLogs";
+import { GuildSavedMessages } from "../../data/GuildSavedMessages";
 import { RegExpRunner } from "../../RegExpRunner";
 
 export const ConfigSchema = t.type({
@@ -35,5 +35,3 @@ export interface CensorPluginType extends BasePluginType {
     onMessageUpdateFn;
   };
 }
-
-export const censorEvent = eventListener<CensorPluginType>();
diff --git a/backend/src/plugins/Censor/util/applyFiltersToMsg.ts b/backend/src/plugins/Censor/util/applyFiltersToMsg.ts
index 92036958..c66648bc 100644
--- a/backend/src/plugins/Censor/util/applyFiltersToMsg.ts
+++ b/backend/src/plugins/Censor/util/applyFiltersToMsg.ts
@@ -1,8 +1,8 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { CensorPluginType } from "../types";
-import { SavedMessage } from "src/data/entities/SavedMessage";
+import { SavedMessage } from "../../../data/entities/SavedMessage";
 import { AnyInvite, Embed, GuildInvite } from "eris";
-import { ZalgoRegex } from "src/data/Zalgo";
+import { ZalgoRegex } from "../../../data/Zalgo";
 import {
   getInviteCodesInString,
   getUrlsInString,
@@ -10,15 +10,15 @@ import {
   resolveInvite,
   isGuildInvite,
   isRESTGuildInvite,
-} from "src/utils";
+} from "../../../utils";
 import cloneDeep from "lodash.clonedeep";
 import { censorMessage } from "./censorMessage";
 import escapeStringRegexp from "escape-string-regexp";
-import { logger } from "src/logger";
+import { logger } from "../../../logger";
 import { allowTimeout } from "../../../RegExpRunner";
 
 export async function applyFiltersToMsg(
-  pluginData: PluginData<CensorPluginType>,
+  pluginData: GuildPluginData<CensorPluginType>,
   savedMessage: SavedMessage,
 ): Promise<boolean> {
   const member = await resolveMember(pluginData.client, pluginData.guild, savedMessage.user_id);
diff --git a/backend/src/plugins/Censor/util/censorMessage.ts b/backend/src/plugins/Censor/util/censorMessage.ts
index 27b41160..233c1aed 100644
--- a/backend/src/plugins/Censor/util/censorMessage.ts
+++ b/backend/src/plugins/Censor/util/censorMessage.ts
@@ -1,12 +1,12 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { CensorPluginType } from "../types";
-import { SavedMessage } from "src/data/entities/SavedMessage";
-import { LogType } from "src/data/LogType";
-import { stripObjectToScalars, resolveUser } from "src/utils";
+import { SavedMessage } from "../../../data/entities/SavedMessage";
+import { LogType } from "../../../data/LogType";
+import { stripObjectToScalars, resolveUser } from "../../../utils";
 import { disableCodeBlocks, deactivateMentions } from "knub/dist/helpers";
 
 export async function censorMessage(
-  pluginData: PluginData<CensorPluginType>,
+  pluginData: GuildPluginData<CensorPluginType>,
   savedMessage: SavedMessage,
   reason: string,
 ) {
diff --git a/backend/src/plugins/Censor/util/onMessageCreate.ts b/backend/src/plugins/Censor/util/onMessageCreate.ts
index dbbb11e6..2042126d 100644
--- a/backend/src/plugins/Censor/util/onMessageCreate.ts
+++ b/backend/src/plugins/Censor/util/onMessageCreate.ts
@@ -1,9 +1,9 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { CensorPluginType } from "../types";
-import { SavedMessage } from "src/data/entities/SavedMessage";
+import { SavedMessage } from "../../../data/entities/SavedMessage";
 import { applyFiltersToMsg } from "./applyFiltersToMsg";
 
-export async function onMessageCreate(pluginData: PluginData<CensorPluginType>, savedMessage: SavedMessage) {
+export async function onMessageCreate(pluginData: GuildPluginData<CensorPluginType>, savedMessage: SavedMessage) {
   if (savedMessage.is_bot) return;
   const lock = await pluginData.locks.acquire(`message-${savedMessage.id}`);
 
diff --git a/backend/src/plugins/Censor/util/onMessageUpdate.ts b/backend/src/plugins/Censor/util/onMessageUpdate.ts
index f427cfef..4c279caa 100644
--- a/backend/src/plugins/Censor/util/onMessageUpdate.ts
+++ b/backend/src/plugins/Censor/util/onMessageUpdate.ts
@@ -1,9 +1,9 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { CensorPluginType } from "../types";
-import { SavedMessage } from "src/data/entities/SavedMessage";
+import { SavedMessage } from "../../../data/entities/SavedMessage";
 import { applyFiltersToMsg } from "./applyFiltersToMsg";
 
-export async function onMessageUpdate(pluginData: PluginData<CensorPluginType>, savedMessage: SavedMessage) {
+export async function onMessageUpdate(pluginData: GuildPluginData<CensorPluginType>, savedMessage: SavedMessage) {
   if (savedMessage.is_bot) return;
   const lock = await pluginData.locks.acquire(`message-${savedMessage.id}`);
 
diff --git a/backend/src/plugins/ChannelArchiver/ChannelArchiverPlugin.ts b/backend/src/plugins/ChannelArchiver/ChannelArchiverPlugin.ts
index 9c34054d..346ad402 100644
--- a/backend/src/plugins/ChannelArchiver/ChannelArchiverPlugin.ts
+++ b/backend/src/plugins/ChannelArchiver/ChannelArchiverPlugin.ts
@@ -1,10 +1,10 @@
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
+import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
 import { ChannelArchiverPluginType } from "./types";
 import { ArchiveChannelCmd } from "./commands/ArchiveChannelCmd";
 import * as t from "io-ts";
 import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin";
 
-export const ChannelArchiverPlugin = zeppelinPlugin<ChannelArchiverPluginType>()("channel_archiver", {
+export const ChannelArchiverPlugin = zeppelinGuildPlugin<ChannelArchiverPluginType>()("channel_archiver", {
   showInDocs: false,
 
   dependencies: [TimeAndDatePlugin],
diff --git a/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts b/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts
index 4f779feb..4193e336 100644
--- a/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts
+++ b/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts
@@ -1,7 +1,7 @@
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { channelArchiverCmd } from "../types";
-import { isOwner, sendErrorMessage } from "src/pluginUtils";
-import { confirm, SECONDS, noop } from "src/utils";
+import { isOwner, sendErrorMessage } from "../../../pluginUtils";
+import { confirm, SECONDS, noop } from "../../../utils";
 import moment from "moment-timezone";
 import { rehostAttachment } from "../rehostAttachment";
 import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin";
diff --git a/backend/src/plugins/ChannelArchiver/rehostAttachment.ts b/backend/src/plugins/ChannelArchiver/rehostAttachment.ts
index 0b12e360..d0d37d16 100644
--- a/backend/src/plugins/ChannelArchiver/rehostAttachment.ts
+++ b/backend/src/plugins/ChannelArchiver/rehostAttachment.ts
@@ -1,5 +1,5 @@
 import { Attachment, TextChannel } from "eris";
-import { downloadFile } from "src/utils";
+import { downloadFile } from "../../utils";
 import fs from "fs";
 const fsp = fs.promises;
 
diff --git a/backend/src/plugins/ChannelArchiver/types.ts b/backend/src/plugins/ChannelArchiver/types.ts
index cbed3e52..95a7368c 100644
--- a/backend/src/plugins/ChannelArchiver/types.ts
+++ b/backend/src/plugins/ChannelArchiver/types.ts
@@ -1,7 +1,7 @@
-import { BasePluginType, command } from "knub";
+import { BasePluginType, guildCommand } from "knub";
 
 export interface ChannelArchiverPluginType extends BasePluginType {
   state: {};
 }
 
-export const channelArchiverCmd = command<ChannelArchiverPluginType>();
+export const channelArchiverCmd = guildCommand<ChannelArchiverPluginType>();
diff --git a/backend/src/plugins/CompanionChannels/CompanionChannelsPlugin.ts b/backend/src/plugins/CompanionChannels/CompanionChannelsPlugin.ts
index dc74002d..221a2bc4 100644
--- a/backend/src/plugins/CompanionChannels/CompanionChannelsPlugin.ts
+++ b/backend/src/plugins/CompanionChannels/CompanionChannelsPlugin.ts
@@ -1,4 +1,4 @@
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
+import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
 import { CompanionChannelsPluginType, ConfigSchema, TCompanionChannelOpts } from "./types";
 import { VoiceChannelJoinEvt } from "./events/VoiceChannelJoinEvt";
 import { VoiceChannelSwitchEvt } from "./events/VoiceChannelSwitchEvt";
@@ -13,7 +13,7 @@ const defaultOptions = {
   },
 };
 
-export const CompanionChannelsPlugin = zeppelinPlugin<CompanionChannelsPluginType>()("companion_channels", {
+export const CompanionChannelsPlugin = zeppelinGuildPlugin<CompanionChannelsPluginType>()("companion_channels", {
   showInDocs: true,
   info: {
     prettyName: "Companion channels",
diff --git a/backend/src/plugins/CompanionChannels/events/VoiceChannelJoinEvt.ts b/backend/src/plugins/CompanionChannels/events/VoiceChannelJoinEvt.ts
index 0794bfd8..b87bd4aa 100644
--- a/backend/src/plugins/CompanionChannels/events/VoiceChannelJoinEvt.ts
+++ b/backend/src/plugins/CompanionChannels/events/VoiceChannelJoinEvt.ts
@@ -1,9 +1,8 @@
-import { eventListener } from "knub";
-import { CompanionChannelsPluginType } from "../types";
+import { companionChannelsEvt } from "../types";
 import { handleCompanionPermissions } from "../functions/handleCompanionPermissions";
-import { stripObjectToScalars } from "src/utils";
+import { stripObjectToScalars } from "../../../utils";
 
-export const VoiceChannelJoinEvt = eventListener<CompanionChannelsPluginType>()(
+export const VoiceChannelJoinEvt = companionChannelsEvt(
   "voiceChannelJoin",
   ({ pluginData, args: { member, newChannel } }) => {
     handleCompanionPermissions(pluginData, member.id, newChannel);
diff --git a/backend/src/plugins/CompanionChannels/events/VoiceChannelLeaveEvt.ts b/backend/src/plugins/CompanionChannels/events/VoiceChannelLeaveEvt.ts
index 171f5341..0711ebbd 100644
--- a/backend/src/plugins/CompanionChannels/events/VoiceChannelLeaveEvt.ts
+++ b/backend/src/plugins/CompanionChannels/events/VoiceChannelLeaveEvt.ts
@@ -1,8 +1,7 @@
-import { eventListener } from "knub";
-import { CompanionChannelsPluginType } from "../types";
+import { companionChannelsEvt } from "../types";
 import { handleCompanionPermissions } from "../functions/handleCompanionPermissions";
 
-export const VoiceChannelLeaveEvt = eventListener<CompanionChannelsPluginType>()(
+export const VoiceChannelLeaveEvt = companionChannelsEvt(
   "voiceChannelLeave",
   ({ pluginData, args: { member, oldChannel } }) => {
     handleCompanionPermissions(pluginData, member.id, null, oldChannel);
diff --git a/backend/src/plugins/CompanionChannels/events/VoiceChannelSwitchEvt.ts b/backend/src/plugins/CompanionChannels/events/VoiceChannelSwitchEvt.ts
index 102e9013..d3c978da 100644
--- a/backend/src/plugins/CompanionChannels/events/VoiceChannelSwitchEvt.ts
+++ b/backend/src/plugins/CompanionChannels/events/VoiceChannelSwitchEvt.ts
@@ -1,8 +1,7 @@
-import { eventListener } from "knub";
-import { CompanionChannelsPluginType } from "../types";
+import { companionChannelsEvt } from "../types";
 import { handleCompanionPermissions } from "../functions/handleCompanionPermissions";
 
-export const VoiceChannelSwitchEvt = eventListener<CompanionChannelsPluginType>()(
+export const VoiceChannelSwitchEvt = companionChannelsEvt(
   "voiceChannelSwitch",
   ({ pluginData, args: { member, oldChannel, newChannel } }) => {
     handleCompanionPermissions(pluginData, member.id, newChannel, oldChannel);
diff --git a/backend/src/plugins/CompanionChannels/functions/getCompanionChannelOptsForVoiceChannelId.ts b/backend/src/plugins/CompanionChannels/functions/getCompanionChannelOptsForVoiceChannelId.ts
index dddfd84c..0b2bded4 100644
--- a/backend/src/plugins/CompanionChannels/functions/getCompanionChannelOptsForVoiceChannelId.ts
+++ b/backend/src/plugins/CompanionChannels/functions/getCompanionChannelOptsForVoiceChannelId.ts
@@ -1,5 +1,5 @@
 import { VoiceChannel } from "eris";
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { CompanionChannelsPluginType, TCompanionChannelOpts } from "../types";
 
 const defaultCompanionChannelOpts: Partial<TCompanionChannelOpts> = {
@@ -7,7 +7,7 @@ const defaultCompanionChannelOpts: Partial<TCompanionChannelOpts> = {
 };
 
 export function getCompanionChannelOptsForVoiceChannelId(
-  pluginData: PluginData<CompanionChannelsPluginType>,
+  pluginData: GuildPluginData<CompanionChannelsPluginType>,
   userId: string,
   voiceChannel: VoiceChannel,
 ): TCompanionChannelOpts[] {
diff --git a/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts b/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts
index 1ac701b8..ec898db6 100644
--- a/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts
+++ b/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts
@@ -1,6 +1,6 @@
 import { CompanionChannelsPluginType, TCompanionChannelOpts } from "../types";
 import { getCompanionChannelOptsForVoiceChannelId } from "./getCompanionChannelOptsForVoiceChannelId";
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { TextChannel, VoiceChannel } from "eris";
 import { isDiscordRESTError, MINUTES } from "../../../utils";
 import { LogsPlugin } from "../../Logs/LogsPlugin";
@@ -10,19 +10,19 @@ const ERROR_COOLDOWN_KEY = "errorCooldown";
 const ERROR_COOLDOWN = 5 * MINUTES;
 
 export async function handleCompanionPermissions(
-  pluginData: PluginData<CompanionChannelsPluginType>,
+  pluginData: GuildPluginData<CompanionChannelsPluginType>,
   userId: string,
   voiceChannel: VoiceChannel,
   oldChannel?: VoiceChannel,
 );
 export async function handleCompanionPermissions(
-  pluginData: PluginData<CompanionChannelsPluginType>,
+  pluginData: GuildPluginData<CompanionChannelsPluginType>,
   userId: string,
   voiceChannel: null,
   oldChannel: VoiceChannel,
 );
 export async function handleCompanionPermissions(
-  pluginData: PluginData<CompanionChannelsPluginType>,
+  pluginData: GuildPluginData<CompanionChannelsPluginType>,
   userId: string,
   voiceChannel?: VoiceChannel,
   oldChannel?: VoiceChannel,
diff --git a/backend/src/plugins/CompanionChannels/types.ts b/backend/src/plugins/CompanionChannels/types.ts
index 781ad7e3..11c451a0 100644
--- a/backend/src/plugins/CompanionChannels/types.ts
+++ b/backend/src/plugins/CompanionChannels/types.ts
@@ -1,6 +1,6 @@
 import * as t from "io-ts";
 import { tNullable } from "../../utils";
-import { BasePluginType, CooldownManager } from "knub";
+import { BasePluginType, CooldownManager, guildEventListener } from "knub";
 import { GuildLogs } from "../../data/GuildLogs";
 import { GuildSavedMessages } from "../../data/GuildSavedMessages";
 
@@ -28,3 +28,5 @@ export interface CompanionChannelsPluginType extends BasePluginType {
     errorCooldownManager: CooldownManager;
   };
 }
+
+export const companionChannelsEvt = guildEventListener<CompanionChannelsPluginType>();
diff --git a/backend/src/plugins/CustomEvents/CustomEventsPlugin.ts b/backend/src/plugins/CustomEvents/CustomEventsPlugin.ts
index d5d7137d..96b415b6 100644
--- a/backend/src/plugins/CustomEvents/CustomEventsPlugin.ts
+++ b/backend/src/plugins/CustomEvents/CustomEventsPlugin.ts
@@ -1,6 +1,6 @@
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
+import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
 import { ConfigSchema, CustomEventsPluginType } from "./types";
-import { command, parseSignature } from "knub";
+import { guildCommand, parseSignature } from "knub";
 import { commandTypes } from "../../commandTypes";
 import { stripObjectToScalars } from "../../utils";
 import { runEvent } from "./functions/runEvent";
@@ -11,7 +11,7 @@ const defaultOptions = {
   },
 };
 
-export const CustomEventsPlugin = zeppelinPlugin<CustomEventsPluginType>()("custom_events", {
+export const CustomEventsPlugin = zeppelinGuildPlugin<CustomEventsPluginType>()("custom_events", {
   showInDocs: false,
 
   configSchema: ConfigSchema,
@@ -22,7 +22,7 @@ export const CustomEventsPlugin = zeppelinPlugin<CustomEventsPluginType>()("cust
     for (const [key, event] of Object.entries(config.events)) {
       if (event.trigger.type === "command") {
         const signature = event.trigger.params ? parseSignature(event.trigger.params, commandTypes) : {};
-        const eventCommand = command({
+        const eventCommand = guildCommand({
           trigger: event.trigger.name,
           permission: `events.${key}.trigger.can_use`,
           signature,
diff --git a/backend/src/plugins/CustomEvents/actions/addRoleAction.ts b/backend/src/plugins/CustomEvents/actions/addRoleAction.ts
index c5430724..3a5faf01 100644
--- a/backend/src/plugins/CustomEvents/actions/addRoleAction.ts
+++ b/backend/src/plugins/CustomEvents/actions/addRoleAction.ts
@@ -1,4 +1,4 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { CustomEventsPluginType, TCustomEvent } from "../types";
 import * as t from "io-ts";
 import { renderTemplate } from "../../../templateFormatter";
@@ -15,7 +15,7 @@ export const AddRoleAction = t.type({
 export type TAddRoleAction = t.TypeOf<typeof AddRoleAction>;
 
 export async function addRoleAction(
-  pluginData: PluginData<CustomEventsPluginType>,
+  pluginData: GuildPluginData<CustomEventsPluginType>,
   action: TAddRoleAction,
   values: any,
   event: TCustomEvent,
diff --git a/backend/src/plugins/CustomEvents/actions/createCaseAction.ts b/backend/src/plugins/CustomEvents/actions/createCaseAction.ts
index bb9359f6..985ff14c 100644
--- a/backend/src/plugins/CustomEvents/actions/createCaseAction.ts
+++ b/backend/src/plugins/CustomEvents/actions/createCaseAction.ts
@@ -1,4 +1,4 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { CustomEventsPluginType, TCustomEvent } from "../types";
 import * as t from "io-ts";
 import { renderTemplate } from "../../../templateFormatter";
@@ -16,7 +16,7 @@ export const CreateCaseAction = t.type({
 export type TCreateCaseAction = t.TypeOf<typeof CreateCaseAction>;
 
 export async function createCaseAction(
-  pluginData: PluginData<CustomEventsPluginType>,
+  pluginData: GuildPluginData<CustomEventsPluginType>,
   action: TCreateCaseAction,
   values: any,
   event: TCustomEvent,
diff --git a/backend/src/plugins/CustomEvents/actions/messageAction.ts b/backend/src/plugins/CustomEvents/actions/messageAction.ts
index a29aa2f8..f137d6b0 100644
--- a/backend/src/plugins/CustomEvents/actions/messageAction.ts
+++ b/backend/src/plugins/CustomEvents/actions/messageAction.ts
@@ -1,4 +1,4 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { CustomEventsPluginType } from "../types";
 import * as t from "io-ts";
 import { renderTemplate } from "../../../templateFormatter";
@@ -13,7 +13,7 @@ export const MessageAction = t.type({
 export type TMessageAction = t.TypeOf<typeof MessageAction>;
 
 export async function messageAction(
-  pluginData: PluginData<CustomEventsPluginType>,
+  pluginData: GuildPluginData<CustomEventsPluginType>,
   action: TMessageAction,
   values: any,
 ) {
diff --git a/backend/src/plugins/CustomEvents/actions/moveToVoiceChannelAction.ts b/backend/src/plugins/CustomEvents/actions/moveToVoiceChannelAction.ts
index 1fdb48f2..1aa0515a 100644
--- a/backend/src/plugins/CustomEvents/actions/moveToVoiceChannelAction.ts
+++ b/backend/src/plugins/CustomEvents/actions/moveToVoiceChannelAction.ts
@@ -1,4 +1,4 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { CustomEventsPluginType, TCustomEvent } from "../types";
 import * as t from "io-ts";
 import { renderTemplate } from "../../../templateFormatter";
@@ -15,7 +15,7 @@ export const MoveToVoiceChannelAction = t.type({
 export type TMoveToVoiceChannelAction = t.TypeOf<typeof MoveToVoiceChannelAction>;
 
 export async function moveToVoiceChannelAction(
-  pluginData: PluginData<CustomEventsPluginType>,
+  pluginData: GuildPluginData<CustomEventsPluginType>,
   action: TMoveToVoiceChannelAction,
   values: any,
   event: TCustomEvent,
diff --git a/backend/src/plugins/CustomEvents/functions/runEvent.ts b/backend/src/plugins/CustomEvents/functions/runEvent.ts
index 20dc842c..56d3a9aa 100644
--- a/backend/src/plugins/CustomEvents/functions/runEvent.ts
+++ b/backend/src/plugins/CustomEvents/functions/runEvent.ts
@@ -1,4 +1,4 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { CustomEventsPluginType, TCustomEvent } from "../types";
 import { sendErrorMessage } from "../../../pluginUtils";
 import { ActionError } from "../ActionError";
@@ -9,7 +9,7 @@ import { moveToVoiceChannelAction } from "../actions/moveToVoiceChannelAction";
 import { messageAction } from "../actions/messageAction";
 
 export async function runEvent(
-  pluginData: PluginData<CustomEventsPluginType>,
+  pluginData: GuildPluginData<CustomEventsPluginType>,
   event: TCustomEvent,
   eventData: any,
   values: any,
diff --git a/backend/src/plugins/GuildAccessMonitor/GuildAccessMonitorPlugin.ts b/backend/src/plugins/GuildAccessMonitor/GuildAccessMonitorPlugin.ts
index 000500fa..df5e8b3e 100644
--- a/backend/src/plugins/GuildAccessMonitor/GuildAccessMonitorPlugin.ts
+++ b/backend/src/plugins/GuildAccessMonitor/GuildAccessMonitorPlugin.ts
@@ -1,5 +1,5 @@
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
-import { BasePluginType, eventListener, PluginData } from "knub";
+import { zeppelinGlobalPlugin } from "../ZeppelinPluginBlueprint";
+import { BasePluginType, globalEventListener, GlobalPluginData } from "knub";
 import * as t from "io-ts";
 import { AllowedGuilds } from "../../data/AllowedGuilds";
 import { Guild } from "eris";
@@ -11,7 +11,7 @@ interface GuildAccessMonitorPluginType extends BasePluginType {
   };
 }
 
-async function checkGuild(pluginData: PluginData<GuildAccessMonitorPluginType>, guild: Guild) {
+async function checkGuild(pluginData: GlobalPluginData<GuildAccessMonitorPluginType>, guild: Guild) {
   if (!(await pluginData.state.allowedGuilds.isAllowed(guild.id))) {
     console.log(`Non-allowed server ${guild.name} (${guild.id}), leaving`);
     guild.leave();
@@ -21,11 +21,11 @@ async function checkGuild(pluginData: PluginData<GuildAccessMonitorPluginType>,
 /**
  * Global plugin to monitor if Zeppelin is invited to a non-whitelisted server, and leave it
  */
-export const GuildAccessMonitorPlugin = zeppelinPlugin<GuildAccessMonitorPluginType>()("guild_access_monitor", {
+export const GuildAccessMonitorPlugin = zeppelinGlobalPlugin<GuildAccessMonitorPluginType>()("guild_access_monitor", {
   configSchema: t.type({}),
 
   events: [
-    eventListener<GuildAccessMonitorPluginType>()("guildAvailable", ({ pluginData, args: { guild } }) => {
+    globalEventListener<GuildAccessMonitorPluginType>()("guildAvailable", ({ pluginData, args: { guild } }) => {
       checkGuild(pluginData, guild);
     }),
   ],
diff --git a/backend/src/plugins/GuildConfigReloader/GuildConfigReloaderPlugin.ts b/backend/src/plugins/GuildConfigReloader/GuildConfigReloaderPlugin.ts
index c89d2277..ddb0b863 100644
--- a/backend/src/plugins/GuildConfigReloader/GuildConfigReloaderPlugin.ts
+++ b/backend/src/plugins/GuildConfigReloader/GuildConfigReloaderPlugin.ts
@@ -1,23 +1,26 @@
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
+import { zeppelinGlobalPlugin } from "../ZeppelinPluginBlueprint";
 import { GuildConfigReloaderPluginType } from "./types";
 import { Configs } from "../../data/Configs";
 import { reloadChangedGuilds } from "./functions/reloadChangedGuilds";
 import * as t from "io-ts";
 
-export const GuildConfigReloaderPlugin = zeppelinPlugin<GuildConfigReloaderPluginType>()("guild_config_reloader", {
-  showInDocs: false,
+export const GuildConfigReloaderPlugin = zeppelinGlobalPlugin<GuildConfigReloaderPluginType>()(
+  "guild_config_reloader",
+  {
+    showInDocs: false,
 
-  configSchema: t.type({}),
+    configSchema: t.type({}),
 
-  async onLoad(pluginData) {
-    pluginData.state.guildConfigs = new Configs();
-    pluginData.state.highestConfigId = await pluginData.state.guildConfigs.getHighestId();
+    async onLoad(pluginData) {
+      pluginData.state.guildConfigs = new Configs();
+      pluginData.state.highestConfigId = await pluginData.state.guildConfigs.getHighestId();
 
-    reloadChangedGuilds(pluginData);
+      reloadChangedGuilds(pluginData);
+    },
+
+    onUnload(pluginData) {
+      clearTimeout(pluginData.state.nextCheckTimeout);
+      pluginData.state.unloaded = true;
+    },
   },
-
-  onUnload(pluginData) {
-    clearTimeout(pluginData.state.nextCheckTimeout);
-    pluginData.state.unloaded = true;
-  },
-});
+);
diff --git a/backend/src/plugins/GuildConfigReloader/functions/reloadChangedGuilds.ts b/backend/src/plugins/GuildConfigReloader/functions/reloadChangedGuilds.ts
index d858ef72..10cd97c0 100644
--- a/backend/src/plugins/GuildConfigReloader/functions/reloadChangedGuilds.ts
+++ b/backend/src/plugins/GuildConfigReloader/functions/reloadChangedGuilds.ts
@@ -1,10 +1,10 @@
-import { PluginData } from "knub";
+import { GlobalPluginData } from "knub";
 import { GuildConfigReloaderPluginType } from "../types";
 import { SECONDS } from "../../../utils";
 
 const CHECK_INTERVAL = 1 * SECONDS;
 
-export async function reloadChangedGuilds(pluginData: PluginData<GuildConfigReloaderPluginType>) {
+export async function reloadChangedGuilds(pluginData: GlobalPluginData<GuildConfigReloaderPluginType>) {
   if (pluginData.state.unloaded) return;
 
   const changedConfigs = await pluginData.state.guildConfigs.getActiveLargerThanId(pluginData.state.highestConfigId);
diff --git a/backend/src/plugins/GuildInfoSaver/GuildInfoSaverPlugin.ts b/backend/src/plugins/GuildInfoSaver/GuildInfoSaverPlugin.ts
index 2d4b4ee3..f9394041 100644
--- a/backend/src/plugins/GuildInfoSaver/GuildInfoSaverPlugin.ts
+++ b/backend/src/plugins/GuildInfoSaver/GuildInfoSaverPlugin.ts
@@ -1,11 +1,11 @@
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
-import { PluginData } from "knub";
-import { AllowedGuilds } from "src/data/AllowedGuilds";
+import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
+import { GuildPluginData } from "knub";
+import { AllowedGuilds } from "../../data/AllowedGuilds";
 import { GuildInfoSaverPluginType } from "./types";
-import { MINUTES } from "src/utils";
+import { MINUTES } from "../../utils";
 import * as t from "io-ts";
 
-export const GuildInfoSaverPlugin = zeppelinPlugin<GuildInfoSaverPluginType>()("guild_info_saver", {
+export const GuildInfoSaverPlugin = zeppelinGuildPlugin<GuildInfoSaverPluginType>()("guild_info_saver", {
   showInDocs: false,
 
   configSchema: t.type({}),
@@ -20,7 +20,7 @@ export const GuildInfoSaverPlugin = zeppelinPlugin<GuildInfoSaverPluginType>()("
   },
 });
 
-function updateGuildInfo(pluginData: PluginData<GuildInfoSaverPluginType>) {
+function updateGuildInfo(pluginData: GuildPluginData<GuildInfoSaverPluginType>) {
   pluginData.state.allowedGuilds.updateInfo(
     pluginData.guild.id,
     pluginData.guild.name,
diff --git a/backend/src/plugins/GuildInfoSaver/types.ts b/backend/src/plugins/GuildInfoSaver/types.ts
index 33e913c9..25926bff 100644
--- a/backend/src/plugins/GuildInfoSaver/types.ts
+++ b/backend/src/plugins/GuildInfoSaver/types.ts
@@ -1,5 +1,5 @@
 import { BasePluginType } from "knub";
-import { AllowedGuilds } from "src/data/AllowedGuilds";
+import { AllowedGuilds } from "../../data/AllowedGuilds";
 
 export interface GuildInfoSaverPluginType extends BasePluginType {
   state: {
diff --git a/backend/src/plugins/LocateUser/LocateUserPlugin.ts b/backend/src/plugins/LocateUser/LocateUserPlugin.ts
index e7fdac73..4d71ea16 100644
--- a/backend/src/plugins/LocateUser/LocateUserPlugin.ts
+++ b/backend/src/plugins/LocateUser/LocateUserPlugin.ts
@@ -1,7 +1,7 @@
 import { PluginOptions } from "knub";
 import { ConfigSchema, LocateUserPluginType } from "./types";
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
-import { GuildVCAlerts } from "src/data/GuildVCAlerts";
+import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
+import { GuildVCAlerts } from "../../data/GuildVCAlerts";
 import { outdatedAlertsLoop } from "./utils/outdatedLoop";
 import { fillActiveAlertsList } from "./utils/fillAlertsList";
 import { WhereCmd } from "./commands/WhereCmd";
@@ -27,7 +27,7 @@ const defaultOptions: PluginOptions<LocateUserPluginType> = {
   ],
 };
 
-export const LocateUserPlugin = zeppelinPlugin<LocateUserPluginType>()("locate_user", {
+export const LocateUserPlugin = zeppelinGuildPlugin<LocateUserPluginType>()("locate_user", {
   showInDocs: true,
   info: {
     prettyName: "Locate user",
diff --git a/backend/src/plugins/LocateUser/commands/FollowCmd.ts b/backend/src/plugins/LocateUser/commands/FollowCmd.ts
index 1f3bd7db..08c105ed 100644
--- a/backend/src/plugins/LocateUser/commands/FollowCmd.ts
+++ b/backend/src/plugins/LocateUser/commands/FollowCmd.ts
@@ -1,11 +1,11 @@
-import { locateUserCommand } from "../types";
+import { locateUserCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import moment from "moment-timezone";
 import humanizeDuration from "humanize-duration";
-import { MINUTES, SECONDS } from "src/utils";
-import { sendErrorMessage, sendSuccessMessage } from "src/pluginUtils";
+import { MINUTES, SECONDS } from "../../../utils";
+import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
 
-export const FollowCmd = locateUserCommand({
+export const FollowCmd = locateUserCmd({
   trigger: ["follow", "f"],
   description: "Sets up an alert that notifies you any time `<member>` switches or joins voice channels",
   usage: "!f 108552944961454080",
diff --git a/backend/src/plugins/LocateUser/commands/ListFollowCmd.ts b/backend/src/plugins/LocateUser/commands/ListFollowCmd.ts
index dc8e4754..67ad383d 100644
--- a/backend/src/plugins/LocateUser/commands/ListFollowCmd.ts
+++ b/backend/src/plugins/LocateUser/commands/ListFollowCmd.ts
@@ -1,9 +1,9 @@
-import { locateUserCommand } from "../types";
-import { sendErrorMessage, sendSuccessMessage } from "src/pluginUtils";
+import { locateUserCmd } from "../types";
+import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
-import { createChunkedMessage, sorter } from "src/utils";
+import { createChunkedMessage, sorter } from "../../../utils";
 
-export const ListFollowCmd = locateUserCommand({
+export const ListFollowCmd = locateUserCmd({
   trigger: ["follows", "fs"],
   description: "Displays all of your active alerts ordered by expiration time",
   usage: "!fs",
@@ -29,7 +29,7 @@ export const ListFollowCmd = locateUserCommand({
   },
 });
 
-export const DeleteFollowCmd = locateUserCommand({
+export const DeleteFollowCmd = locateUserCmd({
   trigger: ["follows delete", "fs d"],
   description:
     "Deletes the alert at the position <num>.\nThe value needed for <num> can be found using `!follows` (`!fs`)",
diff --git a/backend/src/plugins/LocateUser/commands/WhereCmd.ts b/backend/src/plugins/LocateUser/commands/WhereCmd.ts
index 24d3dafe..c8137144 100644
--- a/backend/src/plugins/LocateUser/commands/WhereCmd.ts
+++ b/backend/src/plugins/LocateUser/commands/WhereCmd.ts
@@ -1,9 +1,9 @@
-import { locateUserCommand } from "../types";
+import { locateUserCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
-import { resolveMember } from "src/utils";
+import { resolveMember } from "../../../utils";
 import { sendWhere } from "../utils/sendWhere";
 
-export const WhereCmd = locateUserCommand({
+export const WhereCmd = locateUserCmd({
   trigger: ["where", "w"],
   description: "Posts an instant invite to the voice channel that `<member>` is in",
   usage: "!w 108552944961454080",
diff --git a/backend/src/plugins/LocateUser/events/BanRemoveAlertsEvt.ts b/backend/src/plugins/LocateUser/events/BanRemoveAlertsEvt.ts
index e2eef6dc..cc6c155f 100644
--- a/backend/src/plugins/LocateUser/events/BanRemoveAlertsEvt.ts
+++ b/backend/src/plugins/LocateUser/events/BanRemoveAlertsEvt.ts
@@ -1,6 +1,6 @@
-import { locateUserEvent } from "../types";
+import { locateUserEvt } from "../types";
 
-export const GuildBanRemoveAlertsEvt = locateUserEvent({
+export const GuildBanRemoveAlertsEvt = locateUserEvt({
   event: "guildBanAdd",
 
   async listener(meta) {
diff --git a/backend/src/plugins/LocateUser/events/SendAlertsEvts.ts b/backend/src/plugins/LocateUser/events/SendAlertsEvts.ts
index 687c39c6..e426e704 100644
--- a/backend/src/plugins/LocateUser/events/SendAlertsEvts.ts
+++ b/backend/src/plugins/LocateUser/events/SendAlertsEvts.ts
@@ -1,8 +1,8 @@
-import { locateUserEvent } from "../types";
+import { locateUserEvt } from "../types";
 import { sendAlerts } from "../utils/sendAlerts";
 import { TextableChannel, VoiceChannel } from "eris";
 
-export const ChannelJoinAlertsEvt = locateUserEvent({
+export const ChannelJoinAlertsEvt = locateUserEvt({
   event: "voiceChannelJoin",
 
   async listener(meta) {
@@ -12,7 +12,7 @@ export const ChannelJoinAlertsEvt = locateUserEvent({
   },
 });
 
-export const ChannelSwitchAlertsEvt = locateUserEvent({
+export const ChannelSwitchAlertsEvt = locateUserEvt({
   event: "voiceChannelSwitch",
 
   async listener(meta) {
@@ -22,7 +22,7 @@ export const ChannelSwitchAlertsEvt = locateUserEvent({
   },
 });
 
-export const ChannelLeaveAlertsEvt = locateUserEvent({
+export const ChannelLeaveAlertsEvt = locateUserEvt({
   event: "voiceChannelLeave",
 
   async listener(meta) {
diff --git a/backend/src/plugins/LocateUser/types.ts b/backend/src/plugins/LocateUser/types.ts
index b928862d..c438caf9 100644
--- a/backend/src/plugins/LocateUser/types.ts
+++ b/backend/src/plugins/LocateUser/types.ts
@@ -1,5 +1,7 @@
 import * as t from "io-ts";
-import { BasePluginType, command, eventListener } from "knub";
+import { BasePluginType, guildCommand, guildEventListener } from "knub";
+import { GuildVCAlerts } from "../../data/GuildVCAlerts";
+import Timeout = NodeJS.Timeout;
 
 export const ConfigSchema = t.type({
   can_where: t.boolean,
@@ -9,7 +11,13 @@ export type TConfigSchema = t.TypeOf<typeof ConfigSchema>;
 
 export interface LocateUserPluginType extends BasePluginType {
   config: TConfigSchema;
+  state: {
+    alerts: GuildVCAlerts;
+    outdatedAlertsTimeout: Timeout;
+    usersWithAlerts: string[];
+    unloaded: boolean;
+  };
 }
 
-export const locateUserCommand = command<LocateUserPluginType>();
-export const locateUserEvent = eventListener<LocateUserPluginType>();
+export const locateUserCmd = guildCommand<LocateUserPluginType>();
+export const locateUserEvt = guildEventListener<LocateUserPluginType>();
diff --git a/backend/src/plugins/LocateUser/utils/fillAlertsList.ts b/backend/src/plugins/LocateUser/utils/fillAlertsList.ts
index 675972e6..3c5c90d1 100644
--- a/backend/src/plugins/LocateUser/utils/fillAlertsList.ts
+++ b/backend/src/plugins/LocateUser/utils/fillAlertsList.ts
@@ -1,4 +1,7 @@
-export async function fillActiveAlertsList(pluginData) {
+import { GuildPluginData } from "knub";
+import { LocateUserPluginType } from "../types";
+
+export async function fillActiveAlertsList(pluginData: GuildPluginData<LocateUserPluginType>) {
   const allAlerts = await pluginData.state.alerts.getAllGuildAlerts();
 
   allAlerts.forEach(alert => {
diff --git a/backend/src/plugins/LocateUser/utils/moveMember.ts b/backend/src/plugins/LocateUser/utils/moveMember.ts
index 51d5ea97..327b933f 100644
--- a/backend/src/plugins/LocateUser/utils/moveMember.ts
+++ b/backend/src/plugins/LocateUser/utils/moveMember.ts
@@ -1,10 +1,10 @@
 import { Member, TextableChannel } from "eris";
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { LocateUserPluginType } from "../types";
-import { sendErrorMessage } from "src/pluginUtils";
+import { sendErrorMessage } from "../../../pluginUtils";
 
 export async function moveMember(
-  pluginData: PluginData<LocateUserPluginType>,
+  pluginData: GuildPluginData<LocateUserPluginType>,
   toMoveID: string,
   target: Member,
   errorChannel: TextableChannel,
diff --git a/backend/src/plugins/LocateUser/utils/outdatedLoop.ts b/backend/src/plugins/LocateUser/utils/outdatedLoop.ts
index 192b9cd4..0e3f29cd 100644
--- a/backend/src/plugins/LocateUser/utils/outdatedLoop.ts
+++ b/backend/src/plugins/LocateUser/utils/outdatedLoop.ts
@@ -1,9 +1,11 @@
-import { SECONDS } from "src/utils";
+import { SECONDS } from "../../../utils";
 import { removeUserIdFromActiveAlerts } from "./removeUserIdFromActiveAlerts";
+import { GuildPluginData } from "knub";
+import { LocateUserPluginType } from "../types";
 
 const ALERT_LOOP_TIME = 30 * SECONDS;
 
-export async function outdatedAlertsLoop(pluginData) {
+export async function outdatedAlertsLoop(pluginData: GuildPluginData<LocateUserPluginType>) {
   const outdatedAlerts = await pluginData.state.alerts.getOutdatedAlerts();
 
   for (const alert of outdatedAlerts) {
diff --git a/backend/src/plugins/LocateUser/utils/removeUserIdFromActiveAlerts.ts b/backend/src/plugins/LocateUser/utils/removeUserIdFromActiveAlerts.ts
index 9493e416..adfffb95 100644
--- a/backend/src/plugins/LocateUser/utils/removeUserIdFromActiveAlerts.ts
+++ b/backend/src/plugins/LocateUser/utils/removeUserIdFromActiveAlerts.ts
@@ -1,4 +1,7 @@
-export async function removeUserIdFromActiveAlerts(pluginData, userId: string) {
+import { GuildPluginData } from "knub";
+import { LocateUserPluginType } from "../types";
+
+export async function removeUserIdFromActiveAlerts(pluginData: GuildPluginData<LocateUserPluginType>, userId: string) {
   const index = pluginData.state.usersWithAlerts.indexOf(userId);
   if (index > -1) {
     pluginData.state.usersWithAlerts.splice(index, 1);
diff --git a/backend/src/plugins/LocateUser/utils/sendAlerts.ts b/backend/src/plugins/LocateUser/utils/sendAlerts.ts
index adbb8bbb..f0013492 100644
--- a/backend/src/plugins/LocateUser/utils/sendAlerts.ts
+++ b/backend/src/plugins/LocateUser/utils/sendAlerts.ts
@@ -1,11 +1,11 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { LocateUserPluginType } from "../types";
-import { resolveMember } from "src/utils";
+import { resolveMember } from "../../../utils";
 import { sendWhere } from "./sendWhere";
 import { TextableChannel } from "eris";
 import { moveMember } from "./moveMember";
 
-export async function sendAlerts(pluginData: PluginData<LocateUserPluginType>, userId: string) {
+export async function sendAlerts(pluginData: GuildPluginData<LocateUserPluginType>, userId: string) {
   const triggeredAlerts = await pluginData.state.alerts.getAlertsByUserId(userId);
   const member = await resolveMember(pluginData.client, pluginData.guild, userId);
 
diff --git a/backend/src/plugins/LocateUser/utils/sendWhere.ts b/backend/src/plugins/LocateUser/utils/sendWhere.ts
index 92842f11..87b5f38a 100644
--- a/backend/src/plugins/LocateUser/utils/sendWhere.ts
+++ b/backend/src/plugins/LocateUser/utils/sendWhere.ts
@@ -1,12 +1,12 @@
 import { Member, TextableChannel, VoiceChannel } from "eris";
 import { getInviteLink } from "knub/dist/helpers";
 import { createOrReuseInvite } from "./createOrReuseInvite";
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { LocateUserPluginType } from "../types";
 import { sendErrorMessage } from "../../../pluginUtils";
 
 export async function sendWhere(
-  pluginData: PluginData<LocateUserPluginType>,
+  pluginData: GuildPluginData<LocateUserPluginType>,
   member: Member,
   channel: TextableChannel,
   prepend: string,
diff --git a/backend/src/plugins/Logs/LogsPlugin.ts b/backend/src/plugins/Logs/LogsPlugin.ts
index a678b3e9..92858052 100644
--- a/backend/src/plugins/Logs/LogsPlugin.ts
+++ b/backend/src/plugins/Logs/LogsPlugin.ts
@@ -1,17 +1,17 @@
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
+import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
 import { PluginOptions } from "knub";
 import { ConfigSchema, LogsPluginType } from "./types";
 import DefaultLogMessages from "../../data/DefaultLogMessages.json";
-import { GuildLogs } from "src/data/GuildLogs";
-import { GuildSavedMessages } from "src/data/GuildSavedMessages";
-import { GuildArchives } from "src/data/GuildArchives";
-import { GuildCases } from "src/data/GuildCases";
+import { GuildLogs } from "../../data/GuildLogs";
+import { GuildSavedMessages } from "../../data/GuildSavedMessages";
+import { GuildArchives } from "../../data/GuildArchives";
+import { GuildCases } from "../../data/GuildCases";
 import { onMessageDelete } from "./util/onMessageDelete";
 import { onMessageDeleteBulk } from "./util/onMessageDeleteBulk";
 import { onMessageUpdate } from "./util/onMessageUpdate";
 import { LogsGuildMemberAddEvt } from "./events/LogsGuildMemberAddEvt";
 import { LogsGuildMemberRemoveEvt } from "./events/LogsGuildMemberRemoveEvt";
-import { LogsGuildMemberUpdateEvt, LogsUserUpdateEvt } from "./events/LogsUserUpdateEvts";
+import { LogsGuildMemberUpdateEvt } from "./events/LogsUserUpdateEvts";
 import { LogsChannelCreateEvt, LogsChannelDeleteEvt } from "./events/LogsChannelModifyEvts";
 import { LogsRoleCreateEvt, LogsRoleDeleteEvt } from "./events/LogsRoleModifyEvts";
 import { LogsVoiceJoinEvt, LogsVoiceLeaveEvt, LogsVoiceSwitchEvt } from "./events/LogsVoiceChannelEvts";
@@ -44,7 +44,7 @@ const defaultOptions: PluginOptions<LogsPluginType> = {
   ],
 };
 
-export const LogsPlugin = zeppelinPlugin<LogsPluginType>()("logs", {
+export const LogsPlugin = zeppelinGuildPlugin<LogsPluginType>()("logs", {
   showInDocs: true,
   info: {
     prettyName: "Logs",
@@ -58,7 +58,6 @@ export const LogsPlugin = zeppelinPlugin<LogsPluginType>()("logs", {
     LogsGuildMemberAddEvt,
     LogsGuildMemberRemoveEvt,
     LogsGuildMemberUpdateEvt,
-    LogsUserUpdateEvt,
     LogsChannelCreateEvt,
     LogsChannelDeleteEvt,
     LogsRoleCreateEvt,
diff --git a/backend/src/plugins/Logs/events/LogsChannelModifyEvts.ts b/backend/src/plugins/Logs/events/LogsChannelModifyEvts.ts
index e5e57bfe..dad30a6a 100644
--- a/backend/src/plugins/Logs/events/LogsChannelModifyEvts.ts
+++ b/backend/src/plugins/Logs/events/LogsChannelModifyEvts.ts
@@ -1,8 +1,8 @@
-import { logsEvent } from "../types";
-import { stripObjectToScalars } from "src/utils";
-import { LogType } from "src/data/LogType";
+import { logsEvt } from "../types";
+import { stripObjectToScalars } from "../../../utils";
+import { LogType } from "../../../data/LogType";
 
-export const LogsChannelCreateEvt = logsEvent({
+export const LogsChannelCreateEvt = logsEvt({
   event: "channelCreate",
 
   async listener(meta) {
@@ -12,7 +12,7 @@ export const LogsChannelCreateEvt = logsEvent({
   },
 });
 
-export const LogsChannelDeleteEvt = logsEvent({
+export const LogsChannelDeleteEvt = logsEvt({
   event: "channelDelete",
 
   async listener(meta) {
diff --git a/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts b/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts
index ff327923..27bbbe87 100644
--- a/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts
+++ b/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts
@@ -1,10 +1,10 @@
-import { logsEvent } from "../types";
-import { stripObjectToScalars, UnknownUser } from "src/utils";
-import { LogType } from "src/data/LogType";
+import { logsEvt } from "../types";
+import { stripObjectToScalars, UnknownUser } from "../../../utils";
+import { LogType } from "../../../data/LogType";
 import { Constants as ErisConstants } from "eris";
 import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAuditLogEntry";
 
-export const LogsGuildBanAddEvt = logsEvent({
+export const LogsGuildBanAddEvt = logsEvt({
   event: "guildBanAdd",
 
   async listener(meta) {
@@ -29,7 +29,7 @@ export const LogsGuildBanAddEvt = logsEvent({
   },
 });
 
-export const LogsGuildBanRemoveEvt = logsEvent({
+export const LogsGuildBanRemoveEvt = logsEvt({
   event: "guildBanRemove",
 
   async listener(meta) {
diff --git a/backend/src/plugins/Logs/events/LogsGuildMemberAddEvt.ts b/backend/src/plugins/Logs/events/LogsGuildMemberAddEvt.ts
index fef3505a..f7d71498 100644
--- a/backend/src/plugins/Logs/events/LogsGuildMemberAddEvt.ts
+++ b/backend/src/plugins/Logs/events/LogsGuildMemberAddEvt.ts
@@ -1,11 +1,11 @@
-import { logsEvent } from "../types";
-import { stripObjectToScalars } from "src/utils";
-import { LogType } from "src/data/LogType";
+import { logsEvt } from "../types";
+import { stripObjectToScalars } from "../../../utils";
+import { LogType } from "../../../data/LogType";
 import moment from "moment-timezone";
 import humanizeDuration from "humanize-duration";
 import { CasesPlugin } from "../../Cases/CasesPlugin";
 
-export const LogsGuildMemberAddEvt = logsEvent({
+export const LogsGuildMemberAddEvt = logsEvt({
   event: "guildMemberAdd",
 
   async listener(meta) {
diff --git a/backend/src/plugins/Logs/events/LogsGuildMemberRemoveEvt.ts b/backend/src/plugins/Logs/events/LogsGuildMemberRemoveEvt.ts
index c5274a78..cde1fbd8 100644
--- a/backend/src/plugins/Logs/events/LogsGuildMemberRemoveEvt.ts
+++ b/backend/src/plugins/Logs/events/LogsGuildMemberRemoveEvt.ts
@@ -1,8 +1,8 @@
-import { logsEvent } from "../types";
-import { stripObjectToScalars } from "src/utils";
-import { LogType } from "src/data/LogType";
+import { logsEvt } from "../types";
+import { stripObjectToScalars } from "../../../utils";
+import { LogType } from "../../../data/LogType";
 
-export const LogsGuildMemberRemoveEvt = logsEvent({
+export const LogsGuildMemberRemoveEvt = logsEvt({
   event: "guildMemberRemove",
 
   async listener(meta) {
diff --git a/backend/src/plugins/Logs/events/LogsRoleModifyEvts.ts b/backend/src/plugins/Logs/events/LogsRoleModifyEvts.ts
index 944f408d..a24d7929 100644
--- a/backend/src/plugins/Logs/events/LogsRoleModifyEvts.ts
+++ b/backend/src/plugins/Logs/events/LogsRoleModifyEvts.ts
@@ -1,8 +1,8 @@
-import { logsEvent } from "../types";
-import { stripObjectToScalars } from "src/utils";
-import { LogType } from "src/data/LogType";
+import { logsEvt } from "../types";
+import { stripObjectToScalars } from "../../../utils";
+import { LogType } from "../../../data/LogType";
 
-export const LogsRoleCreateEvt = logsEvent({
+export const LogsRoleCreateEvt = logsEvt({
   event: "guildRoleCreate",
 
   async listener(meta) {
@@ -12,7 +12,7 @@ export const LogsRoleCreateEvt = logsEvent({
   },
 });
 
-export const LogsRoleDeleteEvt = logsEvent({
+export const LogsRoleDeleteEvt = logsEvt({
   event: "guildRoleDelete",
 
   async listener(meta) {
diff --git a/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts b/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts
index 189af03c..46228646 100644
--- a/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts
+++ b/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts
@@ -1,12 +1,12 @@
-import { logsEvent } from "../types";
-import { stripObjectToScalars, UnknownUser } from "src/utils";
+import { logsEvt } from "../types";
+import { stripObjectToScalars, UnknownUser } from "../../../utils";
 import { Constants as ErisConstants } from "eris";
-import { LogType } from "src/data/LogType";
+import { LogType } from "../../../data/LogType";
 import isEqual from "lodash.isequal";
 import diff from "lodash.difference";
 import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAuditLogEntry";
 
-export const LogsGuildMemberUpdateEvt = logsEvent({
+export const LogsGuildMemberUpdateEvt = logsEvt({
   event: "guildMemberUpdate",
 
   async listener(meta) {
@@ -106,25 +106,4 @@ export const LogsGuildMemberUpdateEvt = logsEvent({
   },
 });
 
-export const LogsUserUpdateEvt = logsEvent({
-  event: "userUpdate",
-  allowSelf: true,
-
-  async listener(meta) {
-    const pluginData = meta.pluginData;
-    const oldUser = meta.args.oldUser;
-    const user = meta.args.user;
-
-    if (!oldUser) return;
-
-    if (!pluginData.guild.members.has(user.id)) return;
-
-    if (user.username !== oldUser.username || user.discriminator !== oldUser.discriminator) {
-      pluginData.state.guildLogs.log(LogType.MEMBER_USERNAME_CHANGE, {
-        user: stripObjectToScalars(user),
-        oldName: `${oldUser.username}#${oldUser.discriminator}`,
-        newName: `${user.username}#${user.discriminator}`,
-      });
-    }
-  },
-});
+// TODO: Reimplement USERNAME_CHANGE
diff --git a/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts b/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts
index 051b03a7..a1899d5c 100644
--- a/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts
+++ b/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts
@@ -1,8 +1,8 @@
-import { logsEvent } from "../types";
-import { stripObjectToScalars } from "src/utils";
-import { LogType } from "src/data/LogType";
+import { logsEvt } from "../types";
+import { stripObjectToScalars } from "../../../utils";
+import { LogType } from "../../../data/LogType";
 
-export const LogsVoiceJoinEvt = logsEvent({
+export const LogsVoiceJoinEvt = logsEvt({
   event: "voiceChannelJoin",
 
   async listener(meta) {
@@ -13,7 +13,7 @@ export const LogsVoiceJoinEvt = logsEvent({
   },
 });
 
-export const LogsVoiceLeaveEvt = logsEvent({
+export const LogsVoiceLeaveEvt = logsEvt({
   event: "voiceChannelLeave",
 
   async listener(meta) {
@@ -24,7 +24,7 @@ export const LogsVoiceLeaveEvt = logsEvent({
   },
 });
 
-export const LogsVoiceSwitchEvt = logsEvent({
+export const LogsVoiceSwitchEvt = logsEvt({
   event: "voiceChannelSwitch",
 
   async listener(meta) {
diff --git a/backend/src/plugins/Logs/types.ts b/backend/src/plugins/Logs/types.ts
index 97006927..74b43697 100644
--- a/backend/src/plugins/Logs/types.ts
+++ b/backend/src/plugins/Logs/types.ts
@@ -1,10 +1,10 @@
 import * as t from "io-ts";
-import { BasePluginType, eventListener } from "knub";
-import { TRegex } from "src/validatorUtils";
-import { GuildLogs } from "src/data/GuildLogs";
-import { GuildSavedMessages } from "src/data/GuildSavedMessages";
-import { GuildArchives } from "src/data/GuildArchives";
-import { GuildCases } from "src/data/GuildCases";
+import { BasePluginType, guildEventListener } from "knub";
+import { TRegex } from "../../validatorUtils";
+import { GuildLogs } from "../../data/GuildLogs";
+import { GuildSavedMessages } from "../../data/GuildSavedMessages";
+import { GuildArchives } from "../../data/GuildArchives";
+import { GuildCases } from "../../data/GuildCases";
 import { tMessageContent, tNullable } from "../../utils";
 import { RegExpRunner } from "../../RegExpRunner";
 
@@ -60,4 +60,4 @@ export interface LogsPluginType extends BasePluginType {
   };
 }
 
-export const logsEvent = eventListener<LogsPluginType>();
+export const logsEvt = guildEventListener<LogsPluginType>();
diff --git a/backend/src/plugins/Logs/util/getLogMessage.ts b/backend/src/plugins/Logs/util/getLogMessage.ts
index 92cc073b..c6c00d99 100644
--- a/backend/src/plugins/Logs/util/getLogMessage.ts
+++ b/backend/src/plugins/Logs/util/getLogMessage.ts
@@ -1,6 +1,6 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { LogsPluginType, TLogFormats } from "../types";
-import { LogType } from "src/data/LogType";
+import { LogType } from "../../../data/LogType";
 import {
   verboseUserMention,
   verboseUserName,
@@ -8,15 +8,15 @@ import {
   messageSummary,
   resolveMember,
   renderRecursively,
-} from "src/utils";
-import { SavedMessage } from "src/data/entities/SavedMessage";
-import { renderTemplate, TemplateParseError } from "src/templateFormatter";
-import { logger } from "src/logger";
+} from "../../../utils";
+import { SavedMessage } from "../../../data/entities/SavedMessage";
+import { renderTemplate, TemplateParseError } from "../../../templateFormatter";
+import { logger } from "../../../logger";
 import moment from "moment-timezone";
 import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin";
 
 export async function getLogMessage(
-  pluginData: PluginData<LogsPluginType>,
+  pluginData: GuildPluginData<LogsPluginType>,
   type: LogType,
   data: any,
   formats?: TLogFormats,
diff --git a/backend/src/plugins/Logs/util/log.ts b/backend/src/plugins/Logs/util/log.ts
index 90470fd1..56b36015 100644
--- a/backend/src/plugins/Logs/util/log.ts
+++ b/backend/src/plugins/Logs/util/log.ts
@@ -1,14 +1,14 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { LogsPluginType, TLogChannelMap } from "../types";
-import { LogType } from "src/data/LogType";
+import { LogType } from "../../../data/LogType";
 import { TextChannel } from "eris";
-import { createChunkedMessage, noop } from "src/utils";
+import { createChunkedMessage, noop } from "../../../utils";
 import { getLogMessage } from "./getLogMessage";
 import { allowTimeout } from "../../../RegExpRunner";
 
 const excludedUserProps = ["user", "member", "mod"];
 
-export async function log(pluginData: PluginData<LogsPluginType>, type: LogType, data: any) {
+export async function log(pluginData: GuildPluginData<LogsPluginType>, type: LogType, data: any) {
   const logChannels: TLogChannelMap = pluginData.config.get().channels;
   const typeStr = LogType[type];
 
diff --git a/backend/src/plugins/Logs/util/onMessageDelete.ts b/backend/src/plugins/Logs/util/onMessageDelete.ts
index 80112e22..86eb9c5d 100644
--- a/backend/src/plugins/Logs/util/onMessageDelete.ts
+++ b/backend/src/plugins/Logs/util/onMessageDelete.ts
@@ -1,13 +1,13 @@
-import { SavedMessage } from "src/data/entities/SavedMessage";
+import { SavedMessage } from "../../../data/entities/SavedMessage";
 import { Attachment } from "eris";
-import { useMediaUrls, stripObjectToScalars, resolveUser } from "src/utils";
-import { LogType } from "src/data/LogType";
+import { useMediaUrls, stripObjectToScalars, resolveUser } from "../../../utils";
+import { LogType } from "../../../data/LogType";
 import moment from "moment-timezone";
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { LogsPluginType } from "../types";
 import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin";
 
-export async function onMessageDelete(pluginData: PluginData<LogsPluginType>, savedMessage: SavedMessage) {
+export async function onMessageDelete(pluginData: GuildPluginData<LogsPluginType>, savedMessage: SavedMessage) {
   const user = await resolveUser(pluginData.client, savedMessage.user_id);
   const channel = pluginData.guild.channels.get(savedMessage.channel_id);
 
diff --git a/backend/src/plugins/Logs/util/onMessageDeleteBulk.ts b/backend/src/plugins/Logs/util/onMessageDeleteBulk.ts
index bd447584..6eb1302e 100644
--- a/backend/src/plugins/Logs/util/onMessageDeleteBulk.ts
+++ b/backend/src/plugins/Logs/util/onMessageDeleteBulk.ts
@@ -1,10 +1,10 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { LogsPluginType } from "../types";
-import { SavedMessage } from "src/data/entities/SavedMessage";
-import { LogType } from "src/data/LogType";
-import { getBaseUrl } from "src/pluginUtils";
+import { SavedMessage } from "../../../data/entities/SavedMessage";
+import { LogType } from "../../../data/LogType";
+import { getBaseUrl } from "../../../pluginUtils";
 
-export async function onMessageDeleteBulk(pluginData: PluginData<LogsPluginType>, savedMessages: SavedMessage[]) {
+export async function onMessageDeleteBulk(pluginData: GuildPluginData<LogsPluginType>, savedMessages: SavedMessage[]) {
   const channel = pluginData.guild.channels.get(savedMessages[0].channel_id);
   const archiveId = await pluginData.state.archives.createFromSavedMessages(savedMessages, pluginData.guild);
   const archiveUrl = pluginData.state.archives.getUrl(getBaseUrl(pluginData), archiveId);
diff --git a/backend/src/plugins/Logs/util/onMessageUpdate.ts b/backend/src/plugins/Logs/util/onMessageUpdate.ts
index bd5bc849..91eb7abb 100644
--- a/backend/src/plugins/Logs/util/onMessageUpdate.ts
+++ b/backend/src/plugins/Logs/util/onMessageUpdate.ts
@@ -1,13 +1,13 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { LogsPluginType } from "../types";
-import { SavedMessage } from "src/data/entities/SavedMessage";
+import { SavedMessage } from "../../../data/entities/SavedMessage";
 import { Embed } from "eris";
-import { LogType } from "src/data/LogType";
-import { stripObjectToScalars, resolveUser } from "src/utils";
+import { LogType } from "../../../data/LogType";
+import { stripObjectToScalars, resolveUser } from "../../../utils";
 import cloneDeep from "lodash.clonedeep";
 
 export async function onMessageUpdate(
-  pluginData: PluginData<LogsPluginType>,
+  pluginData: GuildPluginData<LogsPluginType>,
   savedMessage: SavedMessage,
   oldSavedMessage: SavedMessage,
 ) {
diff --git a/backend/src/plugins/MessageSaver/MessageSaverPlugin.ts b/backend/src/plugins/MessageSaver/MessageSaverPlugin.ts
index c06fa2e7..dbf60cb2 100644
--- a/backend/src/plugins/MessageSaver/MessageSaverPlugin.ts
+++ b/backend/src/plugins/MessageSaver/MessageSaverPlugin.ts
@@ -1,4 +1,4 @@
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
+import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
 import { ConfigSchema, MessageSaverPluginType } from "./types";
 import { GuildSavedMessages } from "../../data/GuildSavedMessages";
 import { PluginOptions } from "knub";
@@ -20,7 +20,7 @@ const defaultOptions: PluginOptions<MessageSaverPluginType> = {
   ],
 };
 
-export const MessageSaverPlugin = zeppelinPlugin<MessageSaverPluginType>()("message_saver", {
+export const MessageSaverPlugin = zeppelinGuildPlugin<MessageSaverPluginType>()("message_saver", {
   showInDocs: false,
 
   configSchema: ConfigSchema,
diff --git a/backend/src/plugins/MessageSaver/commands/SaveMessagesToDB.ts b/backend/src/plugins/MessageSaver/commands/SaveMessagesToDB.ts
index 3bddb273..114da844 100644
--- a/backend/src/plugins/MessageSaver/commands/SaveMessagesToDB.ts
+++ b/backend/src/plugins/MessageSaver/commands/SaveMessagesToDB.ts
@@ -1,7 +1,7 @@
 import { messageSaverCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { saveMessagesToDB } from "../saveMessagesToDB";
-import { sendSuccessMessage } from "src/pluginUtils";
+import { sendSuccessMessage } from "../../../pluginUtils";
 
 export const SaveMessagesToDBCmd = messageSaverCmd({
   trigger: "save_messages_to_db",
diff --git a/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts b/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts
index ee462244..2ecbf8e0 100644
--- a/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts
+++ b/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts
@@ -1,7 +1,7 @@
 import { messageSaverCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { saveMessagesToDB } from "../saveMessagesToDB";
-import { sendSuccessMessage } from "src/pluginUtils";
+import { sendSuccessMessage } from "../../../pluginUtils";
 
 export const SavePinsToDBCmd = messageSaverCmd({
   trigger: "save_pins_to_db",
diff --git a/backend/src/plugins/MessageSaver/saveMessagesToDB.ts b/backend/src/plugins/MessageSaver/saveMessagesToDB.ts
index 20920225..61a84dae 100644
--- a/backend/src/plugins/MessageSaver/saveMessagesToDB.ts
+++ b/backend/src/plugins/MessageSaver/saveMessagesToDB.ts
@@ -1,9 +1,9 @@
 import { MessageSaverPluginType } from "./types";
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { Message, TextChannel } from "eris";
 
 export async function saveMessagesToDB(
-  pluginData: PluginData<MessageSaverPluginType>,
+  pluginData: GuildPluginData<MessageSaverPluginType>,
   channel: TextChannel,
   ids: string[],
 ) {
diff --git a/backend/src/plugins/MessageSaver/types.ts b/backend/src/plugins/MessageSaver/types.ts
index 1eb6909a..9701c743 100644
--- a/backend/src/plugins/MessageSaver/types.ts
+++ b/backend/src/plugins/MessageSaver/types.ts
@@ -1,5 +1,5 @@
 import * as t from "io-ts";
-import { BasePluginType, command, eventListener } from "knub";
+import { BasePluginType, guildCommand, guildEventListener } from "knub";
 import { GuildSavedMessages } from "../../data/GuildSavedMessages";
 
 export const ConfigSchema = t.type({
@@ -14,5 +14,5 @@ export interface MessageSaverPluginType extends BasePluginType {
   };
 }
 
-export const messageSaverCmd = command<MessageSaverPluginType>();
-export const messageSaverEvt = eventListener<MessageSaverPluginType>();
+export const messageSaverCmd = guildCommand<MessageSaverPluginType>();
+export const messageSaverEvt = guildEventListener<MessageSaverPluginType>();
diff --git a/backend/src/plugins/ModActions/ModActionsPlugin.ts b/backend/src/plugins/ModActions/ModActionsPlugin.ts
index 1714d7b1..a43a7d1a 100644
--- a/backend/src/plugins/ModActions/ModActionsPlugin.ts
+++ b/backend/src/plugins/ModActions/ModActionsPlugin.ts
@@ -1,4 +1,4 @@
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
+import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
 import { CasesPlugin } from "../Cases/CasesPlugin";
 import { MutesPlugin } from "../Mutes/MutesPlugin";
 import { BanOptions, ConfigSchema, KickOptions, ModActionsPluginType, WarnOptions } from "./types";
@@ -24,9 +24,9 @@ import { CasesUserCmd } from "./commands/CasesUserCmd";
 import { CasesModCmd } from "./commands/CasesModCmd";
 import { HideCaseCmd } from "./commands/HideCaseCmd";
 import { UnhideCaseCmd } from "./commands/UnhideCaseCmd";
-import { GuildMutes } from "src/data/GuildMutes";
-import { GuildCases } from "src/data/GuildCases";
-import { GuildLogs } from "src/data/GuildLogs";
+import { GuildMutes } from "../../data/GuildMutes";
+import { GuildCases } from "../../data/GuildCases";
+import { GuildLogs } from "../../data/GuildLogs";
 import { ForceUnmuteCmd } from "./commands/ForceunmuteCmd";
 import { warnMember } from "./functions/warnMember";
 import { Member } from "eris";
@@ -95,7 +95,7 @@ const defaultOptions = {
   ],
 };
 
-export const ModActionsPlugin = zeppelinPlugin<ModActionsPluginType>()("mod_actions", {
+export const ModActionsPlugin = zeppelinGuildPlugin<ModActionsPluginType>()("mod_actions", {
   showInDocs: true,
   info: {
     prettyName: "Mod actions",
diff --git a/backend/src/plugins/ModActions/commands/AddCaseCmd.ts b/backend/src/plugins/ModActions/commands/AddCaseCmd.ts
index a5bdb40c..42125e3d 100644
--- a/backend/src/plugins/ModActions/commands/AddCaseCmd.ts
+++ b/backend/src/plugins/ModActions/commands/AddCaseCmd.ts
@@ -1,18 +1,18 @@
-import { modActionsCommand } from "../types";
+import { modActionsCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { canActOn, sendErrorMessage, hasPermission, sendSuccessMessage } from "../../../pluginUtils";
 import { resolveUser, resolveMember, stripObjectToScalars } from "../../../utils";
 import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments";
-import { CaseTypes } from "src/data/CaseTypes";
-import { CasesPlugin } from "src/plugins/Cases/CasesPlugin";
-import { Case } from "src/data/entities/Case";
-import { LogType } from "src/data/LogType";
+import { CaseTypes } from "../../../data/CaseTypes";
+import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin";
+import { Case } from "../../../data/entities/Case";
+import { LogType } from "../../../data/LogType";
 
 const opts = {
   mod: ct.member({ option: true }),
 };
 
-export const AddCaseCmd = modActionsCommand({
+export const AddCaseCmd = modActionsCmd({
   trigger: "addcase",
   permission: "can_addcase",
   description: "Add an arbitrary case to the specified user without taking any action",
diff --git a/backend/src/plugins/ModActions/commands/BanCmd.ts b/backend/src/plugins/ModActions/commands/BanCmd.ts
index 2ca34696..18ec3078 100644
--- a/backend/src/plugins/ModActions/commands/BanCmd.ts
+++ b/backend/src/plugins/ModActions/commands/BanCmd.ts
@@ -1,4 +1,4 @@
-import { modActionsCommand, IgnoredEventType } from "../types";
+import { modActionsCmd, IgnoredEventType } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { canActOn, sendErrorMessage, hasPermission, sendSuccessMessage } from "../../../pluginUtils";
 import { resolveUser, resolveMember } from "../../../utils";
@@ -7,7 +7,7 @@ import { readContactMethodsFromArgs } from "../functions/readContactMethodsFromA
 import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments";
 import { banUserId } from "../functions/banUserId";
 import { ignoreEvent } from "../functions/ignoreEvent";
-import { LogType } from "src/data/LogType";
+import { LogType } from "../../../data/LogType";
 
 const opts = {
   mod: ct.member({ option: true }),
@@ -16,7 +16,7 @@ const opts = {
   "delete-days": ct.number({ option: true, shortcut: "d" }),
 };
 
-export const BanCmd = modActionsCommand({
+export const BanCmd = modActionsCmd({
   trigger: "ban",
   permission: "can_ban",
   description: "Ban the specified member",
diff --git a/backend/src/plugins/ModActions/commands/CaseCmd.ts b/backend/src/plugins/ModActions/commands/CaseCmd.ts
index 36d6a86b..ff5932c5 100644
--- a/backend/src/plugins/ModActions/commands/CaseCmd.ts
+++ b/backend/src/plugins/ModActions/commands/CaseCmd.ts
@@ -1,9 +1,9 @@
-import { modActionsCommand } from "../types";
+import { modActionsCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { sendErrorMessage } from "../../../pluginUtils";
-import { CasesPlugin } from "src/plugins/Cases/CasesPlugin";
+import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin";
 
-export const CaseCmd = modActionsCommand({
+export const CaseCmd = modActionsCmd({
   trigger: "case",
   permission: "can_view",
   description: "Show information about a specific case",
diff --git a/backend/src/plugins/ModActions/commands/CasesModCmd.ts b/backend/src/plugins/ModActions/commands/CasesModCmd.ts
index f518d92a..81509109 100644
--- a/backend/src/plugins/ModActions/commands/CasesModCmd.ts
+++ b/backend/src/plugins/ModActions/commands/CasesModCmd.ts
@@ -1,7 +1,7 @@
-import { modActionsCommand } from "../types";
+import { modActionsCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { sendErrorMessage } from "../../../pluginUtils";
-import { trimLines, createChunkedMessage, emptyEmbedValue, sorter } from "src/utils";
+import { trimLines, createChunkedMessage, emptyEmbedValue, sorter } from "../../../utils";
 import { CasesPlugin } from "../../Cases/CasesPlugin";
 import { asyncMap } from "../../../utils/async";
 import { EmbedOptions } from "eris";
@@ -13,7 +13,7 @@ const opts = {
   mod: ct.member({ option: true }),
 };
 
-export const CasesModCmd = modActionsCommand({
+export const CasesModCmd = modActionsCmd({
   trigger: "cases",
   permission: "can_view",
   description: "Show the most recent 5 cases by the specified -mod",
diff --git a/backend/src/plugins/ModActions/commands/CasesUserCmd.ts b/backend/src/plugins/ModActions/commands/CasesUserCmd.ts
index 366ae28e..9b75316d 100644
--- a/backend/src/plugins/ModActions/commands/CasesUserCmd.ts
+++ b/backend/src/plugins/ModActions/commands/CasesUserCmd.ts
@@ -1,7 +1,7 @@
-import { modActionsCommand } from "../types";
+import { modActionsCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { sendErrorMessage } from "../../../pluginUtils";
-import { CasesPlugin } from "src/plugins/Cases/CasesPlugin";
+import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin";
 import {
   UnknownUser,
   multiSorter,
@@ -10,7 +10,7 @@ import {
   resolveUser,
   emptyEmbedValue,
   chunkArray,
-} from "src/utils";
+} from "../../../utils";
 import { getGuildPrefix } from "../../../utils/getGuildPrefix";
 import { EmbedOptions, User } from "eris";
 import { getChunkedEmbedFields } from "../../../utils/getChunkedEmbedFields";
@@ -21,7 +21,7 @@ const opts = {
   hidden: ct.bool({ option: true, isSwitch: true, shortcut: "h" }),
 };
 
-export const CasesUserCmd = modActionsCommand({
+export const CasesUserCmd = modActionsCmd({
   trigger: "cases",
   permission: "can_view",
   description: "Show a list of cases the specified user has",
diff --git a/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts b/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts
index ce02c85a..c8bdbd6d 100644
--- a/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts
+++ b/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts
@@ -1,4 +1,4 @@
-import { modActionsCommand } from "../types";
+import { modActionsCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
 import { helpers } from "knub";
@@ -10,7 +10,7 @@ import { LogType } from "../../../data/LogType";
 import moment from "moment-timezone";
 import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin";
 
-export const DeleteCaseCmd = modActionsCommand({
+export const DeleteCaseCmd = modActionsCmd({
   trigger: ["delete_case", "deletecase"],
   permission: "can_deletecase",
   description: trimLines(`
diff --git a/backend/src/plugins/ModActions/commands/ForcebanCmd.ts b/backend/src/plugins/ModActions/commands/ForcebanCmd.ts
index 72dd908b..2d9c2c50 100644
--- a/backend/src/plugins/ModActions/commands/ForcebanCmd.ts
+++ b/backend/src/plugins/ModActions/commands/ForcebanCmd.ts
@@ -1,4 +1,4 @@
-import { modActionsCommand, IgnoredEventType } from "../types";
+import { modActionsCmd, IgnoredEventType } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { canActOn, sendErrorMessage, hasPermission, sendSuccessMessage } from "../../../pluginUtils";
 import { resolveUser, resolveMember, stripObjectToScalars } from "../../../utils";
@@ -7,15 +7,15 @@ import { readContactMethodsFromArgs } from "../functions/readContactMethodsFromA
 import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments";
 import { banUserId } from "../functions/banUserId";
 import { ignoreEvent } from "../functions/ignoreEvent";
-import { LogType } from "src/data/LogType";
-import { CaseTypes } from "src/data/CaseTypes";
-import { CasesPlugin } from "src/plugins/Cases/CasesPlugin";
+import { LogType } from "../../../data/LogType";
+import { CaseTypes } from "../../../data/CaseTypes";
+import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin";
 
 const opts = {
   mod: ct.member({ option: true }),
 };
 
-export const ForcebanCmd = modActionsCommand({
+export const ForcebanCmd = modActionsCmd({
   trigger: "forceban",
   permission: "can_ban",
   description: "Force-ban the specified user, even if they aren't on the server",
diff --git a/backend/src/plugins/ModActions/commands/ForcemuteCmd.ts b/backend/src/plugins/ModActions/commands/ForcemuteCmd.ts
index f61ae5a8..fbf8dc8a 100644
--- a/backend/src/plugins/ModActions/commands/ForcemuteCmd.ts
+++ b/backend/src/plugins/ModActions/commands/ForcemuteCmd.ts
@@ -1,4 +1,4 @@
-import { modActionsCommand } from "../types";
+import { modActionsCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { canActOn, sendErrorMessage } from "../../../pluginUtils";
 import { resolveMember, resolveUser } from "../../../utils";
@@ -10,7 +10,7 @@ const opts = {
   "notify-channel": ct.textChannel({ option: true }),
 };
 
-export const ForcemuteCmd = modActionsCommand({
+export const ForcemuteCmd = modActionsCmd({
   trigger: "forcemute",
   permission: "can_mute",
   description: "Force-mute the specified user, even if they're not on the server",
diff --git a/backend/src/plugins/ModActions/commands/ForceunmuteCmd.ts b/backend/src/plugins/ModActions/commands/ForceunmuteCmd.ts
index 92a3d70d..025a7bfa 100644
--- a/backend/src/plugins/ModActions/commands/ForceunmuteCmd.ts
+++ b/backend/src/plugins/ModActions/commands/ForceunmuteCmd.ts
@@ -1,4 +1,4 @@
-import { modActionsCommand } from "../types";
+import { modActionsCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { canActOn, sendErrorMessage } from "../../../pluginUtils";
 import { resolveUser, resolveMember } from "../../../utils";
@@ -8,7 +8,7 @@ const opts = {
   mod: ct.member({ option: true }),
 };
 
-export const ForceUnmuteCmd = modActionsCommand({
+export const ForceUnmuteCmd = modActionsCmd({
   trigger: "forceunmute",
   permission: "can_mute",
   description: "Force-unmute the specified user, even if they're not on the server",
diff --git a/backend/src/plugins/ModActions/commands/HideCaseCmd.ts b/backend/src/plugins/ModActions/commands/HideCaseCmd.ts
index 095713f2..b86a42c2 100644
--- a/backend/src/plugins/ModActions/commands/HideCaseCmd.ts
+++ b/backend/src/plugins/ModActions/commands/HideCaseCmd.ts
@@ -1,8 +1,8 @@
-import { modActionsCommand } from "../types";
+import { modActionsCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
 
-export const HideCaseCmd = modActionsCommand({
+export const HideCaseCmd = modActionsCmd({
   trigger: ["hide", "hidecase", "hide_case"],
   permission: "can_hidecase",
   description: "Hide the specified case so it doesn't appear in !cases or !info",
diff --git a/backend/src/plugins/ModActions/commands/KickCmd.ts b/backend/src/plugins/ModActions/commands/KickCmd.ts
index 321277cc..d93e0369 100644
--- a/backend/src/plugins/ModActions/commands/KickCmd.ts
+++ b/backend/src/plugins/ModActions/commands/KickCmd.ts
@@ -1,11 +1,10 @@
-import { modActionsCommand } from "../types";
+import { modActionsCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { canActOn, sendErrorMessage } from "../../../pluginUtils";
 import { resolveUser, resolveMember } from "../../../utils";
-import { MutesPlugin } from "src/plugins/Mutes/MutesPlugin";
+import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin";
 import { actualUnmuteCmd } from "../functions/actualUnmuteUserCmd";
 import { isBanned } from "../functions/isBanned";
-import { plugin } from "knub";
 import { actualKickMemberCmd } from "../functions/actualKickMemberCmd";
 
 const opts = {
@@ -15,7 +14,7 @@ const opts = {
   clean: ct.bool({ option: true, isSwitch: true }),
 };
 
-export const KickCmd = modActionsCommand({
+export const KickCmd = modActionsCmd({
   trigger: "kick",
   permission: "can_kick",
   description: "Kick the specified member",
diff --git a/backend/src/plugins/ModActions/commands/MassBanCmd.ts b/backend/src/plugins/ModActions/commands/MassBanCmd.ts
index 9f5063c1..c3ed7732 100644
--- a/backend/src/plugins/ModActions/commands/MassBanCmd.ts
+++ b/backend/src/plugins/ModActions/commands/MassBanCmd.ts
@@ -1,4 +1,4 @@
-import { modActionsCommand, IgnoredEventType } from "../types";
+import { modActionsCmd, IgnoredEventType } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { canActOn, sendErrorMessage, hasPermission, sendSuccessMessage } from "../../../pluginUtils";
 import { resolveUser, resolveMember, stripObjectToScalars } from "../../../utils";
@@ -6,14 +6,14 @@ import { isBanned } from "../functions/isBanned";
 import { readContactMethodsFromArgs } from "../functions/readContactMethodsFromArgs";
 import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments";
 import { banUserId } from "../functions/banUserId";
-import { CaseTypes } from "src/data/CaseTypes";
+import { CaseTypes } from "../../../data/CaseTypes";
 import { TextChannel } from "eris";
 import { waitForReply } from "knub/dist/helpers";
 import { ignoreEvent } from "../functions/ignoreEvent";
-import { CasesPlugin } from "src/plugins/Cases/CasesPlugin";
-import { LogType } from "src/data/LogType";
+import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin";
+import { LogType } from "../../../data/LogType";
 
-export const MassbanCmd = modActionsCommand({
+export const MassbanCmd = modActionsCmd({
   trigger: "massban",
   permission: "can_massban",
   description: "Mass-ban a list of user IDs",
diff --git a/backend/src/plugins/ModActions/commands/MassmuteCmd.ts b/backend/src/plugins/ModActions/commands/MassmuteCmd.ts
index 5b446c03..1a129ad1 100644
--- a/backend/src/plugins/ModActions/commands/MassmuteCmd.ts
+++ b/backend/src/plugins/ModActions/commands/MassmuteCmd.ts
@@ -1,15 +1,15 @@
-import { modActionsCommand } from "../types";
+import { modActionsCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
 import { stripObjectToScalars } from "../../../utils";
 import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments";
 import { TextChannel } from "eris";
 import { waitForReply } from "knub/dist/helpers";
-import { LogType } from "src/data/LogType";
-import { logger } from "src/logger";
-import { MutesPlugin } from "src/plugins/Mutes/MutesPlugin";
+import { LogType } from "../../../data/LogType";
+import { logger } from "../../../logger";
+import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin";
 
-export const MassmuteCmd = modActionsCommand({
+export const MassmuteCmd = modActionsCmd({
   trigger: "massmute",
   permission: "can_massmute",
   description: "Mass-mute a list of user IDs",
diff --git a/backend/src/plugins/ModActions/commands/MuteCmd.ts b/backend/src/plugins/ModActions/commands/MuteCmd.ts
index e97ad983..721a1338 100644
--- a/backend/src/plugins/ModActions/commands/MuteCmd.ts
+++ b/backend/src/plugins/ModActions/commands/MuteCmd.ts
@@ -1,4 +1,4 @@
-import { modActionsCommand } from "../types";
+import { modActionsCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { Case } from "../../../data/entities/Case";
 import { canActOn, hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
@@ -20,7 +20,7 @@ const opts = {
   "notify-channel": ct.textChannel({ option: true }),
 };
 
-export const MuteCmd = modActionsCommand({
+export const MuteCmd = modActionsCmd({
   trigger: "mute",
   permission: "can_mute",
   description: "Mute the specified member",
@@ -49,7 +49,7 @@ export const MuteCmd = modActionsCommand({
 
     if (!memberToMute) {
       const _isBanned = await isBanned(pluginData, user.id);
-      const prefix = pluginData.guildConfig.prefix;
+      const prefix = pluginData.fullConfig.prefix;
       if (_isBanned) {
         sendErrorMessage(
           pluginData,
diff --git a/backend/src/plugins/ModActions/commands/NoteCmd.ts b/backend/src/plugins/ModActions/commands/NoteCmd.ts
index e7ad485d..8e95552d 100644
--- a/backend/src/plugins/ModActions/commands/NoteCmd.ts
+++ b/backend/src/plugins/ModActions/commands/NoteCmd.ts
@@ -1,4 +1,4 @@
-import { modActionsCommand } from "../types";
+import { modActionsCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { Case } from "../../../data/entities/Case";
 import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
@@ -8,7 +8,7 @@ import { LogType } from "../../../data/LogType";
 import { CaseTypes } from "../../../data/CaseTypes";
 import { resolveUser, stripObjectToScalars } from "../../../utils";
 
-export const NoteCmd = modActionsCommand({
+export const NoteCmd = modActionsCmd({
   trigger: "note",
   permission: "can_note",
   description: "Add a note to the specified user",
diff --git a/backend/src/plugins/ModActions/commands/SoftbanCommand.ts b/backend/src/plugins/ModActions/commands/SoftbanCommand.ts
index 3e7910b0..8105aae3 100644
--- a/backend/src/plugins/ModActions/commands/SoftbanCommand.ts
+++ b/backend/src/plugins/ModActions/commands/SoftbanCommand.ts
@@ -1,4 +1,4 @@
-import { modActionsCommand } from "../types";
+import { modActionsCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { trimPluginDescription } from "../../../utils";
 import { actualKickMemberCmd } from "../functions/actualKickMemberCmd";
@@ -9,7 +9,7 @@ const opts = {
   "notify-channel": ct.textChannel({ option: true }),
 };
 
-export const SoftbanCmd = modActionsCommand({
+export const SoftbanCmd = modActionsCmd({
   trigger: "softban",
   permission: "can_kick",
   description: trimPluginDescription(`
diff --git a/backend/src/plugins/ModActions/commands/UnbanCmd.ts b/backend/src/plugins/ModActions/commands/UnbanCmd.ts
index 46db49c7..92ba46a3 100644
--- a/backend/src/plugins/ModActions/commands/UnbanCmd.ts
+++ b/backend/src/plugins/ModActions/commands/UnbanCmd.ts
@@ -1,18 +1,18 @@
-import { modActionsCommand, IgnoredEventType } from "../types";
+import { modActionsCmd, IgnoredEventType } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { sendErrorMessage, hasPermission, sendSuccessMessage } from "../../../pluginUtils";
 import { resolveUser, stripObjectToScalars } from "../../../utils";
 import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments";
-import { LogType } from "src/data/LogType";
+import { LogType } from "../../../data/LogType";
 import { ignoreEvent } from "../functions/ignoreEvent";
-import { CaseTypes } from "src/data/CaseTypes";
-import { CasesPlugin } from "src/plugins/Cases/CasesPlugin";
+import { CaseTypes } from "../../../data/CaseTypes";
+import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin";
 
 const opts = {
   mod: ct.member({ option: true }),
 };
 
-export const UnbanCmd = modActionsCommand({
+export const UnbanCmd = modActionsCmd({
   trigger: "unban",
   permission: "can_ban",
   description: "Unban the specified member",
diff --git a/backend/src/plugins/ModActions/commands/UnhideCaseCmd.ts b/backend/src/plugins/ModActions/commands/UnhideCaseCmd.ts
index adb70b68..60e756b8 100644
--- a/backend/src/plugins/ModActions/commands/UnhideCaseCmd.ts
+++ b/backend/src/plugins/ModActions/commands/UnhideCaseCmd.ts
@@ -1,8 +1,8 @@
-import { modActionsCommand } from "../types";
+import { modActionsCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
 
-export const UnhideCaseCmd = modActionsCommand({
+export const UnhideCaseCmd = modActionsCmd({
   trigger: ["unhide", "unhidecase", "unhide_case"],
   permission: "can_hidecase",
   description: "Un-hide the specified case, making it appear in !cases and !info again",
diff --git a/backend/src/plugins/ModActions/commands/UnmuteCmd.ts b/backend/src/plugins/ModActions/commands/UnmuteCmd.ts
index 716ce3f1..aa128eb9 100644
--- a/backend/src/plugins/ModActions/commands/UnmuteCmd.ts
+++ b/backend/src/plugins/ModActions/commands/UnmuteCmd.ts
@@ -1,17 +1,16 @@
-import { modActionsCommand } from "../types";
+import { modActionsCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { canActOn, sendErrorMessage } from "../../../pluginUtils";
 import { resolveUser, resolveMember } from "../../../utils";
-import { MutesPlugin } from "src/plugins/Mutes/MutesPlugin";
+import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin";
 import { actualUnmuteCmd } from "../functions/actualUnmuteUserCmd";
 import { isBanned } from "../functions/isBanned";
-import { plugin } from "knub";
 
 const opts = {
   mod: ct.member({ option: true }),
 };
 
-export const UnmuteCmd = modActionsCommand({
+export const UnmuteCmd = modActionsCmd({
   trigger: "unmute",
   permission: "can_mute",
   description: "Unmute the specified member",
@@ -48,7 +47,7 @@ export const UnmuteCmd = modActionsCommand({
 
     if (!memberToUnmute) {
       const banned = await isBanned(pluginData, user.id);
-      const prefix = pluginData.guildConfig.prefix;
+      const prefix = pluginData.fullConfig.prefix;
       if (banned) {
         sendErrorMessage(
           pluginData,
diff --git a/backend/src/plugins/ModActions/commands/UpdateCmd.ts b/backend/src/plugins/ModActions/commands/UpdateCmd.ts
index 0b4f64f4..8bb9bbfc 100644
--- a/backend/src/plugins/ModActions/commands/UpdateCmd.ts
+++ b/backend/src/plugins/ModActions/commands/UpdateCmd.ts
@@ -1,4 +1,4 @@
-import { modActionsCommand } from "../types";
+import { modActionsCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { Case } from "../../../data/entities/Case";
 import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
@@ -7,7 +7,7 @@ import { CasesPlugin } from "../../Cases/CasesPlugin";
 import { LogType } from "../../../data/LogType";
 import { CaseTypes } from "../../../data/CaseTypes";
 
-export const UpdateCmd = modActionsCommand({
+export const UpdateCmd = modActionsCmd({
   trigger: "update",
   permission: "can_note",
   description:
diff --git a/backend/src/plugins/ModActions/commands/WarnCmd.ts b/backend/src/plugins/ModActions/commands/WarnCmd.ts
index 19dc2fbf..401aa211 100644
--- a/backend/src/plugins/ModActions/commands/WarnCmd.ts
+++ b/backend/src/plugins/ModActions/commands/WarnCmd.ts
@@ -1,4 +1,4 @@
-import { modActionsCommand } from "../types";
+import { modActionsCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { Case } from "../../../data/entities/Case";
 import { canActOn, hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
@@ -13,7 +13,7 @@ import { readContactMethodsFromArgs } from "../functions/readContactMethodsFromA
 import { warnMember } from "../functions/warnMember";
 import { TextChannel } from "eris";
 
-export const WarnCmd = modActionsCommand({
+export const WarnCmd = modActionsCmd({
   trigger: "warn",
   permission: "can_warn",
   description: "Send a warning to the specified user",
diff --git a/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts b/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts
index 251420c2..e9324508 100644
--- a/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts
+++ b/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts
@@ -1,19 +1,18 @@
-import { eventListener } from "knub";
-import { IgnoredEventType, ModActionsPluginType } from "../types";
+import { IgnoredEventType, modActionsEvt } from "../types";
 import { isEventIgnored } from "../functions/isEventIgnored";
 import { clearIgnoredEvents } from "../functions/clearIgnoredEvents";
 import { Constants as ErisConstants } from "eris";
 import { CasesPlugin } from "../../Cases/CasesPlugin";
 import { CaseTypes } from "../../../data/CaseTypes";
 import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAuditLogEntry";
-import { LogType } from "src/data/LogType";
-import { stripObjectToScalars, resolveUser } from "src/utils";
+import { LogType } from "../../../data/LogType";
+import { stripObjectToScalars, resolveUser } from "../../../utils";
 
 /**
  * Create a BAN case automatically when a user is banned manually.
  * Attempts to find the ban's details in the audit log.
  */
-export const CreateBanCaseOnManualBanEvt = eventListener<ModActionsPluginType>()(
+export const CreateBanCaseOnManualBanEvt = modActionsEvt(
   "guildBanAdd",
   async ({ pluginData, args: { guild, user } }) => {
     if (isEventIgnored(pluginData, IgnoredEventType.Ban, user.id)) {
diff --git a/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts b/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts
index 486e59ef..610767ca 100644
--- a/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts
+++ b/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts
@@ -1,5 +1,4 @@
-import { eventListener } from "knub";
-import { IgnoredEventType, ModActionsPluginType } from "../types";
+import { IgnoredEventType, modActionsEvt } from "../types";
 import { isEventIgnored } from "../functions/isEventIgnored";
 import { clearIgnoredEvents } from "../functions/clearIgnoredEvents";
 import { Constants as ErisConstants } from "eris";
@@ -14,7 +13,7 @@ import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAu
  * Create a KICK case automatically when a user is kicked manually.
  * Attempts to find the kick's details in the audit log.
  */
-export const CreateKickCaseOnManualKickEvt = eventListener<ModActionsPluginType>()(
+export const CreateKickCaseOnManualKickEvt = modActionsEvt(
   "guildMemberRemove",
   async ({ pluginData, args: { member } }) => {
     if (isEventIgnored(pluginData, IgnoredEventType.Kick, member.id)) {
diff --git a/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts b/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts
index ffa1e9e5..0d368615 100644
--- a/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts
+++ b/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts
@@ -1,19 +1,18 @@
-import { eventListener } from "knub";
-import { IgnoredEventType, ModActionsPluginType } from "../types";
+import { IgnoredEventType, modActionsEvt } from "../types";
 import { isEventIgnored } from "../functions/isEventIgnored";
 import { clearIgnoredEvents } from "../functions/clearIgnoredEvents";
 import { Constants as ErisConstants } from "eris";
 import { CasesPlugin } from "../../Cases/CasesPlugin";
 import { CaseTypes } from "../../../data/CaseTypes";
 import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAuditLogEntry";
-import { stripObjectToScalars, resolveUser } from "src/utils";
-import { LogType } from "src/data/LogType";
+import { stripObjectToScalars, resolveUser } from "../../../utils";
+import { LogType } from "../../../data/LogType";
 
 /**
  * Create an UNBAN case automatically when a user is unbanned manually.
  * Attempts to find the unban's details in the audit log.
  */
-export const CreateUnbanCaseOnManualUnbanEvt = eventListener<ModActionsPluginType>()(
+export const CreateUnbanCaseOnManualUnbanEvt = modActionsEvt(
   "guildBanRemove",
   async ({ pluginData, args: { guild, user } }) => {
     if (isEventIgnored(pluginData, IgnoredEventType.Unban, user.id)) {
diff --git a/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts b/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts
index 8d66902b..55753118 100644
--- a/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts
+++ b/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts
@@ -1,5 +1,4 @@
-import { eventListener } from "knub";
-import { ModActionsPluginType } from "../types";
+import { modActionsEvt } from "../types";
 import { LogsPlugin } from "../../Logs/LogsPlugin";
 import { LogType } from "../../../data/LogType";
 import { TextChannel } from "eris";
@@ -7,7 +6,7 @@ import { TextChannel } from "eris";
 /**
  * Show an alert if a member with prior notes joins the server
  */
-export const PostAlertOnMemberJoinEvt = eventListener<ModActionsPluginType>()(
+export const PostAlertOnMemberJoinEvt = modActionsEvt(
   "guildMemberAdd",
   async ({ pluginData, args: { guild, member } }) => {
     const config = pluginData.config.get();
diff --git a/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts b/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts
index 147a3145..6cb792a0 100644
--- a/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts
+++ b/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts
@@ -1,9 +1,9 @@
 import { Member, TextChannel } from "eris";
-import { LogType } from "src/data/LogType";
+import { LogType } from "../../../data/LogType";
 import { IgnoredEventType, ModActionsPluginType } from "../types";
-import { errorMessage, resolveUser, resolveMember } from "src/utils";
-import { PluginData } from "knub";
-import { sendErrorMessage, canActOn, sendSuccessMessage } from "src/pluginUtils";
+import { errorMessage, resolveUser, resolveMember } from "../../../utils";
+import { GuildPluginData } from "knub";
+import { sendErrorMessage, canActOn, sendSuccessMessage } from "../../../pluginUtils";
 import { hasPermission } from "knub/dist/helpers";
 import { readContactMethodsFromArgs } from "./readContactMethodsFromArgs";
 import { formatReasonWithAttachments } from "./formatReasonWithAttachments";
@@ -12,7 +12,7 @@ import { ignoreEvent } from "./ignoreEvent";
 import { isBanned } from "./isBanned";
 
 export async function actualKickMemberCmd(
-  pluginData: PluginData<ModActionsPluginType>,
+  pluginData: GuildPluginData<ModActionsPluginType>,
   msg,
   args: {
     user: string;
diff --git a/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts b/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts
index c56786ed..afd83af3 100644
--- a/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts
+++ b/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts
@@ -1,7 +1,7 @@
 import { Member, Message, TextChannel, User } from "eris";
 import { asSingleLine, isDiscordRESTError, UnknownUser } from "../../../utils";
 import { hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { ModActionsPluginType } from "../types";
 import humanizeDuration from "humanize-duration";
 import { formatReasonWithAttachments } from "./formatReasonWithAttachments";
@@ -16,7 +16,7 @@ import { logger } from "../../../logger";
  * The only difference between the two commands is in target member validation.
  */
 export async function actualMuteUserCmd(
-  pluginData: PluginData<ModActionsPluginType>,
+  pluginData: GuildPluginData<ModActionsPluginType>,
   user: User | UnknownUser,
   msg: Message,
   args: { time?: number; reason?: string; mod: Member; notify?: string; "notify-channel"?: TextChannel },
diff --git a/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts b/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts
index 85402438..e7b89049 100644
--- a/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts
+++ b/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts
@@ -1,14 +1,14 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { ModActionsPluginType } from "../types";
 import { User, Message, Member } from "eris";
-import { UnknownUser, asSingleLine } from "src/utils";
-import { sendErrorMessage, sendSuccessMessage, hasPermission } from "src/pluginUtils";
+import { UnknownUser, asSingleLine } from "../../../utils";
+import { sendErrorMessage, sendSuccessMessage, hasPermission } from "../../../pluginUtils";
 import { formatReasonWithAttachments } from "./formatReasonWithAttachments";
-import { MutesPlugin } from "src/plugins/Mutes/MutesPlugin";
+import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin";
 import humanizeDuration from "humanize-duration";
 
 export async function actualUnmuteCmd(
-  pluginData: PluginData<ModActionsPluginType>,
+  pluginData: GuildPluginData<ModActionsPluginType>,
   user: User | UnknownUser,
   msg: Message,
   args: { time?: number; reason?: string; mod?: Member },
diff --git a/backend/src/plugins/ModActions/functions/banUserId.ts b/backend/src/plugins/ModActions/functions/banUserId.ts
index 5d6d615f..913b8e7e 100644
--- a/backend/src/plugins/ModActions/functions/banUserId.ts
+++ b/backend/src/plugins/ModActions/functions/banUserId.ts
@@ -1,4 +1,4 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { BanOptions, BanResult, IgnoredEventType, ModActionsPluginType } from "../types";
 import { notifyUser, resolveUser, stripObjectToScalars, ucfirst, UserNotificationResult } from "../../../utils";
 import { User } from "eris";
@@ -13,7 +13,7 @@ import { CaseTypes } from "../../../data/CaseTypes";
  * Ban the specified user id, whether or not they're actually on the server at the time. Generates a case.
  */
 export async function banUserId(
-  pluginData: PluginData<ModActionsPluginType>,
+  pluginData: GuildPluginData<ModActionsPluginType>,
   userId: string,
   reason: string = null,
   banOptions: BanOptions = {},
diff --git a/backend/src/plugins/ModActions/functions/clearIgnoredEvents.ts b/backend/src/plugins/ModActions/functions/clearIgnoredEvents.ts
index 765a4c1e..cbcf082f 100644
--- a/backend/src/plugins/ModActions/functions/clearIgnoredEvents.ts
+++ b/backend/src/plugins/ModActions/functions/clearIgnoredEvents.ts
@@ -1,8 +1,8 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { IgnoredEventType, ModActionsPluginType } from "../types";
 
 export function clearIgnoredEvents(
-  pluginData: PluginData<ModActionsPluginType>,
+  pluginData: GuildPluginData<ModActionsPluginType>,
   type: IgnoredEventType,
   userId: string,
 ) {
diff --git a/backend/src/plugins/ModActions/functions/getDefaultContactMethods.ts b/backend/src/plugins/ModActions/functions/getDefaultContactMethods.ts
index 0343e55b..4ebc4d8d 100644
--- a/backend/src/plugins/ModActions/functions/getDefaultContactMethods.ts
+++ b/backend/src/plugins/ModActions/functions/getDefaultContactMethods.ts
@@ -1,10 +1,10 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { ModActionsPluginType } from "../types";
 import { UserNotificationMethod } from "../../../utils";
 import { TextChannel } from "eris";
 
 export function getDefaultContactMethods(
-  pluginData: PluginData<ModActionsPluginType>,
+  pluginData: GuildPluginData<ModActionsPluginType>,
   type: "warn" | "kick" | "ban",
 ): UserNotificationMethod[] {
   const methods: UserNotificationMethod[] = [];
diff --git a/backend/src/plugins/ModActions/functions/ignoreEvent.ts b/backend/src/plugins/ModActions/functions/ignoreEvent.ts
index aef0a30e..6f97e84f 100644
--- a/backend/src/plugins/ModActions/functions/ignoreEvent.ts
+++ b/backend/src/plugins/ModActions/functions/ignoreEvent.ts
@@ -1,4 +1,4 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { IgnoredEventType, ModActionsPluginType } from "../types";
 import { SECONDS } from "../../../utils";
 import { clearIgnoredEvents } from "./clearIgnoredEvents";
@@ -6,7 +6,7 @@ import { clearIgnoredEvents } from "./clearIgnoredEvents";
 const DEFAULT_TIMEOUT = 15 * SECONDS;
 
 export function ignoreEvent(
-  pluginData: PluginData<ModActionsPluginType>,
+  pluginData: GuildPluginData<ModActionsPluginType>,
   type: IgnoredEventType,
   userId: string,
   timeout = DEFAULT_TIMEOUT,
diff --git a/backend/src/plugins/ModActions/functions/isBanned.ts b/backend/src/plugins/ModActions/functions/isBanned.ts
index 4aed74b3..c809a30c 100644
--- a/backend/src/plugins/ModActions/functions/isBanned.ts
+++ b/backend/src/plugins/ModActions/functions/isBanned.ts
@@ -1,8 +1,8 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { ModActionsPluginType } from "../types";
 import { isDiscordHTTPError } from "../../../utils";
 
-export async function isBanned(pluginData: PluginData<ModActionsPluginType>, userId: string): Promise<boolean> {
+export async function isBanned(pluginData: GuildPluginData<ModActionsPluginType>, userId: string): Promise<boolean> {
   try {
     const bans = await pluginData.guild.getBans();
     return bans.some(b => b.user.id === userId);
diff --git a/backend/src/plugins/ModActions/functions/isEventIgnored.ts b/backend/src/plugins/ModActions/functions/isEventIgnored.ts
index 0a28a8b2..32ae4acf 100644
--- a/backend/src/plugins/ModActions/functions/isEventIgnored.ts
+++ b/backend/src/plugins/ModActions/functions/isEventIgnored.ts
@@ -1,6 +1,10 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { IgnoredEventType, ModActionsPluginType } from "../types";
 
-export function isEventIgnored(pluginData: PluginData<ModActionsPluginType>, type: IgnoredEventType, userId: string) {
+export function isEventIgnored(
+  pluginData: GuildPluginData<ModActionsPluginType>,
+  type: IgnoredEventType,
+  userId: string,
+) {
   return pluginData.state.ignoredEvents.some(info => type === info.type && userId === info.userId);
 }
diff --git a/backend/src/plugins/ModActions/functions/kickMember.ts b/backend/src/plugins/ModActions/functions/kickMember.ts
index 44ec7b7d..497b252f 100644
--- a/backend/src/plugins/ModActions/functions/kickMember.ts
+++ b/backend/src/plugins/ModActions/functions/kickMember.ts
@@ -1,4 +1,4 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { IgnoredEventType, KickOptions, KickResult, ModActionsPluginType } from "../types";
 import { Member } from "eris";
 import { notifyUser, resolveUser, stripObjectToScalars, ucfirst, UserNotificationResult } from "../../../utils";
@@ -13,7 +13,7 @@ import { CasesPlugin } from "../../Cases/CasesPlugin";
  * Kick the specified server member. Generates a case.
  */
 export async function kickMember(
-  pluginData: PluginData<ModActionsPluginType>,
+  pluginData: GuildPluginData<ModActionsPluginType>,
   member: Member,
   reason: string = null,
   kickOptions: KickOptions = {},
diff --git a/backend/src/plugins/ModActions/functions/warnMember.ts b/backend/src/plugins/ModActions/functions/warnMember.ts
index 323f05f1..fdaf15c7 100644
--- a/backend/src/plugins/ModActions/functions/warnMember.ts
+++ b/backend/src/plugins/ModActions/functions/warnMember.ts
@@ -1,4 +1,4 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { ModActionsPluginType, WarnOptions, WarnResult } from "../types";
 import { Member } from "eris";
 import { getDefaultContactMethods } from "./getDefaultContactMethods";
@@ -9,7 +9,7 @@ import { CaseTypes } from "../../../data/CaseTypes";
 import { LogType } from "../../../data/LogType";
 
 export async function warnMember(
-  pluginData: PluginData<ModActionsPluginType>,
+  pluginData: GuildPluginData<ModActionsPluginType>,
   member: Member,
   reason: string,
   warnOptions: WarnOptions = {},
diff --git a/backend/src/plugins/ModActions/types.ts b/backend/src/plugins/ModActions/types.ts
index 72c60724..a8cce398 100644
--- a/backend/src/plugins/ModActions/types.ts
+++ b/backend/src/plugins/ModActions/types.ts
@@ -1,6 +1,6 @@
 import * as t from "io-ts";
 import { tNullable, UserNotificationMethod, UserNotificationResult } from "../../utils";
-import { BasePluginType, command } from "knub";
+import { BasePluginType, guildCommand, guildEventListener } from "knub";
 import { GuildMutes } from "../../data/GuildMutes";
 import { GuildCases } from "../../data/GuildCases";
 import { GuildLogs } from "../../data/GuildLogs";
@@ -114,4 +114,5 @@ export interface BanOptions {
   deleteMessageDays?: number;
 }
 
-export const modActionsCommand = command<ModActionsPluginType>();
+export const modActionsCmd = guildCommand<ModActionsPluginType>();
+export const modActionsEvt = guildEventListener<ModActionsPluginType>();
diff --git a/backend/src/plugins/Mutes/MutesPlugin.ts b/backend/src/plugins/Mutes/MutesPlugin.ts
index f8b44416..14b73e61 100644
--- a/backend/src/plugins/Mutes/MutesPlugin.ts
+++ b/backend/src/plugins/Mutes/MutesPlugin.ts
@@ -1,4 +1,4 @@
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
+import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
 import { ConfigSchema, MuteOptions, MutesPluginType } from "./types";
 import { CasesPlugin } from "../Cases/CasesPlugin";
 import { GuildMutes } from "../../data/GuildMutes";
@@ -55,7 +55,7 @@ const EXPIRED_MUTE_CHECK_INTERVAL = 60 * 1000;
 let FIRST_CHECK_TIME = Date.now();
 const FIRST_CHECK_INCREMENT = 5 * 1000;
 
-export const MutesPlugin = zeppelinPlugin<MutesPluginType>()("mutes", {
+export const MutesPlugin = zeppelinGuildPlugin<MutesPluginType>()("mutes", {
   showInDocs: true,
   info: {
     prettyName: "Mutes",
diff --git a/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts b/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts
index f0e6deb4..b59f1165 100644
--- a/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts
+++ b/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts
@@ -1,9 +1,8 @@
-import { command } from "knub";
-import { MutesPluginType } from "../types";
+import { mutesCmd } from "../types";
 import { User } from "eris";
 import { sendSuccessMessage } from "../../../pluginUtils";
 
-export const ClearBannedMutesCmd = command<MutesPluginType>()({
+export const ClearBannedMutesCmd = mutesCmd({
   trigger: "clear_banned_mutes",
   permission: "can_cleanup",
   description: "Clear dangling mutes for members who have been banned",
diff --git a/backend/src/plugins/Mutes/commands/ClearMutesCmd.ts b/backend/src/plugins/Mutes/commands/ClearMutesCmd.ts
index 87fa730d..028266dc 100644
--- a/backend/src/plugins/Mutes/commands/ClearMutesCmd.ts
+++ b/backend/src/plugins/Mutes/commands/ClearMutesCmd.ts
@@ -1,9 +1,8 @@
-import { command } from "knub";
-import { MutesPluginType } from "../types";
+import { mutesCmd } from "../types";
 import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 
-export const ClearMutesCmd = command<MutesPluginType>()({
+export const ClearMutesCmd = mutesCmd({
   trigger: "clear_mutes",
   permission: "can_cleanup",
   description: "Clear dangling mute records from the bot. Be careful not to clear valid mutes.",
diff --git a/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts b/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts
index b463a9ba..f05b16cf 100644
--- a/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts
+++ b/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts
@@ -1,9 +1,8 @@
-import { command } from "knub";
-import { MutesPluginType } from "../types";
+import { mutesCmd } from "../types";
 import { sendSuccessMessage } from "../../../pluginUtils";
 import { resolveMember } from "../../../utils";
 
-export const ClearMutesWithoutRoleCmd = command<MutesPluginType>()({
+export const ClearMutesWithoutRoleCmd = mutesCmd({
   trigger: "clear_mutes_without_role",
   permission: "can_cleanup",
   description: "Clear dangling mutes for members whose mute role was removed by other means",
diff --git a/backend/src/plugins/Mutes/commands/MutesCmd.ts b/backend/src/plugins/Mutes/commands/MutesCmd.ts
index 81f06d8d..d03c0ec3 100644
--- a/backend/src/plugins/Mutes/commands/MutesCmd.ts
+++ b/backend/src/plugins/Mutes/commands/MutesCmd.ts
@@ -1,12 +1,11 @@
-import { command } from "knub";
-import { IMuteWithDetails, MutesPluginType } from "../types";
+import { IMuteWithDetails, mutesCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { DBDateFormat, isFullMessage, MINUTES, noop, resolveMember } from "../../../utils";
 import moment from "moment-timezone";
 import { humanizeDurationShort } from "../../../humanizeDurationShort";
 import { getBaseUrl } from "../../../pluginUtils";
 
-export const MutesCmd = command<MutesPluginType>()({
+export const MutesCmd = mutesCmd({
   trigger: "mutes",
   permission: "can_view_list",
 
diff --git a/backend/src/plugins/Mutes/events/ClearActiveMuteOnMemberBanEvt.ts b/backend/src/plugins/Mutes/events/ClearActiveMuteOnMemberBanEvt.ts
index ff2756e3..c6cae2b7 100644
--- a/backend/src/plugins/Mutes/events/ClearActiveMuteOnMemberBanEvt.ts
+++ b/backend/src/plugins/Mutes/events/ClearActiveMuteOnMemberBanEvt.ts
@@ -1,15 +1,11 @@
-import { eventListener } from "knub";
-import { MutesPluginType } from "../types";
+import { mutesEvt } from "../types";
 
 /**
  * Clear active mute from the member if the member is banned
  */
-export const ClearActiveMuteOnMemberBanEvt = eventListener<MutesPluginType>()(
-  "guildBanAdd",
-  async ({ pluginData, args: { user } }) => {
-    const mute = await pluginData.state.mutes.findExistingMuteForUserId(user.id);
-    if (mute) {
-      pluginData.state.mutes.clear(user.id);
-    }
-  },
-);
+export const ClearActiveMuteOnMemberBanEvt = mutesEvt("guildBanAdd", async ({ pluginData, args: { user } }) => {
+  const mute = await pluginData.state.mutes.findExistingMuteForUserId(user.id);
+  if (mute) {
+    pluginData.state.mutes.clear(user.id);
+  }
+});
diff --git a/backend/src/plugins/Mutes/events/ClearActiveMuteOnRoleRemovalEvt.ts b/backend/src/plugins/Mutes/events/ClearActiveMuteOnRoleRemovalEvt.ts
index 6edc6d7b..26727248 100644
--- a/backend/src/plugins/Mutes/events/ClearActiveMuteOnRoleRemovalEvt.ts
+++ b/backend/src/plugins/Mutes/events/ClearActiveMuteOnRoleRemovalEvt.ts
@@ -1,11 +1,10 @@
-import { eventListener } from "knub";
-import { MutesPluginType } from "../types";
+import { mutesEvt } from "../types";
 import { memberHasMutedRole } from "../functions/memberHasMutedRole";
 
 /**
  * Clear active mute if the mute role is removed manually
  */
-export const ClearActiveMuteOnRoleRemovalEvt = eventListener<MutesPluginType>()(
+export const ClearActiveMuteOnRoleRemovalEvt = mutesEvt(
   "guildMemberUpdate",
   async ({ pluginData, args: { member } }) => {
     const muteRole = pluginData.config.get().mute_role;
diff --git a/backend/src/plugins/Mutes/events/ReapplyActiveMuteOnJoinEvt.ts b/backend/src/plugins/Mutes/events/ReapplyActiveMuteOnJoinEvt.ts
index cd6c0985..cc5a4df0 100644
--- a/backend/src/plugins/Mutes/events/ReapplyActiveMuteOnJoinEvt.ts
+++ b/backend/src/plugins/Mutes/events/ReapplyActiveMuteOnJoinEvt.ts
@@ -1,25 +1,21 @@
-import { eventListener } from "knub";
-import { MutesPluginType } from "../types";
-import { LogType } from "src/data/LogType";
-import { stripObjectToScalars } from "src/utils";
+import { mutesEvt } from "../types";
+import { LogType } from "../../../data/LogType";
+import { stripObjectToScalars } from "../../../utils";
 
 /**
  * Reapply active mutes on join
  */
-export const ReapplyActiveMuteOnJoinEvt = eventListener<MutesPluginType>()(
-  "guildMemberAdd",
-  async ({ pluginData, args: { member } }) => {
-    const mute = await pluginData.state.mutes.findExistingMuteForUserId(member.id);
-    if (mute) {
-      const muteRole = pluginData.config.get().mute_role;
+export const ReapplyActiveMuteOnJoinEvt = mutesEvt("guildMemberAdd", async ({ pluginData, args: { member } }) => {
+  const mute = await pluginData.state.mutes.findExistingMuteForUserId(member.id);
+  if (mute) {
+    const muteRole = pluginData.config.get().mute_role;
 
-      const memberRolesLock = await pluginData.locks.acquire(`member-roles-${member.id}`);
-      await member.addRole(muteRole);
-      memberRolesLock.unlock();
+    const memberRolesLock = await pluginData.locks.acquire(`member-roles-${member.id}`);
+    await member.addRole(muteRole);
+    memberRolesLock.unlock();
 
-      pluginData.state.serverLogs.log(LogType.MEMBER_MUTE_REJOIN, {
-        member: stripObjectToScalars(member, ["user", "roles"]),
-      });
-    }
-  },
-);
+    pluginData.state.serverLogs.log(LogType.MEMBER_MUTE_REJOIN, {
+      member: stripObjectToScalars(member, ["user", "roles"]),
+    });
+  }
+});
diff --git a/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts b/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts
index 742c5532..86851637 100644
--- a/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts
+++ b/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts
@@ -1,9 +1,9 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { MutesPluginType } from "../types";
 import { LogType } from "../../../data/LogType";
 import { resolveMember, stripObjectToScalars, UnknownUser } from "../../../utils";
 
-export async function clearExpiredMutes(pluginData: PluginData<MutesPluginType>) {
+export async function clearExpiredMutes(pluginData: GuildPluginData<MutesPluginType>) {
   const expiredMutes = await pluginData.state.mutes.getExpiredMutes();
   for (const mute of expiredMutes) {
     const member = await resolveMember(pluginData.client, pluginData.guild, mute.user_id);
diff --git a/backend/src/plugins/Mutes/functions/memberHasMutedRole.ts b/backend/src/plugins/Mutes/functions/memberHasMutedRole.ts
index 474d6fa9..1dda81c1 100644
--- a/backend/src/plugins/Mutes/functions/memberHasMutedRole.ts
+++ b/backend/src/plugins/Mutes/functions/memberHasMutedRole.ts
@@ -1,7 +1,7 @@
 import { Member } from "eris";
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { MutesPluginType } from "../types";
 
-export function memberHasMutedRole(pluginData: PluginData<MutesPluginType>, member: Member) {
+export function memberHasMutedRole(pluginData: GuildPluginData<MutesPluginType>, member: Member) {
   return member.roles.includes(pluginData.config.get().mute_role);
 }
diff --git a/backend/src/plugins/Mutes/functions/muteUser.ts b/backend/src/plugins/Mutes/functions/muteUser.ts
index 46126656..168bc198 100644
--- a/backend/src/plugins/Mutes/functions/muteUser.ts
+++ b/backend/src/plugins/Mutes/functions/muteUser.ts
@@ -1,4 +1,4 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { MuteOptions, MutesPluginType } from "../types";
 import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError";
 import humanizeDuration from "humanize-duration";
@@ -15,10 +15,10 @@ import { TextChannel, User } from "eris";
 import { CasesPlugin } from "../../Cases/CasesPlugin";
 import { CaseTypes } from "../../../data/CaseTypes";
 import { LogType } from "../../../data/LogType";
-import { Case } from "src/data/entities/Case";
+import { Case } from "../../../data/entities/Case";
 
 export async function muteUser(
-  pluginData: PluginData<MutesPluginType>,
+  pluginData: GuildPluginData<MutesPluginType>,
   userId: string,
   muteTime: number = null,
   reason: string = null,
diff --git a/backend/src/plugins/Mutes/functions/unmuteUser.ts b/backend/src/plugins/Mutes/functions/unmuteUser.ts
index cebbdf9b..a734de6a 100644
--- a/backend/src/plugins/Mutes/functions/unmuteUser.ts
+++ b/backend/src/plugins/Mutes/functions/unmuteUser.ts
@@ -1,4 +1,4 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { MutesPluginType, UnmuteResult } from "../types";
 import { CaseArgs } from "../../Cases/types";
 import { resolveUser, stripObjectToScalars, resolveMember } from "../../../utils";
@@ -9,7 +9,7 @@ import { CaseTypes } from "../../../data/CaseTypes";
 import { LogType } from "../../../data/LogType";
 
 export async function unmuteUser(
-  pluginData: PluginData<MutesPluginType>,
+  pluginData: GuildPluginData<MutesPluginType>,
   userId: string,
   unmuteTime: number = null,
   caseArgs: Partial<CaseArgs> = {},
diff --git a/backend/src/plugins/Mutes/types.ts b/backend/src/plugins/Mutes/types.ts
index d780d618..8fe7eb55 100644
--- a/backend/src/plugins/Mutes/types.ts
+++ b/backend/src/plugins/Mutes/types.ts
@@ -3,7 +3,7 @@ import { tNullable, UserNotificationMethod, UserNotificationResult } from "../..
 import { Mute } from "../../data/entities/Mute";
 import { Member } from "eris";
 import { Case } from "../../data/entities/Case";
-import { BasePluginType } from "knub";
+import { BasePluginType, guildCommand, guildEventListener } from "knub";
 import { GuildLogs } from "../../data/GuildLogs";
 import { GuildCases } from "../../data/GuildCases";
 import { GuildArchives } from "../../data/GuildArchives";
@@ -60,3 +60,6 @@ export interface MuteOptions {
   caseArgs?: Partial<CaseArgs>;
   contactMethods?: UserNotificationMethod[];
 }
+
+export const mutesCmd = guildCommand<MutesPluginType>();
+export const mutesEvt = guildEventListener<MutesPluginType>();
diff --git a/backend/src/plugins/NameHistory/NameHistoryPlugin.ts b/backend/src/plugins/NameHistory/NameHistoryPlugin.ts
index 090a1b17..4bc080b4 100644
--- a/backend/src/plugins/NameHistory/NameHistoryPlugin.ts
+++ b/backend/src/plugins/NameHistory/NameHistoryPlugin.ts
@@ -1,9 +1,9 @@
 import { PluginOptions } from "knub";
 import { ConfigSchema, NameHistoryPluginType } from "./types";
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
-import { GuildNicknameHistory } from "src/data/GuildNicknameHistory";
-import { UsernameHistory } from "src/data/UsernameHistory";
-import { Queue } from "src/Queue";
+import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
+import { GuildNicknameHistory } from "../../data/GuildNicknameHistory";
+import { UsernameHistory } from "../../data/UsernameHistory";
+import { Queue } from "../../Queue";
 import { NamesCmd } from "./commands/NamesCmd";
 import { ChannelJoinEvt, MessageCreateEvt } from "./events/UpdateNameEvts";
 
@@ -21,7 +21,7 @@ const defaultOptions: PluginOptions<NameHistoryPluginType> = {
   ],
 };
 
-export const NameHistoryPlugin = zeppelinPlugin<NameHistoryPluginType>()("name_history", {
+export const NameHistoryPlugin = zeppelinGuildPlugin<NameHistoryPluginType>()("name_history", {
   showInDocs: false,
 
   configSchema: ConfigSchema,
diff --git a/backend/src/plugins/NameHistory/commands/NamesCmd.ts b/backend/src/plugins/NameHistory/commands/NamesCmd.ts
index 56b35c3b..dfb1f3cb 100644
--- a/backend/src/plugins/NameHistory/commands/NamesCmd.ts
+++ b/backend/src/plugins/NameHistory/commands/NamesCmd.ts
@@ -1,11 +1,11 @@
 import { nameHistoryCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { createChunkedMessage, disableCodeBlocks } from "knub/dist/helpers";
-import { NICKNAME_RETENTION_PERIOD } from "src/data/cleanup/nicknames";
-import { DAYS } from "src/utils";
-import { MAX_NICKNAME_ENTRIES_PER_USER } from "src/data/GuildNicknameHistory";
-import { MAX_USERNAME_ENTRIES_PER_USER } from "src/data/UsernameHistory";
-import { sendErrorMessage } from "src/pluginUtils";
+import { NICKNAME_RETENTION_PERIOD } from "../../../data/cleanup/nicknames";
+import { DAYS } from "../../../utils";
+import { MAX_NICKNAME_ENTRIES_PER_USER } from "../../../data/GuildNicknameHistory";
+import { MAX_USERNAME_ENTRIES_PER_USER } from "../../../data/UsernameHistory";
+import { sendErrorMessage } from "../../../pluginUtils";
 
 export const NamesCmd = nameHistoryCmd({
   trigger: "names",
diff --git a/backend/src/plugins/NameHistory/types.ts b/backend/src/plugins/NameHistory/types.ts
index ad9f6833..abe781e8 100644
--- a/backend/src/plugins/NameHistory/types.ts
+++ b/backend/src/plugins/NameHistory/types.ts
@@ -1,8 +1,8 @@
 import * as t from "io-ts";
-import { BasePluginType, command, eventListener } from "knub";
-import { GuildNicknameHistory } from "src/data/GuildNicknameHistory";
-import { UsernameHistory } from "src/data/UsernameHistory";
-import { Queue } from "src/Queue";
+import { BasePluginType, guildCommand, guildEventListener } from "knub";
+import { GuildNicknameHistory } from "../../data/GuildNicknameHistory";
+import { UsernameHistory } from "../../data/UsernameHistory";
+import { Queue } from "../../Queue";
 
 export const ConfigSchema = t.type({
   can_view: t.boolean,
@@ -18,5 +18,5 @@ export interface NameHistoryPluginType extends BasePluginType {
   };
 }
 
-export const nameHistoryCmd = command<NameHistoryPluginType>();
-export const nameHistoryEvt = eventListener<NameHistoryPluginType>();
+export const nameHistoryCmd = guildCommand<NameHistoryPluginType>();
+export const nameHistoryEvt = guildEventListener<NameHistoryPluginType>();
diff --git a/backend/src/plugins/NameHistory/updateNickname.ts b/backend/src/plugins/NameHistory/updateNickname.ts
index b00e01fa..2ac8471f 100644
--- a/backend/src/plugins/NameHistory/updateNickname.ts
+++ b/backend/src/plugins/NameHistory/updateNickname.ts
@@ -1,8 +1,8 @@
 import { Member } from "eris";
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { NameHistoryPluginType } from "./types";
 
-export async function updateNickname(pluginData: PluginData<NameHistoryPluginType>, member: Member) {
+export async function updateNickname(pluginData: GuildPluginData<NameHistoryPluginType>, member: Member) {
   if (!member) return;
   const latestEntry = await pluginData.state.nicknameHistory.getLastEntry(member.id);
   if (!latestEntry || latestEntry.nickname !== member.nick) {
diff --git a/backend/src/plugins/Persist/PersistPlugin.ts b/backend/src/plugins/Persist/PersistPlugin.ts
index c802d783..54913ad2 100644
--- a/backend/src/plugins/Persist/PersistPlugin.ts
+++ b/backend/src/plugins/Persist/PersistPlugin.ts
@@ -1,8 +1,8 @@
 import { PluginOptions } from "knub";
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
+import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
 import { ConfigSchema, PersistPluginType } from "./types";
-import { GuildPersistedData } from "src/data/GuildPersistedData";
-import { GuildLogs } from "src/data/GuildLogs";
+import { GuildPersistedData } from "../../data/GuildPersistedData";
+import { GuildLogs } from "../../data/GuildLogs";
 import { StoreDataEvt } from "./events/StoreDataEvt";
 import { LoadDataEvt } from "./events/LoadDataEvt";
 import { trimPluginDescription } from "../../utils";
@@ -16,7 +16,7 @@ const defaultOptions: PluginOptions<PersistPluginType> = {
   },
 };
 
-export const PersistPlugin = zeppelinPlugin<PersistPluginType>()("persist", {
+export const PersistPlugin = zeppelinGuildPlugin<PersistPluginType>()("persist", {
   showInDocs: true,
   info: {
     prettyName: "Persist",
diff --git a/backend/src/plugins/Persist/events/LoadDataEvt.ts b/backend/src/plugins/Persist/events/LoadDataEvt.ts
index d4a2bd03..e89e51be 100644
--- a/backend/src/plugins/Persist/events/LoadDataEvt.ts
+++ b/backend/src/plugins/Persist/events/LoadDataEvt.ts
@@ -1,8 +1,8 @@
-import { persistEvent } from "../types";
+import { persistEvt } from "../types";
 import { Constants, MemberOptions } from "eris";
 import intersection from "lodash.intersection";
-import { LogType } from "src/data/LogType";
-import { stripObjectToScalars } from "src/utils";
+import { LogType } from "../../../data/LogType";
+import { stripObjectToScalars } from "../../../utils";
 import { getMissingPermissions } from "../../../utils/getMissingPermissions";
 import { LogsPlugin } from "../../Logs/LogsPlugin";
 import { missingPermissionError } from "../../../utils/missingPermissionError";
@@ -10,7 +10,7 @@ import { canAssignRole } from "../../../utils/canAssignRole";
 
 const p = Constants.Permissions;
 
-export const LoadDataEvt = persistEvent({
+export const LoadDataEvt = persistEvt({
   event: "guildMemberAdd",
 
   async listener(meta) {
diff --git a/backend/src/plugins/Persist/events/StoreDataEvt.ts b/backend/src/plugins/Persist/events/StoreDataEvt.ts
index 5de3bc8a..3c5e2681 100644
--- a/backend/src/plugins/Persist/events/StoreDataEvt.ts
+++ b/backend/src/plugins/Persist/events/StoreDataEvt.ts
@@ -1,9 +1,9 @@
-import { persistEvent } from "../types";
-import { IPartialPersistData } from "src/data/GuildPersistedData";
+import { persistEvt } from "../types";
+import { IPartialPersistData } from "../../../data/GuildPersistedData";
 import { Member } from "eris";
 import intersection from "lodash.intersection";
 
-export const StoreDataEvt = persistEvent({
+export const StoreDataEvt = persistEvt({
   event: "guildMemberRemove",
 
   async listener(meta) {
diff --git a/backend/src/plugins/Persist/types.ts b/backend/src/plugins/Persist/types.ts
index d7900cbd..62ba8828 100644
--- a/backend/src/plugins/Persist/types.ts
+++ b/backend/src/plugins/Persist/types.ts
@@ -1,7 +1,7 @@
 import * as t from "io-ts";
-import { BasePluginType, eventListener } from "knub";
-import { GuildPersistedData } from "src/data/GuildPersistedData";
-import { GuildLogs } from "src/data/GuildLogs";
+import { BasePluginType, guildEventListener } from "knub";
+import { GuildPersistedData } from "../../data/GuildPersistedData";
+import { GuildLogs } from "../../data/GuildLogs";
 
 export const ConfigSchema = t.type({
   persisted_roles: t.array(t.string),
@@ -19,4 +19,4 @@ export interface PersistPluginType extends BasePluginType {
   };
 }
 
-export const persistEvent = eventListener<PersistPluginType>();
+export const persistEvt = guildEventListener<PersistPluginType>();
diff --git a/backend/src/plugins/PingableRoles/PingableRolesPlugin.ts b/backend/src/plugins/PingableRoles/PingableRolesPlugin.ts
index 94424e1b..49e176be 100644
--- a/backend/src/plugins/PingableRoles/PingableRolesPlugin.ts
+++ b/backend/src/plugins/PingableRoles/PingableRolesPlugin.ts
@@ -1,7 +1,7 @@
 import { PluginOptions } from "knub";
 import { ConfigSchema, PingableRolesPluginType } from "./types";
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
-import { GuildPingableRoles } from "src/data/GuildPingableRoles";
+import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
+import { GuildPingableRoles } from "../../data/GuildPingableRoles";
 import { PingableRoleEnableCmd } from "./commands/PingableRoleEnableCmd";
 import { PingableRoleDisableCmd } from "./commands/PingableRoleDisableCmd";
 import { MessageCreateDisablePingableEvt, TypingEnablePingableEvt } from "./events/ChangePingableEvts";
@@ -20,7 +20,7 @@ const defaultOptions: PluginOptions<PingableRolesPluginType> = {
   ],
 };
 
-export const PingableRolesPlugin = zeppelinPlugin<PingableRolesPluginType>()("pingable_roles", {
+export const PingableRolesPlugin = zeppelinGuildPlugin<PingableRolesPluginType>()("pingable_roles", {
   showInDocs: true,
   info: {
     prettyName: "Pingable roles",
diff --git a/backend/src/plugins/PingableRoles/commands/PingableRoleDisableCmd.ts b/backend/src/plugins/PingableRoles/commands/PingableRoleDisableCmd.ts
index 9d635d0f..02dc86cf 100644
--- a/backend/src/plugins/PingableRoles/commands/PingableRoleDisableCmd.ts
+++ b/backend/src/plugins/PingableRoles/commands/PingableRoleDisableCmd.ts
@@ -1,6 +1,6 @@
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { pingableRolesCmd } from "../types";
-import { sendErrorMessage, sendSuccessMessage } from "src/pluginUtils";
+import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
 
 export const PingableRoleDisableCmd = pingableRolesCmd({
   trigger: ["pingable_role disable", "pingable_role d"],
diff --git a/backend/src/plugins/PingableRoles/commands/PingableRoleEnableCmd.ts b/backend/src/plugins/PingableRoles/commands/PingableRoleEnableCmd.ts
index 9927e49a..6cf6ef8d 100644
--- a/backend/src/plugins/PingableRoles/commands/PingableRoleEnableCmd.ts
+++ b/backend/src/plugins/PingableRoles/commands/PingableRoleEnableCmd.ts
@@ -1,6 +1,6 @@
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { pingableRolesCmd } from "../types";
-import { sendErrorMessage, sendSuccessMessage } from "src/pluginUtils";
+import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
 
 export const PingableRoleEnableCmd = pingableRolesCmd({
   trigger: "pingable_role",
diff --git a/backend/src/plugins/PingableRoles/types.ts b/backend/src/plugins/PingableRoles/types.ts
index 15c3886b..f66bdb1c 100644
--- a/backend/src/plugins/PingableRoles/types.ts
+++ b/backend/src/plugins/PingableRoles/types.ts
@@ -1,7 +1,7 @@
 import * as t from "io-ts";
-import { BasePluginType, command, eventListener } from "knub";
-import { GuildPingableRoles } from "src/data/GuildPingableRoles";
-import { PingableRole } from "src/data/entities/PingableRole";
+import { BasePluginType, guildCommand, guildEventListener } from "knub";
+import { GuildPingableRoles } from "../../data/GuildPingableRoles";
+import { PingableRole } from "../../data/entities/PingableRole";
 
 export const ConfigSchema = t.type({
   can_manage: t.boolean,
@@ -18,5 +18,5 @@ export interface PingableRolesPluginType extends BasePluginType {
   };
 }
 
-export const pingableRolesCmd = command<PingableRolesPluginType>();
-export const pingableRolesEvt = eventListener<PingableRolesPluginType>();
+export const pingableRolesCmd = guildCommand<PingableRolesPluginType>();
+export const pingableRolesEvt = guildEventListener<PingableRolesPluginType>();
diff --git a/backend/src/plugins/PingableRoles/utils/disablePingableRoles.ts b/backend/src/plugins/PingableRoles/utils/disablePingableRoles.ts
index 823ae705..f4d735b1 100644
--- a/backend/src/plugins/PingableRoles/utils/disablePingableRoles.ts
+++ b/backend/src/plugins/PingableRoles/utils/disablePingableRoles.ts
@@ -1,8 +1,11 @@
-import { PingableRole } from "src/data/entities/PingableRole";
-import { PluginData } from "knub";
+import { PingableRole } from "../../../data/entities/PingableRole";
+import { GuildPluginData } from "knub";
 import { PingableRolesPluginType } from "../types";
 
-export function disablePingableRoles(pluginData: PluginData<PingableRolesPluginType>, pingableRoles: PingableRole[]) {
+export function disablePingableRoles(
+  pluginData: GuildPluginData<PingableRolesPluginType>,
+  pingableRoles: PingableRole[],
+) {
   for (const pingableRole of pingableRoles) {
     const role = pluginData.guild.roles.get(pingableRole.role_id);
     if (!role) continue;
diff --git a/backend/src/plugins/PingableRoles/utils/enablePingableRoles.ts b/backend/src/plugins/PingableRoles/utils/enablePingableRoles.ts
index b8632dc7..f4ab93c9 100644
--- a/backend/src/plugins/PingableRoles/utils/enablePingableRoles.ts
+++ b/backend/src/plugins/PingableRoles/utils/enablePingableRoles.ts
@@ -1,8 +1,11 @@
-import { PingableRole } from "src/data/entities/PingableRole";
-import { PluginData } from "knub";
+import { PingableRole } from "../../../data/entities/PingableRole";
+import { GuildPluginData } from "knub";
 import { PingableRolesPluginType } from "../types";
 
-export function enablePingableRoles(pluginData: PluginData<PingableRolesPluginType>, pingableRoles: PingableRole[]) {
+export function enablePingableRoles(
+  pluginData: GuildPluginData<PingableRolesPluginType>,
+  pingableRoles: PingableRole[],
+) {
   for (const pingableRole of pingableRoles) {
     const role = pluginData.guild.roles.get(pingableRole.role_id);
     if (!role) continue;
diff --git a/backend/src/plugins/PingableRoles/utils/getPingableRolesForChannel.ts b/backend/src/plugins/PingableRoles/utils/getPingableRolesForChannel.ts
index 4e4ad089..5714632b 100644
--- a/backend/src/plugins/PingableRoles/utils/getPingableRolesForChannel.ts
+++ b/backend/src/plugins/PingableRoles/utils/getPingableRolesForChannel.ts
@@ -1,9 +1,9 @@
-import { PingableRole } from "src/data/entities/PingableRole";
-import { PluginData } from "knub";
+import { PingableRole } from "../../../data/entities/PingableRole";
+import { GuildPluginData } from "knub";
 import { PingableRolesPluginType } from "../types";
 
 export async function getPingableRolesForChannel(
-  pluginData: PluginData<PingableRolesPluginType>,
+  pluginData: GuildPluginData<PingableRolesPluginType>,
   channelId: string,
 ): Promise<PingableRole[]> {
   if (!pluginData.state.cache.has(channelId)) {
diff --git a/backend/src/plugins/Post/PostPlugin.ts b/backend/src/plugins/Post/PostPlugin.ts
index 93d46605..d1824a49 100644
--- a/backend/src/plugins/Post/PostPlugin.ts
+++ b/backend/src/plugins/Post/PostPlugin.ts
@@ -1,9 +1,9 @@
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
+import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
 import { PluginOptions } from "knub";
 import { ConfigSchema, PostPluginType } from "./types";
-import { GuildSavedMessages } from "src/data/GuildSavedMessages";
-import { GuildScheduledPosts } from "src/data/GuildScheduledPosts";
-import { GuildLogs } from "src/data/GuildLogs";
+import { GuildSavedMessages } from "../../data/GuildSavedMessages";
+import { GuildScheduledPosts } from "../../data/GuildScheduledPosts";
+import { GuildLogs } from "../../data/GuildLogs";
 import { PostCmd } from "./commands/PostCmd";
 import { PostEmbedCmd } from "./commands/PostEmbedCmd";
 import { EditCmd } from "./commands/EditCmd";
@@ -28,7 +28,7 @@ const defaultOptions: PluginOptions<PostPluginType> = {
   ],
 };
 
-export const PostPlugin = zeppelinPlugin<PostPluginType>()("post", {
+export const PostPlugin = zeppelinGuildPlugin<PostPluginType>()("post", {
   showInDocs: true,
   info: {
     prettyName: "Post",
diff --git a/backend/src/plugins/Post/commands/EditCmd.ts b/backend/src/plugins/Post/commands/EditCmd.ts
index d061f8a9..64f471e2 100644
--- a/backend/src/plugins/Post/commands/EditCmd.ts
+++ b/backend/src/plugins/Post/commands/EditCmd.ts
@@ -1,6 +1,6 @@
 import { postCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
-import { sendErrorMessage, sendSuccessMessage } from "src/pluginUtils";
+import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
 import { formatContent } from "../util/formatContent";
 
 export const EditCmd = postCmd({
diff --git a/backend/src/plugins/Post/commands/EditEmbedCmd.ts b/backend/src/plugins/Post/commands/EditEmbedCmd.ts
index 584f780c..9a79bd57 100644
--- a/backend/src/plugins/Post/commands/EditEmbedCmd.ts
+++ b/backend/src/plugins/Post/commands/EditEmbedCmd.ts
@@ -1,8 +1,8 @@
 import { postCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
-import { sendErrorMessage, sendSuccessMessage } from "src/pluginUtils";
+import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
 import { Embed } from "eris";
-import { trimLines } from "src/utils";
+import { trimLines } from "../../../utils";
 import { formatContent } from "../util/formatContent";
 import { parseColor } from "../../../utils/parseColor";
 import { rgbToInt } from "../../../utils/rgbToInt";
@@ -52,7 +52,7 @@ export const EditEmbedCmd = postCmd({
     await sendSuccessMessage(pluginData, msg.channel, "Embed edited");
 
     if (args.content) {
-      const prefix = pluginData.guildConfig.prefix || "!";
+      const prefix = pluginData.fullConfig.prefix || "!";
       msg.channel.createMessage(
         trimLines(`
         <@!${msg.author.id}> You can now specify an embed's content directly at the end of the command:
diff --git a/backend/src/plugins/Post/commands/PostEmbedCmd.ts b/backend/src/plugins/Post/commands/PostEmbedCmd.ts
index 06c57b20..40eac84e 100644
--- a/backend/src/plugins/Post/commands/PostEmbedCmd.ts
+++ b/backend/src/plugins/Post/commands/PostEmbedCmd.ts
@@ -1,9 +1,9 @@
 import { postCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { actualPostCmd } from "../util/actualPostCmd";
-import { sendErrorMessage } from "src/pluginUtils";
+import { sendErrorMessage } from "../../../pluginUtils";
 import { Embed } from "eris";
-import { isValidEmbed, trimLines } from "src/utils";
+import { isValidEmbed, trimLines } from "../../../utils";
 import { formatContent } from "../util/formatContent";
 import { parseColor } from "../../../utils/parseColor";
 import { rgbToInt } from "../../../utils/rgbToInt";
@@ -72,7 +72,7 @@ export const PostEmbedCmd = postCmd({
     }
 
     if (args.content) {
-      const prefix = pluginData.guildConfig.prefix || "!";
+      const prefix = pluginData.fullConfig.prefix || "!";
       msg.channel.createMessage(
         trimLines(`
         <@!${msg.author.id}> You can now specify an embed's content directly at the end of the command:
diff --git a/backend/src/plugins/Post/commands/SchedluedPostsDeleteCmd.ts b/backend/src/plugins/Post/commands/SchedluedPostsDeleteCmd.ts
index f78e7006..cc5222ec 100644
--- a/backend/src/plugins/Post/commands/SchedluedPostsDeleteCmd.ts
+++ b/backend/src/plugins/Post/commands/SchedluedPostsDeleteCmd.ts
@@ -1,6 +1,6 @@
 import { postCmd } from "../types";
-import { sorter } from "src/utils";
-import { sendErrorMessage, sendSuccessMessage } from "src/pluginUtils";
+import { sorter } from "../../../utils";
+import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 
 export const ScheduledPostsDeleteCmd = postCmd({
diff --git a/backend/src/plugins/Post/commands/ScheduledPostsListCmd.ts b/backend/src/plugins/Post/commands/ScheduledPostsListCmd.ts
index 28b123bc..399ca6f0 100644
--- a/backend/src/plugins/Post/commands/ScheduledPostsListCmd.ts
+++ b/backend/src/plugins/Post/commands/ScheduledPostsListCmd.ts
@@ -6,7 +6,7 @@ import {
   deactivateMentions,
   createChunkedMessage,
   DBDateFormat,
-} from "src/utils";
+} from "../../../utils";
 import humanizeDuration from "humanize-duration";
 import moment from "moment-timezone";
 import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin";
diff --git a/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts b/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts
index cc0e3a42..0e76f134 100644
--- a/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts
+++ b/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts
@@ -1,6 +1,6 @@
 import { postCmd } from "../types";
-import { sorter } from "src/utils";
-import { sendErrorMessage } from "src/pluginUtils";
+import { sorter } from "../../../utils";
+import { sendErrorMessage } from "../../../pluginUtils";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { postMessage } from "../util/postMessage";
 import { TextChannel } from "eris";
diff --git a/backend/src/plugins/Post/types.ts b/backend/src/plugins/Post/types.ts
index f1d697bf..5d02fc4d 100644
--- a/backend/src/plugins/Post/types.ts
+++ b/backend/src/plugins/Post/types.ts
@@ -1,8 +1,8 @@
 import * as t from "io-ts";
-import { BasePluginType, command } from "knub";
-import { GuildSavedMessages } from "src/data/GuildSavedMessages";
-import { GuildScheduledPosts } from "src/data/GuildScheduledPosts";
-import { GuildLogs } from "src/data/GuildLogs";
+import { BasePluginType, guildCommand } from "knub";
+import { GuildSavedMessages } from "../../data/GuildSavedMessages";
+import { GuildScheduledPosts } from "../../data/GuildScheduledPosts";
+import { GuildLogs } from "../../data/GuildLogs";
 
 export const ConfigSchema = t.type({
   can_post: t.boolean,
@@ -20,4 +20,4 @@ export interface PostPluginType extends BasePluginType {
   };
 }
 
-export const postCmd = command<PostPluginType>();
+export const postCmd = guildCommand<PostPluginType>();
diff --git a/backend/src/plugins/Post/util/actualPostCmd.ts b/backend/src/plugins/Post/util/actualPostCmd.ts
index 885e32dd..16046ffd 100644
--- a/backend/src/plugins/Post/util/actualPostCmd.ts
+++ b/backend/src/plugins/Post/util/actualPostCmd.ts
@@ -1,10 +1,10 @@
 import { Message, Channel, TextChannel } from "eris";
-import { StrictMessageContent, errorMessage, stripObjectToScalars, MINUTES, DBDateFormat } from "src/utils";
+import { StrictMessageContent, errorMessage, stripObjectToScalars, MINUTES, DBDateFormat } from "../../../utils";
 import moment from "moment-timezone";
-import { LogType } from "src/data/LogType";
+import { LogType } from "../../../data/LogType";
 import humanizeDuration from "humanize-duration";
-import { sendErrorMessage, sendSuccessMessage } from "src/pluginUtils";
-import { PluginData } from "knub";
+import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
+import { GuildPluginData } from "knub";
 import { PostPluginType } from "../types";
 import { parseScheduleTime } from "./parseScheduleTime";
 import { postMessage } from "./postMessage";
@@ -15,7 +15,7 @@ const MAX_REPEAT_TIME = Math.pow(2, 32);
 const MAX_REPEAT_UNTIL = moment.utc().add(100, "years");
 
 export async function actualPostCmd(
-  pluginData: PluginData<PostPluginType>,
+  pluginData: GuildPluginData<PostPluginType>,
   msg: Message,
   targetChannel: Channel,
   content: StrictMessageContent,
diff --git a/backend/src/plugins/Post/util/formatContent.ts b/backend/src/plugins/Post/util/formatContent.ts
index e8d6ba93..b98f5c3b 100644
--- a/backend/src/plugins/Post/util/formatContent.ts
+++ b/backend/src/plugins/Post/util/formatContent.ts
@@ -1,3 +1,3 @@
-export function formatContent(str) {
+export function formatContent(str: string) {
   return str.replace(/\\n/g, "\n");
 }
diff --git a/backend/src/plugins/Post/util/parseScheduleTime.ts b/backend/src/plugins/Post/util/parseScheduleTime.ts
index 6db95ed0..e6f7fa9a 100644
--- a/backend/src/plugins/Post/util/parseScheduleTime.ts
+++ b/backend/src/plugins/Post/util/parseScheduleTime.ts
@@ -1,10 +1,14 @@
 import moment, { Moment } from "moment-timezone";
-import { convertDelayStringToMS } from "src/utils";
-import { PluginData } from "knub";
+import { convertDelayStringToMS } from "../../../utils";
+import { GuildPluginData } from "knub";
 import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin";
 
 // TODO: Extract out of the Post plugin, use everywhere with a date input
-export async function parseScheduleTime(pluginData: PluginData<any>, memberId: string, str: string): Promise<Moment> {
+export async function parseScheduleTime(
+  pluginData: GuildPluginData<any>,
+  memberId: string,
+  str: string,
+): Promise<Moment> {
   const tz = await pluginData.getPlugin(TimeAndDatePlugin).getMemberTz(memberId);
 
   const dt1 = moment.tz(str, "YYYY-MM-DD HH:mm:ss", tz);
diff --git a/backend/src/plugins/Post/util/postMessage.ts b/backend/src/plugins/Post/util/postMessage.ts
index 199b0ead..b26446e5 100644
--- a/backend/src/plugins/Post/util/postMessage.ts
+++ b/backend/src/plugins/Post/util/postMessage.ts
@@ -1,14 +1,14 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { PostPluginType } from "../types";
 import { TextChannel, MessageContent, Attachment, Message, Role } from "eris";
-import { downloadFile, getRoleMentions } from "src/utils";
+import { downloadFile, getRoleMentions } from "../../../utils";
 import fs from "fs";
 import { formatContent } from "./formatContent";
 
 const fsp = fs.promises;
 
 export async function postMessage(
-  pluginData: PluginData<PostPluginType>,
+  pluginData: GuildPluginData<PostPluginType>,
   channel: TextChannel,
   content: MessageContent,
   attachments: Attachment[] = [],
diff --git a/backend/src/plugins/Post/util/scheduledPostLoop.ts b/backend/src/plugins/Post/util/scheduledPostLoop.ts
index 58e0d545..a5f05138 100644
--- a/backend/src/plugins/Post/util/scheduledPostLoop.ts
+++ b/backend/src/plugins/Post/util/scheduledPostLoop.ts
@@ -1,15 +1,15 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { PostPluginType } from "../types";
-import { logger } from "src/logger";
-import { stripObjectToScalars, SECONDS, DBDateFormat } from "src/utils";
-import { LogType } from "src/data/LogType";
+import { logger } from "../../../logger";
+import { stripObjectToScalars, SECONDS, DBDateFormat } from "../../../utils";
+import { LogType } from "../../../data/LogType";
 import moment from "moment-timezone";
 import { TextChannel, User } from "eris";
 import { postMessage } from "./postMessage";
 
 const SCHEDULED_POST_CHECK_INTERVAL = 5 * SECONDS;
 
-export async function scheduledPostLoop(pluginData: PluginData<PostPluginType>) {
+export async function scheduledPostLoop(pluginData: GuildPluginData<PostPluginType>) {
   const duePosts = await pluginData.state.scheduledPosts.getDueScheduledPosts();
   for (const post of duePosts) {
     const channel = pluginData.guild.channels.get(post.channel_id);
diff --git a/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts b/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts
index d10d95d1..40c447df 100644
--- a/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts
+++ b/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts
@@ -1,9 +1,9 @@
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
+import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
 import { PluginOptions } from "knub";
 import { ConfigSchema, ReactionRolesPluginType } from "./types";
-import { GuildReactionRoles } from "src/data/GuildReactionRoles";
-import { GuildSavedMessages } from "src/data/GuildSavedMessages";
-import { Queue } from "src/Queue";
+import { GuildReactionRoles } from "../../data/GuildReactionRoles";
+import { GuildSavedMessages } from "../../data/GuildSavedMessages";
+import { Queue } from "../../Queue";
 import { autoRefreshLoop } from "./util/autoRefreshLoop";
 import { InitReactionRolesCmd } from "./commands/InitReactionRolesCmd";
 import { RefreshReactionRolesCmd } from "./commands/RefreshReactionRolesCmd";
@@ -31,7 +31,7 @@ const defaultOptions: PluginOptions<ReactionRolesPluginType> = {
   ],
 };
 
-export const ReactionRolesPlugin = zeppelinPlugin<ReactionRolesPluginType>()("reaction_roles", {
+export const ReactionRolesPlugin = zeppelinGuildPlugin<ReactionRolesPluginType>()("reaction_roles", {
   showInDocs: true,
   info: {
     prettyName: "Reaction roles",
diff --git a/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts
index 5c7ed88d..6b5329b3 100644
--- a/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts
+++ b/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts
@@ -1,6 +1,6 @@
 import { reactionRolesCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
-import { sendErrorMessage, sendSuccessMessage } from "src/pluginUtils";
+import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
 import { TextChannel } from "eris";
 
 export const ClearReactionRolesCmd = reactionRolesCmd({
diff --git a/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts
index af8c8231..d1eab7f3 100644
--- a/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts
+++ b/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts
@@ -2,7 +2,7 @@ import { reactionRolesCmd, TReactionRolePair } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
 import { TextChannel } from "eris";
-import { RecoverablePluginError, ERRORS } from "src/RecoverablePluginError";
+import { RecoverablePluginError, ERRORS } from "../../../RecoverablePluginError";
 import { canUseEmoji, isDiscordRESTError, noop } from "../../../utils";
 import { applyReactionRoleReactionsToMessage } from "../util/applyReactionRoleReactionsToMessage";
 import { canReadChannel } from "../../../utils/canReadChannel";
diff --git a/backend/src/plugins/ReactionRoles/commands/RefreshReactionRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/RefreshReactionRolesCmd.ts
index 0848a31e..7a93165b 100644
--- a/backend/src/plugins/ReactionRoles/commands/RefreshReactionRolesCmd.ts
+++ b/backend/src/plugins/ReactionRoles/commands/RefreshReactionRolesCmd.ts
@@ -1,6 +1,6 @@
 import { reactionRolesCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
-import { sendErrorMessage, sendSuccessMessage } from "src/pluginUtils";
+import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
 import { refreshReactionRoles } from "../util/refreshReactionRoles";
 
 export const RefreshReactionRolesCmd = reactionRolesCmd({
diff --git a/backend/src/plugins/ReactionRoles/events/AddReactionRoleEvt.ts b/backend/src/plugins/ReactionRoles/events/AddReactionRoleEvt.ts
index ec5974a1..734b591a 100644
--- a/backend/src/plugins/ReactionRoles/events/AddReactionRoleEvt.ts
+++ b/backend/src/plugins/ReactionRoles/events/AddReactionRoleEvt.ts
@@ -1,11 +1,11 @@
-import { reactionRolesEvent } from "../types";
-import { resolveMember, noop, sleep } from "src/utils";
+import { reactionRolesEvt } from "../types";
+import { resolveMember, noop, sleep } from "../../../utils";
 import { addMemberPendingRoleChange } from "../util/addMemberPendingRoleChange";
 import { Message } from "eris";
 
 const CLEAR_ROLES_EMOJI = "❌";
 
-export const AddReactionRoleEvt = reactionRolesEvent({
+export const AddReactionRoleEvt = reactionRolesEvt({
   event: "messageReactionAdd",
 
   async listener(meta) {
diff --git a/backend/src/plugins/ReactionRoles/types.ts b/backend/src/plugins/ReactionRoles/types.ts
index 11d3235c..9ea9db20 100644
--- a/backend/src/plugins/ReactionRoles/types.ts
+++ b/backend/src/plugins/ReactionRoles/types.ts
@@ -1,8 +1,8 @@
 import * as t from "io-ts";
-import { BasePluginType, eventListener, command, PluginData } from "knub";
-import { GuildSavedMessages } from "src/data/GuildSavedMessages";
-import { GuildReactionRoles } from "src/data/GuildReactionRoles";
-import { Queue } from "src/Queue";
+import { BasePluginType, guildEventListener, guildCommand } from "knub";
+import { GuildSavedMessages } from "../../data/GuildSavedMessages";
+import { GuildReactionRoles } from "../../data/GuildReactionRoles";
+import { Queue } from "../../Queue";
 
 export const ConfigSchema = t.type({
   auto_refresh_interval: t.number,
@@ -41,5 +41,5 @@ export interface ReactionRolesPluginType extends BasePluginType {
   };
 }
 
-export const reactionRolesCmd = command<ReactionRolesPluginType>();
-export const reactionRolesEvent = eventListener<ReactionRolesPluginType>();
+export const reactionRolesCmd = guildCommand<ReactionRolesPluginType>();
+export const reactionRolesEvt = guildEventListener<ReactionRolesPluginType>();
diff --git a/backend/src/plugins/ReactionRoles/util/addMemberPendingRoleChange.ts b/backend/src/plugins/ReactionRoles/util/addMemberPendingRoleChange.ts
index a6043377..e682ff49 100644
--- a/backend/src/plugins/ReactionRoles/util/addMemberPendingRoleChange.ts
+++ b/backend/src/plugins/ReactionRoles/util/addMemberPendingRoleChange.ts
@@ -1,12 +1,12 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { ReactionRolesPluginType, RoleChangeMode, PendingMemberRoleChanges } from "../types";
-import { resolveMember } from "src/utils";
-import { logger } from "src/logger";
+import { resolveMember } from "../../../utils";
+import { logger } from "../../../logger";
 
 const ROLE_CHANGE_BATCH_DEBOUNCE_TIME = 1500;
 
 export async function addMemberPendingRoleChange(
-  pluginData: PluginData<ReactionRolesPluginType>,
+  pluginData: GuildPluginData<ReactionRolesPluginType>,
   memberId: string,
   mode: RoleChangeMode,
   roleId: string,
diff --git a/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts b/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts
index 4e2f8c48..3d612cc6 100644
--- a/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts
+++ b/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts
@@ -1,9 +1,9 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { ReactionRolesPluginType } from "../types";
-import { ReactionRole } from "src/data/entities/ReactionRole";
+import { ReactionRole } from "../../../data/entities/ReactionRole";
 import { TextChannel } from "eris";
-import { isDiscordRESTError, sleep, isSnowflake } from "src/utils";
-import { logger } from "src/logger";
+import { isDiscordRESTError, sleep, isSnowflake } from "../../../utils";
+import { logger } from "../../../logger";
 import { LogsPlugin } from "../../Logs/LogsPlugin";
 import { LogType } from "../../../data/LogType";
 
@@ -13,7 +13,7 @@ const CLEAR_ROLES_EMOJI = "❌";
  * @return Errors encountered while applying reaction roles, if any
  */
 export async function applyReactionRoleReactionsToMessage(
-  pluginData: PluginData<ReactionRolesPluginType>,
+  pluginData: GuildPluginData<ReactionRolesPluginType>,
   channelId: string,
   messageId: string,
   reactionRoles: ReactionRole[],
diff --git a/backend/src/plugins/ReactionRoles/util/autoRefreshLoop.ts b/backend/src/plugins/ReactionRoles/util/autoRefreshLoop.ts
index e29e3dfa..90b12578 100644
--- a/backend/src/plugins/ReactionRoles/util/autoRefreshLoop.ts
+++ b/backend/src/plugins/ReactionRoles/util/autoRefreshLoop.ts
@@ -1,8 +1,8 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { ReactionRolesPluginType } from "../types";
 import { runAutoRefresh } from "./runAutoRefresh";
 
-export async function autoRefreshLoop(pluginData: PluginData<ReactionRolesPluginType>, interval: number) {
+export async function autoRefreshLoop(pluginData: GuildPluginData<ReactionRolesPluginType>, interval: number) {
   pluginData.state.autoRefreshTimeout = setTimeout(async () => {
     await runAutoRefresh(pluginData);
     autoRefreshLoop(pluginData, interval);
diff --git a/backend/src/plugins/ReactionRoles/util/refreshReactionRoles.ts b/backend/src/plugins/ReactionRoles/util/refreshReactionRoles.ts
index 4ea195f7..3d85ac52 100644
--- a/backend/src/plugins/ReactionRoles/util/refreshReactionRoles.ts
+++ b/backend/src/plugins/ReactionRoles/util/refreshReactionRoles.ts
@@ -1,9 +1,9 @@
 import { ReactionRolesPluginType } from "../types";
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { applyReactionRoleReactionsToMessage } from "./applyReactionRoleReactionsToMessage";
 
 export async function refreshReactionRoles(
-  pluginData: PluginData<ReactionRolesPluginType>,
+  pluginData: GuildPluginData<ReactionRolesPluginType>,
   channelId: string,
   messageId: string,
 ) {
diff --git a/backend/src/plugins/ReactionRoles/util/runAutoRefresh.ts b/backend/src/plugins/ReactionRoles/util/runAutoRefresh.ts
index 666df965..c365c18f 100644
--- a/backend/src/plugins/ReactionRoles/util/runAutoRefresh.ts
+++ b/backend/src/plugins/ReactionRoles/util/runAutoRefresh.ts
@@ -1,8 +1,8 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { ReactionRolesPluginType } from "../types";
 import { refreshReactionRoles } from "./refreshReactionRoles";
 
-export async function runAutoRefresh(pluginData: PluginData<ReactionRolesPluginType>) {
+export async function runAutoRefresh(pluginData: GuildPluginData<ReactionRolesPluginType>) {
   // Refresh reaction roles on all reaction role messages
   const reactionRoles = await pluginData.state.reactionRoles.all();
   const idPairs = new Set(reactionRoles.map(r => `${r.channel_id}-${r.message_id}`));
diff --git a/backend/src/plugins/Reminders/RemindersPlugin.ts b/backend/src/plugins/Reminders/RemindersPlugin.ts
index 80100578..dd3906f5 100644
--- a/backend/src/plugins/Reminders/RemindersPlugin.ts
+++ b/backend/src/plugins/Reminders/RemindersPlugin.ts
@@ -1,7 +1,7 @@
 import { PluginOptions } from "knub";
 import { ConfigSchema, RemindersPluginType } from "./types";
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
-import { GuildReminders } from "src/data/GuildReminders";
+import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
+import { GuildReminders } from "../../data/GuildReminders";
 import { postDueRemindersLoop } from "./utils/postDueRemindersLoop";
 import { RemindCmd } from "./commands/RemindCmd";
 import { RemindersCmd } from "./commands/RemindersCmd";
@@ -22,7 +22,7 @@ const defaultOptions: PluginOptions<RemindersPluginType> = {
   ],
 };
 
-export const RemindersPlugin = zeppelinPlugin<RemindersPluginType>()("reminders", {
+export const RemindersPlugin = zeppelinGuildPlugin<RemindersPluginType>()("reminders", {
   showInDocs: true,
   info: {
     prettyName: "Reminders",
diff --git a/backend/src/plugins/Reminders/commands/RemindCmd.ts b/backend/src/plugins/Reminders/commands/RemindCmd.ts
index 326b9ac3..67a2cfc1 100644
--- a/backend/src/plugins/Reminders/commands/RemindCmd.ts
+++ b/backend/src/plugins/Reminders/commands/RemindCmd.ts
@@ -1,12 +1,12 @@
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import moment from "moment-timezone";
-import { convertDelayStringToMS, messageLink } from "src/utils";
+import { convertDelayStringToMS, messageLink } from "../../../utils";
 import humanizeDuration from "humanize-duration";
-import { sendErrorMessage, sendSuccessMessage } from "src/pluginUtils";
-import { remindersCommand } from "../types";
+import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
+import { remindersCmd } from "../types";
 import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin";
 
-export const RemindCmd = remindersCommand({
+export const RemindCmd = remindersCmd({
   trigger: ["remind", "remindme"],
   usage: "!remind 3h Remind me of this in 3 hours please",
   permission: "can_use",
diff --git a/backend/src/plugins/Reminders/commands/RemindersCmd.ts b/backend/src/plugins/Reminders/commands/RemindersCmd.ts
index 1c7b3470..1a32533e 100644
--- a/backend/src/plugins/Reminders/commands/RemindersCmd.ts
+++ b/backend/src/plugins/Reminders/commands/RemindersCmd.ts
@@ -1,11 +1,11 @@
-import { remindersCommand } from "../types";
-import { sendErrorMessage } from "src/pluginUtils";
-import { createChunkedMessage, DBDateFormat, sorter } from "src/utils";
+import { remindersCmd } from "../types";
+import { sendErrorMessage } from "../../../pluginUtils";
+import { createChunkedMessage, DBDateFormat, sorter } from "../../../utils";
 import moment from "moment-timezone";
 import humanizeDuration from "humanize-duration";
 import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin";
 
-export const RemindersCmd = remindersCommand({
+export const RemindersCmd = remindersCmd({
   trigger: "reminders",
   permission: "can_use",
 
diff --git a/backend/src/plugins/Reminders/commands/RemindersDeleteCmd.ts b/backend/src/plugins/Reminders/commands/RemindersDeleteCmd.ts
index f19905d2..7b9f33c6 100644
--- a/backend/src/plugins/Reminders/commands/RemindersDeleteCmd.ts
+++ b/backend/src/plugins/Reminders/commands/RemindersDeleteCmd.ts
@@ -1,9 +1,9 @@
-import { remindersCommand } from "../types";
-import { sendErrorMessage, sendSuccessMessage } from "src/pluginUtils";
-import { sorter } from "src/utils";
+import { remindersCmd } from "../types";
+import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
+import { sorter } from "../../../utils";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 
-export const RemindersDeleteCmd = remindersCommand({
+export const RemindersDeleteCmd = remindersCmd({
   trigger: ["reminders delete", "reminders d"],
   permission: "can_use",
 
diff --git a/backend/src/plugins/Reminders/types.ts b/backend/src/plugins/Reminders/types.ts
index 8154e6a2..9a3efa9d 100644
--- a/backend/src/plugins/Reminders/types.ts
+++ b/backend/src/plugins/Reminders/types.ts
@@ -1,6 +1,6 @@
 import * as t from "io-ts";
-import { BasePluginType, command } from "knub";
-import { GuildReminders } from "src/data/GuildReminders";
+import { BasePluginType, guildCommand } from "knub";
+import { GuildReminders } from "../../data/GuildReminders";
 
 export const ConfigSchema = t.type({
   can_use: t.boolean,
@@ -19,4 +19,4 @@ export interface RemindersPluginType extends BasePluginType {
   };
 }
 
-export const remindersCommand = command<RemindersPluginType>();
+export const remindersCmd = guildCommand<RemindersPluginType>();
diff --git a/backend/src/plugins/Reminders/utils/postDueRemindersLoop.ts b/backend/src/plugins/Reminders/utils/postDueRemindersLoop.ts
index b4d972a6..cc774436 100644
--- a/backend/src/plugins/Reminders/utils/postDueRemindersLoop.ts
+++ b/backend/src/plugins/Reminders/utils/postDueRemindersLoop.ts
@@ -1,15 +1,15 @@
 import { TextChannel } from "eris";
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { RemindersPluginType } from "../types";
 import moment from "moment-timezone";
 import humanizeDuration from "humanize-duration";
 import { disableLinkPreviews } from "knub/dist/helpers";
-import { SECONDS } from "src/utils";
+import { SECONDS } from "../../../utils";
 
 const REMINDER_LOOP_TIME = 10 * SECONDS;
 const MAX_TRIES = 3;
 
-export async function postDueRemindersLoop(pluginData: PluginData<RemindersPluginType>) {
+export async function postDueRemindersLoop(pluginData: GuildPluginData<RemindersPluginType>) {
   const pendingReminders = await pluginData.state.reminders.getDueReminders();
   for (const reminder of pendingReminders) {
     const channel = pluginData.guild.channels.get(reminder.channel_id);
diff --git a/backend/src/plugins/Roles/RolesPlugin.ts b/backend/src/plugins/Roles/RolesPlugin.ts
index 59dbfa6e..050797a5 100644
--- a/backend/src/plugins/Roles/RolesPlugin.ts
+++ b/backend/src/plugins/Roles/RolesPlugin.ts
@@ -1,7 +1,7 @@
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
+import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
 import { PluginOptions } from "knub";
 import { ConfigSchema, RolesPluginType } from "./types";
-import { GuildLogs } from "src/data/GuildLogs";
+import { GuildLogs } from "../../data/GuildLogs";
 import { AddRoleCmd } from "./commands/AddRoleCmd";
 import { RemoveRoleCmd } from "./commands/RemoveRoleCmd";
 import { MassAddRoleCmd } from "./commands/MassAddRoleCmd";
@@ -30,7 +30,7 @@ const defaultOptions: PluginOptions<RolesPluginType> = {
   ],
 };
 
-export const RolesPlugin = zeppelinPlugin<RolesPluginType>()("roles", {
+export const RolesPlugin = zeppelinGuildPlugin<RolesPluginType>()("roles", {
   showInDocs: true,
   info: {
     prettyName: "Roles",
diff --git a/backend/src/plugins/Roles/commands/AddRoleCmd.ts b/backend/src/plugins/Roles/commands/AddRoleCmd.ts
index 76a43e1e..a17042c9 100644
--- a/backend/src/plugins/Roles/commands/AddRoleCmd.ts
+++ b/backend/src/plugins/Roles/commands/AddRoleCmd.ts
@@ -1,8 +1,8 @@
 import { commandTypeHelpers as ct } from "../../../commandTypes";
-import { sendErrorMessage, sendSuccessMessage, canActOn } from "src/pluginUtils";
+import { sendErrorMessage, sendSuccessMessage, canActOn } from "../../../pluginUtils";
 import { rolesCmd } from "../types";
-import { resolveRoleId, stripObjectToScalars, verboseUserMention } from "src/utils";
-import { LogType } from "src/data/LogType";
+import { resolveRoleId, stripObjectToScalars, verboseUserMention } from "../../../utils";
+import { LogType } from "../../../data/LogType";
 import { GuildChannel } from "eris";
 
 export const AddRoleCmd = rolesCmd({
diff --git a/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts b/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts
index d916ea10..a4bb8f48 100644
--- a/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts
+++ b/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts
@@ -1,9 +1,9 @@
 import { commandTypeHelpers as ct } from "../../../commandTypes";
-import { sendErrorMessage, canActOn } from "src/pluginUtils";
+import { sendErrorMessage, canActOn } from "../../../pluginUtils";
 import { rolesCmd } from "../types";
-import { resolveMember, resolveRoleId, stripObjectToScalars, successMessage } from "src/utils";
-import { LogType } from "src/data/LogType";
-import { logger } from "src/logger";
+import { resolveMember, resolveRoleId, stripObjectToScalars, successMessage } from "../../../utils";
+import { LogType } from "../../../data/LogType";
+import { logger } from "../../../logger";
 
 export const MassAddRoleCmd = rolesCmd({
   trigger: "massaddrole",
diff --git a/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts b/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts
index e88115ae..c4009b59 100644
--- a/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts
+++ b/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts
@@ -1,9 +1,9 @@
 import { commandTypeHelpers as ct } from "../../../commandTypes";
-import { sendErrorMessage, canActOn } from "src/pluginUtils";
+import { sendErrorMessage, canActOn } from "../../../pluginUtils";
 import { rolesCmd } from "../types";
-import { resolveMember, stripObjectToScalars, successMessage, resolveRoleId } from "src/utils";
-import { LogType } from "src/data/LogType";
-import { logger } from "src/logger";
+import { resolveMember, stripObjectToScalars, successMessage, resolveRoleId } from "../../../utils";
+import { LogType } from "../../../data/LogType";
+import { logger } from "../../../logger";
 
 export const MassRemoveRoleCmd = rolesCmd({
   trigger: "massremoverole",
diff --git a/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts b/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts
index a34298c7..f3af983b 100644
--- a/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts
+++ b/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts
@@ -1,9 +1,9 @@
 import { commandTypeHelpers as ct } from "../../../commandTypes";
-import { sendErrorMessage, sendSuccessMessage, canActOn } from "src/pluginUtils";
+import { sendErrorMessage, sendSuccessMessage, canActOn } from "../../../pluginUtils";
 import { rolesCmd } from "../types";
 import { GuildChannel } from "eris";
-import { LogType } from "src/data/LogType";
-import { stripObjectToScalars, verboseUserMention, resolveRoleId } from "src/utils";
+import { LogType } from "../../../data/LogType";
+import { stripObjectToScalars, verboseUserMention, resolveRoleId } from "../../../utils";
 
 export const RemoveRoleCmd = rolesCmd({
   trigger: "removerole",
diff --git a/backend/src/plugins/Roles/types.ts b/backend/src/plugins/Roles/types.ts
index fa86518f..e7f12e11 100644
--- a/backend/src/plugins/Roles/types.ts
+++ b/backend/src/plugins/Roles/types.ts
@@ -1,6 +1,6 @@
 import * as t from "io-ts";
-import { BasePluginType, eventListener, command } from "knub";
-import { GuildLogs } from "src/data/GuildLogs";
+import { BasePluginType, guildCommand } from "knub";
+import { GuildLogs } from "../../data/GuildLogs";
 
 export const ConfigSchema = t.type({
   can_assign: t.boolean,
@@ -16,4 +16,4 @@ export interface RolesPluginType extends BasePluginType {
   };
 }
 
-export const rolesCmd = command<RolesPluginType>();
+export const rolesCmd = guildCommand<RolesPluginType>();
diff --git a/backend/src/plugins/SelfGrantableRoles/SelfGrantableRolesPlugin.ts b/backend/src/plugins/SelfGrantableRoles/SelfGrantableRolesPlugin.ts
index 58cc05da..9b1e5b2c 100644
--- a/backend/src/plugins/SelfGrantableRoles/SelfGrantableRolesPlugin.ts
+++ b/backend/src/plugins/SelfGrantableRoles/SelfGrantableRolesPlugin.ts
@@ -1,7 +1,7 @@
 import { CooldownManager, PluginOptions } from "knub";
 import { SelfGrantableRolesPluginType, ConfigSchema, defaultSelfGrantableRoleEntry } from "./types";
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
-import { trimPluginDescription } from "src/utils";
+import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
+import { trimPluginDescription } from "../../utils";
 import { RoleAddCmd } from "./commands/RoleAddCmd";
 import { RoleRemoveCmd } from "./commands/RoleRemoveCmd";
 import { RoleHelpCmd } from "./commands/RoleHelpCmd";
@@ -13,7 +13,7 @@ const defaultOptions: PluginOptions<SelfGrantableRolesPluginType> = {
   },
 };
 
-export const SelfGrantableRolesPlugin = zeppelinPlugin<SelfGrantableRolesPluginType>()("self_grantable_roles", {
+export const SelfGrantableRolesPlugin = zeppelinGuildPlugin<SelfGrantableRolesPluginType>()("self_grantable_roles", {
   showInDocs: true,
 
   configSchema: ConfigSchema,
diff --git a/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts b/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts
index 411e266f..7aa26fa2 100644
--- a/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts
+++ b/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts
@@ -1,7 +1,7 @@
 import { selfGrantableRolesCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { getApplyingEntries } from "../util/getApplyingEntries";
-import { sendErrorMessage, sendSuccessMessage } from "src/pluginUtils";
+import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
 import { splitRoleNames } from "../util/splitRoleNames";
 import { normalizeRoleNames } from "../util/normalizeRoleNames";
 import { findMatchingRoles } from "../util/findMatchingRoles";
diff --git a/backend/src/plugins/SelfGrantableRoles/commands/RoleHelpCmd.ts b/backend/src/plugins/SelfGrantableRoles/commands/RoleHelpCmd.ts
index 388ac618..5bd35283 100644
--- a/backend/src/plugins/SelfGrantableRoles/commands/RoleHelpCmd.ts
+++ b/backend/src/plugins/SelfGrantableRoles/commands/RoleHelpCmd.ts
@@ -1,5 +1,5 @@
 import { selfGrantableRolesCmd } from "../types";
-import { asSingleLine, trimLines } from "src/utils";
+import { asSingleLine, trimLines } from "../../../utils";
 import { getApplyingEntries } from "../util/getApplyingEntries";
 
 export const RoleHelpCmd = selfGrantableRolesCmd({
@@ -19,7 +19,7 @@ export const RoleHelpCmd = selfGrantableRolesCmd({
       }
     }
 
-    const prefix = pluginData.guildConfig.prefix;
+    const prefix = pluginData.fullConfig.prefix;
     const [firstRole, secondRole] = allPrimaryAliases;
 
     const help1 = asSingleLine(`
diff --git a/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts b/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts
index e41a8bc8..af0b8bc5 100644
--- a/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts
+++ b/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts
@@ -1,7 +1,7 @@
 import { selfGrantableRolesCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { getApplyingEntries } from "../util/getApplyingEntries";
-import { sendErrorMessage, sendSuccessMessage } from "src/pluginUtils";
+import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
 import { splitRoleNames } from "../util/splitRoleNames";
 import { normalizeRoleNames } from "../util/normalizeRoleNames";
 import { findMatchingRoles } from "../util/findMatchingRoles";
diff --git a/backend/src/plugins/SelfGrantableRoles/types.ts b/backend/src/plugins/SelfGrantableRoles/types.ts
index 825b1498..eabcd941 100644
--- a/backend/src/plugins/SelfGrantableRoles/types.ts
+++ b/backend/src/plugins/SelfGrantableRoles/types.ts
@@ -1,5 +1,5 @@
 import * as t from "io-ts";
-import { BasePluginType, command, CooldownManager } from "knub";
+import { BasePluginType, guildCommand, CooldownManager } from "knub";
 
 const RoleMap = t.record(t.string, t.array(t.string));
 
@@ -31,4 +31,4 @@ export interface SelfGrantableRolesPluginType extends BasePluginType {
   };
 }
 
-export const selfGrantableRolesCmd = command<SelfGrantableRolesPluginType>();
+export const selfGrantableRolesCmd = guildCommand<SelfGrantableRolesPluginType>();
diff --git a/backend/src/plugins/SelfGrantableRoles/util/findMatchingRoles.ts b/backend/src/plugins/SelfGrantableRoles/util/findMatchingRoles.ts
index eec62a07..69daae02 100644
--- a/backend/src/plugins/SelfGrantableRoles/util/findMatchingRoles.ts
+++ b/backend/src/plugins/SelfGrantableRoles/util/findMatchingRoles.ts
@@ -1,6 +1,6 @@
 import { TSelfGrantableRoleEntry } from "../types";
 
-export function findMatchingRoles(roleNames, entries: TSelfGrantableRoleEntry[]): string[] {
+export function findMatchingRoles(roleNames: string[], entries: TSelfGrantableRoleEntry[]): string[] {
   const aliasToRoleId = entries.reduce((map, entry) => {
     for (const [roleId, aliases] of Object.entries(entry.roles)) {
       for (const alias of aliases) {
diff --git a/backend/src/plugins/SelfGrantableRoles/util/getApplyingEntries.ts b/backend/src/plugins/SelfGrantableRoles/util/getApplyingEntries.ts
index 39860bc9..d921002d 100644
--- a/backend/src/plugins/SelfGrantableRoles/util/getApplyingEntries.ts
+++ b/backend/src/plugins/SelfGrantableRoles/util/getApplyingEntries.ts
@@ -1,8 +1,8 @@
 import { TSelfGrantableRoleEntry, SelfGrantableRolesPluginType } from "../types";
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 
 export function getApplyingEntries(
-  pluginData: PluginData<SelfGrantableRolesPluginType>,
+  pluginData: GuildPluginData<SelfGrantableRolesPluginType>,
   msg,
 ): TSelfGrantableRoleEntry[] {
   const config = pluginData.config.getForMessage(msg);
diff --git a/backend/src/plugins/Slowmode/SlowmodePlugin.ts b/backend/src/plugins/Slowmode/SlowmodePlugin.ts
index 49405c42..1983a6a7 100644
--- a/backend/src/plugins/Slowmode/SlowmodePlugin.ts
+++ b/backend/src/plugins/Slowmode/SlowmodePlugin.ts
@@ -1,10 +1,10 @@
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
+import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
 import { PluginOptions } from "knub";
 import { ConfigSchema, SlowmodePluginType } from "./types";
-import { GuildSlowmodes } from "src/data/GuildSlowmodes";
-import { GuildSavedMessages } from "src/data/GuildSavedMessages";
-import { GuildLogs } from "src/data/GuildLogs";
-import { SECONDS } from "src/utils";
+import { GuildSlowmodes } from "../../data/GuildSlowmodes";
+import { GuildSavedMessages } from "../../data/GuildSavedMessages";
+import { GuildLogs } from "../../data/GuildLogs";
+import { SECONDS } from "../../utils";
 import { onMessageCreate } from "./util/onMessageCreate";
 import { clearExpiredSlowmodes } from "./util/clearExpiredSlowmodes";
 import { SlowmodeDisableCmd } from "./commands/SlowmodeDisableCmd";
@@ -35,7 +35,7 @@ const defaultOptions: PluginOptions<SlowmodePluginType> = {
   ],
 };
 
-export const SlowmodePlugin = zeppelinPlugin<SlowmodePluginType>()("slowmode", {
+export const SlowmodePlugin = zeppelinGuildPlugin<SlowmodePluginType>()("slowmode", {
   showInDocs: true,
   info: {
     prettyName: "Slowmode",
diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts
index 31eacfb5..5f1a4b15 100644
--- a/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts
+++ b/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts
@@ -1,5 +1,5 @@
 import { commandTypeHelpers as ct } from "../../../commandTypes";
-import { sendErrorMessage, sendSuccessMessage } from "src/pluginUtils";
+import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
 import { slowmodeCmd } from "../types";
 import { clearBotSlowmodeFromUserId } from "../util/clearBotSlowmodeFromUserId";
 import { asSingleLine, disableInlineCode } from "../../../utils";
diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeListCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeListCmd.ts
index 422cb503..136ff277 100644
--- a/backend/src/plugins/Slowmode/commands/SlowmodeListCmd.ts
+++ b/backend/src/plugins/Slowmode/commands/SlowmodeListCmd.ts
@@ -1,7 +1,7 @@
 import { slowmodeCmd } from "../types";
 import { GuildChannel, TextChannel } from "eris";
 import { createChunkedMessage } from "knub/dist/helpers";
-import { errorMessage } from "src/utils";
+import { errorMessage } from "../../../utils";
 import humanizeDuration from "humanize-duration";
 
 export const SlowmodeListCmd = slowmodeCmd({
diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts
index d79fcea5..1da1dc29 100644
--- a/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts
+++ b/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts
@@ -2,8 +2,8 @@ import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { slowmodeCmd } from "../types";
 import { TextChannel } from "eris";
 import humanizeDuration from "humanize-duration";
-import { sendErrorMessage, sendSuccessMessage } from "src/pluginUtils";
-import { asSingleLine, DAYS, disableInlineCode, HOURS, MINUTES } from "src/utils";
+import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
+import { asSingleLine, DAYS, disableInlineCode, HOURS, MINUTES } from "../../../utils";
 import { disableBotSlowmodeForChannel } from "../util/disableBotSlowmodeForChannel";
 import { actualDisableSlowmodeCmd } from "../util/actualDisableSlowmodeCmd";
 import { getMissingPermissions } from "../../../utils/getMissingPermissions";
diff --git a/backend/src/plugins/Slowmode/types.ts b/backend/src/plugins/Slowmode/types.ts
index 9f37e67d..7855dd0f 100644
--- a/backend/src/plugins/Slowmode/types.ts
+++ b/backend/src/plugins/Slowmode/types.ts
@@ -1,8 +1,8 @@
 import * as t from "io-ts";
-import { BasePluginType, command, eventListener } from "knub";
-import { GuildSlowmodes } from "src/data/GuildSlowmodes";
-import { GuildSavedMessages } from "src/data/GuildSavedMessages";
-import { GuildLogs } from "src/data/GuildLogs";
+import { BasePluginType, guildCommand, guildEventListener } from "knub";
+import { GuildSlowmodes } from "../../data/GuildSlowmodes";
+import { GuildSavedMessages } from "../../data/GuildSavedMessages";
+import { GuildLogs } from "../../data/GuildLogs";
 
 export const ConfigSchema = t.type({
   use_native_slowmode: t.boolean,
@@ -24,5 +24,5 @@ export interface SlowmodePluginType extends BasePluginType {
   };
 }
 
-export const slowmodeCmd = command<SlowmodePluginType>();
-export const slowmodeEvt = eventListener<SlowmodePluginType>();
+export const slowmodeCmd = guildCommand<SlowmodePluginType>();
+export const slowmodeEvt = guildEventListener<SlowmodePluginType>();
diff --git a/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts b/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts
index 607e9c0d..f8abccc8 100644
--- a/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts
+++ b/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts
@@ -1,7 +1,7 @@
 import { Message } from "eris";
-import { sendErrorMessage, sendSuccessMessage } from "src/pluginUtils";
+import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
 import { disableBotSlowmodeForChannel } from "./disableBotSlowmodeForChannel";
-import { noop } from "src/utils";
+import { noop } from "../../../utils";
 import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions";
 import { BOT_SLOWMODE_DISABLE_PERMISSIONS } from "../requiredPermissions";
 import { missingPermissionError } from "../../../utils/missingPermissionError";
diff --git a/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts b/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts
index 300998bd..1e6510c5 100644
--- a/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts
+++ b/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts
@@ -1,12 +1,12 @@
 import { SlowmodePluginType } from "../types";
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { Constants, GuildChannel, TextChannel } from "eris";
-import { isDiscordRESTError, stripObjectToScalars, UnknownUser } from "src/utils";
-import { LogType } from "src/data/LogType";
-import { logger } from "src/logger";
+import { isDiscordRESTError, stripObjectToScalars, UnknownUser } from "../../../utils";
+import { LogType } from "../../../data/LogType";
+import { logger } from "../../../logger";
 
 export async function applyBotSlowmodeToUserId(
-  pluginData: PluginData<SlowmodePluginType>,
+  pluginData: GuildPluginData<SlowmodePluginType>,
   channel: GuildChannel & TextChannel,
   userId: string,
 ) {
diff --git a/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts b/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts
index dcde2322..7a33d4aa 100644
--- a/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts
+++ b/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts
@@ -1,9 +1,9 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { SlowmodePluginType } from "../types";
 import { GuildChannel, TextChannel } from "eris";
 
 export async function clearBotSlowmodeFromUserId(
-  pluginData: PluginData<SlowmodePluginType>,
+  pluginData: GuildPluginData<SlowmodePluginType>,
   channel: GuildChannel & TextChannel,
   userId: string,
   force = false,
diff --git a/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts b/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts
index 01cb95c1..5bf650c2 100644
--- a/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts
+++ b/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts
@@ -1,12 +1,12 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { SlowmodePluginType } from "../types";
-import { LogType } from "src/data/LogType";
-import { logger } from "src/logger";
+import { LogType } from "../../../data/LogType";
+import { logger } from "../../../logger";
 import { GuildChannel, TextChannel } from "eris";
-import { stripObjectToScalars, UnknownUser } from "src/utils";
+import { stripObjectToScalars, UnknownUser } from "../../../utils";
 import { clearBotSlowmodeFromUserId } from "./clearBotSlowmodeFromUserId";
 
-export async function clearExpiredSlowmodes(pluginData: PluginData<SlowmodePluginType>) {
+export async function clearExpiredSlowmodes(pluginData: GuildPluginData<SlowmodePluginType>) {
   const expiredSlowmodeUsers = await pluginData.state.slowmodes.getExpiredSlowmodeUsers();
   for (const user of expiredSlowmodeUsers) {
     const channel = pluginData.guild.channels.get(user.channel_id);
diff --git a/backend/src/plugins/Slowmode/util/disableBotSlowmodeForChannel.ts b/backend/src/plugins/Slowmode/util/disableBotSlowmodeForChannel.ts
index f505a9c1..a52b9ab8 100644
--- a/backend/src/plugins/Slowmode/util/disableBotSlowmodeForChannel.ts
+++ b/backend/src/plugins/Slowmode/util/disableBotSlowmodeForChannel.ts
@@ -1,10 +1,10 @@
 import { GuildChannel, TextChannel } from "eris";
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { SlowmodePluginType } from "../types";
 import { clearBotSlowmodeFromUserId } from "./clearBotSlowmodeFromUserId";
 
 export async function disableBotSlowmodeForChannel(
-  pluginData: PluginData<SlowmodePluginType>,
+  pluginData: GuildPluginData<SlowmodePluginType>,
   channel: GuildChannel & TextChannel,
 ) {
   // Disable channel slowmode
diff --git a/backend/src/plugins/Slowmode/util/onMessageCreate.ts b/backend/src/plugins/Slowmode/util/onMessageCreate.ts
index 81e9799f..1500e614 100644
--- a/backend/src/plugins/Slowmode/util/onMessageCreate.ts
+++ b/backend/src/plugins/Slowmode/util/onMessageCreate.ts
@@ -1,17 +1,17 @@
-import { SavedMessage } from "src/data/entities/SavedMessage";
+import { SavedMessage } from "../../../data/entities/SavedMessage";
 import { TextChannel } from "eris";
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { SlowmodePluginType } from "../types";
-import { resolveMember } from "src/utils";
+import { resolveMember } from "../../../utils";
 import { applyBotSlowmodeToUserId } from "./applyBotSlowmodeToUserId";
-import { hasPermission } from "src/pluginUtils";
+import { hasPermission } from "../../../pluginUtils";
 import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions";
 import { BOT_SLOWMODE_PERMISSIONS } from "../requiredPermissions";
 import { LogsPlugin } from "../../Logs/LogsPlugin";
 import { LogType } from "../../../data/LogType";
 import { missingPermissionError } from "../../../utils/missingPermissionError";
 
-export async function onMessageCreate(pluginData: PluginData<SlowmodePluginType>, msg: SavedMessage) {
+export async function onMessageCreate(pluginData: GuildPluginData<SlowmodePluginType>, msg: SavedMessage) {
   if (msg.is_bot) return;
 
   const channel = pluginData.guild.channels.get(msg.channel_id) as TextChannel;
diff --git a/backend/src/plugins/Spam/SpamPlugin.ts b/backend/src/plugins/Spam/SpamPlugin.ts
index 31abb3fb..a09261bd 100644
--- a/backend/src/plugins/Spam/SpamPlugin.ts
+++ b/backend/src/plugins/Spam/SpamPlugin.ts
@@ -1,10 +1,10 @@
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
+import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
 import { PluginOptions } from "knub";
 import { ConfigSchema, SpamPluginType } from "./types";
-import { GuildLogs } from "src/data/GuildLogs";
-import { GuildArchives } from "src/data/GuildArchives";
-import { GuildSavedMessages } from "src/data/GuildSavedMessages";
-import { GuildMutes } from "src/data/GuildMutes";
+import { GuildLogs } from "../../data/GuildLogs";
+import { GuildArchives } from "../../data/GuildArchives";
+import { GuildSavedMessages } from "../../data/GuildSavedMessages";
+import { GuildMutes } from "../../data/GuildMutes";
 import { onMessageCreate } from "./util/onMessageCreate";
 import { clearOldRecentActions } from "./util/clearOldRecentActions";
 import { SpamVoiceJoinEvt, SpamVoiceSwitchEvt } from "./events/SpamVoiceEvt";
@@ -42,7 +42,7 @@ const defaultOptions: PluginOptions<SpamPluginType> = {
   ],
 };
 
-export const SpamPlugin = zeppelinPlugin<SpamPluginType>()("spam", {
+export const SpamPlugin = zeppelinGuildPlugin<SpamPluginType>()("spam", {
   showInDocs: true,
   info: {
     prettyName: "Spam protection",
diff --git a/backend/src/plugins/Spam/events/SpamVoiceEvt.ts b/backend/src/plugins/Spam/events/SpamVoiceEvt.ts
index 207bcbf5..bd537d39 100644
--- a/backend/src/plugins/Spam/events/SpamVoiceEvt.ts
+++ b/backend/src/plugins/Spam/events/SpamVoiceEvt.ts
@@ -1,7 +1,7 @@
-import { spamEvent, RecentActionType } from "../types";
+import { spamEvt, RecentActionType } from "../types";
 import { logAndDetectOtherSpam } from "../util/logAndDetectOtherSpam";
 
-export const SpamVoiceJoinEvt = spamEvent({
+export const SpamVoiceJoinEvt = spamEvt({
   event: "voiceChannelJoin",
 
   async listener(meta) {
@@ -26,7 +26,7 @@ export const SpamVoiceJoinEvt = spamEvent({
   },
 });
 
-export const SpamVoiceSwitchEvt = spamEvent({
+export const SpamVoiceSwitchEvt = spamEvt({
   event: "voiceChannelSwitch",
 
   async listener(meta) {
diff --git a/backend/src/plugins/Spam/types.ts b/backend/src/plugins/Spam/types.ts
index 67964e35..127a1e2c 100644
--- a/backend/src/plugins/Spam/types.ts
+++ b/backend/src/plugins/Spam/types.ts
@@ -1,10 +1,10 @@
 import * as t from "io-ts";
-import { BasePluginType, eventListener } from "knub";
-import { tNullable } from "src/utils";
-import { GuildLogs } from "src/data/GuildLogs";
-import { GuildArchives } from "src/data/GuildArchives";
-import { GuildSavedMessages } from "src/data/GuildSavedMessages";
-import { GuildMutes } from "src/data/GuildMutes";
+import { BasePluginType, guildEventListener } from "knub";
+import { tNullable } from "../../utils";
+import { GuildLogs } from "../../data/GuildLogs";
+import { GuildArchives } from "../../data/GuildArchives";
+import { GuildSavedMessages } from "../../data/GuildSavedMessages";
+import { GuildMutes } from "../../data/GuildMutes";
 
 const BaseSingleSpamConfig = t.type({
   interval: t.number,
@@ -75,4 +75,4 @@ export interface SpamPluginType extends BasePluginType {
   };
 }
 
-export const spamEvent = eventListener<SpamPluginType>();
+export const spamEvt = guildEventListener<SpamPluginType>();
diff --git a/backend/src/plugins/Spam/util/addRecentAction.ts b/backend/src/plugins/Spam/util/addRecentAction.ts
index d545e9ce..ec9e1261 100644
--- a/backend/src/plugins/Spam/util/addRecentAction.ts
+++ b/backend/src/plugins/Spam/util/addRecentAction.ts
@@ -1,8 +1,8 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { SpamPluginType, RecentActionType } from "../types";
 
 export function addRecentAction(
-  pluginData: PluginData<SpamPluginType>,
+  pluginData: GuildPluginData<SpamPluginType>,
   type: RecentActionType,
   userId: string,
   actionGroupId: string,
diff --git a/backend/src/plugins/Spam/util/clearOldRecentActions.ts b/backend/src/plugins/Spam/util/clearOldRecentActions.ts
index 6e3a1d24..4f42211c 100644
--- a/backend/src/plugins/Spam/util/clearOldRecentActions.ts
+++ b/backend/src/plugins/Spam/util/clearOldRecentActions.ts
@@ -1,6 +1,9 @@
+import { GuildPluginData } from "knub";
+import { SpamPluginType } from "../types";
+
 const MAX_INTERVAL = 300;
 
-export function clearOldRecentActions(pluginData) {
+export function clearOldRecentActions(pluginData: GuildPluginData<SpamPluginType>) {
   // TODO: Figure out expiry time from longest interval in the config?
   const expiryTimestamp = Date.now() - 1000 * MAX_INTERVAL;
   pluginData.state.recentActions = pluginData.state.recentActions.filter(action => action.timestamp >= expiryTimestamp);
diff --git a/backend/src/plugins/Spam/util/clearRecentUserActions.ts b/backend/src/plugins/Spam/util/clearRecentUserActions.ts
index f52730cf..839ac107 100644
--- a/backend/src/plugins/Spam/util/clearRecentUserActions.ts
+++ b/backend/src/plugins/Spam/util/clearRecentUserActions.ts
@@ -1,6 +1,12 @@
-import { RecentActionType } from "../types";
+import { RecentActionType, SpamPluginType } from "../types";
+import { GuildPluginData } from "knub";
 
-export function clearRecentUserActions(pluginData, type: RecentActionType, userId: string, actionGroupId: string) {
+export function clearRecentUserActions(
+  pluginData: GuildPluginData<SpamPluginType>,
+  type: RecentActionType,
+  userId: string,
+  actionGroupId: string,
+) {
   pluginData.state.recentActions = pluginData.state.recentActions.filter(action => {
     return action.type !== type || action.userId !== userId || action.actionGroupId !== actionGroupId;
   });
diff --git a/backend/src/plugins/Spam/util/getRecentActionCount.ts b/backend/src/plugins/Spam/util/getRecentActionCount.ts
index 776a0ab5..fc0c898a 100644
--- a/backend/src/plugins/Spam/util/getRecentActionCount.ts
+++ b/backend/src/plugins/Spam/util/getRecentActionCount.ts
@@ -1,7 +1,8 @@
-import { RecentActionType } from "../types";
+import { RecentActionType, SpamPluginType } from "../types";
+import { GuildPluginData } from "knub";
 
 export function getRecentActionCount(
-  pluginData,
+  pluginData: GuildPluginData<SpamPluginType>,
   type: RecentActionType,
   userId: string,
   actionGroupId: string,
diff --git a/backend/src/plugins/Spam/util/getRecentActions.ts b/backend/src/plugins/Spam/util/getRecentActions.ts
index bc74d016..765a1300 100644
--- a/backend/src/plugins/Spam/util/getRecentActions.ts
+++ b/backend/src/plugins/Spam/util/getRecentActions.ts
@@ -1,7 +1,8 @@
-import { RecentActionType } from "../types";
+import { RecentActionType, SpamPluginType } from "../types";
+import { GuildPluginData } from "knub";
 
 export function getRecentActions(
-  pluginData,
+  pluginData: GuildPluginData<SpamPluginType>,
   type: RecentActionType,
   userId: string,
   actionGroupId: string,
diff --git a/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts b/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts
index 4979d3c7..9b039ef8 100644
--- a/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts
+++ b/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts
@@ -1,14 +1,21 @@
-import { SavedMessage } from "src/data/entities/SavedMessage";
+import { SavedMessage } from "../../../data/entities/SavedMessage";
 import { RecentActionType, SpamPluginType, TBaseSingleSpamConfig } from "../types";
 import moment from "moment-timezone";
-import { MuteResult } from "src/plugins/Mutes/types";
-import { convertDelayStringToMS, DBDateFormat, noop, resolveMember, stripObjectToScalars, trimLines } from "src/utils";
-import { LogType } from "src/data/LogType";
-import { CaseTypes } from "src/data/CaseTypes";
-import { logger } from "src/logger";
-import { PluginData } from "knub";
-import { MutesPlugin } from "src/plugins/Mutes/MutesPlugin";
-import { CasesPlugin } from "src/plugins/Cases/CasesPlugin";
+import { MuteResult } from "../../../plugins/Mutes/types";
+import {
+  convertDelayStringToMS,
+  DBDateFormat,
+  noop,
+  resolveMember,
+  stripObjectToScalars,
+  trimLines,
+} from "../../../utils";
+import { LogType } from "../../../data/LogType";
+import { CaseTypes } from "../../../data/CaseTypes";
+import { logger } from "../../../logger";
+import { GuildPluginData } from "knub";
+import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin";
+import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin";
 import { addRecentAction } from "./addRecentAction";
 import { getRecentActionCount } from "./getRecentActionCount";
 import { getRecentActions } from "./getRecentActions";
@@ -18,7 +25,7 @@ import { LogsPlugin } from "../../Logs/LogsPlugin";
 import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError";
 
 export async function logAndDetectMessageSpam(
-  pluginData: PluginData<SpamPluginType>,
+  pluginData: GuildPluginData<SpamPluginType>,
   savedMessage: SavedMessage,
   type: RecentActionType,
   spamConfig: TBaseSingleSpamConfig,
diff --git a/backend/src/plugins/Spam/util/logAndDetectOtherSpam.ts b/backend/src/plugins/Spam/util/logAndDetectOtherSpam.ts
index ec44dbc1..471257d4 100644
--- a/backend/src/plugins/Spam/util/logAndDetectOtherSpam.ts
+++ b/backend/src/plugins/Spam/util/logAndDetectOtherSpam.ts
@@ -1,18 +1,18 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { SpamPluginType, RecentActionType } from "../types";
 import { addRecentAction } from "./addRecentAction";
 import { getRecentActionCount } from "./getRecentActionCount";
-import { resolveMember, convertDelayStringToMS, stripObjectToScalars } from "src/utils";
-import { MutesPlugin } from "src/plugins/Mutes/MutesPlugin";
-import { CasesPlugin } from "src/plugins/Cases/CasesPlugin";
-import { CaseTypes } from "src/data/CaseTypes";
+import { resolveMember, convertDelayStringToMS, stripObjectToScalars } from "../../../utils";
+import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin";
+import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin";
+import { CaseTypes } from "../../../data/CaseTypes";
 import { clearRecentUserActions } from "./clearRecentUserActions";
-import { LogType } from "src/data/LogType";
+import { LogType } from "../../../data/LogType";
 import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError";
 import { LogsPlugin } from "../../Logs/LogsPlugin";
 
 export async function logAndDetectOtherSpam(
-  pluginData: PluginData<SpamPluginType>,
+  pluginData: GuildPluginData<SpamPluginType>,
   type: RecentActionType,
   spamConfig: any,
   userId: string,
diff --git a/backend/src/plugins/Spam/util/logCensor.ts b/backend/src/plugins/Spam/util/logCensor.ts
index 8a806120..1d4f1d49 100644
--- a/backend/src/plugins/Spam/util/logCensor.ts
+++ b/backend/src/plugins/Spam/util/logCensor.ts
@@ -1,9 +1,9 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { SpamPluginType, RecentActionType } from "../types";
-import { SavedMessage } from "src/data/entities/SavedMessage";
+import { SavedMessage } from "../../../data/entities/SavedMessage";
 import { logAndDetectMessageSpam } from "./logAndDetectMessageSpam";
 
-export async function logCensor(pluginData: PluginData<SpamPluginType>, savedMessage: SavedMessage) {
+export async function logCensor(pluginData: GuildPluginData<SpamPluginType>, savedMessage: SavedMessage) {
   const member = pluginData.guild.members.get(savedMessage.user_id);
   const config = pluginData.config.getMatchingConfig({
     userId: savedMessage.user_id,
diff --git a/backend/src/plugins/Spam/util/onMessageCreate.ts b/backend/src/plugins/Spam/util/onMessageCreate.ts
index bc6924b0..7a38a617 100644
--- a/backend/src/plugins/Spam/util/onMessageCreate.ts
+++ b/backend/src/plugins/Spam/util/onMessageCreate.ts
@@ -1,10 +1,10 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { SpamPluginType, RecentActionType } from "../types";
-import { SavedMessage } from "src/data/entities/SavedMessage";
-import { getUserMentions, getRoleMentions, getUrlsInString, getEmojiInString } from "src/utils";
+import { SavedMessage } from "../../../data/entities/SavedMessage";
+import { getUserMentions, getRoleMentions, getUrlsInString, getEmojiInString } from "../../../utils";
 import { logAndDetectMessageSpam } from "./logAndDetectMessageSpam";
 
-export async function onMessageCreate(pluginData: PluginData<SpamPluginType>, savedMessage: SavedMessage) {
+export async function onMessageCreate(pluginData: GuildPluginData<SpamPluginType>, savedMessage: SavedMessage) {
   if (savedMessage.is_bot) return;
 
   const member = pluginData.guild.members.get(savedMessage.user_id);
diff --git a/backend/src/plugins/Spam/util/saveSpamArchives.ts b/backend/src/plugins/Spam/util/saveSpamArchives.ts
index 0e2a425e..9a3b3cac 100644
--- a/backend/src/plugins/Spam/util/saveSpamArchives.ts
+++ b/backend/src/plugins/Spam/util/saveSpamArchives.ts
@@ -1,10 +1,12 @@
-import { SavedMessage } from "src/data/entities/SavedMessage";
+import { SavedMessage } from "../../../data/entities/SavedMessage";
 import moment from "moment-timezone";
-import { getBaseUrl } from "src/pluginUtils";
+import { getBaseUrl } from "../../../pluginUtils";
+import { GuildPluginData } from "knub";
+import { SpamPluginType } from "../types";
 
 const SPAM_ARCHIVE_EXPIRY_DAYS = 90;
 
-export async function saveSpamArchives(pluginData, savedMessages: SavedMessage[]) {
+export async function saveSpamArchives(pluginData: GuildPluginData<SpamPluginType>, savedMessages: SavedMessage[]) {
   const expiresAt = moment.utc().add(SPAM_ARCHIVE_EXPIRY_DAYS, "days");
   const archiveId = await pluginData.state.archives.createFromSavedMessages(savedMessages, pluginData.guild, expiresAt);
 
diff --git a/backend/src/plugins/Starboard/StarboardPlugin.ts b/backend/src/plugins/Starboard/StarboardPlugin.ts
index c127d316..f84b8358 100644
--- a/backend/src/plugins/Starboard/StarboardPlugin.ts
+++ b/backend/src/plugins/Starboard/StarboardPlugin.ts
@@ -1,10 +1,10 @@
 import { PluginOptions } from "knub";
 import { ConfigSchema, defaultStarboardOpts, StarboardPluginType } from "./types";
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
-import { trimPluginDescription } from "src/utils";
-import { GuildSavedMessages } from "src/data/GuildSavedMessages";
-import { GuildStarboardMessages } from "src/data/GuildStarboardMessages";
-import { GuildStarboardReactions } from "src/data/GuildStarboardReactions";
+import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
+import { trimPluginDescription } from "../../utils";
+import { GuildSavedMessages } from "../../data/GuildSavedMessages";
+import { GuildStarboardMessages } from "../../data/GuildStarboardMessages";
+import { GuildStarboardReactions } from "../../data/GuildStarboardReactions";
 import { onMessageDelete } from "./util/onMessageDelete";
 import { MigratePinsCmd } from "./commands/MigratePinsCmd";
 import { StarboardReactionAddEvt } from "./events/StarboardReactionAddEvt";
@@ -26,7 +26,7 @@ const defaultOptions: PluginOptions<StarboardPluginType> = {
   ],
 };
 
-export const StarboardPlugin = zeppelinPlugin<StarboardPluginType>()("starboard", {
+export const StarboardPlugin = zeppelinGuildPlugin<StarboardPluginType>()("starboard", {
   showInDocs: true,
 
   configSchema: ConfigSchema,
diff --git a/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts b/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts
index e37155c3..f109150a 100644
--- a/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts
+++ b/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts
@@ -1,6 +1,6 @@
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { starboardCmd } from "../types";
-import { sendSuccessMessage, sendErrorMessage } from "src/pluginUtils";
+import { sendSuccessMessage, sendErrorMessage } from "../../../pluginUtils";
 import { TextChannel } from "eris";
 import { saveMessageToStarboard } from "../util/saveMessageToStarboard";
 
diff --git a/backend/src/plugins/Starboard/events/StarboardReactionAddEvt.ts b/backend/src/plugins/Starboard/events/StarboardReactionAddEvt.ts
index 9635989f..b97e8686 100644
--- a/backend/src/plugins/Starboard/events/StarboardReactionAddEvt.ts
+++ b/backend/src/plugins/Starboard/events/StarboardReactionAddEvt.ts
@@ -1,6 +1,6 @@
 import { starboardEvt } from "../types";
 import { Message, TextChannel } from "eris";
-import { UnknownUser, resolveMember, noop, resolveUser } from "src/utils";
+import { UnknownUser, resolveMember, noop, resolveUser } from "../../../utils";
 import { saveMessageToStarboard } from "../util/saveMessageToStarboard";
 
 export const StarboardReactionAddEvt = starboardEvt({
diff --git a/backend/src/plugins/Starboard/types.ts b/backend/src/plugins/Starboard/types.ts
index 4f382ab8..eb2c3c40 100644
--- a/backend/src/plugins/Starboard/types.ts
+++ b/backend/src/plugins/Starboard/types.ts
@@ -1,9 +1,9 @@
 import * as t from "io-ts";
-import { BasePluginType, command, eventListener } from "knub";
-import { tNullable, tDeepPartial } from "src/utils";
-import { GuildSavedMessages } from "src/data/GuildSavedMessages";
-import { GuildStarboardMessages } from "src/data/GuildStarboardMessages";
-import { GuildStarboardReactions } from "src/data/GuildStarboardReactions";
+import { BasePluginType, guildCommand, guildEventListener } from "knub";
+import { tNullable, tDeepPartial } from "../../utils";
+import { GuildSavedMessages } from "../../data/GuildSavedMessages";
+import { GuildStarboardMessages } from "../../data/GuildStarboardMessages";
+import { GuildStarboardReactions } from "../../data/GuildStarboardReactions";
 
 const StarboardOpts = t.type({
   channel_id: t.string,
@@ -39,5 +39,5 @@ export interface StarboardPluginType extends BasePluginType {
   };
 }
 
-export const starboardCmd = command<StarboardPluginType>();
-export const starboardEvt = eventListener<StarboardPluginType>();
+export const starboardCmd = guildCommand<StarboardPluginType>();
+export const starboardEvt = guildEventListener<StarboardPluginType>();
diff --git a/backend/src/plugins/Starboard/util/onMessageDelete.ts b/backend/src/plugins/Starboard/util/onMessageDelete.ts
index c79e3da8..74477afe 100644
--- a/backend/src/plugins/Starboard/util/onMessageDelete.ts
+++ b/backend/src/plugins/Starboard/util/onMessageDelete.ts
@@ -1,10 +1,10 @@
-import { SavedMessage } from "src/data/entities/SavedMessage";
-import { PluginData } from "knub";
+import { SavedMessage } from "../../../data/entities/SavedMessage";
+import { GuildPluginData } from "knub";
 import { StarboardPluginType } from "../types";
 import { removeMessageFromStarboard } from "./removeMessageFromStarboard";
 import { removeMessageFromStarboardMessages } from "./removeMessageFromStarboardMessages";
 
-export async function onMessageDelete(pluginData: PluginData<StarboardPluginType>, msg: SavedMessage) {
+export async function onMessageDelete(pluginData: GuildPluginData<StarboardPluginType>, msg: SavedMessage) {
   // Deleted source message
   const starboardMessages = await pluginData.state.starboardMessages.getStarboardMessagesForMessageId(msg.id);
   for (const starboardMessage of starboardMessages) {
diff --git a/backend/src/plugins/Starboard/util/removeMessageFromStarboard.ts b/backend/src/plugins/Starboard/util/removeMessageFromStarboard.ts
index 6c790b5d..1a331358 100644
--- a/backend/src/plugins/Starboard/util/removeMessageFromStarboard.ts
+++ b/backend/src/plugins/Starboard/util/removeMessageFromStarboard.ts
@@ -1,5 +1,5 @@
-import { StarboardMessage } from "src/data/entities/StarboardMessage";
-import { noop } from "src/utils";
+import { StarboardMessage } from "../../../data/entities/StarboardMessage";
+import { noop } from "../../../utils";
 
 export async function removeMessageFromStarboard(pluginData, msg: StarboardMessage) {
   await pluginData.client.deleteMessage(msg.starboard_channel_id, msg.starboard_message_id).catch(noop);
diff --git a/backend/src/plugins/Starboard/util/removeMessageFromStarboardMessages.ts b/backend/src/plugins/Starboard/util/removeMessageFromStarboardMessages.ts
index 1d00177d..698b7b09 100644
--- a/backend/src/plugins/Starboard/util/removeMessageFromStarboardMessages.ts
+++ b/backend/src/plugins/Starboard/util/removeMessageFromStarboardMessages.ts
@@ -1,3 +1,10 @@
-export async function removeMessageFromStarboardMessages(pluginData, starboard_message_id: string, channel_id: string) {
+import { GuildPluginData } from "knub";
+import { StarboardPluginType } from "../types";
+
+export async function removeMessageFromStarboardMessages(
+  pluginData: GuildPluginData<StarboardPluginType>,
+  starboard_message_id: string,
+  channel_id: string,
+) {
   await pluginData.state.starboardMessages.deleteStarboardMessage(starboard_message_id, channel_id);
 }
diff --git a/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts b/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts
index 8fc2be24..d098e72d 100644
--- a/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts
+++ b/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts
@@ -1,12 +1,12 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { StarboardPluginType, TStarboardOpts } from "../types";
 import { Message, GuildChannel, TextChannel, Embed } from "eris";
 import moment from "moment-timezone";
-import { EMPTY_CHAR, messageLink } from "src/utils";
+import { EMPTY_CHAR, messageLink } from "../../../utils";
 import path from "path";
 
 export async function saveMessageToStarboard(
-  pluginData: PluginData<StarboardPluginType>,
+  pluginData: GuildPluginData<StarboardPluginType>,
   msg: Message,
   starboard: TStarboardOpts,
 ) {
diff --git a/backend/src/plugins/Tags/TagsPlugin.ts b/backend/src/plugins/Tags/TagsPlugin.ts
index 3ee41bf9..4dc3e32d 100644
--- a/backend/src/plugins/Tags/TagsPlugin.ts
+++ b/backend/src/plugins/Tags/TagsPlugin.ts
@@ -1,10 +1,10 @@
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
+import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
 import { ConfigSchema, TagsPluginType } from "./types";
 import { PluginOptions } from "knub";
-import { GuildArchives } from "src/data/GuildArchives";
-import { GuildTags } from "src/data/GuildTags";
-import { GuildSavedMessages } from "src/data/GuildSavedMessages";
-import { GuildLogs } from "src/data/GuildLogs";
+import { GuildArchives } from "../../data/GuildArchives";
+import { GuildTags } from "../../data/GuildTags";
+import { GuildSavedMessages } from "../../data/GuildSavedMessages";
+import { GuildLogs } from "../../data/GuildLogs";
 import { onMessageCreate } from "./util/onMessageCreate";
 import { onMessageDelete } from "./util/onMessageDelete";
 import { TagCreateCmd } from "./commands/TagCreateCmd";
@@ -48,7 +48,7 @@ const defaultOptions: PluginOptions<TagsPluginType> = {
   ],
 };
 
-export const TagsPlugin = zeppelinPlugin<TagsPluginType>()("tags", {
+export const TagsPlugin = zeppelinGuildPlugin<TagsPluginType>()("tags", {
   showInDocs: true,
   info: {
     prettyName: "Tags",
diff --git a/backend/src/plugins/Tags/commands/TagCreateCmd.ts b/backend/src/plugins/Tags/commands/TagCreateCmd.ts
index 9e828c14..c55a5cab 100644
--- a/backend/src/plugins/Tags/commands/TagCreateCmd.ts
+++ b/backend/src/plugins/Tags/commands/TagCreateCmd.ts
@@ -1,7 +1,7 @@
 import { tagsCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
-import { parseTemplate, TemplateParseError } from "src/templateFormatter";
-import { sendErrorMessage, sendSuccessMessage } from "src/pluginUtils";
+import { parseTemplate, TemplateParseError } from "../../../templateFormatter";
+import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
 
 export const TagCreateCmd = tagsCmd({
   trigger: "tag",
diff --git a/backend/src/plugins/Tags/commands/TagDeleteCmd.ts b/backend/src/plugins/Tags/commands/TagDeleteCmd.ts
index 182867a6..40875d21 100644
--- a/backend/src/plugins/Tags/commands/TagDeleteCmd.ts
+++ b/backend/src/plugins/Tags/commands/TagDeleteCmd.ts
@@ -1,6 +1,6 @@
 import { tagsCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
-import { sendErrorMessage, sendSuccessMessage } from "src/pluginUtils";
+import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
 
 export const TagDeleteCmd = tagsCmd({
   trigger: "tag delete",
diff --git a/backend/src/plugins/Tags/commands/TagSourceCmd.ts b/backend/src/plugins/Tags/commands/TagSourceCmd.ts
index 27fe79e3..ed3fde87 100644
--- a/backend/src/plugins/Tags/commands/TagSourceCmd.ts
+++ b/backend/src/plugins/Tags/commands/TagSourceCmd.ts
@@ -1,6 +1,6 @@
 import { tagsCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
-import { sendErrorMessage, getBaseUrl, sendSuccessMessage } from "src/pluginUtils";
+import { sendErrorMessage, getBaseUrl, sendSuccessMessage } from "../../../pluginUtils";
 import moment from "moment-timezone";
 
 export const TagSourceCmd = tagsCmd({
diff --git a/backend/src/plugins/Tags/types.ts b/backend/src/plugins/Tags/types.ts
index cbbb6f97..f22e0eac 100644
--- a/backend/src/plugins/Tags/types.ts
+++ b/backend/src/plugins/Tags/types.ts
@@ -1,10 +1,10 @@
 import * as t from "io-ts";
-import { BasePluginType, command, eventListener } from "knub";
-import { tNullable, tEmbed } from "src/utils";
-import { GuildArchives } from "src/data/GuildArchives";
-import { GuildTags } from "src/data/GuildTags";
-import { GuildSavedMessages } from "src/data/GuildSavedMessages";
-import { GuildLogs } from "src/data/GuildLogs";
+import { BasePluginType, guildCommand, guildEventListener } from "knub";
+import { tNullable, tEmbed } from "../../utils";
+import { GuildArchives } from "../../data/GuildArchives";
+import { GuildTags } from "../../data/GuildTags";
+import { GuildSavedMessages } from "../../data/GuildSavedMessages";
+import { GuildLogs } from "../../data/GuildLogs";
 
 export const Tag = t.union([t.string, tEmbed]);
 
@@ -55,5 +55,5 @@ export interface TagsPluginType extends BasePluginType {
   };
 }
 
-export const tagsCmd = command<TagsPluginType>();
-export const tagsEvent = eventListener<TagsPluginType>();
+export const tagsCmd = guildCommand<TagsPluginType>();
+export const tagsEvt = guildEventListener<TagsPluginType>();
diff --git a/backend/src/plugins/Tags/util/findTagByName.ts b/backend/src/plugins/Tags/util/findTagByName.ts
index dd48dcca..380e685b 100644
--- a/backend/src/plugins/Tags/util/findTagByName.ts
+++ b/backend/src/plugins/Tags/util/findTagByName.ts
@@ -1,10 +1,10 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { Tag, TagsPluginType } from "../types";
 import { ExtendedMatchParams } from "knub/dist/config/PluginConfigManager";
 import * as t from "io-ts";
 
 export async function findTagByName(
-  pluginData: PluginData<TagsPluginType>,
+  pluginData: GuildPluginData<TagsPluginType>,
   name: string,
   matchParams: ExtendedMatchParams = {},
 ): Promise<t.TypeOf<typeof Tag> | null> {
diff --git a/backend/src/plugins/Tags/util/matchAndRenderTagFromString.ts b/backend/src/plugins/Tags/util/matchAndRenderTagFromString.ts
index 43676a80..cd38124d 100644
--- a/backend/src/plugins/Tags/util/matchAndRenderTagFromString.ts
+++ b/backend/src/plugins/Tags/util/matchAndRenderTagFromString.ts
@@ -1,5 +1,5 @@
 import { ExtendedMatchParams } from "knub/dist/config/PluginConfigManager";
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { TagsPluginType, TTagCategory } from "../types";
 import { renderTagFromString } from "./renderTagFromString";
 import { convertDelayStringToMS, StrictMessageContent } from "../../../utils";
@@ -14,7 +14,7 @@ interface Result {
 }
 
 export async function matchAndRenderTagFromString(
-  pluginData: PluginData<TagsPluginType>,
+  pluginData: GuildPluginData<TagsPluginType>,
   str: string,
   member: Member,
   extraMatchParams: ExtendedMatchParams = {},
diff --git a/backend/src/plugins/Tags/util/onMessageCreate.ts b/backend/src/plugins/Tags/util/onMessageCreate.ts
index 04589cdc..6e62d89d 100644
--- a/backend/src/plugins/Tags/util/onMessageCreate.ts
+++ b/backend/src/plugins/Tags/util/onMessageCreate.ts
@@ -1,13 +1,13 @@
 import { TagsPluginType } from "../types";
-import { SavedMessage } from "src/data/entities/SavedMessage";
-import { PluginData } from "knub";
-import { convertDelayStringToMS, resolveMember, tStrictMessageContent } from "src/utils";
-import { validate } from "src/validatorUtils";
-import { LogType } from "src/data/LogType";
+import { SavedMessage } from "../../../data/entities/SavedMessage";
+import { GuildPluginData } from "knub";
+import { convertDelayStringToMS, resolveMember, tStrictMessageContent } from "../../../utils";
+import { validate } from "../../../validatorUtils";
+import { LogType } from "../../../data/LogType";
 import { TextChannel } from "eris";
 import { matchAndRenderTagFromString } from "./matchAndRenderTagFromString";
 
-export async function onMessageCreate(pluginData: PluginData<TagsPluginType>, msg: SavedMessage) {
+export async function onMessageCreate(pluginData: GuildPluginData<TagsPluginType>, msg: SavedMessage) {
   if (msg.is_bot) return;
   if (!msg.data.content) return;
 
diff --git a/backend/src/plugins/Tags/util/onMessageDelete.ts b/backend/src/plugins/Tags/util/onMessageDelete.ts
index 01719320..ee887444 100644
--- a/backend/src/plugins/Tags/util/onMessageDelete.ts
+++ b/backend/src/plugins/Tags/util/onMessageDelete.ts
@@ -1,9 +1,9 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { TagsPluginType } from "../types";
-import { SavedMessage } from "src/data/entities/SavedMessage";
+import { SavedMessage } from "../../../data/entities/SavedMessage";
 import { TextChannel } from "eris";
 
-export async function onMessageDelete(pluginData: PluginData<TagsPluginType>, msg: SavedMessage) {
+export async function onMessageDelete(pluginData: GuildPluginData<TagsPluginType>, msg: SavedMessage) {
   // Command message was deleted -> delete the response as well
   const commandMsgResponse = await pluginData.state.tags.findResponseByCommandMessageId(msg.id);
   if (commandMsgResponse) {
diff --git a/backend/src/plugins/Tags/util/renderTagBody.ts b/backend/src/plugins/Tags/util/renderTagBody.ts
index e82488a4..a45dab4d 100644
--- a/backend/src/plugins/Tags/util/renderTagBody.ts
+++ b/backend/src/plugins/Tags/util/renderTagBody.ts
@@ -1,5 +1,5 @@
 import { renderTemplate } from "../../../templateFormatter";
-import { PluginData, plugin } from "knub";
+import { GuildPluginData } from "knub";
 import { Tag, TagsPluginType } from "../types";
 import { renderRecursively, StrictMessageContent } from "../../../utils";
 import * as t from "io-ts";
@@ -7,7 +7,7 @@ import { findTagByName } from "./findTagByName";
 import { ExtendedMatchParams } from "knub/dist/config/PluginConfigManager";
 
 export async function renderTagBody(
-  pluginData: PluginData<TagsPluginType>,
+  pluginData: GuildPluginData<TagsPluginType>,
   body: t.TypeOf<typeof Tag>,
   args = [],
   extraData = {},
diff --git a/backend/src/plugins/Tags/util/renderTagFromString.ts b/backend/src/plugins/Tags/util/renderTagFromString.ts
index db75c621..5c9986ac 100644
--- a/backend/src/plugins/Tags/util/renderTagFromString.ts
+++ b/backend/src/plugins/Tags/util/renderTagFromString.ts
@@ -1,17 +1,17 @@
 import { Tag, TagsPluginType } from "../types";
 import { Member } from "eris";
 import * as t from "io-ts";
-import { renderRecursively, StrictMessageContent, stripObjectToScalars } from "src/utils";
+import { renderRecursively, StrictMessageContent, stripObjectToScalars } from "../../../utils";
 import { parseArguments } from "knub-command-manager";
-import { TemplateParseError } from "src/templateFormatter";
-import { PluginData } from "knub";
-import { logger } from "src/logger";
+import { TemplateParseError } from "../../../templateFormatter";
+import { GuildPluginData } from "knub";
+import { logger } from "../../../logger";
 import { LogsPlugin } from "../../Logs/LogsPlugin";
 import { LogType } from "../../../data/LogType";
 import { renderTagBody } from "./renderTagBody";
 
 export async function renderTagFromString(
-  pluginData: PluginData<TagsPluginType>,
+  pluginData: GuildPluginData<TagsPluginType>,
   str: string,
   prefix: string,
   tagName: string,
diff --git a/backend/src/plugins/TimeAndDate/TimeAndDatePlugin.ts b/backend/src/plugins/TimeAndDate/TimeAndDatePlugin.ts
index 1218cf4f..1bff078f 100644
--- a/backend/src/plugins/TimeAndDate/TimeAndDatePlugin.ts
+++ b/backend/src/plugins/TimeAndDate/TimeAndDatePlugin.ts
@@ -1,4 +1,4 @@
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
+import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
 import { ConfigSchema, TimeAndDatePluginType } from "./types";
 import { GuildMemberTimezones } from "../../data/GuildMemberTimezones";
 import { PluginOptions } from "knub";
@@ -32,7 +32,7 @@ const defaultOptions: PluginOptions<TimeAndDatePluginType> = {
   ],
 };
 
-export const TimeAndDatePlugin = zeppelinPlugin<TimeAndDatePluginType>()("time_and_date", {
+export const TimeAndDatePlugin = zeppelinGuildPlugin<TimeAndDatePluginType>()("time_and_date", {
   showInDocs: true,
   info: {
     prettyName: "Time and date",
diff --git a/backend/src/plugins/TimeAndDate/functions/getDateFormat.ts b/backend/src/plugins/TimeAndDate/functions/getDateFormat.ts
index d8e9ab65..d420ab26 100644
--- a/backend/src/plugins/TimeAndDate/functions/getDateFormat.ts
+++ b/backend/src/plugins/TimeAndDate/functions/getDateFormat.ts
@@ -1,6 +1,10 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { defaultDateFormats } from "../defaultDateFormats";
+import { TimeAndDatePluginType } from "../types";
 
-export function getDateFormat(pluginData: PluginData<any>, formatName: keyof typeof defaultDateFormats) {
+export function getDateFormat(
+  pluginData: GuildPluginData<TimeAndDatePluginType>,
+  formatName: keyof typeof defaultDateFormats,
+) {
   return pluginData.config.get().date_formats?.[formatName] || defaultDateFormats[formatName];
 }
diff --git a/backend/src/plugins/TimeAndDate/functions/getGuildTz.ts b/backend/src/plugins/TimeAndDate/functions/getGuildTz.ts
index d619a6fb..ed30d67e 100644
--- a/backend/src/plugins/TimeAndDate/functions/getGuildTz.ts
+++ b/backend/src/plugins/TimeAndDate/functions/getGuildTz.ts
@@ -1,7 +1,7 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { ZeppelinGuildConfig } from "../../../types";
 import { TimeAndDatePluginType } from "../types";
 
-export function getGuildTz(pluginData: PluginData<TimeAndDatePluginType>) {
+export function getGuildTz(pluginData: GuildPluginData<TimeAndDatePluginType>) {
   return pluginData.config.get().timezone;
 }
diff --git a/backend/src/plugins/TimeAndDate/functions/getMemberTz.ts b/backend/src/plugins/TimeAndDate/functions/getMemberTz.ts
index 6f8b1e70..8194a5ba 100644
--- a/backend/src/plugins/TimeAndDate/functions/getMemberTz.ts
+++ b/backend/src/plugins/TimeAndDate/functions/getMemberTz.ts
@@ -1,8 +1,8 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { TimeAndDatePluginType } from "../types";
 import { getGuildTz } from "./getGuildTz";
 
-export async function getMemberTz(pluginData: PluginData<TimeAndDatePluginType>, memberId: string) {
+export async function getMemberTz(pluginData: GuildPluginData<TimeAndDatePluginType>, memberId: string) {
   const memberTz = await pluginData.state.memberTimezones.get(memberId);
   return memberTz?.timezone || getGuildTz(pluginData);
 }
diff --git a/backend/src/plugins/TimeAndDate/functions/inGuildTz.ts b/backend/src/plugins/TimeAndDate/functions/inGuildTz.ts
index 51485d05..118e5789 100644
--- a/backend/src/plugins/TimeAndDate/functions/inGuildTz.ts
+++ b/backend/src/plugins/TimeAndDate/functions/inGuildTz.ts
@@ -1,9 +1,9 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { TimeAndDatePluginType } from "../types";
 import moment from "moment-timezone";
 import { getGuildTz } from "./getGuildTz";
 
-export function inGuildTz(pluginData: PluginData<TimeAndDatePluginType>, input?: moment.Moment | number) {
+export function inGuildTz(pluginData: GuildPluginData<TimeAndDatePluginType>, input?: moment.Moment | number) {
   let momentObj: moment.Moment;
   if (typeof input === "number") {
     momentObj = moment.utc(input, "x");
diff --git a/backend/src/plugins/TimeAndDate/functions/inMemberTz.ts b/backend/src/plugins/TimeAndDate/functions/inMemberTz.ts
index ad082e80..f6adc85a 100644
--- a/backend/src/plugins/TimeAndDate/functions/inMemberTz.ts
+++ b/backend/src/plugins/TimeAndDate/functions/inMemberTz.ts
@@ -1,11 +1,11 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { TimeAndDatePluginType } from "../types";
 import moment from "moment-timezone";
 import { getGuildTz } from "./getGuildTz";
 import { getMemberTz } from "./getMemberTz";
 
 export async function inMemberTz(
-  pluginData: PluginData<TimeAndDatePluginType>,
+  pluginData: GuildPluginData<TimeAndDatePluginType>,
   memberId: string,
   input?: moment.Moment | number,
 ) {
diff --git a/backend/src/plugins/TimeAndDate/types.ts b/backend/src/plugins/TimeAndDate/types.ts
index f38ad34a..50826963 100644
--- a/backend/src/plugins/TimeAndDate/types.ts
+++ b/backend/src/plugins/TimeAndDate/types.ts
@@ -1,6 +1,6 @@
 import * as t from "io-ts";
 import { tNullable, tPartialDictionary } from "../../utils";
-import { BasePluginType, command } from "knub";
+import { BasePluginType, guildCommand } from "knub";
 import { GuildMemberTimezones } from "../../data/GuildMemberTimezones";
 import { tValidTimezone } from "../../utils/tValidTimezone";
 import { defaultDateFormats } from "./defaultDateFormats";
@@ -19,4 +19,4 @@ export interface TimeAndDatePluginType extends BasePluginType {
   };
 }
 
-export const timeAndDateCmd = command<TimeAndDatePluginType>();
+export const timeAndDateCmd = guildCommand<TimeAndDatePluginType>();
diff --git a/backend/src/plugins/UsernameSaver/UsernameSaverPlugin.ts b/backend/src/plugins/UsernameSaver/UsernameSaverPlugin.ts
index eb8dae81..34b8e053 100644
--- a/backend/src/plugins/UsernameSaver/UsernameSaverPlugin.ts
+++ b/backend/src/plugins/UsernameSaver/UsernameSaverPlugin.ts
@@ -1,11 +1,11 @@
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
-import { UsernameHistory } from "src/data/UsernameHistory";
-import { Queue } from "src/Queue";
+import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
+import { UsernameHistory } from "../../data/UsernameHistory";
+import { Queue } from "../../Queue";
 import { UsernameSaverPluginType } from "./types";
 import { MessageCreateUpdateUsernameEvt, VoiceChannelJoinUpdateUsernameEvt } from "./events/UpdateUsernameEvts";
 import * as t from "io-ts";
 
-export const UsernameSaverPlugin = zeppelinPlugin<UsernameSaverPluginType>()("username_saver", {
+export const UsernameSaverPlugin = zeppelinGuildPlugin<UsernameSaverPluginType>()("username_saver", {
   showInDocs: false,
 
   configSchema: t.type({}),
diff --git a/backend/src/plugins/UsernameSaver/events/UpdateUsernameEvts.ts b/backend/src/plugins/UsernameSaver/events/UpdateUsernameEvts.ts
index fbff87ea..8b8a8fb8 100644
--- a/backend/src/plugins/UsernameSaver/events/UpdateUsernameEvts.ts
+++ b/backend/src/plugins/UsernameSaver/events/UpdateUsernameEvts.ts
@@ -1,7 +1,7 @@
-import { usernameEvent } from "../types";
+import { usernameSaverEvt } from "../types";
 import { updateUsername } from "../updateUsername";
 
-export const MessageCreateUpdateUsernameEvt = usernameEvent({
+export const MessageCreateUpdateUsernameEvt = usernameSaverEvt({
   event: "messageCreate",
 
   async listener(meta) {
@@ -10,7 +10,7 @@ export const MessageCreateUpdateUsernameEvt = usernameEvent({
   },
 });
 
-export const VoiceChannelJoinUpdateUsernameEvt = usernameEvent({
+export const VoiceChannelJoinUpdateUsernameEvt = usernameSaverEvt({
   event: "voiceChannelJoin",
 
   async listener(meta) {
diff --git a/backend/src/plugins/UsernameSaver/types.ts b/backend/src/plugins/UsernameSaver/types.ts
index eeb078e7..2714a1e0 100644
--- a/backend/src/plugins/UsernameSaver/types.ts
+++ b/backend/src/plugins/UsernameSaver/types.ts
@@ -1,6 +1,6 @@
-import { BasePluginType, eventListener } from "knub";
-import { UsernameHistory } from "src/data/UsernameHistory";
-import { Queue } from "src/Queue";
+import { BasePluginType, guildEventListener } from "knub";
+import { UsernameHistory } from "../../data/UsernameHistory";
+import { Queue } from "../../Queue";
 
 export interface UsernameSaverPluginType extends BasePluginType {
   state: {
@@ -9,4 +9,4 @@ export interface UsernameSaverPluginType extends BasePluginType {
   };
 }
 
-export const usernameEvent = eventListener<UsernameSaverPluginType>();
+export const usernameSaverEvt = guildEventListener<UsernameSaverPluginType>();
diff --git a/backend/src/plugins/UsernameSaver/updateUsername.ts b/backend/src/plugins/UsernameSaver/updateUsername.ts
index 6b5129a9..5e0a3288 100644
--- a/backend/src/plugins/UsernameSaver/updateUsername.ts
+++ b/backend/src/plugins/UsernameSaver/updateUsername.ts
@@ -1,8 +1,8 @@
 import { User } from "eris";
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { UsernameSaverPluginType } from "./types";
 
-export async function updateUsername(pluginData: PluginData<UsernameSaverPluginType>, user: User) {
+export async function updateUsername(pluginData: GuildPluginData<UsernameSaverPluginType>, user: User) {
   if (!user) return;
   const newUsername = `${user.username}#${user.discriminator}`;
   const latestEntry = await pluginData.state.usernameHistory.getLastEntry(user.id);
diff --git a/backend/src/plugins/Utility/UtilityPlugin.ts b/backend/src/plugins/Utility/UtilityPlugin.ts
index 301137c7..2f09cdc7 100644
--- a/backend/src/plugins/Utility/UtilityPlugin.ts
+++ b/backend/src/plugins/Utility/UtilityPlugin.ts
@@ -1,4 +1,4 @@
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
+import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
 import { ConfigSchema, UtilityPluginType } from "./types";
 import { GuildLogs } from "../../data/GuildLogs";
 import { GuildCases } from "../../data/GuildCases";
@@ -96,7 +96,7 @@ const defaultOptions: PluginOptions<UtilityPluginType> = {
   ],
 };
 
-export const UtilityPlugin = zeppelinPlugin<UtilityPluginType>()("utility", {
+export const UtilityPlugin = zeppelinGuildPlugin<UtilityPluginType>()("utility", {
   showInDocs: true,
   info: {
     prettyName: "Utility",
diff --git a/backend/src/plugins/Utility/commands/CleanCmd.ts b/backend/src/plugins/Utility/commands/CleanCmd.ts
index e3341c5f..717f0ddc 100644
--- a/backend/src/plugins/Utility/commands/CleanCmd.ts
+++ b/backend/src/plugins/Utility/commands/CleanCmd.ts
@@ -4,7 +4,7 @@ import { DAYS, getInviteCodesInString, noop, SECONDS, stripObjectToScalars } fro
 import { getBaseUrl, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
 import { Message, TextChannel, User } from "eris";
 import moment from "moment-timezone";
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { SavedMessage } from "../../../data/entities/SavedMessage";
 import { LogType } from "../../../data/LogType";
 import { allowTimeout } from "../../../RegExpRunner";
@@ -14,7 +14,7 @@ const MAX_CLEAN_TIME = 1 * DAYS;
 const CLEAN_COMMAND_DELETE_DELAY = 5 * SECONDS;
 
 async function cleanMessages(
-  pluginData: PluginData<UtilityPluginType>,
+  pluginData: GuildPluginData<UtilityPluginType>,
   channel: TextChannel,
   savedMessages: SavedMessage[],
   mod: User,
diff --git a/backend/src/plugins/Utility/commands/HelpCmd.ts b/backend/src/plugins/Utility/commands/HelpCmd.ts
index d7468537..76067c86 100644
--- a/backend/src/plugins/Utility/commands/HelpCmd.ts
+++ b/backend/src/plugins/Utility/commands/HelpCmd.ts
@@ -2,7 +2,7 @@ import { utilityCmd } from "../types";
 import { commandTypeHelpers as ct } from "../../../commandTypes";
 import { createChunkedMessage } from "../../../utils";
 import { PluginCommandDefinition } from "knub/dist/commands/commandUtils";
-import { LoadedPlugin } from "knub";
+import { LoadedGuildPlugin } from "knub";
 
 export const HelpCmd = utilityCmd({
   trigger: "help",
@@ -18,7 +18,7 @@ export const HelpCmd = utilityCmd({
     const searchStr = args.command.toLowerCase();
 
     const matchingCommands: Array<{
-      plugin: LoadedPlugin<any>;
+      plugin: LoadedGuildPlugin<any>;
       command: PluginCommandDefinition;
     }> = [];
 
diff --git a/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts b/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts
index b837cca1..95b91d15 100644
--- a/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts
+++ b/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts
@@ -1,4 +1,4 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { UtilityPluginType } from "../types";
 import { Constants, EmbedOptions } from "eris";
 import moment from "moment-timezone";
@@ -14,7 +14,7 @@ const ANNOUNCEMENT_CHANNEL_ICON =
   "https://cdn.discordapp.com/attachments/740650744830623756/740656841687564348/announcement-channel.png";
 
 export async function getChannelInfoEmbed(
-  pluginData: PluginData<UtilityPluginType>,
+  pluginData: GuildPluginData<UtilityPluginType>,
   channelId: string,
   requestMemberId?: string,
 ): Promise<EmbedOptions | null> {
diff --git a/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts b/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts
index 4f3f47a1..8e2b671d 100644
--- a/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts
+++ b/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts
@@ -1,4 +1,4 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { UtilityPluginType } from "../types";
 import { BaseInvite, Constants, EmbedOptions, RESTChannelInvite, RESTPrivateInvite } from "eris";
 import { snowflakeToTimestamp } from "../../../utils/snowflakeToTimestamp";
@@ -16,7 +16,7 @@ import {
 } from "../../../utils";
 
 export async function getInviteInfoEmbed(
-  pluginData: PluginData<UtilityPluginType>,
+  pluginData: GuildPluginData<UtilityPluginType>,
   inviteCode: string,
 ): Promise<EmbedOptions | null> {
   const invite = await resolveInvite(pluginData.client, inviteCode, true);
diff --git a/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts b/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts
index bde02308..b6003026 100644
--- a/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts
+++ b/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts
@@ -1,4 +1,4 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { UtilityPluginType } from "../types";
 import { Constants, EmbedOptions } from "eris";
 import moment from "moment-timezone";
@@ -10,7 +10,7 @@ import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin";
 const MESSAGE_ICON = "https://cdn.discordapp.com/attachments/740650744830623756/740685652152025088/message.png";
 
 export async function getMessageInfoEmbed(
-  pluginData: PluginData<UtilityPluginType>,
+  pluginData: GuildPluginData<UtilityPluginType>,
   channelId: string,
   messageId: string,
   requestMemberId?: string,
@@ -132,7 +132,7 @@ export async function getMessageInfoEmbed(
   }
 
   if (message.embeds.length) {
-    const prefix = pluginData.guildConfig.prefix || getDefaultPrefix(pluginData.client);
+    const prefix = pluginData.fullConfig.prefix || getDefaultPrefix(pluginData.client);
     embed.fields.push({
       name: preEmbedPadding + "Embeds",
       value: `Message contains an embed, use \`${prefix}source\` to see the embed source`,
diff --git a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts
index 5cad208f..6d5e2af5 100644
--- a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts
+++ b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts
@@ -1,4 +1,4 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { UtilityPluginType } from "../types";
 import { embedPadding, formatNumber, memoize, MINUTES, preEmbedPadding, resolveUser, trimLines } from "../../../utils";
 import { CategoryChannel, EmbedOptions, Guild, RESTChannelInvite, TextChannel, VoiceChannel } from "eris";
@@ -8,7 +8,7 @@ import { getGuildPreview } from "./getGuildPreview";
 import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin";
 
 export async function getServerInfoEmbed(
-  pluginData: PluginData<UtilityPluginType>,
+  pluginData: GuildPluginData<UtilityPluginType>,
   serverId: string,
   requestMemberId?: string,
 ): Promise<EmbedOptions> {
diff --git a/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts b/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts
index d4561348..5cfa9b1d 100644
--- a/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts
+++ b/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts
@@ -1,9 +1,9 @@
 import { Message, GuildTextableChannel, EmbedOptions } from "eris";
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { UtilityPluginType } from "../types";
-import { UnknownUser, trimLines, embedPadding, resolveMember, resolveUser, preEmbedPadding } from "src/utils";
+import { UnknownUser, trimLines, embedPadding, resolveMember, resolveUser, preEmbedPadding } from "../../../utils";
 import moment from "moment-timezone";
-import { CaseTypes } from "src/data/CaseTypes";
+import { CaseTypes } from "../../../data/CaseTypes";
 import humanizeDuration from "humanize-duration";
 import { snowflakeToTimestamp } from "../../../utils/snowflakeToTimestamp";
 import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin";
@@ -11,7 +11,7 @@ import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin";
 const SNOWFLAKE_ICON = "https://cdn.discordapp.com/attachments/740650744830623756/742020790471491668/snowflake.png";
 
 export async function getSnowflakeInfoEmbed(
-  pluginData: PluginData<UtilityPluginType>,
+  pluginData: GuildPluginData<UtilityPluginType>,
   snowflake: string,
   showUnknownWarning = false,
   requestMemberId?: string,
diff --git a/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts b/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts
index 6a127206..55cb2c0f 100644
--- a/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts
+++ b/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts
@@ -1,5 +1,5 @@
 import { Message, GuildTextableChannel, EmbedOptions } from "eris";
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { UtilityPluginType } from "../types";
 import {
   UnknownUser,
@@ -10,14 +10,14 @@ import {
   preEmbedPadding,
   sorter,
   messageLink,
-} from "src/utils";
+} from "../../../utils";
 import moment from "moment-timezone";
-import { CaseTypes } from "src/data/CaseTypes";
+import { CaseTypes } from "../../../data/CaseTypes";
 import humanizeDuration from "humanize-duration";
 import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin";
 
 export async function getUserInfoEmbed(
-  pluginData: PluginData<UtilityPluginType>,
+  pluginData: GuildPluginData<UtilityPluginType>,
   userId: string,
   compact = false,
   requestMemberId?: string,
diff --git a/backend/src/plugins/Utility/search.ts b/backend/src/plugins/Utility/search.ts
index a148e7d4..826ce922 100644
--- a/backend/src/plugins/Utility/search.ts
+++ b/backend/src/plugins/Utility/search.ts
@@ -3,7 +3,7 @@ import moment from "moment-timezone";
 import escapeStringRegexp from "escape-string-regexp";
 import { isFullMessage, MINUTES, multiSorter, noop, sorter, trimLines } from "../../utils";
 import { getBaseUrl, sendErrorMessage } from "../../pluginUtils";
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { ArgsFromSignatureOrArray } from "knub/dist/commands/commandUtils";
 import { searchCmdSignature } from "./commands/SearchCmd";
 import { banSearchSignature } from "./commands/BanSearchCmd";
@@ -29,19 +29,19 @@ type MemberSearchParams = ArgsFromSignatureOrArray<typeof searchCmdSignature>;
 type BanSearchParams = ArgsFromSignatureOrArray<typeof banSearchSignature>;
 
 export async function displaySearch(
-  pluginData: PluginData<UtilityPluginType>,
+  pluginData: GuildPluginData<UtilityPluginType>,
   args: MemberSearchParams,
   searchType: SearchType.MemberSearch,
   msg: Message,
 );
 export async function displaySearch(
-  pluginData: PluginData<UtilityPluginType>,
+  pluginData: GuildPluginData<UtilityPluginType>,
   args: BanSearchParams,
   searchType: SearchType.BanSearch,
   msg: Message,
 );
 export async function displaySearch(
-  pluginData: PluginData<UtilityPluginType>,
+  pluginData: GuildPluginData<UtilityPluginType>,
   args: MemberSearchParams | BanSearchParams,
   searchType: SearchType,
   msg: Message,
@@ -173,19 +173,19 @@ export async function displaySearch(
 }
 
 export async function archiveSearch(
-  pluginData: PluginData<UtilityPluginType>,
+  pluginData: GuildPluginData<UtilityPluginType>,
   args: MemberSearchParams,
   searchType: SearchType.MemberSearch,
   msg: Message,
 );
 export async function archiveSearch(
-  pluginData: PluginData<UtilityPluginType>,
+  pluginData: GuildPluginData<UtilityPluginType>,
   args: BanSearchParams,
   searchType: SearchType.BanSearch,
   msg: Message,
 );
 export async function archiveSearch(
-  pluginData: PluginData<UtilityPluginType>,
+  pluginData: GuildPluginData<UtilityPluginType>,
   args: MemberSearchParams | BanSearchParams,
   searchType: SearchType,
   msg: Message,
@@ -234,7 +234,7 @@ export async function archiveSearch(
 }
 
 async function performMemberSearch(
-  pluginData: PluginData<UtilityPluginType>,
+  pluginData: GuildPluginData<UtilityPluginType>,
   args: MemberSearchParams,
   page = 1,
   perPage = SEARCH_RESULTS_PER_PAGE,
@@ -368,7 +368,7 @@ async function performMemberSearch(
 }
 
 async function performBanSearch(
-  pluginData: PluginData<UtilityPluginType>,
+  pluginData: GuildPluginData<UtilityPluginType>,
   args: BanSearchParams,
   page = 1,
   perPage = SEARCH_RESULTS_PER_PAGE,
diff --git a/backend/src/plugins/Utility/types.ts b/backend/src/plugins/Utility/types.ts
index 346dfdfa..710fa788 100644
--- a/backend/src/plugins/Utility/types.ts
+++ b/backend/src/plugins/Utility/types.ts
@@ -1,5 +1,5 @@
 import * as t from "io-ts";
-import { BasePluginType, command, eventListener } from "knub";
+import { BasePluginType, guildCommand, guildEventListener } from "knub";
 import { GuildLogs } from "../../data/GuildLogs";
 import { GuildCases } from "../../data/GuildCases";
 import { GuildSavedMessages } from "../../data/GuildSavedMessages";
@@ -48,5 +48,5 @@ export interface UtilityPluginType extends BasePluginType {
   };
 }
 
-export const utilityCmd = command<UtilityPluginType>();
-export const utilityEvent = eventListener<UtilityPluginType>();
+export const utilityCmd = guildCommand<UtilityPluginType>();
+export const utilityEvt = guildEventListener<UtilityPluginType>();
diff --git a/backend/src/plugins/WelcomeMessage/WelcomeMessagePlugin.ts b/backend/src/plugins/WelcomeMessage/WelcomeMessagePlugin.ts
index 68f16605..56c523dc 100644
--- a/backend/src/plugins/WelcomeMessage/WelcomeMessagePlugin.ts
+++ b/backend/src/plugins/WelcomeMessage/WelcomeMessagePlugin.ts
@@ -1,7 +1,7 @@
-import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
+import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
 import { PluginOptions } from "knub";
 import { ConfigSchema, WelcomeMessagePluginType } from "./types";
-import { GuildLogs } from "src/data/GuildLogs";
+import { GuildLogs } from "../../data/GuildLogs";
 import { SendWelcomeMessageEvt } from "./events/SendWelcomeMessageEvt";
 
 const defaultOptions: PluginOptions<WelcomeMessagePluginType> = {
@@ -12,7 +12,7 @@ const defaultOptions: PluginOptions<WelcomeMessagePluginType> = {
   },
 };
 
-export const WelcomeMessagePlugin = zeppelinPlugin<WelcomeMessagePluginType>()("welcome_message", {
+export const WelcomeMessagePlugin = zeppelinGuildPlugin<WelcomeMessagePluginType>()("welcome_message", {
   showInDocs: true,
   info: {
     prettyName: "Welcome message",
diff --git a/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts b/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts
index abf5b7da..cbd04093 100644
--- a/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts
+++ b/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts
@@ -1,11 +1,11 @@
-import { welcomeEvent } from "../types";
-import { renderTemplate, TemplateParseError } from "src/templateFormatter";
-import { createChunkedMessage, stripObjectToScalars } from "src/utils";
-import { LogType } from "src/data/LogType";
+import { welcomeMessageEvt } from "../types";
+import { renderTemplate, TemplateParseError } from "../../../templateFormatter";
+import { createChunkedMessage, stripObjectToScalars } from "../../../utils";
+import { LogType } from "../../../data/LogType";
 import { TextChannel } from "eris";
 import { sendDM } from "../../../utils/sendDM";
 
-export const SendWelcomeMessageEvt = welcomeEvent({
+export const SendWelcomeMessageEvt = welcomeMessageEvt({
   event: "guildMemberAdd",
 
   async listener(meta) {
diff --git a/backend/src/plugins/WelcomeMessage/types.ts b/backend/src/plugins/WelcomeMessage/types.ts
index 33302578..63228df2 100644
--- a/backend/src/plugins/WelcomeMessage/types.ts
+++ b/backend/src/plugins/WelcomeMessage/types.ts
@@ -1,7 +1,7 @@
 import * as t from "io-ts";
-import { BasePluginType, eventListener } from "knub";
-import { tNullable } from "src/utils";
-import { GuildLogs } from "src/data/GuildLogs";
+import { BasePluginType, guildEventListener } from "knub";
+import { tNullable } from "../../utils";
+import { GuildLogs } from "../../data/GuildLogs";
 
 export const ConfigSchema = t.type({
   send_dm: t.boolean,
@@ -18,4 +18,4 @@ export interface WelcomeMessagePluginType extends BasePluginType {
   };
 }
 
-export const welcomeEvent = eventListener<WelcomeMessagePluginType>();
+export const welcomeMessageEvt = guildEventListener<WelcomeMessagePluginType>();
diff --git a/backend/src/plugins/ZeppelinPlugin.ts b/backend/src/plugins/ZeppelinPlugin.ts
index 41ff2d98..3937f53a 100644
--- a/backend/src/plugins/ZeppelinPlugin.ts
+++ b/backend/src/plugins/ZeppelinPlugin.ts
@@ -1,3 +1,3 @@
-import { ZeppelinPluginBlueprint } from "./ZeppelinPluginBlueprint";
+import { ZeppelinGlobalPluginBlueprint, ZeppelinGuildPluginBlueprint } from "./ZeppelinPluginBlueprint";
 
-export type ZeppelinPlugin = ZeppelinPluginBlueprint<any>;
+export type ZeppelinPlugin = ZeppelinGuildPluginBlueprint<any> | ZeppelinGlobalPluginBlueprint<any>;
diff --git a/backend/src/plugins/ZeppelinPluginBlueprint.ts b/backend/src/plugins/ZeppelinPluginBlueprint.ts
index e36623b3..483ec3cb 100644
--- a/backend/src/plugins/ZeppelinPluginBlueprint.ts
+++ b/backend/src/plugins/ZeppelinPluginBlueprint.ts
@@ -1,10 +1,14 @@
-import { BasePluginType, plugin, PluginBlueprint } from "knub";
+import { BasePluginType, globalPlugin, GlobalPluginBlueprint, guildPlugin, GuildPluginBlueprint } from "knub";
 import * as t from "io-ts";
 import { getPluginConfigPreprocessor } from "../pluginUtils";
 import { TMarkdown } from "../types";
 
-export interface ZeppelinPluginBlueprint<TPluginType extends BasePluginType = BasePluginType>
-  extends PluginBlueprint<TPluginType> {
+/**
+ * GUILD PLUGINS
+ */
+
+export interface ZeppelinGuildPluginBlueprint<TPluginType extends BasePluginType = BasePluginType>
+  extends GuildPluginBlueprint<TPluginType> {
   configSchema: t.TypeC<any>;
   showInDocs?: boolean;
 
@@ -16,27 +20,65 @@ export interface ZeppelinPluginBlueprint<TPluginType extends BasePluginType = Ba
   };
 }
 
-export function zeppelinPlugin<TPartialBlueprint extends Omit<ZeppelinPluginBlueprint, "name">>(
+export function zeppelinGuildPlugin<TPartialBlueprint extends Omit<ZeppelinGuildPluginBlueprint, "name">>(
   name: string,
   blueprint: TPartialBlueprint,
-): TPartialBlueprint & { name: string; configPreprocessor: ZeppelinPluginBlueprint["configPreprocessor"] };
+): TPartialBlueprint & { name: string; configPreprocessor: ZeppelinGuildPluginBlueprint["configPreprocessor"] };
 
-export function zeppelinPlugin<TPluginType extends BasePluginType>(): <
-  TPartialBlueprint extends Omit<ZeppelinPluginBlueprint<TPluginType>, "name">
+export function zeppelinGuildPlugin<TPluginType extends BasePluginType>(): <
+  TPartialBlueprint extends Omit<ZeppelinGuildPluginBlueprint<TPluginType>, "name">
 >(
   name: string,
   blueprint: TPartialBlueprint,
 ) => TPartialBlueprint & {
   name: string;
-  configPreprocessor: ZeppelinPluginBlueprint<TPluginType>["configPreprocessor"];
+  configPreprocessor: ZeppelinGuildPluginBlueprint<TPluginType>["configPreprocessor"];
 };
 
-export function zeppelinPlugin(...args) {
+export function zeppelinGuildPlugin(...args) {
   if (args.length) {
-    const blueprint = (plugin(...(args as Parameters<typeof plugin>)) as unknown) as ZeppelinPluginBlueprint;
+    const blueprint = (guildPlugin(
+      ...(args as Parameters<typeof guildPlugin>),
+    ) as unknown) as ZeppelinGuildPluginBlueprint;
     blueprint.configPreprocessor = getPluginConfigPreprocessor(blueprint, blueprint.configPreprocessor);
     return blueprint;
   } else {
-    return zeppelinPlugin as (name, blueprint) => ZeppelinPluginBlueprint;
+    return zeppelinGuildPlugin as (name, blueprint) => ZeppelinGuildPluginBlueprint;
+  }
+}
+
+/**
+ * GLOBAL PLUGINS
+ */
+
+export interface ZeppelinGlobalPluginBlueprint<TPluginType extends BasePluginType = BasePluginType>
+  extends GlobalPluginBlueprint<TPluginType> {
+  configSchema: t.TypeC<any>;
+}
+
+export function zeppelinGlobalPlugin<TPartialBlueprint extends Omit<ZeppelinGlobalPluginBlueprint, "name">>(
+  name: string,
+  blueprint: TPartialBlueprint,
+): TPartialBlueprint & { name: string; configPreprocessor: ZeppelinGlobalPluginBlueprint["configPreprocessor"] };
+
+export function zeppelinGlobalPlugin<TPluginType extends BasePluginType>(): <
+  TPartialBlueprint extends Omit<ZeppelinGlobalPluginBlueprint<TPluginType>, "name">
+>(
+  name: string,
+  blueprint: TPartialBlueprint,
+) => TPartialBlueprint & {
+  name: string;
+  configPreprocessor: ZeppelinGlobalPluginBlueprint<TPluginType>["configPreprocessor"];
+};
+
+export function zeppelinGlobalPlugin(...args) {
+  if (args.length) {
+    const blueprint = (globalPlugin(
+      ...(args as Parameters<typeof globalPlugin>),
+    ) as unknown) as ZeppelinGlobalPluginBlueprint;
+    blueprint.configPreprocessor = getPluginConfigPreprocessor(blueprint, blueprint.configPreprocessor);
+    return blueprint;
+  } else {
+    return zeppelinGlobalPlugin as (name, blueprint) => ZeppelinGlobalPluginBlueprint;
   }
 }
diff --git a/backend/src/plugins/availablePlugins.ts b/backend/src/plugins/availablePlugins.ts
index 149d9d2a..5777e343 100644
--- a/backend/src/plugins/availablePlugins.ts
+++ b/backend/src/plugins/availablePlugins.ts
@@ -1,6 +1,6 @@
 import { UtilityPlugin } from "./Utility/UtilityPlugin";
 import { LocateUserPlugin } from "./LocateUser/LocateUserPlugin";
-import { ZeppelinPluginBlueprint } from "./ZeppelinPluginBlueprint";
+import { ZeppelinGlobalPluginBlueprint, ZeppelinGuildPluginBlueprint } from "./ZeppelinPluginBlueprint";
 import { PersistPlugin } from "./Persist/PersistPlugin";
 import { NameHistoryPlugin } from "./NameHistory/NameHistoryPlugin";
 import { MessageSaverPlugin } from "./MessageSaver/MessageSaverPlugin";
@@ -34,7 +34,7 @@ import { GuildAccessMonitorPlugin } from "./GuildAccessMonitor/GuildAccessMonito
 import { TimeAndDatePlugin } from "./TimeAndDate/TimeAndDatePlugin";
 
 // prettier-ignore
-export const guildPlugins: Array<ZeppelinPluginBlueprint<any>> = [
+export const guildPlugins: Array<ZeppelinGuildPluginBlueprint<any>> = [
   AutoDeletePlugin,
   AutoReactionsPlugin,
   GuildInfoSaverPlugin,
@@ -68,14 +68,14 @@ export const guildPlugins: Array<ZeppelinPluginBlueprint<any>> = [
 ];
 
 // prettier-ignore
-export const globalPlugins = [
+export const globalPlugins: Array<ZeppelinGlobalPluginBlueprint<any>> = [
   GuildConfigReloaderPlugin,
   BotControlPlugin,
   GuildAccessMonitorPlugin,
 ];
 
 // prettier-ignore
-export const baseGuildPlugins: Array<ZeppelinPluginBlueprint<any>> = [
+export const baseGuildPlugins: Array<ZeppelinGuildPluginBlueprint<any>> = [
   GuildInfoSaverPlugin,
   MessageSaverPlugin,
   NameHistoryPlugin,
diff --git a/backend/src/utils/getGuildPrefix.ts b/backend/src/utils/getGuildPrefix.ts
index 5ed32ed2..763a5032 100644
--- a/backend/src/utils/getGuildPrefix.ts
+++ b/backend/src/utils/getGuildPrefix.ts
@@ -1,6 +1,6 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { getDefaultPrefix } from "knub/dist/commands/commandUtils";
 
-export function getGuildPrefix(pluginData: PluginData<any>) {
-  return pluginData.guildConfig.prefix || getDefaultPrefix(pluginData.client);
+export function getGuildPrefix(pluginData: GuildPluginData<any>) {
+  return pluginData.fullConfig.prefix || getDefaultPrefix(pluginData.client);
 }
diff --git a/backend/src/utils/resolveMessageTarget.ts b/backend/src/utils/resolveMessageTarget.ts
index 9ce2a3ba..4e06c52a 100644
--- a/backend/src/utils/resolveMessageTarget.ts
+++ b/backend/src/utils/resolveMessageTarget.ts
@@ -1,6 +1,6 @@
 import { disableInlineCode, isSnowflake } from "../utils";
 import { getChannelIdFromMessageId } from "../data/getChannelIdFromMessageId";
-import { PluginData, TypeConversionError } from "knub";
+import { GuildPluginData, TypeConversionError } from "knub";
 import { TextChannel } from "eris";
 
 const channelAndMessageIdRegex = /^(\d+)[\-\/](\d+)$/;
@@ -11,7 +11,7 @@ export interface MessageTarget {
   messageId: string;
 }
 
-export async function resolveMessageTarget(pluginData: PluginData<any>, value: string) {
+export async function resolveMessageTarget(pluginData: GuildPluginData<any>, value: string) {
   const result = await (async () => {
     if (isSnowflake(value)) {
       const channelId = await getChannelIdFromMessageId(value);
diff --git a/backend/src/utils/safeFindRelevantAuditLogEntry.ts b/backend/src/utils/safeFindRelevantAuditLogEntry.ts
index d8d1e55b..ab196cf0 100644
--- a/backend/src/utils/safeFindRelevantAuditLogEntry.ts
+++ b/backend/src/utils/safeFindRelevantAuditLogEntry.ts
@@ -1,4 +1,4 @@
-import { PluginData } from "knub";
+import { GuildPluginData } from "knub";
 import { LogsPlugin } from "../plugins/Logs/LogsPlugin";
 import { findRelevantAuditLogEntry, isDiscordRESTError } from "../utils";
 import { LogType } from "../data/LogType";
@@ -8,7 +8,7 @@ import { LogType } from "../data/LogType";
  * Calling plugin must have LogsPlugin as a dependency (or be LogsPlugin itself).
  */
 export async function safeFindRelevantAuditLogEntry(
-  pluginData: PluginData<any>,
+  pluginData: GuildPluginData<any>,
   actionType: number,
   userId: string,
   attempts?: number,