{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "688b53dc-149a-41b6-8447-cde64f7a5c5c",
      "name": "Basic LLM Chain",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        -700,
        -120
      ],
      "parameters": {
        "text": "=You are an AI rewards assistant for a hotel CRM.  \n\nWhen given the guest\u2019s spend summary in optional paid amenities:\n-  {{ $json.Total_Room_Service_Spend__c }}\n-  {{ $json.Total_Minibar_Spend__c }}\n- {{ $json.Total_Laundry_Spend__c }}\n- {{ $json.Total_Late_Checkout_Fees__c }}\n- {{ $json.Total_Extra_Bed_Fees__c }}\n- {{ $json.Total_Airport_Transfer_Spend__c }}\n\n**Task:**\n- STRICTLY CHOOSE THE OPTION BETWEEN THESE 5 REWARDS: ROOM SERVICE, MINI BAR, LAUNDARY, LATE CHECKOUT, EXTRA BED, AIRPORT TRANSFER\n- Look at which services the guest *already paid for* (any spend > $0)\n- Randomly pick **one** of the *other* services they haven\u2019t used (spend = 0). If used everything then look for where the user spend the most on... and then give the offer on which he spent less on.\n- Offer a realistic, valuable, **one-time free perk** on that unused service\n- The offer should be concrete, short, and sound like a real hotel promotion (e.g., \"One free airport drop on your next stay\", \"Free late checkout on your next booking\")\n\n**Output:**\nAlways return JSON with this structure:\n{\n  \"suggested_offer\": \"...\"\n}\n\nDo not include anything else.\n",
        "batching": {},
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 1.7
    },
    {
      "id": "01bd11e8-4a82-4906-91e6-8e26976f0bbf",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        -540,
        100
      ],
      "parameters": {
        "jsonSchemaExample": "{\n  \"suggested_offer\": \"...\"\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "a741b4b3-0cec-4c40-aa3d-517d7d1ea315",
      "name": "Check for any latest checkouts",
      "type": "n8n-nodes-base.salesforceTrigger",
      "position": [
        -1620,
        -100
      ],
      "parameters": {
        "pollTimes": {
          "item": [
            {
              "mode": "everyWeek"
            }
          ]
        },
        "triggerOn": "customObjectUpdated",
        "customObject": "Guest__c"
      },
      "credentials": {
        "salesforceOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "ae15b8b0-3f66-434d-8730-5baf744984e7",
      "name": "Extract Checkout information",
      "type": "n8n-nodes-base.salesforce",
      "position": [
        -1400,
        -100
      ],
      "parameters": {
        "options": {
          "fields": [
            "Name",
            "guest_id__c",
            "phone__c",
            "Total_Room_Service_Spend__c",
            "Total_Minibar_Spend__c",
            "Total_Laundry_Spend__c",
            "Total_Late_Checkout_Fees__c",
            "Total_Extra_Bed_Fees__c",
            "Total_Airport_Transfer_Spend__c",
            "Email__c"
          ]
        },
        "resource": "customObject",
        "operation": "getAll",
        "returnAll": true,
        "customObject": "Guest__c"
      },
      "credentials": {
        "salesforceOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "75fc4e53-a12d-4dfe-85cf-f1ceb4a80c19",
      "name": "Look For VIP Clients",
      "type": "n8n-nodes-base.code",
      "position": [
        -1180,
        -100
      ],
      "parameters": {
        "jsCode": "return $input.all().map(item => {\n  const data = item.json;\n\n  const total = \n    (data.Total_Room_Service_Spend__c || 0) +\n    (data.Total_Minibar_Spend__c || 0) +\n    (data.Total_Laundry_Spend__c || 0) +\n    (data.Total_Late_Checkout_Fees__c || 0) +\n    (data.Total_Airport_Transfer_Spend__c || 0);\n\n  return {\n    json: {\n      ...data,\n      total\n    }\n  };\n});\n"
      },
      "typeVersion": 2
    },
    {
      "id": "26bd7967-8885-474e-bac2-c1aabb7bcf2f",
      "name": "Check the threshold exceedings",
      "type": "n8n-nodes-base.if",
      "position": [
        -960,
        -100
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "e8573d13-cdb4-48b7-a52d-f923cf4f9ebb",
              "operator": {
                "type": "number",
                "operation": "gte"
              },
              "leftValue": "={{ $json.total }}",
              "rightValue": 50
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "e04b8b27-474b-498d-ba44-04110d993217",
      "name": "Give Away Personalised Offers",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleVertex",
      "position": [
        -700,
        100
      ],
      "parameters": {
        "options": {},
        "modelName": "gemini-2.5-flash",
        "projectId": {
          "__rl": true,
          "mode": "list",
          "value": "slidingpuzzlepro1",
          "cachedResultName": "Slidingpuzzlepro"
        }
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "6e1c0c4b-a767-4420-bf30-1a91c4d539e6",
      "name": "Send offer via email",
      "type": "n8n-nodes-base.sendInBlue",
      "position": [
        -340,
        -120
      ],
      "parameters": {
        "sender": "emailplaceholder",
        "subject": "={{ $('Check the threshold exceedings').item.json.Name }}, We Have Something Special for Your Next Stay",
        "sendHTML": true,
        "htmlContent": "=<!DOCTYPE html> <html> <head>   <meta charset=\"UTF-8\" />   <title>Exclusive Offer Just for You</title>   <style>     body {       font-family: Arial, sans-serif;       background-color: #f7f7f7;       margin: 0;       padding: 0;     }     .container {       background-color: #ffffff;       width: 100%;       max-width: 600px;       margin: 40px auto;       border-radius: 8px;       box-shadow: 0 0 10px rgba(0,0,0,0.1);       overflow: hidden;     }     .header {       background-color: #003366;       color: #ffffff;       padding: 20px;       text-align: center;       font-size: 22px;     }     .content {       padding: 30px 20px;       text-align: center;     }     .offer {       font-size: 18px;       color: #333333;       margin: 20px 0;       font-weight: bold;     }     .footer {       font-size: 12px;       color: #999999;       text-align: center;       padding: 20px;     }   </style> </head> <body>   <div class=\"container\">     <div class=\"header\">       A Special Thank You     </div>     <div class=\"content\">       <p>We're delighted to share an exclusive offer with you:</p>       <p class=\"offer\">{{ $json.output.suggested_offer }}</p>       <p>We look forward to welcoming you again soon!</p>     </div>     <div class=\"footer\">       &copy; 2025 Hilton Garden Inn New York Times Square South. All rights reserved.     </div>   </div> </body> </html>",
        "receipients": "={{ $('Check the threshold exceedings').item.json.Email__c }}",
        "requestOptions": {},
        "additionalFields": {}
      },
      "credentials": {
        "sendInBlueApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "9135c69d-9372-4f77-8fd9-b50e915daa64",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2446.94942319236,
        -420
      ],
      "parameters": {
        "width": 760,
        "height": 1120,
        "content": "## \ud83d\udce9 **High-Spender Guest Reward Automation**\n\nThis workflow automatically detects high\u2011spending guests after checkout and sends them a personalized reward offer by email...\n\n---\n\n### **\ud83d\udd27 What it does**\n- Listens for updates on the `Guest__c` custom object in Salesforce.\n- Fetches guests\u2019 spend across optional paid amenities:\n  - Room Service\n  - Minibar\n  - Laundry\n  - Late Checkout\n  - Extra Bed\n  - Airport Transfer\n- Calculates total spend to find VIP guests (threshold \u2265 **$50**).\n- Uses an AI agent to:\n  - Spot which services the guest hasn\u2019t used yet.\n  - Randomly pick one unused service to offer as a free perk.\n  - Generate a realistic, short promotional text.\n- Parses the AI output.\n- Sends a branded HTML email to the guest with the customized offer.\n\n---\n\n### **\ud83d\udce6 Key nodes**\n- `Salesforce Trigger` \u2192 watches for checkout updates.\n- `Salesforce` \u2192 pulls guest spend details.\n- `Function` \u2192 computes total amenity spend.\n- `IF` \u2192 filters guests who spent over the threshold.\n- `LangChain LLM + Google Vertex AI` \u2192 drafts the offer text.\n- `Structured Output Parser` \u2192 extracts clean JSON.\n- `Brevo` \u2192 delivers the email.\n\n---\n\n### **\ud83d\udcca Example output**\n> _Subject:_ `John, We Have Something Special for Your Next Stay`  \n> _Offer in email:_ `Enjoy a complimentary minibar selection on your next stay.`\n\n---\n\n### **\u2728 Why**\nRewarding guests *who already show willingness to spend* increases loyalty and repeat bookings \u2014 without blanket discounts. The offer feels personal, relevant, and exclusive."
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Basic LLM Chain": {
      "main": [
        [
          {
            "node": "Send offer via email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Look For VIP Clients": {
      "main": [
        [
          {
            "node": "Check the threshold exceedings",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Basic LLM Chain",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Extract Checkout information": {
      "main": [
        [
          {
            "node": "Look For VIP Clients",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Give Away Personalised Offers": {
      "ai_languageModel": [
        [
          {
            "node": "Basic LLM Chain",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Check for any latest checkouts": {
      "main": [
        [
          {
            "node": "Extract Checkout information",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check the threshold exceedings": {
      "main": [
        [
          {
            "node": "Basic LLM Chain",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}