{
  "name": "Ratifia: approve a customer reply (community node)",
  "nodes": [
    {
      "parameters": {
        "content": "## Approve an AI-drafted reply, with the Ratifia node\n\n**Ask for approval** sends the draft to the people in your policy and waits. Its **Facts** are the exact email: recipient, subject, body and attachments.\n\nAn approval is not a green light for anything. Before sending, **Verify** and **Consume** check that it covers *this* email: edit it after approval and it is refused; send it twice and it goes out once.",
        "height": 240,
        "width": 560
      },
      "id": "57f64f80-41de-4e17-96b7-d7dfd7e45ea9",
      "name": "Note 6caa66",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        0,
        0
      ]
    },
    {
      "parameters": {},
      "id": "a1b79c2b-e07c-4d6e-90f5-bd08285806dc",
      "name": "Run it",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        0,
        300
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "7e762ece-3595-4005-ae04-a89bc7fd598f",
              "name": "recipient",
              "value": "dana@acme.com",
              "type": "string"
            },
            {
              "id": "5c66dcc6-1d18-4c98-8de6-3e7686394296",
              "name": "subject",
              "value": "Your refund for invoice INV-2291",
              "type": "string"
            },
            {
              "id": "f7adcf2e-7b45-4a38-9712-730ab2792c94",
              "name": "body",
              "value": "Hi Dana,\n\nWe've refunded the duplicate charge of $620.00 to the card ending 4242. It should appear within 5 business days.\n\nThanks for your patience,\nAcme Support",
              "type": "string"
            },
            {
              "id": "5112d74c-fa95-419a-a523-f3e71ab54d38",
              "name": "attachments",
              "value": "={{ [\"refund-receipt-INV-2291.pdf\"] }}",
              "type": "array"
            },
            {
              "id": "61951e81-fb44-4a01-aa61-d1cead07ff8a",
              "name": "amount",
              "value": 620,
              "type": "number"
            }
          ]
        },
        "options": {}
      },
      "id": "1d964715-ed8e-46ec-94df-f0e24f60b266",
      "name": "Draft reply",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        220,
        300
      ]
    },
    {
      "parameters": {
        "operation": "requestAndWait",
        "prompt": "=Send this reply to {{ $json.recipient }}?\n\nSubject: {{ $json.subject }}\n\n{{ $json.body }}",
        "policy": "customer-replies",
        "factsTable": {
          "fact": [
            {
              "name": "recipient",
              "type": "string",
              "value": "={{ $(\"Draft reply\").item.json.recipient }}",
              "showReviewer": true,
              "src": "tool"
            },
            {
              "name": "subject",
              "type": "string",
              "value": "={{ $(\"Draft reply\").item.json.subject }}",
              "showReviewer": true,
              "src": "tool"
            },
            {
              "name": "body",
              "type": "string",
              "value": "={{ $(\"Draft reply\").item.json.body }}",
              "showReviewer": true,
              "src": "tool"
            },
            {
              "name": "attachments",
              "type": "array",
              "value": "={{ $(\"Draft reply\").item.json.attachments }}",
              "showReviewer": true,
              "src": "tool"
            }
          ]
        },
        "options": {
          "title": "=Reply to {{ $json.recipient }}",
          "workflowRef": "customer-replies"
        },
        "waitOptions": {
          "pollIntervalSec": 15,
          "maxWaitMinutes": 60
        }
      },
      "id": "662e6120-f781-46fa-a5ec-e01b2ff83173",
      "name": "Ask for approval",
      "type": "n8n-nodes-ratifia.ratifia",
      "typeVersion": 1,
      "position": [
        440,
        300
      ]
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "loose",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "8b85ebf6-437f-4d57-8fc0-74249df8e603",
                    "leftValue": "={{ $json.status }}",
                    "rightValue": "APPROVED",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Approved"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "loose",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "d140a3d2-a24d-487e-b530-02f1935aba03",
                    "leftValue": "={{ $json.status }}",
                    "rightValue": "REJECTED",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Rejected"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "loose",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "ecc37216-cb13-4dbd-a9b9-9b1013cd63a2",
                    "leftValue": "={{ $json.status }}",
                    "rightValue": "EXPIRED",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Expired"
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra",
          "renameFallbackOutput": "Cancelled"
        }
      },
      "id": "06d707ae-f5ab-4b98-b3d7-5e3963f94372",
      "name": "Verdict",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.2,
      "position": [
        660,
        300
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "2d0510c6-f2f7-465f-a4f8-190ed513cb5e",
              "name": "recipient",
              "value": "={{ $(\"Draft reply\").item.json.recipient }}",
              "type": "string"
            },
            {
              "id": "97f6e75b-476d-45ef-ab56-29efb11ededa",
              "name": "subject",
              "value": "={{ $(\"Draft reply\").item.json.subject }}",
              "type": "string"
            },
            {
              "id": "42641f78-5327-49c5-a683-9ef5f5d8e179",
              "name": "body",
              "value": "={{ $(\"Draft reply\").item.json.body }}",
              "type": "string"
            },
            {
              "id": "717c2942-9a2e-4b6b-bf0c-b0deb43b65e5",
              "name": "attachments",
              "value": "={{ $(\"Draft reply\").item.json.attachments }}",
              "type": "array"
            }
          ]
        },
        "options": {}
      },
      "id": "ea2d0f84-83a2-42e1-9d25-d536cae2e47a",
      "name": "The email to send",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        880,
        140
      ]
    },
    {
      "parameters": {
        "operation": "verify",
        "decisionId": "={{ $(\"Ask for approval\").item.json.id }}",
        "actionFactsTable": {
          "fact": [
            {
              "name": "recipient",
              "type": "string",
              "value": "={{ $(\"The email to send\").item.json.recipient }}"
            },
            {
              "name": "subject",
              "type": "string",
              "value": "={{ $(\"The email to send\").item.json.subject }}"
            },
            {
              "name": "body",
              "type": "string",
              "value": "={{ $(\"The email to send\").item.json.body }}"
            },
            {
              "name": "attachments",
              "type": "array",
              "value": "={{ $(\"The email to send\").item.json.attachments }}"
            }
          ]
        }
      },
      "id": "805ec4ad-cd36-4ddb-9faa-8beb5af5fca2",
      "name": "Verify approval",
      "type": "n8n-nodes-ratifia.ratifia",
      "typeVersion": 1,
      "position": [
        1100,
        140
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 2
          },
          "conditions": [
            {
              "id": "6defc4f1-e96d-4592-bd68-a443dc57f9c7",
              "leftValue": "={{ $json.valid }}",
              "rightValue": "",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            },
            {
              "id": "57e15772-6e41-41fa-90e3-d554e33194e6",
              "leftValue": "={{ $json.reason }}",
              "rightValue": "consumed",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            }
          ],
          "combinator": "or"
        },
        "options": {}
      },
      "id": "164284af-8fd2-4071-abc0-55b62c9e20f2",
      "name": "Covers this email?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        1320,
        140
      ]
    },
    {
      "parameters": {
        "operation": "consume",
        "decisionId": "={{ $(\"Ask for approval\").item.json.id }}",
        "actionFactsTable": {
          "fact": [
            {
              "name": "recipient",
              "type": "string",
              "value": "={{ $(\"The email to send\").item.json.recipient }}"
            },
            {
              "name": "subject",
              "type": "string",
              "value": "={{ $(\"The email to send\").item.json.subject }}"
            },
            {
              "name": "body",
              "type": "string",
              "value": "={{ $(\"The email to send\").item.json.body }}"
            },
            {
              "name": "attachments",
              "type": "array",
              "value": "={{ $(\"The email to send\").item.json.attachments }}"
            }
          ]
        },
        "consumer": "={{ \"send-email:\" + $(\"Verify approval\").item.json.factsHash }}"
      },
      "id": "4d779520-6f99-4f0c-ad17-2c7f448dc61a",
      "name": "Consume approval",
      "type": "n8n-nodes-ratifia.ratifia",
      "typeVersion": 1,
      "position": [
        1540,
        40
      ]
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "loose",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "74ee13cf-0e13-4afd-9e1e-93e11663dc43",
                    "leftValue": "={{ $json.alreadyConsumed }}",
                    "rightValue": "",
                    "operator": {
                      "type": "boolean",
                      "operation": "true",
                      "singleValue": true
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Already sent"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "loose",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "aa1f3b14-a068-4295-9cc0-f5873fdf1687",
                    "leftValue": "={{ $json.consumed }}",
                    "rightValue": "",
                    "operator": {
                      "type": "boolean",
                      "operation": "true",
                      "singleValue": true
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Send"
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra",
          "renameFallbackOutput": "Refused"
        }
      },
      "id": "03e2d60c-7942-4fc7-a15c-d738af8dcb33",
      "name": "Send it?",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.2,
      "position": [
        1760,
        40
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "89da3a80-6ae2-4c94-a500-146d9c89bf7b",
              "name": "sent",
              "value": "={{ true }}",
              "type": "boolean"
            },
            {
              "id": "c6a77af5-77da-4321-8332-c2abe937355b",
              "name": "to",
              "value": "={{ $(\"The email to send\").item.json.recipient }}",
              "type": "string"
            },
            {
              "id": "e93dc2b6-4001-484e-897d-66e98e9699a5",
              "name": "subject",
              "value": "={{ $(\"The email to send\").item.json.subject }}",
              "type": "string"
            },
            {
              "id": "64499641-c334-4228-9387-a0c566ae01f4",
              "name": "approvedUnder",
              "value": "={{ $json.decision.policyVersion ? \"policy v\" + $json.decision.policyVersion : \"no policy\" }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "acfee49b-465d-4370-86c7-cc8d822b59f6",
      "name": "Send customer email (stand-in)",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        2000,
        -120
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "36579367-f1b8-4974-bfc9-91373075af00",
              "name": "sent",
              "value": "={{ false }}",
              "type": "boolean"
            },
            {
              "id": "8058b22d-55d0-4cde-bba7-c9ad71117ce2",
              "name": "why",
              "value": "a retry of an email that was already sent",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "0d0daf6a-b489-424a-a769-dedc80c6a73a",
      "name": "Already sent, not sending again",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        2000,
        40
      ]
    },
    {
      "parameters": {
        "errorMessage": "=Not sent: {{ $json.reason }}"
      },
      "id": "ff5d6762-42bf-4291-8cb7-12607b0b1057",
      "name": "Refuse: approval already spent",
      "type": "n8n-nodes-base.stopAndError",
      "typeVersion": 1,
      "position": [
        2000,
        200
      ]
    },
    {
      "parameters": {
        "errorMessage": "=Not sent: {{ $json.reason }}"
      },
      "id": "e9c9fe7f-1550-425e-ba12-338f597c6c07",
      "name": "Refuse: approval does not cover this email",
      "type": "n8n-nodes-base.stopAndError",
      "typeVersion": 1,
      "position": [
        1540,
        380
      ]
    },
    {
      "parameters": {},
      "id": "2070c2a0-76b2-47b6-8bd1-2e5512f99450",
      "name": "Rejected: do not send",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        880,
        460
      ]
    },
    {
      "parameters": {},
      "id": "0e3685ab-e5f0-4dd0-aa4d-ea2848f16281",
      "name": "Nobody answered in time",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        880,
        600
      ]
    },
    {
      "parameters": {},
      "id": "613c5a63-41fd-4f2f-ac03-27d950019bb6",
      "name": "Request was cancelled",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        880,
        740
      ]
    }
  ],
  "connections": {
    "Run it": {
      "main": [
        [
          {
            "node": "Draft reply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Draft reply": {
      "main": [
        [
          {
            "node": "Ask for approval",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Ask for approval": {
      "main": [
        [
          {
            "node": "Verdict",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "The email to send": {
      "main": [
        [
          {
            "node": "Verify approval",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Verdict": {
      "main": [
        [
          {
            "node": "The email to send",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Rejected: do not send",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Nobody answered in time",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Request was cancelled",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Verify approval": {
      "main": [
        [
          {
            "node": "Covers this email?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Covers this email?": {
      "main": [
        [
          {
            "node": "Consume approval",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Refuse: approval does not cover this email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Consume approval": {
      "main": [
        [
          {
            "node": "Send it?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send it?": {
      "main": [
        [
          {
            "node": "Already sent, not sending again",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send customer email (stand-in)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Refuse: approval already spent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  }
}
