{
  "name": "Generate EPUB Book",
  "nodes": [
    {
      "parameters": {
        "content": "## Generate EPUB Book\n\nTechnical publishers and self-publishing platforms use this recipe to generate an EPUB e-book from structured content. Define chapters with headings, paragraphs, and a table of contents \u2014 the API handles formatting and packaging into a valid EPUB file ready for distribution.\n\n**Note:** This workflow uses the Iteration Layer community node (`n8n-nodes-iterationlayer`). Install it via Settings > Community Nodes on self-hosted n8n, or add it directly on n8n Cloud with Verified Community Nodes enabled.",
        "height": 280,
        "width": 500,
        "color": 2
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        200,
        40
      ],
      "id": "5ef83154-90d3-4f16-aae2-2eb0792447d2",
      "name": "Overview"
    },
    {
      "parameters": {
        "content": "### Step 1: Generate Document\nResource: **Document Generation**\n\nConfigure the Document Generation parameters below, then connect your credentials.",
        "height": 160,
        "width": 300,
        "color": 6
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        475,
        100
      ],
      "id": "0859a215-9a92-497e-99d7-5fbffa72c539",
      "name": "Step 1 Note"
    },
    {
      "parameters": {},
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        250,
        300
      ],
      "id": "40dd8a1c-dd01-4281-ae11-a98d806008d8",
      "name": "Manual Trigger"
    },
    {
      "parameters": {
        "resource": "documentGeneration",
        "format": "epub",
        "documentJson": "{\n  \"metadata\": {\n    \"title\": \"Practical Guide to Event-Driven Architecture\",\n    \"author\": \"Sarah Chen\"\n  },\n  \"page\": {\n    \"size\": {\n      \"preset\": \"A5\"\n    },\n    \"margins\": {\n      \"top_in_pt\": 54,\n      \"right_in_pt\": 54,\n      \"bottom_in_pt\": 54,\n      \"left_in_pt\": 54\n    }\n  },\n  \"styles\": {\n    \"text\": {\n      \"font_family\": \"Helvetica\",\n      \"font_size_in_pt\": 11.0,\n      \"line_height\": 1.5,\n      \"color\": \"#333333\"\n    },\n    \"headline\": {\n      \"font_family\": \"Helvetica\",\n      \"font_size_in_pt\": 24.0,\n      \"color\": \"#111111\",\n      \"spacing_before_in_pt\": 12.0,\n      \"spacing_after_in_pt\": 6.0,\n      \"font_weight\": \"bold\"\n    },\n    \"link\": {\n      \"color\": \"#0066CC\",\n      \"is_underlined\": true\n    },\n    \"list\": {\n      \"text_style\": {\n        \"font_family\": \"Helvetica\",\n        \"font_size_in_pt\": 11.0,\n        \"line_height\": 1.5,\n        \"color\": \"#333333\"\n      },\n      \"marker_color\": \"#333333\",\n      \"marker_gap_in_pt\": 8.0\n    },\n    \"table\": {\n      \"header\": {\n        \"background_color\": \"#333333\",\n        \"text_color\": \"#FFFFFF\",\n        \"font_size_in_pt\": 11.0,\n        \"font_weight\": \"bold\"\n      },\n      \"body\": {\n        \"background_color\": \"#FFFFFF\",\n        \"text_color\": \"#333333\",\n        \"font_size_in_pt\": 11.0\n      },\n      \"border\": {\n        \"outer\": {\n          \"top\": {\n            \"color\": \"#CCCCCC\",\n            \"width_in_pt\": 1.0\n          },\n          \"right\": {\n            \"color\": \"#CCCCCC\",\n            \"width_in_pt\": 1.0\n          },\n          \"bottom\": {\n            \"color\": \"#CCCCCC\",\n            \"width_in_pt\": 1.0\n          },\n          \"left\": {\n            \"color\": \"#CCCCCC\",\n            \"width_in_pt\": 1.0\n          }\n        },\n        \"inner\": {\n          \"horizontal\": {\n            \"color\": \"#EEEEEE\",\n            \"width_in_pt\": 0.5\n          },\n          \"vertical\": {\n            \"color\": \"#EEEEEE\",\n            \"width_in_pt\": 0.5\n          }\n        }\n      }\n    },\n    \"grid\": {\n      \"background_color\": \"#FFFFFF\",\n      \"border_color\": \"#CCCCCC\",\n      \"border_width_in_pt\": 0.0,\n      \"gap_in_pt\": 12.0\n    },\n    \"separator\": {\n      \"color\": \"#CCCCCC\",\n      \"thickness_in_pt\": 1.0,\n      \"spacing_before_in_pt\": 12.0,\n      \"spacing_after_in_pt\": 12.0\n    },\n    \"image\": {\n      \"border_color\": \"#000000\",\n      \"border_width_in_pt\": 0.0\n    }\n  },\n  \"content\": [\n    {\n      \"type\": \"headline\",\n      \"level\": \"h1\",\n      \"text\": \"Practical Guide to Event-Driven Architecture\"\n    },\n    {\n      \"type\": \"paragraph\",\n      \"markdown\": \"*By Sarah Chen*\"\n    },\n    {\n      \"type\": \"separator\"\n    },\n    {\n      \"type\": \"table-of-contents\",\n      \"levels\": [\n        \"h1\",\n        \"h2\"\n      ],\n      \"leader\": \"dots\"\n    },\n    {\n      \"type\": \"page-break\"\n    },\n    {\n      \"type\": \"headline\",\n      \"level\": \"h1\",\n      \"text\": \"Chapter 1: Core Concepts\"\n    },\n    {\n      \"type\": \"paragraph\",\n      \"markdown\": \"Event-driven architecture (EDA) is a software design pattern in which the flow of the program is determined by **events** \\u2014 significant changes in state that the system needs to react to. Unlike traditional request-response models,\\n            EDA decouples producers from consumers,\\n            enabling systems to scale independently.\"\n    },\n    {\n      \"type\": \"paragraph\",\n      \"markdown\": \"At its core,\\n            every event-driven system consists of three parts: **event producers**,\\n            which detect and publish state changes; **event channels**,\\n            which transport events between components; and **event consumers**,\\n            which react to incoming events by executing business logic.\"\n    },\n    {\n      \"type\": \"list\",\n      \"variant\": \"unordered\",\n      \"items\": [\n        {\n          \"text\": \"Loose coupling between services\"\n        },\n        {\n          \"text\": \"Independent scalability of producers and consumers\"\n        },\n        {\n          \"text\": \"Natural audit trail through event logs\"\n        },\n        {\n          \"text\": \"Resilience through asynchronous processing\"\n        }\n      ]\n    },\n    {\n      \"type\": \"page-break\"\n    },\n    {\n      \"type\": \"headline\",\n      \"level\": \"h1\",\n      \"text\": \"Chapter 2: Messaging Patterns\"\n    },\n    {\n      \"type\": \"paragraph\",\n      \"markdown\": \"Choosing the right messaging pattern is critical to building a reliable event-driven system. The two most common approaches are **publish-subscribe** and **event streaming**. Publish-subscribe delivers events to all interested subscribers in real time,\\n            while event streaming persists events in an ordered log that consumers can replay at their own pace.\"\n    },\n    {\n      \"type\": \"paragraph\",\n      \"markdown\": \"A robust messaging layer must handle **at-least-once delivery**,\\n            **idempotency**,\\n            and **ordering guarantees**. Without these properties,\\n            consumers may process duplicate events,\\n            miss events entirely,\\n            or see them out of order \\u2014 all of which can corrupt downstream state.\"\n    },\n    {\n      \"type\": \"table\",\n      \"column_widths_in_percent\": [\n        30,\n        35,\n        35\n      ],\n      \"header\": {\n        \"cells\": [\n          {\n            \"text\": \"Pattern\"\n          },\n          {\n            \"text\": \"Best For\"\n          },\n          {\n            \"text\": \"Trade-off\"\n          }\n        ]\n      },\n      \"rows\": [\n        {\n          \"cells\": [\n            {\n              \"text\": \"Publish-Subscribe\"\n            },\n            {\n              \"text\": \"Real-time notifications\"\n            },\n            {\n              \"text\": \"No replay capability\"\n            }\n          ]\n        },\n        {\n          \"cells\": [\n            {\n              \"text\": \"Event Streaming\"\n            },\n            {\n              \"text\": \"Audit logs,\\n                  replay\"\n            },\n            {\n              \"text\": \"Higher storage cost\"\n            }\n          ]\n        },\n        {\n          \"cells\": [\n            {\n              \"text\": \"Request-Reply\"\n            },\n            {\n              \"text\": \"Synchronous workflows\"\n            },\n            {\n              \"text\": \"Tight coupling\"\n            }\n          ]\n        }\n      ]\n    },\n    {\n      \"type\": \"page-break\"\n    },\n    {\n      \"type\": \"headline\",\n      \"level\": \"h1\",\n      \"text\": \"Chapter 3: Implementation Strategies\"\n    },\n    {\n      \"type\": \"paragraph\",\n      \"markdown\": \"When implementing event-driven architecture in production,\\n            start with a **single event bus** and a small number of well-defined event types. Resist the temptation to model every state change as an event. Instead,\\n            focus on domain events that carry business meaning \\u2014 an order was placed,\\n            a payment was processed,\\n            a shipment was dispatched.\"\n    },\n    {\n      \"type\": \"paragraph\",\n      \"markdown\": \"Adopt a **schema registry** early to enforce contracts between producers and consumers. Versioned schemas prevent breaking changes from propagating through the system and make it safe for teams to evolve their events independently.\"\n    },\n    {\n      \"type\": \"list\",\n      \"variant\": \"ordered\",\n      \"items\": [\n        {\n          \"text\": \"Define your domain events and their schemas\"\n        },\n        {\n          \"text\": \"Set up a message broker with dead-letter queues\"\n        },\n        {\n          \"text\": \"Implement idempotent consumers with deduplication\"\n        },\n        {\n          \"text\": \"Add monitoring and alerting for consumer lag\"\n        },\n        {\n          \"text\": \"Introduce event versioning and a schema registry\"\n        }\n      ]\n    }\n  ]\n}"
      },
      "type": "n8n-nodes-iterationlayer.iterationLayer",
      "typeVersion": 1,
      "position": [
        500,
        300
      ],
      "id": "e71ccba8-093a-4a70-9d9f-614bd8864e35",
      "name": "Generate Document",
      "credentials": {
        "iterationLayerApi": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "Manual Trigger": {
      "main": [
        [
          {
            "node": "Generate Document",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  }
}