diff --git a/src/applications/macro/editor/PhabricatorMacroEditor.php b/src/applications/macro/editor/PhabricatorMacroEditor.php
--- a/src/applications/macro/editor/PhabricatorMacroEditor.php
+++ b/src/applications/macro/editor/PhabricatorMacroEditor.php
@@ -19,44 +19,6 @@
     return pht('%s created %s.', $author, $object);
   }
 
-  protected function applyCustomExternalTransaction(
-    PhabricatorLiskDAO $object,
-    PhabricatorApplicationTransaction $xaction) {
-
-    switch ($xaction->getTransactionType()) {
-      case PhabricatorMacroFileTransaction::TRANSACTIONTYPE:
-      case PhabricatorMacroAudioTransaction::TRANSACTIONTYPE:
-        // When changing a macro's image or audio, attach the underlying files
-        // to the macro (and detach the old files).
-        $old = $xaction->getOldValue();
-        $new = $xaction->getNewValue();
-        $all = array();
-        if ($old) {
-          $all[] = $old;
-        }
-        if ($new) {
-          $all[] = $new;
-        }
-
-        $files = id(new PhabricatorFileQuery())
-          ->setViewer($this->requireActor())
-          ->withPHIDs($all)
-          ->execute();
-        $files = mpull($files, null, 'getPHID');
-
-        $old_file = idx($files, $old);
-        if ($old_file) {
-          $old_file->detachFromObject($object->getPHID());
-        }
-
-        $new_file = idx($files, $new);
-        if ($new_file) {
-          $new_file->attachToObject($object->getPHID());
-        }
-        break;
-    }
-  }
-
   protected function shouldSendMail(
     PhabricatorLiskDAO $object,
     array $xactions) {
diff --git a/src/applications/macro/xaction/PhabricatorMacroAudioTransaction.php b/src/applications/macro/xaction/PhabricatorMacroAudioTransaction.php
--- a/src/applications/macro/xaction/PhabricatorMacroAudioTransaction.php
+++ b/src/applications/macro/xaction/PhabricatorMacroAudioTransaction.php
@@ -13,6 +13,34 @@
     $object->setAudioPHID($value);
   }
 
+  public function applyExternalEffects($object, $value) {
+    $old = $this->generateOldValue($object);
+    $new = $value;
+    $all = array();
+    if ($old) {
+      $all[] = $old;
+    }
+    if ($new) {
+      $all[] = $new;
+    }
+
+    $files = id(new PhabricatorFileQuery())
+      ->setViewer($this->getActor())
+      ->withPHIDs($all)
+      ->execute();
+    $files = mpull($files, null, 'getPHID');
+
+    $old_file = idx($files, $old);
+    if ($old_file) {
+      $old_file->detachFromObject($object->getPHID());
+    }
+
+    $new_file = idx($files, $new);
+    if ($new_file) {
+      $new_file->attachToObject($object->getPHID());
+    }
+  }
+
   public function getTitle() {
     $new = $this->getNewValue();
     $old = $this->getOldValue();
diff --git a/src/applications/macro/xaction/PhabricatorMacroFileTransaction.php b/src/applications/macro/xaction/PhabricatorMacroFileTransaction.php
--- a/src/applications/macro/xaction/PhabricatorMacroFileTransaction.php
+++ b/src/applications/macro/xaction/PhabricatorMacroFileTransaction.php
@@ -13,6 +13,34 @@
     $object->setFilePHID($value);
   }
 
+  public function applyExternalEffects($object, $value) {
+    $old = $this->generateOldValue($object);
+    $new = $value;
+    $all = array();
+    if ($old) {
+      $all[] = $old;
+    }
+    if ($new) {
+      $all[] = $new;
+    }
+
+    $files = id(new PhabricatorFileQuery())
+      ->setViewer($this->getActor())
+      ->withPHIDs($all)
+      ->execute();
+    $files = mpull($files, null, 'getPHID');
+
+    $old_file = idx($files, $old);
+    if ($old_file) {
+      $old_file->detachFromObject($object->getPHID());
+    }
+
+    $new_file = idx($files, $new);
+    if ($new_file) {
+      $new_file->attachToObject($object->getPHID());
+    }
+  }
+
   public function getTitle() {
     return pht(
       '%s changed the image for this macro.',