class_docstr: A publisher that attaches previous publications as an attachment
  
  By default, this publisher needs to be run after the Summary publisher, as it depends on
  the magic-magic _previous_publication field.
class_docstr_tok: ["A","publisher","that","attaches","previous","publications","as","an","attachment","By","default",",","this","publisher","needs","to","be","run","after","the","Summary","publisher",",","as","it","depends","on","the","magic-magic","_previous_publication","field","."]
code: def publish(self, alert, publication):
      if (
          "@slack._previous_publication" not in publication
          or "@slack.attachments" not in publication
      ):
          # This publisher cannot be run except immediately after the Summary publisher
          return publication
  
      publication_block = "```\n{}\n```".format(
          json.dumps(
              self._get_publication(alert, publication),
              indent=2,
              sort_keys=True,
              separators=(",", ": "),
          )
      )
  
      publication["@slack.attachments"].append(
          {
              "color": self._color(),
              "title": "Alert Data:",
              "text": cgi.escape(publication_block),
              "mrkdwn_in": ["text"],
          }
      )
  
      return publication
  
imports: import calendar
  import cgi
  import json
  import urllib.request, urllib.parse, urllib.error
  from streamalert.shared.publisher import AlertPublisher, Register
  from streamalert.shared.description import RuleDescriptionParser
label_desc: Use image node_id 1 for calling the AttachPublication obj's underlying member method code with example usage: obj.publish(alert, publication) and returns: publication, publication