diff --git a/Commands/AddMessageCommand.cs b/Commands/AddMessageCommand.cs
deleted file mode 100644
index ff9057c..0000000
--- a/Commands/AddMessageCommand.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-using System.ComponentModel;
-using System.Globalization;
-using DSharpPlus.Entities;
-using System.Threading.Tasks;
-using DSharpPlus.Commands;
-using DSharpPlus.Commands.ContextChecks;
-using DSharpPlus.Commands.Processors.SlashCommands;
-using DSharpPlus.Exceptions;
-
-namespace SupportChild.Commands;
-
-public class AddMessageCommand
-{
-    [RequireGuild]
-    [Command("addmessage")]
-    [Description("Adds a new message for the 'say' command.")]
-    public async Task OnExecute(SlashCommandContext command,
-        [Parameter("identifier")][Description("The identifier word used in the /say command.")] string identifier,
-        [Parameter("message")][Description("The message the /say command will return.")] string message)
-    {
-        if (string.IsNullOrEmpty(message))
-        {
-            await command.RespondAsync(new DiscordEmbedBuilder
-            {
-                Color = DiscordColor.Red,
-                Description = "No message specified."
-            }, true);
-            return;
-        }
-
-        if (Database.TryGetMessage(identifier.ToLower(CultureInfo.InvariantCulture), out Database.Message _))
-        {
-            await command.RespondAsync(new DiscordEmbedBuilder
-            {
-                Color = DiscordColor.Red,
-                Description = "There is already a message with that identifier."
-            }, true);
-            return;
-        }
-
-        if (Database.AddMessage(identifier, command.Member.Id, message))
-        {
-            await command.RespondAsync(new DiscordEmbedBuilder
-            {
-                Color = DiscordColor.Green,
-                Description = "Message added."
-            }, true);
-        }
-        else
-        {
-            await command.RespondAsync(new DiscordEmbedBuilder
-            {
-                Color = DiscordColor.Red,
-                Description = "Error: Failed adding the message to the database."
-            }, true);
-        }
-
-        await LogChannel.Success(command.User.Mention + " added or updated `" + identifier + "` in the /say command.\n\nContent:\n\n" + message);
-    }
-}
\ No newline at end of file
diff --git a/Commands/RemoveMessageCommand.cs b/Commands/RemoveMessageCommand.cs
deleted file mode 100644
index 1506c6b..0000000
--- a/Commands/RemoveMessageCommand.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-using System.ComponentModel;
-using System.Globalization;
-using DSharpPlus.Entities;
-using System.Threading.Tasks;
-using DSharpPlus.Commands;
-using DSharpPlus.Commands.ContextChecks;
-using DSharpPlus.Commands.Processors.SlashCommands;
-using DSharpPlus.Exceptions;
-
-namespace SupportChild.Commands;
-
-public class RemoveMessageCommand
-{
-    [RequireGuild]
-    [Command("removemessage")]
-    [Description("Removes a message from the 'say' command.")]
-    public async Task OnExecute(SlashCommandContext command,
-        [Parameter("identifier")][Description("The identifier word used in the /say command.")] string identifier)
-    {
-        if (!Database.TryGetMessage(identifier.ToLower(CultureInfo.InvariantCulture), out Database.Message _))
-        {
-            await command.RespondAsync(new DiscordEmbedBuilder
-            {
-                Color = DiscordColor.Red,
-                Description = "There is no message with that identifier."
-            }, true);
-            return;
-        }
-
-        if (Database.RemoveMessage(identifier))
-        {
-            await command.RespondAsync(new DiscordEmbedBuilder
-            {
-                Color = DiscordColor.Green,
-                Description = "Message removed."
-            }, true);
-        }
-        else
-        {
-            await command.RespondAsync(new DiscordEmbedBuilder
-            {
-                Color = DiscordColor.Red,
-                Description = "Error: Failed removing the message from the database."
-            }, true);
-        }
-
-        await LogChannel.Success("`" + identifier + "` was removed from the /say command by " + command.User.Mention + ".");
-    }
-}
\ No newline at end of file
diff --git a/Commands/SetMessageCommand.cs b/Commands/SetMessageCommand.cs
new file mode 100644
index 0000000..0e0127e
--- /dev/null
+++ b/Commands/SetMessageCommand.cs
@@ -0,0 +1,200 @@
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Globalization;
+using System.Linq;
+using DSharpPlus.Entities;
+using System.Threading.Tasks;
+using DSharpPlus.Commands;
+using DSharpPlus.Commands.ContextChecks;
+using DSharpPlus.Commands.Processors.SlashCommands;
+
+namespace SupportChild.Commands;
+
+public class SetMessageCommand
+{
+    private readonly struct CommandInfo(string identifier, string message)
+    {
+        public string identifier { get; } = identifier;
+        public string message { get; } = message;
+    }
+
+    private static Dictionary<ulong, CommandInfo> waitingCommands = new();
+
+    [RequireGuild]
+    [Command("setmessage")]
+    [Description("Adds or updates message for the 'say' command.")]
+    public async Task OnExecute(SlashCommandContext command,
+        [Parameter("identifier")][Description("The identifier word used in the /say command.")] string identifier,
+        [Parameter("message")][Description("The message the /say command will return. Empty to delete message.")] string message = "")
+    {
+
+
+        if (Database.TryGetMessage(identifier.ToLower(CultureInfo.InvariantCulture), out Database.Message oldMessage))
+        {
+            if (string.IsNullOrEmpty(message))
+            {
+                await command.RespondAsync(new DiscordInteractionResponseBuilder()
+                    .AddEmbed(new DiscordEmbedBuilder
+                    {
+                        Color = DiscordColor.Orange,
+                        Description = "Are you sure you want to delete the `" + identifier + "` message?"
+                    })
+                    .AddComponents(new DiscordButtonComponent(DiscordButtonStyle.Danger, "supportchild_confirmmessagedelete " + command.Interaction.Id, "Confirm"),
+                                   new DiscordButtonComponent(DiscordButtonStyle.Secondary, "supportchild_cancelmessagedelete " + command.Interaction.Id, "Cancel")));
+            }
+            else
+            {
+                await command.RespondAsync(new DiscordInteractionResponseBuilder()
+                    .AddEmbed(new DiscordEmbedBuilder
+                    {
+                        Color = DiscordColor.Cyan,
+                        Title = "Replace the `" + identifier + "` message?"
+                    }
+                    .AddField("Old message:", oldMessage.message.Truncate(1024)).AddField("New message:", message.Truncate(1024)))
+                    .AddComponents(new DiscordButtonComponent(DiscordButtonStyle.Success, "supportchild_confirmmessageupdate " + command.Interaction.Id, "Confirm"),
+                                   new DiscordButtonComponent(DiscordButtonStyle.Secondary, "supportchild_cancelmessageupdate " + command.Interaction.Id, "Cancel")));
+            }
+
+            waitingCommands.Add(command.Interaction.Id, new CommandInfo(identifier, message));
+        }
+        else
+        {
+            if (string.IsNullOrEmpty(message))
+            {
+                await command.RespondAsync(new DiscordEmbedBuilder
+                {
+                    Color = DiscordColor.Red,
+                    Description = "Cannot delete that message, it does not exist."
+                }, true);
+            }
+            else
+            {
+                await AddNewMessage(command, identifier, message);
+            }
+        }
+    }
+
+    private static async Task AddNewMessage(SlashCommandContext command, string identifier, string message)
+    {
+        if (Database.AddMessage(identifier, command.Member.Id, message))
+        {
+            await command.RespondAsync(new DiscordEmbedBuilder
+            {
+                Color = DiscordColor.Green,
+                Description = "Message added."
+            }, true);
+        }
+        else
+        {
+            await command.RespondAsync(new DiscordEmbedBuilder
+            {
+                Color = DiscordColor.Red,
+                Description = "Error: Failed adding the message to the database."
+            }, true);
+        }
+
+        await LogChannel.Success(command.User.Mention + " added the `" + identifier + "` message for the /say command.\n\n**Content:**\n\n" + message);
+    }
+
+    public static async Task ConfirmMessageDeletion(DiscordInteraction interaction, ulong previousInteractionID)
+    {
+        if (!waitingCommands.Remove(previousInteractionID, out CommandInfo command))
+        {
+            await interaction.CreateResponseAsync(DiscordInteractionResponseType.UpdateMessage, new DiscordInteractionResponseBuilder().AddEmbed(new DiscordEmbedBuilder
+            {
+                Color = DiscordColor.Red,
+                Description = "I don't remember which message you wanted to delete, has the bot been restarted since the command was used?"
+            }));
+            return;
+        }
+
+        if (!Database.TryGetMessage(command.identifier.ToLower(CultureInfo.InvariantCulture), out Database.Message _))
+        {
+            await interaction.CreateResponseAsync(DiscordInteractionResponseType.UpdateMessage, new DiscordInteractionResponseBuilder().AddEmbed(new DiscordEmbedBuilder
+            {
+                Color = DiscordColor.Red,
+                Description = "There is no message with that identifier."
+            }));
+            return;
+        }
+
+        if (Database.RemoveMessage(command.identifier))
+        {
+            await interaction.CreateResponseAsync(DiscordInteractionResponseType.UpdateMessage, new DiscordInteractionResponseBuilder().AddEmbed(new DiscordEmbedBuilder
+            {
+                Color = DiscordColor.Green,
+                Description = "Message removed."
+            }));
+        }
+        else
+        {
+            await interaction.CreateResponseAsync(DiscordInteractionResponseType.UpdateMessage, new DiscordInteractionResponseBuilder().AddEmbed(new DiscordEmbedBuilder
+            {
+                Color = DiscordColor.Red,
+                Description = "Error: Failed removing the message from the database."
+            }));
+        }
+
+        await LogChannel.Success("`" + command.identifier + "` was removed from the /say command by " + interaction.User.Mention + ".");
+    }
+
+    public static async Task CancelMessageDeletion(DiscordInteraction interaction, ulong previousInteractionID)
+    {
+        waitingCommands.Remove(previousInteractionID);
+        if (interaction.Message != null)
+        {
+            await interaction.Message.DeleteAsync();
+        }
+    }
+
+    public static async Task ConfirmMessageUpdate(DiscordInteraction interaction, ulong previousInteractionID)
+    {
+        if (!waitingCommands.Remove(previousInteractionID, out CommandInfo command))
+        {
+            await interaction.CreateResponseAsync(DiscordInteractionResponseType.UpdateMessage, new DiscordInteractionResponseBuilder().AddEmbed(new DiscordEmbedBuilder
+            {
+                Color = DiscordColor.Red,
+                Description = "I don't remember which message you wanted to update, has the bot been restarted since the command was used?"
+            }));
+            return;
+        }
+
+        if (!Database.TryGetMessage(command.identifier.ToLower(CultureInfo.InvariantCulture), out Database.Message _))
+        {
+            await interaction.CreateResponseAsync(DiscordInteractionResponseType.UpdateMessage, new DiscordInteractionResponseBuilder().AddEmbed(new DiscordEmbedBuilder
+            {
+                Color = DiscordColor.Red,
+                Description = "There is no message with that identifier."
+            }));
+            return;
+        }
+
+        if (Database.UpdateMessage(command.identifier, interaction.User.Id, command.message))
+        {
+            await interaction.CreateResponseAsync(DiscordInteractionResponseType.UpdateMessage, new DiscordInteractionResponseBuilder().AddEmbed(new DiscordEmbedBuilder
+            {
+                Color = DiscordColor.Green,
+                Description = "Message updated."
+            }));
+        }
+        else
+        {
+            await interaction.CreateResponseAsync(DiscordInteractionResponseType.UpdateMessage, new DiscordInteractionResponseBuilder().AddEmbed(new DiscordEmbedBuilder
+            {
+                Color = DiscordColor.Red,
+                Description = "Error: Failed updating the message in the database."
+            }));
+        }
+
+        await LogChannel.Success("`" + command.identifier + "` was updated for the /say command by " + interaction.User.Mention + ".");
+    }
+
+    public static async Task CancelMessageUpdate(DiscordInteraction interaction, ulong previousInteractionID)
+    {
+        waitingCommands.Remove(previousInteractionID);
+        if (interaction.Message != null)
+        {
+            await interaction.Message.DeleteAsync();
+        }
+    }
+}
\ No newline at end of file
diff --git a/Database.cs b/Database.cs
index 7f2b610..40a55a6 100644
--- a/Database.cs
+++ b/Database.cs
@@ -619,6 +619,26 @@ public static class Database
         }
     }
 
+    public static bool UpdateMessage(string identifier, ulong userID, string message)
+    {
+        try
+        {
+            using MySqlConnection c = GetConnection();
+            c.Open();
+            using MySqlCommand cmd = new MySqlCommand(@"UPDATE messages SET message = @message, user_id = @user_id WHERE identifier=@identifier", c);
+            cmd.Parameters.AddWithValue("@identifier", identifier);
+            cmd.Parameters.AddWithValue("@user_id", userID);
+            cmd.Parameters.AddWithValue("@message", message);
+            cmd.Prepare();
+            return cmd.ExecuteNonQuery() > 0;
+        }
+        catch (MySqlException e)
+        {
+            Logger.Error("Could not add message to database.", e);
+            return false;
+        }
+    }
+
     public static bool RemoveMessage(string identifier)
     {
         try
diff --git a/EventHandler.cs b/EventHandler.cs
index f9ba1fd..04ae879 100644
--- a/EventHandler.cs
+++ b/EventHandler.cs
@@ -205,6 +205,18 @@ public static class EventHandler
                         case not null when e.Id.StartsWith("supportchild_interviewbutton"):
                             await Interviewer.ProcessButtonOrSelectorResponse(e.Interaction);
                             return;
+                        case not null when e.Id.StartsWith("supportchild_confirmmessagedelete"):
+                            await SetMessageCommand.ConfirmMessageDeletion(e.Interaction, GetIDFromCustomID(e.Id));
+                            return;
+                        case not null when e.Id.StartsWith("supportchild_cancelmessagedelete"):
+                            await SetMessageCommand.CancelMessageDeletion(e.Interaction, GetIDFromCustomID(e.Id));
+                            return;
+                        case not null when e.Id.StartsWith("supportchild_confirmmessageupdate"):
+                            await SetMessageCommand.ConfirmMessageUpdate(e.Interaction, GetIDFromCustomID(e.Id));
+                            return;
+                        case not null when e.Id.StartsWith("supportchild_cancelmessageupdate"):
+                            await SetMessageCommand.CancelMessageUpdate(e.Interaction, GetIDFromCustomID(e.Id));
+                            return;
                         case "right":
                         case "left":
                         case "rightskip":
@@ -289,6 +301,17 @@ public static class EventHandler
         }
     }
 
+    private static ulong GetIDFromCustomID(string customID)
+    {
+        List<string> values = customID.Split(' ').ToList();
+        if (values.Count < 2 || !ulong.TryParse(values[1], out ulong id))
+        {
+            Logger.Warn("Got an invalid button/selector ID: " + customID);
+            return 0;
+        }
+        return id;
+    }
+
     private static async Task OnNewTicketButtonUsed(DiscordInteraction interaction)
     {
         await interaction.CreateResponseAsync(DiscordInteractionResponseType.DeferredChannelMessageWithSource, new DiscordInteractionResponseBuilder().AsEphemeral());
diff --git a/SupportChild.cs b/SupportChild.cs
index 2fd07ed..4484a28 100644
--- a/SupportChild.cs
+++ b/SupportChild.cs
@@ -193,7 +193,6 @@ internal static class SupportChild
             [
                 typeof(AddCategoryCommand),
                 typeof(AddCommand),
-                typeof(AddMessageCommand),
                 typeof(AddStaffCommand),
                 typeof(AdminCommands),
                 typeof(AssignCommand),
@@ -201,6 +200,7 @@ internal static class SupportChild
                 typeof(CloseCommand),
                 typeof(CreateButtonPanelCommand),
                 typeof(CreateSelectionBoxPanelCommand),
+                typeof(InterviewCommands),
                 typeof(InterviewTemplateCommands),
                 typeof(ListAssignedCommand),
                 typeof(ListCommand),
@@ -211,10 +211,9 @@ internal static class SupportChild
                 typeof(NewCommand),
                 typeof(RandomAssignCommand),
                 typeof(RemoveCategoryCommand),
-                typeof(RemoveMessageCommand),
                 typeof(RemoveStaffCommand),
-                typeof(InterviewCommands),
                 typeof(SayCommand),
+                typeof(SetMessageCommand),
                 typeof(SetSummaryCommand),
                 typeof(StatusCommand),
                 typeof(SummaryCommand),
diff --git a/Utilities.cs b/Utilities.cs
index 792d8a9..5a5d6f2 100644
--- a/Utilities.cs
+++ b/Utilities.cs
@@ -20,6 +20,11 @@ public static class Extensions
     {
         return needles.Any(haystack.Contains);
     }
+
+    public static string Truncate(this string value, int maxChars)
+    {
+        return value.Length <= maxChars ? value : string.Concat(value.AsSpan(0, maxChars - 3), "...");
+    }
 }
 
 public static class Utilities