diff --git a/webv4/lib/forum.js b/webv4/lib/forum.js
index 9dcf3cca65f6aca33d86055493e4dec4e0fc599e..069bcd112a9b59b767da5f114ffd81a36882d7bc 100644
--- a/webv4/lib/forum.js
+++ b/webv4/lib/forum.js
@@ -1,4 +1,5 @@
 require('sbbsdefs.js', 'MSG_DELETE');
+require('xjs.js', 'xjs_compile');
 load(settings.web_lib + 'mime-decode.js');
 
 function listGroups() {
@@ -404,10 +405,25 @@ function getMailBody(number) {
     ret.body = formatMessage(pt_body == body ? decoded.body : pt_body); // See above re: pt_body
     ret.inlines = decoded.inlines;
     ret.attachments = decoded.attachments;
+    if (user.is_sysop) {
+        ret.buttons = [
+            format(xjs_eval(settings.web_components + 'twit-button.xjs', true), number, number, header.from, header.from_net_addr),
+        ];
+    }
 
     return ret;
 }
 
+function addTwit(str) {
+    const f = new File(system.ctrl_dir + 'twitlist.cfg');
+    if (!f.open('a')) {
+        log(LOG_ERR, 'Failed to add ' + str + ' to twitlist');
+        return;
+    }
+    f.writeln(str);
+    f.close();
+}
+
 // Returns the user's signature, or an empty String
 function getSignature() {
     var fn = format('%s/user/%04d.sig', system.data_dir, user.number);