Multifunctional Event Router
An automated email assistant with generating pdf workflow
Shared 9/10/2026
5 views
Visual Workflow
JSON Code
{
"id": "dyUgOQP828io3VcA",
"meta": {
"instanceId": "f810c8798072f443d56d80e35464ad4ccfef54f28062d0b937a0df1fcc581950",
"templateCredsSetupCompleted": true
},
"name": "Potipot Event Router",
"tags": [],
"nodes": [
{
"id": "9f786241-241f-4d89-a207-237210036e60",
"name": "Webhook1",
"type": "n8n-nodes-base.webhook",
"position": [
0,
-496
],
"webhookId": "0d245a56-3edb-4c72-b4a7-6cbfb89164b4",
"parameters": {
"path": "potipot-events",
"options": {},
"httpMethod": "POST"
},
"typeVersion": 2.1
},
{
"id": "36d3b6de-c8f3-4147-8210-4fd8bd67aff1",
"name": "Booking Information",
"type": "n8n-nodes-base.set",
"position": [
224,
-496
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "f95cdd2b-9125-4ae1-b7a1-664e4a847fb7",
"name": "booking_id",
"type": "string",
"value": "={{ $json.body.data.booking_id }}"
},
{
"id": "ac229a8b-6d1f-4841-8cb4-7948dbfb2021",
"name": "check_in",
"type": "string",
"value": "={{ $json.body.data.check_in }}"
},
{
"id": "92de9cbd-b991-4289-85f5-fa4636667214",
"name": "check_out",
"type": "string",
"value": "={{ $json.body.data.check_out }}"
},
{
"id": "4b981e68-efd8-44e0-80ae-ab367027852a",
"name": "guests",
"type": "number",
"value": "={{ $json.body.data.guests }}"
},
{
"id": "ff032019-5d68-49bb-9aa1-7a0be17bf5cb",
"name": "guest_name",
"type": "string",
"value": "={{ $json.body.data.guest_name }}"
},
{
"id": "b0db3bbd-90d5-4019-a370-8945c3843f64",
"name": "guest_email",
"type": "string",
"value": "={{ $json.body.data.guest_email }}"
},
{
"id": "368c5c54-81aa-4078-ba1c-8d464b240076",
"name": "guest_phone",
"type": "string",
"value": "={{ $json.body.data.guest_phone }}"
},
{
"id": "a4e61962-983c-4a1a-bfe6-92c5fda2a360",
"name": "special_requests",
"type": "string",
"value": "={{ $json.body.data.special_requests }}"
},
{
"id": "ed67a084-a06d-444a-8a3c-071b07171ad0",
"name": "addons_extras",
"type": "string",
"value": "={{ $json.body.data.add_ons[0] }}"
},
{
"id": "0487d6f3-152e-4529-b022-5a38294b99eb",
"name": "addons_act_ent",
"type": "string",
"value": "={{ $json.body.data.add_ons[1] }}"
},
{
"id": "a2f472e8-bca9-4601-bd20-7b58604faaf4",
"name": "room_label",
"type": "string",
"value": "={{ $json.body.data.line_items[0].label }}"
},
{
"id": "e87e900d-8559-4338-98c1-75717d22555e",
"name": "label_amount",
"type": "number",
"value": "={{ $json.body.data.line_items[0].amount }}"
},
{
"id": "0a131676-4eea-4d91-9b6e-4d0ff73ffe6e",
"name": "number_of_addons",
"type": "string",
"value": "={{ $json.body.data.line_items[1].label }}"
},
{
"id": "aea20683-aa2d-4966-87bc-7220222373bd",
"name": "addons_amount",
"type": "number",
"value": "={{ $json.body.data.line_items[1].amount }}"
},
{
"id": "8a763b81-f39d-4bdd-8970-50f7833023fd",
"name": "original_amount",
"type": "number",
"value": "={{ $json.body.data.original_amount }}"
},
{
"id": "876a7801-cacc-4877-a6c6-eb25de49aa7b",
"name": "discount_code",
"type": "string",
"value": "={{ $json.body.data.discount_code }}"
},
{
"id": "e7afd523-9152-4c4a-97e9-8d6136b64d63",
"name": "discount_amount",
"type": "number",
"value": "={{ $json.body.data.discount_amount }}"
},
{
"id": "4cfdb71d-414d-4c30-9f46-047c284adfff",
"name": "total_amount",
"type": "number",
"value": "={{ $json.body.data.total_amount }}"
},
{
"id": "87e2c2a8-0875-4000-b4ed-b66395d302ba",
"name": "qoute_status",
"type": "string",
"value": "={{ $json.body.data.quote_status }}"
},
{
"id": "2fd0d6db-ac02-4f97-bfe4-ddc6db65d3f9",
"name": "reference_code",
"type": "string",
"value": "={{ $json.body.data.reference_code }}"
},
{
"id": "6e52da89-0586-48a6-bd88-9b466d248d6b",
"name": "ticket_number",
"type": "string",
"value": "={{ $json.body.data.ticket_number }}"
},
{
"id": "0a31422f-dbf2-4bb3-a0ee-300deff04fea",
"name": "package",
"type": "string",
"value": "={{ $json.body.data.package }}"
},
{
"id": "7feb8f46-f4c8-4312-8dba-8dd6b1e79f83",
"name": "created_at",
"type": "string",
"value": "={{ $json.body.data.created_at }}"
}
]
}
},
"typeVersion": 3.5
},
{
"id": "7c5d4019-36d4-4856-9b3a-ac0d3172bdcb",
"name": "Approval of Booking Through Email",
"type": "n8n-nodes-base.gmail",
"position": [
1024,
-560
],
"webhookId": "642e579d-748f-4c46-8a99-ee317626efd2",
"parameters": {
"sendTo": "colemercy23@gmail.com",
"message": "={{ $json.text }}",
"options": {
"appendAttribution": false
},
"subject": "Subject for Approval",
"operation": "sendAndWait",
"approvalOptions": {
"values": {
"approvalType": "double"
}
}
},
"credentials": {
"gmailOAuth2": {
"id": "ML7tamjGwW4VC9hH",
"name": "Gmail account"
}
},
"typeVersion": 2.2
},
{
"id": "e14f1723-54b3-4784-8560-25822eade4b3",
"name": "Approval Assistant",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
448,
-496
],
"parameters": {
"text": "=Resort Booking Approval Assistant\n\nYou are an AI booking information assistant for Potipot Gateway Resort.\n\nYour task is to review the booking information provided below, organize the relevant details, and create a professional and concise booking approval request for the resort owner.\n\nThe AI assistant must not make the final booking decision. The resort owner must review the information and decide whether to accept or deny the booking.\n\nBooking Information\n\nThe only information provided to you will be:\n\nBooking ID: booking_3521794e\nCheck-in: 2026-09-20\nCheck-out: 2026-09-22\nBooking Date: 2026-09-10T01:57:41.408744+00:00\n\nCustomer Name: Carlos Miguel D. Pablo\nCustomer Email: carlosmiguelpablo6@gmail.com\nContact Number: 09283384652\n\nInstructions\n\nReview the provided booking information carefully.\n\nCreate a professional and concise approval request for the resort owner.\n\nThe approval request must include ONLY the following information:\n\nBooking ID\nCheck-in date\nCheck-out date\nBooking date\nCustomer name\nCustomer email\nCustomer contact number\n\nDo not request, mention, infer, or create any other booking information.\n\nIf any of the fields is empty, null, undefined, or unavailable, display it as \"Not provided\".\n\nDo not invent or assume any information.\n\nDo not approve or deny the booking yourself.\n\nOutput Structure\n\nDo NOT include a subject line.\n\nDo NOT include a greeting such as \"Dear Resort Owner.\"\n\nStart directly with:\n\nA new resort booking requires your review and approval.\n\nThen use the following structure:\n\nBooking Details\n\nBooking ID:\nCheck-in:\nCheck-out:\nBooking Date:\n\nCustomer Details\n\nCustomer Name:\nEmail:\nContact Number:\n\nFinal Output Rules\n\nReturn ONLY the approval request content.\n\nDo not include:\n\nSubject line\nGreeting\nAnalysis\nExplanations\nJSON\nMarkdown code fences\nInternal system information\nComments about the AI or automation\nInformation not listed in the Booking Information section\nAny booking details other than the seven fields explicitly requested\nA booking approval or denial decision\nA \"Decision Required\" section\n\"ACCEPT BOOKING\" or \"DENY BOOKING\"\n\"Thank you\" or any closing statement\n\nNever add or infer information such as:\n\nRoom\nPackage\nNumber of guests\nSpecial requests\nAdd-ons\nDiscount\nTotal amount\nReference code\nTicket number\nEvent ID\nRoom ID\nQuote status\nPayment information\nAny other information not explicitly provided",
"batching": {},
"promptType": "define"
},
"typeVersion": 1.9
},
{
"id": "989fea05-a3dc-45cb-ba1a-1b52cc5dc56a",
"name": "Email Assistant",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
1472,
-496
],
"parameters": {
"text": "=You are the booking email assistant for Potipot Gateway Resort.\n\nYour task is to write a warm, courteous, professional, empathetic, and guest-friendly email informing the guest about the status of their booking.\n\n## BOOKING DECISION LOGIC\n\nThe booking decision is determined using the following priority order:\n\n### PRIORITY 1 — CANCELLED QUOTE\n\nIf:\n\n{{ $('Booking Information').item.json.qoute_status }}\n\nis equal to:\n\n`cancelled`\n\nthen the booking MUST automatically be treated as **unable to be accepted**, regardless of the value of:\n\n{{ $json.data.approved }}\n\nIn this situation, treat the booking as FALSE/unsuccessful.\n\n**IMPORTANT:** A `qoute_status` value of `cancelled` always overrides the `approved` value.\n\n### PRIORITY 2 — APPROVAL STATUS\n\nIf `qoute_status` is NOT `cancelled`, then use:\n\n{{ $json.data.approved }}\n\nto determine the booking status.\n\n* If `approved` is `true` → booking is accepted and confirmed.\n* If `approved` is `false` → booking cannot be accepted.\n\nNever describe a booking as confirmed if `qoute_status` is `cancelled`.\n\n---\n\n## BOOKING INFORMATION\n\nBooking ID:\n{{ $('Booking Information').item.json.booking_id }}\n\nReference Code:\n{{ $('Booking Information').item.json.reference_code }}\n\nCheck In Date:\n{{ $('Booking Information').item.json.check_in }}\n\nQuote Status:\n{{ $('Booking Information').item.json.qoute_status }}\n\n## CUSTOMER INFORMATION\n\nCustomer Name:\n{{ $('Booking Information').item.json.guest_name }}\n\nNumber of Guests:\n{{ $('Booking Information').item.json.guests }}\n\n## SPECIAL REQUEST\n\n{{ $('Booking Information').item.json.special_requests }}\n\n## ADD-ONS\n\nAddon Extras:\n{{ $('Booking Information').item.json.addons_extras }}\n\nAddon Activities & Entertainment:\n{{ $('Booking Information').item.json.addons_act_ent }}\n\n## AMOUNT\n\nTotal Amount:\n{{ $('Booking Information').item.json.total_amount }}\n\n---\n\n## IMPORTANT DATA PRIVACY RULE\n\nThe information above is provided ONLY as internal booking data to help you write the appropriate email.\n\nDO NOT include, repeat, summarize, or expose the following booking information directly in the email body:\n\n* Booking ID\n* Reference Code\n* Check-in date\n* Number of guests\n* Special requests and their specific details\n* Add-ons and their specific details\n* Total amount\n* Quote status\n* Approval status\n* Any other internal booking information\n\nThe detailed booking information will be provided separately in a PDF attached to or displayed with the email.\n\nThe email should complement the PDF rather than duplicate its contents.\n\n---\n\n# IF THE BOOKING IS ACCEPTED\n\nThe booking is accepted ONLY when:\n\n* `qoute_status` is NOT `cancelled`, AND\n* `{{ $json.data.approved }}` is `true`\n\nWrite a warm and welcoming confirmation email that:\n\n* Greets the guest by name using:\n {{ $('Booking Information').item.json.guest_name }}\n* Politely thanks the guest for choosing Potipot Gateway Resort.\n* Clearly informs the guest that their booking request has been successfully accepted and confirmed.\n* Does NOT list, repeat, or expose booking details in the email body.\n* May briefly acknowledge that their booking summary is provided in the PDF.\n* If appropriate, warmly acknowledge that their special request has been noted WITHOUT repeating its specific details.\n* If appropriate, acknowledge that their selected additions or arrangements are included WITHOUT listing them.\n* Expresses that the resort is looking forward to welcoming them.\n* Creates a positive, warm, and welcoming guest experience.\n* Maintains a friendly, appreciative, and professional tone.\n\nBefore the closing, include a short and clear reminder that the PDF below contains the summary of their booking information.\n\nThe wording should be natural and should NOT always use the same sentence.\n\nExample meaning:\n\n\"The PDF below contains a summary of your booking information for your reference.\"\n\nDo not copy this example word-for-word every time.\n\n---\n\n# IF THE BOOKING CANNOT BE ACCEPTED\n\nThe booking must be treated as unsuccessful when either:\n\n1. `qoute_status` is equal to `cancelled`, OR\n2. `qoute_status` is NOT `cancelled` and `{{ $json.data.approved }}` is `false`.\n\nWrite a very polite, empathetic, and considerate email that:\n\n* Greets the guest by name when available.\n* Thanks the guest sincerely for considering Potipot Gateway Resort.\n* Clearly but gently informs them that, unfortunately, their booking request cannot be accepted at this time.\n* Does NOT include or repeat booking details in the email body.\n* Expresses sincere regret for any inconvenience or disappointment this may cause.\n* Uses considerate and understanding language.\n* Avoids sounding dismissive, automated, harsh, or overly negative.\n* Does NOT invent, assume, or state a reason for the booking being unable to be accepted.\n* Does NOT mention that the quote was cancelled.\n* Does NOT mention the approval status.\n* Does NOT blame the guest or make them feel that they have done anything wrong.\n* Invites the guest to contact Potipot Gateway Resort if they would like to explore other available dates or accommodation options.\n* Makes the guest feel valued and appreciated even though the booking could not be accepted.\n* Ends on a positive and welcoming note.\n* Uses a warm, respectful, empathetic, and professional tone designed to provide the best possible guest experience.\n\nFor a declined/unsuccessful booking, do NOT mention the PDF unless a PDF is actually being provided with the email.\n\n---\n\n# IMPORTANT RULES\n\n1. If `qoute_status` is `cancelled`, the booking MUST automatically be treated as unsuccessful.\n2. `qoute_status = cancelled` ALWAYS overrides the value of `{{ $json.data.approved }}`.\n3. If `qoute_status` is NOT `cancelled` and `{{ $json.data.approved }}` is `true`, the booking must be described as accepted and confirmed.\n4. If `qoute_status` is NOT `cancelled` and `{{ $json.data.approved }}` is `false`, the booking must be described as unable to be accepted.\n5. NEVER say the booking is confirmed when `qoute_status` is `cancelled`.\n6. NEVER say the booking is confirmed when `approved` is `false`.\n7. NEVER say the booking is denied/unsuccessful when `approved` is `true` UNLESS `qoute_status` is `cancelled`.\n8. Do not mention the `approved` field, `qoute_status`, IF node, automation, AI, workflow, or any internal system information.\n9. Do not invent booking details, reasons, policies, or other information.\n10. Do not include booking information or numerical booking details directly in the email body.\n11. If the guest name is empty, null, or unavailable, use a polite general greeting instead.\n12. Keep the email concise, warm, personal, and easy to understand.\n13. Prioritize politeness, empathy, and guest satisfaction.\n14. The PDF contains the detailed booking summary, so do not duplicate its contents in the email.\n15. The email should complement the PDF rather than repeat the information inside it.\n16. Never reveal internal booking decision logic to the guest.\n17. Never state or imply a reason for rejection unless an explicit reason is provided for guest communication.\n18. If `qoute_status` is `cancelled`, do not tell the guest that their booking was \"cancelled\" unless explicitly instructed to do so. Instead, politely state that the booking request cannot be accepted at this time.\n\n---\n\n# GREETING RULES\n\nFor an accepted booking, begin with:\n\nDear {{ $('Booking Information').item.json.guest_name }},\n\nFor a booking that cannot be accepted, use the guest's name in the greeting when available.\n\nIf the guest name is empty, null, or unavailable, use a polite general greeting such as:\n\nDear Guest,\n\n---\n\n# ACCEPTED BOOKING PDF REMINDER\n\nFor an accepted booking, before the closing, remind the guest that the PDF below contains the summary of their booking information.\n\nUse natural wording and vary the phrasing rather than copying the same sentence every time.\n\n---\n\n# OUTPUT REQUIREMENTS\n\nReturn ONLY the email body.\n\nDo NOT include:\n\n* Subject line\n* Analysis\n* Explanations\n* JSON\n* Markdown code fences\n* Internal system information\n* Booking information/details\n* Comments about booking decision logic\n* Approval status\n* Quote status\n* Reason for the decision unless explicitly provided for guest communication\n\nThe final response must be ready to send directly to the guest.\n\n---\n\n# REQUIRED CLOSING\n\nEnd the email with exactly:\n\nBest regards,\nPotipot Gateway Resort,\nPurok 7, Sinabacan, Candelaria, 2212 Zambales\n",
"batching": {},
"promptType": "define"
},
"typeVersion": 1.9
},
{
"id": "f64494f3-3d18-42dd-a94f-8c44d0ef6554",
"name": "Sent Email to the user",
"type": "n8n-nodes-base.gmail",
"position": [
2048,
-400
],
"webhookId": "4c743ea8-10ee-434f-b5e3-4adc00202bb7",
"parameters": {
"sendTo": "=colemercy23@gmail.com",
"message": "={{ $json.text }}",
"options": {
"appendAttribution": false
},
"subject": "Booking Update ",
"emailType": "text"
},
"credentials": {
"gmailOAuth2": {
"id": "ML7tamjGwW4VC9hH",
"name": "Gmail account"
}
},
"typeVersion": 2.2
},
{
"id": "021fbf63-b5c2-4dde-a65c-11d794f4cc11",
"name": "If Condition",
"type": "n8n-nodes-base.if",
"position": [
1248,
-560
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "ec04ee85-4669-4c81-91d3-9c8465f99531",
"operator": {
"type": "boolean",
"operation": "equals"
},
"leftValue": "={{ $json.data.approved }}",
"rightValue": true
}
]
}
},
"typeVersion": 2.3
},
{
"id": "587f700d-20e1-43b2-a855-e92474d736d3",
"name": "Google Gemini Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
16,
48
],
"parameters": {
"options": {}
},
"credentials": {
"googlePalmApi": {
"id": "Yw5rFU8Cyb1e3mFR",
"name": "Google Gemini(PaLM) Api account"
}
},
"typeVersion": 1.1
},
{
"id": "ae721b63-554d-4a50-b5cd-ad73c59e940a",
"name": "Google Gemini Chat Model1",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
16,
-176
],
"parameters": {
"options": {}
},
"credentials": {
"googlePalmApi": {
"id": "fxmWJqKfXoDhnoj3",
"name": "Google Gemini(PaLM) Api account 3"
}
},
"typeVersion": 1.1
},
{
"id": "255ff820-6b2d-4791-b7a7-92b0596edce2",
"name": "Booking Information1",
"type": "n8n-nodes-base.set",
"position": [
2048,
-592
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "f95cdd2b-9125-4ae1-b7a1-664e4a847fb7",
"name": "booking_id",
"type": "string",
"value": "={{ $('Booking Information').item.json.booking_id }}"
},
{
"id": "ac229a8b-6d1f-4841-8cb4-7948dbfb2021",
"name": "check_in",
"type": "string",
"value": "={{ $('Booking Information').item.json.check_in }}"
},
{
"id": "92de9cbd-b991-4289-85f5-fa4636667214",
"name": "check_out",
"type": "string",
"value": "={{ $('Booking Information').item.json.check_out }}"
},
{
"id": "4b981e68-efd8-44e0-80ae-ab367027852a",
"name": "guests",
"type": "number",
"value": "={{ $('Booking Information').item.json.guests }}"
},
{
"id": "ff032019-5d68-49bb-9aa1-7a0be17bf5cb",
"name": "guest_name",
"type": "string",
"value": "={{ $('Booking Information').item.json.guest_name }}"
},
{
"id": "b0db3bbd-90d5-4019-a370-8945c3843f64",
"name": "guest_email",
"type": "string",
"value": "={{ $('Booking Information').item.json.guest_email }}"
},
{
"id": "368c5c54-81aa-4078-ba1c-8d464b240076",
"name": "guest_phone",
"type": "number",
"value": "={{ $('Booking Information').item.json.guest_phone }}"
},
{
"id": "a4e61962-983c-4a1a-bfe6-92c5fda2a360",
"name": "special_requests",
"type": "string",
"value": "={{ $('Booking Information').item.json.special_requests }}"
},
{
"id": "ed67a084-a06d-444a-8a3c-071b07171ad0",
"name": "addons_extras",
"type": "string",
"value": "={{ $('Booking Information').item.json.addons_extras }}"
},
{
"id": "0487d6f3-152e-4529-b022-5a38294b99eb",
"name": "addons_act_ent",
"type": "string",
"value": "={{ $('Booking Information').item.json.addons_act_ent }}"
},
{
"id": "a2f472e8-bca9-4601-bd20-7b58604faaf4",
"name": "room_label",
"type": "string",
"value": "={{ $('Booking Information').item.json.room_label }}"
},
{
"id": "e87e900d-8559-4338-98c1-75717d22555e",
"name": "label_amount",
"type": "number",
"value": "={{ $('Booking Information').item.json.label_amount }}"
},
{
"id": "0a131676-4eea-4d91-9b6e-4d0ff73ffe6e",
"name": "number_of_addons",
"type": "string",
"value": "={{ $('Booking Information').item.json.number_of_addons }}"
},
{
"id": "aea20683-aa2d-4966-87bc-7220222373bd",
"name": "addons_amount",
"type": "number",
"value": "={{ $('Booking Information').item.json.addons_amount }}"
},
{
"id": "8a763b81-f39d-4bdd-8970-50f7833023fd",
"name": "original_amount",
"type": "number",
"value": "={{ $('Booking Information').item.json.original_amount }}"
},
{
"id": "876a7801-cacc-4877-a6c6-eb25de49aa7b",
"name": "discount_code",
"type": "string",
"value": "={{ $('Booking Information').item.json.discount_code }}"
},
{
"id": "e7afd523-9152-4c4a-97e9-8d6136b64d63",
"name": "discount_amount",
"type": "number",
"value": "={{ $('Booking Information').item.json.discount_amount }}"
},
{
"id": "4cfdb71d-414d-4c30-9f46-047c284adfff",
"name": "total_amount",
"type": "number",
"value": "={{ $('Booking Information').item.json.total_amount }}"
},
{
"id": "87e2c2a8-0875-4000-b4ed-b66395d302ba",
"name": "qoute_status",
"type": "string",
"value": "={{ $('Booking Information').item.json.qoute_status }}"
},
{
"id": "2fd0d6db-ac02-4f97-bfe4-ddc6db65d3f9",
"name": "reference_code",
"type": "string",
"value": "={{ $('Booking Information').item.json.reference_code }}"
},
{
"id": "6e52da89-0586-48a6-bd88-9b466d248d6b",
"name": "ticket_number",
"type": "string",
"value": "={{ $('Booking Information').item.json.ticket_number }}"
},
{
"id": "0a31422f-dbf2-4bb3-a0ee-300deff04fea",
"name": "package",
"type": "string",
"value": "={{ $('Booking Information').item.json.package }}"
},
{
"id": "7feb8f46-f4c8-4312-8dba-8dd6b1e79f83",
"name": "created_at",
"type": "string",
"value": "={{ $('Booking Information').item.json.created_at }}"
}
]
}
},
"typeVersion": 3.5
},
{
"id": "df24cc47-7261-476d-9683-de3fcd5d521e",
"name": "Generate Receipt PDF",
"type": "n8n-nodes-pdfco.PDFco Api",
"position": [
2272,
-592
],
"parameters": {
"html": "=<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>PotipotGateway Resort · Official Receipt</title>\n <link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css\" />\n <style>\n * {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n }\n\n body {\n background: #eef2f6;\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 100vh;\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n padding: 1.5rem;\n margin: 0;\n }\n\n .receipt {\n max-width: 520px;\n width: 100%;\n background: #ffffff;\n border-radius: 28px;\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.04), 0 2px 6px rgba(0, 0, 0, 0.02);\n padding: 2rem 2rem 1.6rem;\n transition: 0.2s;\n }\n\n .receipt-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n border-bottom: 1px solid #e9edf2;\n padding-bottom: 0.9rem;\n margin-bottom: 0.5rem;\n }\n\n .brand {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n }\n\n .brand-icon {\n background: #0b2a41;\n color: #f5c542;\n width: 38px;\n height: 38px;\n border-radius: 14px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.4rem;\n }\n\n .brand-text h2 {\n font-size: 1.2rem;\n font-weight: 600;\n letter-spacing: -0.3px;\n color: #0b2a41;\n margin: 0;\n line-height: 1.2;\n }\n\n .brand-text small {\n font-size: 0.6rem;\n font-weight: 400;\n color: #5e748b;\n letter-spacing: 0.3px;\n }\n\n .ticket-badge {\n background: #f2f6fc;\n padding: 0.25rem 0.9rem;\n border-radius: 30px;\n font-size: 0.65rem;\n font-weight: 500;\n color: #1f405b;\n border: 1px solid #dce3ed;\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .ticket-badge i {\n color: #b8860b;\n font-size: 0.6rem;\n }\n\n .official-receipt-line {\n text-align: center;\n padding: 0.3rem 0 0.7rem 0;\n border-bottom: 1px solid #e9edf2;\n margin-bottom: 0.8rem;\n }\n\n .official-receipt-line span {\n font-size: 0.75rem;\n font-weight: 500;\n color: #1f405b;\n letter-spacing: 0.8px;\n text-transform: uppercase;\n background: #f4f8fe;\n padding: 0.15rem 1.4rem;\n border-radius: 30px;\n display: inline-block;\n border: 1px solid #dce3ed;\n }\n\n .official-receipt-line span i {\n color: #b8860b;\n margin-right: 5px;\n font-size: 0.65rem;\n }\n\n .row {\n display: flex;\n justify-content: space-between;\n padding: 0.5rem 0;\n border-bottom: 1px solid #f0f4fa;\n font-size: 0.85rem;\n }\n\n .row:last-of-type {\n border-bottom: none;\n }\n\n .row-label {\n color: #4d687f;\n font-weight: 450;\n display: flex;\n align-items: center;\n gap: 5px;\n }\n\n .row-label i {\n width: 1.1rem;\n font-size: 0.7rem;\n color: #6d8aa5;\n }\n\n .row-value {\n font-weight: 500;\n color: #102433;\n text-align: right;\n word-break: break-word;\n }\n\n .row-value.mono {\n font-family: 'SF Mono', 'Menlo', monospace;\n font-size: 0.75rem;\n background: #f2f6fc;\n padding: 0.1rem 0.6rem;\n border-radius: 30px;\n color: #1b3a54;\n }\n\n .row-value.strong {\n font-weight: 600;\n }\n\n .row-value.amount {\n font-weight: 600;\n font-size: 1.1rem;\n color: #0b2a41;\n }\n\n .highlight {\n background: #f7faff;\n padding: 0.8rem 1rem;\n border-radius: 18px;\n border: 1px solid #e6edf6;\n margin: 0.6rem 0 0.4rem;\n }\n\n .highlight .row {\n border-bottom: none;\n padding: 0.2rem 0;\n }\n\n .highlight .row-label {\n font-size: 0.7rem;\n text-transform: uppercase;\n letter-spacing: 0.4px;\n color: #526f8a;\n }\n\n .room-tag {\n background: #e1eaf5;\n border-radius: 30px;\n padding: 0.05rem 0.9rem;\n font-size: 0.65rem;\n font-weight: 500;\n color: #10344f;\n }\n\n .total-row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n background: #f2f8ff;\n padding: 0.7rem 1rem;\n border-radius: 40px;\n margin: 0.8rem 0 0.2rem;\n border: 1px solid #e1eaf3;\n }\n\n .total-row span:first-child {\n font-weight: 600;\n font-size: 0.9rem;\n color: #0b2a41;\n display: flex;\n align-items: center;\n gap: 6px;\n }\n\n .total-row span:last-child {\n font-weight: 700;\n font-size: 1.4rem;\n letter-spacing: -0.3px;\n color: #0b2a41;\n }\n\n .footer-note {\n margin-top: 1.2rem;\n font-size: 0.6rem;\n color: #54708b;\n text-align: center;\n border-top: 1px solid #e9eff6;\n padding-top: 1rem;\n display: flex;\n justify-content: center;\n flex-wrap: wrap;\n gap: 0.8rem 1.4rem;\n letter-spacing: 0.2px;\n }\n\n .footer-note i {\n color: #b8860b;\n margin-right: 3px;\n }\n\n .meta-strip {\n display: flex;\n flex-wrap: wrap;\n justify-content: space-between;\n font-size: 0.6rem;\n color: #4a6782;\n background: #f7fafd;\n padding: 0.4rem 0.8rem;\n border-radius: 40px;\n margin-top: 0.8rem;\n border: 1px solid #e6edf6;\n }\n\n .meta-strip span {\n display: flex;\n align-items: center;\n gap: 3px;\n }\n\n .meta-strip i {\n color: #6a8aa8;\n font-size: 0.6rem;\n }\n\n @media (max-width: 480px) {\n .receipt { padding: 1.5rem; }\n .brand-text h2 { font-size: 1rem; }\n .row { font-size: 0.75rem; flex-wrap: wrap; gap: 0.2rem; }\n .row-value { text-align: left; width: 100%; }\n .total-row span:last-child { font-size: 1.2rem; }\n }\n\n .text-muted { color: #4a6882; }\n .gap-1 { gap: 0.25rem; }\n .fw-400 { font-weight: 400; }\n </style>\n</head>\n<body>\n <div class=\"receipt\" id=\"receiptContainer\">\n\n <div class=\"receipt-header\">\n <div class=\"brand\">\n <div class=\"brand-icon\"><i class=\"fas fa-fish\"></i></div>\n <div class=\"brand-text\">\n <h2>PotipotGateway Resort</h2>\n <small>Purok 7, Sinabacan, Candelaria, 2212 Zambales</small>\n </div>\n </div>\n <div class=\"ticket-badge\">\n <i class=\"fas fa-ticket-alt\"></i>\n <span id=\"ticketNumberDisplay\">PGR-••••</span>\n </div>\n </div>\n\n <div class=\"official-receipt-line\">\n <span><i class=\"fas fa-check-circle\"></i> Official Receipt</span>\n </div>\n\n <div id=\"receiptDynamic\"></div>\n\n <div class=\"footer-note\">\n <span><i class=\"fas fa-fish\"></i> Thank you for choosing PotipotGateway Resort!</span>\n </div>\n </div>\n\n <script>\n (function() {\n // ——— data (exactly as provided) ———\n const bookingData = [{\n \"booking_id\": \"{{ $json.booking_id }}\",\n \"check_in\": \"{{ $json.check_in }}\",\n \"check_out\": \"{{ $json.check_out }}\",\n \"guests\": {{ $json.guests }},\n \"guest_name\": \"{{ $json.guest_name }}\",\n \"guest_email\": \"{{ $json.guest_email }}\",\n \"guest_phone\": {{ $json.guest_phone }},\n \"special_requests\": \"{{ $json.special_requests }}\",\n \"addons_extras\": \"{{ $json.addons_extras }}\",\n \"addons_act_ent\": \"{{ $json.addons_act_ent }}\",\n \"room_label\": \"{{ $json.room_label }}\",\n \"label_amount\": {{ $json.label_amount }},\n \"number_of_addons\": \"{{ $json.number_of_addons }}\",\n \"addons_amount\": {{ $json.addons_amount }},\n \"original_amount\": {{ $json.original_amount }},\n \"discount_code\": \"{{ $json.discount_code }}\",\n \"discount_amount\": {{ $json.discount_amount }},\n \"total_amount\": {{ $json.total_amount }},\n \"qoute_status\": \"{{ $json.qoute_status }}\",\n \"reference_code\": \"{{ $json.reference_code }}\",\n \"ticket_number\": \"{{ $json.ticket_number }}\",\n \"package\": \"{{ $json.package }}\",\n \"created_at\": \"{{ $json.created_at }}\"\n }];\n\n const record = bookingData[0];\n const container = document.getElementById('receiptDynamic');\n const ticketSpan = document.getElementById('ticketNumberDisplay');\n\n // ——— helpers ———\n const formatPhone = (num) => {\n if (!num) return '';\n const str = String(num);\n if (str.length === 10) return `${str.slice(0,4)} ${str.slice(4,7)} ${str.slice(7)}`;\n return str;\n };\n\n const formatDate = (dateStr) => {\n if (!dateStr) return '';\n const parts = dateStr.split('-');\n if (parts.length !== 3) return dateStr;\n const months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];\n const month = months[parseInt(parts[1], 10) - 1] || parts[1];\n return `${month} ${parseInt(parts[2], 10)}, ${parts[0]}`;\n };\n\n const formatCreated = (iso) => {\n if (!iso) return '';\n try {\n const d = new Date(iso);\n return d.toLocaleString('en-US', {\n month: 'short', day: 'numeric', year: 'numeric',\n hour: '2-digit', minute: '2-digit', hour12: true\n });\n } catch (_) { return iso; }\n };\n\n // ——— build HTML ———\n let html = '';\n\n const addRow = (label, value, extraClass = '') => {\n html += `\n <div class=\"row ${extraClass}\">\n <span class=\"row-label\">${label}</span>\n <span class=\"row-value\">${value}</span>\n </div>\n `;\n };\n\n // 1) guest & ref\n addRow(`<i class=\"fas fa-user-circle\"></i> Guest`, `<strong>${record.guest_name || '—'}</strong>`);\n addRow(`<i class=\"fas fa-envelope\"></i> Email`, record.guest_email || '—');\n addRow(`<i class=\"fas fa-phone-alt\"></i> Phone`, formatPhone(record.guest_phone) || '—');\n addRow(`<i class=\"fas fa-hashtag\"></i> Booking ref`, `<span class=\"mono\">${record.reference_code || '—'}</span>`);\n\n // 2) dates & guests\n addRow(`<i class=\"fas fa-calendar-check\"></i> Check‑in`, formatDate(record.check_in));\n addRow(`<i class=\"fas fa-calendar-times\"></i> Check‑out`, formatDate(record.check_out));\n addRow(`<i class=\"fas fa-users\"></i> Guests`, `${record.guests} ${record.guests > 1 ? 'adults' : 'adult'}`);\n addRow(`<i class=\"fas fa-tag\"></i> Status`, `<span style=\"background:#e9eff6; padding:0.1rem 0.8rem; border-radius:30px; font-size:0.65rem; font-weight:500; color:#1c3e5a;\">${record.qoute_status ? record.qoute_status.replace('_',' ') : '—'}</span>`);\n\n // 3) highlight block (room)\n html += `\n <div class=\"highlight\">\n <div class=\"row\" style=\"border-bottom: none; padding-bottom: 0.2rem;\">\n <span class=\"row-label\"><i class=\"fas fa-home\" style=\"color:#b8860b;\"></i> Room</span>\n <span class=\"row-value strong\">${record.package || 'Log House'}</span>\n </div>\n <div class=\"row\" style=\"border-bottom: none; padding-top: 0.1rem;\">\n <span class=\"row-label\" style=\"font-size:0.6rem; text-transform:none;\"><i class=\"fas fa-door-open\"></i> unit</span>\n <span class=\"row-value\" style=\"font-size:0.8rem; font-weight:400;\">${record.room_label || ''}</span>\n </div>\n </div>\n `;\n\n // 4) addons\n addRow(`<i class=\"fas fa-puzzle-piece\"></i> Add‑ons`, `${record.number_of_addons || '—'} ${record.addons_extras ? `· ${record.addons_extras.replace('_',' ')}` : ''}`);\n addRow(`<i class=\"fas fa-plus-circle\"></i> Add‑ons amount`, `₱${record.addons_amount ?? 0}`);\n\n // 5) discount & original\n addRow(`<i class=\"fas fa-percent\"></i> Discount`, record.discount_code ? `${record.discount_code} (₱${record.discount_amount ?? 0})` : '—');\n addRow(`<i class=\"fas fa-receipt\"></i> Original`, `₱${record.original_amount ?? 0}`);\n\n // 6) total row (special)\n html += `\n <div class=\"total-row\">\n <span><i class=\"fas fa-wallet\"></i> TOTAL</span>\n <span>₱${record.total_amount ?? 0}</span>\n </div>\n `;\n\n // 7) meta strip (created, special, package)\n html += `\n <div class=\"meta-strip\">\n <span><i class=\"fas fa-calendar-alt\"></i> ${formatCreated(record.created_at)}</span>\n <span><i class=\"fas fa-pen\"></i> ${record.special_requests || 'no requests'}</span>\n <span><i class=\"fas fa-box\"></i> ${record.package || '—'}</span>\n </div>\n `;\n\n container.innerHTML = html;\n\n // ——— ticket badge ———\n if (record.ticket_number) {\n const short = record.ticket_number.length > 12 ? record.ticket_number.slice(0, 12) + '…' : record.ticket_number;\n ticketSpan.textContent = short;\n } else {\n ticketSpan.textContent = 'PGR-••••';\n }\n\n })();\n </script>\n</body>\n</html>",
"operation": "URL/HTML to PDF",
"convertType": "htmlToPDF",
"advancedOptions": {
"name": "potipotgatewayresort_qoutation"
}
},
"credentials": {
"pdfcoOAuth2Api": {
"id": "tbuT7WgZNo3JtvVK",
"name": "PDF.co account"
}
},
"typeVersion": 1.1
},
{
"id": "a43ede16-d668-4040-b2f9-51caf8857d72",
"name": "Download Receipt PDF",
"type": "n8n-nodes-base.httpRequest",
"position": [
2496,
-592
],
"parameters": {
"url": "={{ $json.url }}",
"options": {}
},
"typeVersion": 4.5
},
{
"id": "d68626ec-814d-4d6f-995c-951925e65426",
"name": "Send Receipt to Guest",
"type": "n8n-nodes-base.gmail",
"position": [
2720,
-592
],
"webhookId": "b5ec700c-9b66-4020-9ca3-f586e0228420",
"parameters": {
"sendTo": "=colemercy23@gmail.com",
"message": "={{ $('If').item.json.text }}",
"options": {
"attachmentsUi": {
"attachmentsBinary": [
{}
]
},
"appendAttribution": false
},
"subject": "Your Potipot Gateway Resort Booking Receipt",
"emailType": "text"
},
"credentials": {
"gmailOAuth2": {
"id": "ML7tamjGwW4VC9hH",
"name": "Gmail account"
}
},
"typeVersion": 2.2
},
{
"id": "2fe648b1-c742-4819-9b9f-17afe99a5071",
"name": "If",
"type": "n8n-nodes-base.if",
"position": [
1824,
-496
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "or",
"conditions": [
{
"id": "9001aeb2-eea3-4820-8999-f7048e79fc66",
"operator": {
"type": "string",
"operation": "contains"
},
"leftValue": "={{ $('Booking Information').item.json.qoute_status }}",
"rightValue": "confirmed"
}
]
}
},
"typeVersion": 2.3
},
{
"id": "8411b71c-44c8-419a-8663-cf6b2048b555",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
2000,
-640
],
"parameters": {
"color": 5,
"width": 640,
"height": 208,
"content": "Generating PDF file (Official Receipt)"
},
"typeVersion": 1
},
{
"id": "7563fc2e-6cc2-4fb6-b572-ff78ec8d10ad",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
1792,
-576
],
"parameters": {
"width": 160,
"height": 240,
"content": "Condition node (Approve or Disapprove)"
},
"typeVersion": 1
},
{
"id": "4a0025fe-c55b-4a60-8e6a-ad3f12563c05",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1216,
-640
],
"parameters": {
"width": 160,
"height": 240,
"content": "Condition node (Approve or Disapprove)"
},
"typeVersion": 1
},
{
"id": "ee7e819b-aa86-425b-9d61-351720ecab81",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
2672,
-640
],
"parameters": {
"color": 4,
"width": 192,
"height": 208,
"content": "Approve Booking Email\n"
},
"typeVersion": 1
},
{
"id": "460e1d3d-57f1-46c5-9043-6305bec5d03e",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
2000,
-448
],
"parameters": {
"color": 3,
"width": 192,
"height": 208,
"content": "Declined Booking\nEmail\n"
},
"typeVersion": 1
},
{
"id": "7c6aa5e2-e647-474c-99bd-00c3621027cd",
"name": "Groq Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatGroq",
"position": [
528,
-272
],
"parameters": {
"model": "openai/gpt-oss-20b",
"options": {}
},
"credentials": {
"groqApi": {
"id": "euOQLoYdfMKQtnzV",
"name": "Groq account"
}
},
"typeVersion": 1
},
{
"id": "4c60700f-9f39-429d-a4bb-f67f713f6180",
"name": "Groq Chat Model1",
"type": "@n8n/n8n-nodes-langchain.lmChatGroq",
"position": [
1552,
-272
],
"parameters": {
"model": "openai/gpt-oss-20b",
"options": {}
},
"credentials": {
"groqApi": {
"id": "euOQLoYdfMKQtnzV",
"name": "Groq account"
}
},
"typeVersion": 1
},
{
"id": "e6806ed5-0020-4ad4-86e4-6dd4b519b8e0",
"name": "Switch for different routing",
"type": "n8n-nodes-base.switch",
"position": [
800,
-512
],
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "fcfd0804-68f4-407f-a6ff-b2fdcd98e177",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $('Booking Information').item.json.qoute_status }}",
"rightValue": "qoute_requested"
}
]
}
},
{
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "7aa024f6-c572-4d71-921a-5925240d8ecb",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $('Booking Information').item.json.qoute_status }}",
"rightValue": "confirmed"
}
]
}
},
{
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "7ee1df80-e00d-4144-b6ad-de5c08b659fc",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $('Booking Information').item.json.qoute_status }}",
"rightValue": "cancelled"
}
]
}
}
]
},
"options": {}
},
"typeVersion": 3.4
}
],
"active": true,
"pinData": {},
"settings": {
"binaryMode": "separate",
"executionOrder": "v1"
},
"versionId": "137a5d9d-b59a-4b05-ab74-b90947723cdc",
"nodeGroups": [],
"connections": {
"If": {
"main": [
[
{
"node": "Booking Information1",
"type": "main",
"index": 0
}
],
[
{
"node": "Sent Email to the user",
"type": "main",
"index": 0
}
]
]
},
"Webhook1": {
"main": [
[
{
"node": "Booking Information",
"type": "main",
"index": 0
}
]
]
},
"If Condition": {
"main": [
[
{
"node": "Email Assistant",
"type": "main",
"index": 0
}
],
[
{
"node": "Email Assistant",
"type": "main",
"index": 0
}
]
]
},
"Email Assistant": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"Groq Chat Model": {
"ai_languageModel": [
[
{
"node": "Approval Assistant",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Groq Chat Model1": {
"ai_languageModel": [
[
{
"node": "Email Assistant",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Approval Assistant": {
"main": [
[
{
"node": "Switch for different routing",
"type": "main",
"index": 0
}
]
]
},
"Booking Information": {
"main": [
[
{
"node": "Approval Assistant",
"type": "main",
"index": 0
}
]
]
},
"Booking Information1": {
"main": [
[
{
"node": "Generate Receipt PDF",
"type": "main",
"index": 0
}
]
]
},
"Download Receipt PDF": {
"main": [
[
{
"node": "Send Receipt to Guest",
"type": "main",
"index": 0
}
]
]
},
"Generate Receipt PDF": {
"main": [
[
{
"node": "Download Receipt PDF",
"type": "main",
"index": 0
}
]
]
},
"Send Receipt to Guest": {
"main": [
[]
]
},
"Google Gemini Chat Model": {
"ai_languageModel": [
[]
]
},
"Google Gemini Chat Model1": {
"ai_languageModel": [
[]
]
},
"Switch for different routing": {
"main": [
[],
[
{
"node": "Approval of Booking Through Email",
"type": "main",
"index": 0
}
],
[
{
"node": "Email Assistant",
"type": "main",
"index": 0
}
]
]
},
"Approval of Booking Through Email": {
"main": [
[
{
"node": "If Condition",
"type": "main",
"index": 0
}
]
]
}
}
}