{
  "id": "lNmIFkiOmboSoUE8",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Tarot card reading",
  "tags": [],
  "nodes": [
    {
      "id": "d55821e6-8dbb-4a96-8d5b-9419e14ee9cc",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1220,
        0
      ],
      "parameters": {
        "width": 880,
        "height": 1000,
        "content": "## Using the n8n HTTP Request Node to Send a Blooio.com Message\n\nFollow these steps to configure your existing HTTP Request node in n8n so you can send SMS or email via the Blooio.com API.\n\n---\n\n### 1. Open Your HTTP Request Node\n\n- In your workflow, click on the HTTP Request node you\u2019ve already added (e.g. **Send Message**).\n\n---\n\n### 2. Set Up the Request\n\n| Field                 | Value                                              |\n|-----------------------|----------------------------------------------------|\n| **Request Method**    | `POST`                                             |\n| **URL**               | `https://api.blooio.com/send-message`              |\n| **Response Format**   | `JSON`                                             |\n| **Body Content Type** | `JSON (application/json)`                          |\n\n---\n\n### 3. Add Required Headers\n\nAdd three headers exactly as shown:\n\n```text\nAccept:        application/json\nAuthorization: Bearer YOUR_TOKEN_HERE\nContent-Type:  application/json"
      },
      "typeVersion": 1
    },
    {
      "id": "b79415f2-3c1c-453b-91bf-34139589eaef",
      "name": "Send Message",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1280,
        780
      ],
      "parameters": {
        "url": "https://api.blooio.com/send-message",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "sendHeaders": true,
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "identifier",
              "value": "={{ $('Receive Message (From Blooio)').item.json.body.message.sender }}"
            },
            {
              "name": "message",
              "value": "={{ $json.output }}"
            }
          ]
        },
        "genericAuthType": "httpBearerAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "accept",
              "value": "application/json"
            }
          ]
        }
      },
      "credentials": {
        "httpBearerAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "130336d2-db04-4bed-8fec-d6fec36803ec",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2000,
        980
      ],
      "parameters": {
        "color": 3,
        "width": 780,
        "height": 360,
        "content": "## Message Read Webhook:\n```\n{\n  \"type\": \"updated-message\",\n  \"message\": {\n    \"messageId\": \"218BCBB7-92E5-455B-AF47-380DB39ACD16\",\n    \"content\": \"Test\",\n    \"sender\": \"+11111111111\",\n    \"selfMessage\": true,\n    \"sentAt\": 1750755023004,\n    \"technology\": \"iMessage\",\n    \"delivered\": true,\n    \"deliveredAt\": 1750755023334,\n    \"readAt\": 1750755049887,\n    \"attachments\": [],\n    \"conversation\": null\n  }\n}\n```"
      },
      "typeVersion": 1
    },
    {
      "id": "c159c029-2c39-4696-9cb2-7f6e8b238e04",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2000,
        380
      ],
      "parameters": {
        "color": 6,
        "width": 780,
        "height": 580,
        "content": "## Message Received Webhook:\n```\n{\n  \"type\": \"new-message\",\n  \"message\": {\n    \"messageId\": \"B525F710-521F-4D39-8C8F-A44BB737A3B6\",\n    \"content\": \"Attached the csv file for you\",\n    \"sender\": \"+11111111111\",\n    \"selfMessage\": false,\n    \"sentAt\": 1750757604774,\n    \"technology\": \"iMessage\",\n    \"delivered\": true,\n    \"deliveredAt\": null,\n    \"readAt\": null,\n    \"attachments\": [\n      {\n        \"id\": \"F933522B-8DC1-47DB-9274-7508B16D15BF\",\n        \"filename\": \"high_volume_b2b_laser_cnc_products.csv\",\n        \"mimeType\": \"text/csv\",\n        \"url\": \"https://bucket.blooio.com/custom-webhook-attachments/-xxxx.csv\",\n        \"size\": 1962,\n        \"expiresAt\": \"2025-07-24T09:33:26.934Z\",\n        \"expiresAtUnix\": 1753349606934\n      }\n    ],\n    \"conversation\": {\n      \"id\": \"iMessage;-;+11111111111\",\n      \"recipient\": \"+11111111111\",\n      \"name\": null\n    }\n  }\n}\n```"
      },
      "typeVersion": 1
    },
    {
      "id": "6d590245-abed-488a-bc31-cfe947a96237",
      "name": "AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -160,
        780
      ],
      "parameters": {
        "text": "=User message: {{ $('Receive Message (From Blooio)').item.json.body.message.content }}",
        "options": {
          "systemMessage": "<identity>\nYou are Mystic Tarot Reader \u2014 a visually intuitive, spiritually attuned AI tarot guide who interprets card images and text queries to offer soulful, empowering readings. Your presence is warm, sacred, and mystical, like a trusted oracle who responds with care and wonder through iMessage.\n</identity>\n\n<mission>\nYour task is to receive either:\n- A photo of tarot cards, with or without a question\n- A text-based inquiry for a virtual reading\n\nYou will identify the cards (visually or by name), interpret their symbolism in context, and provide heartfelt spiritual guidance. Your goal is to empower, comfort, and awaken insight in the user \u2014 never to predict fixed futures.\n\nYou respond with poetic clarity, emotional resonance, and intuitive warmth, making every reading feel personal and magical.\n</mission>\n\n<analysis_protocol>\n1. Visual Recognition  \n   - If a card image is provided, identify each card\u2019s name, suit, and whether it is upright or reversed.\n   - Recognize the spread type if evident (e.g., single, 3-card, Celtic Cross). If unclear, treat it as a general pull.\n\n2. Interpretation  \n   - Explain the meaning of each card, combining traditional symbolism and intuitive energy.\n   - Relate each card\u2019s message to the user's question or emotional tone if one is given.\n\n3. Integration Guidance  \n   - Offer gentle actions, mindset shifts, or spiritual practices to reflect the card\u2019s message.\n   - Avoid predictions; speak in terms of energy, archetypes, invitations, and choices.\n\n4. Visuals  \n   - When helpful or upon request, show an elegant rendering of the pulled tarot card(s) for mystical immersion.\n\n</analysis_protocol>\n\n<response_format>\nYou reply in a mystical iMessage-style voice \u2014 soft, intuitive, and soulful. Never respond in markdown or put start *** around words since iMessages does not format text.\n\nStart with a gentle greeting or acknowledgment of the card(s) and inquiry.  \nThen:\n- Reveal and describe each card, using emotive language and symbolic insight.\n- Integrate their meanings into a cohesive message or reflection.\n- Offer soulful next steps, journaling prompts, affirmations, or things to consider.\n- Conclude with an invitation to draw again or check in if they need more clarity.\n\nYour readings should sound like this:\n> \"Ahh, The Empress... lush with creativity, sensuality, and divine receiving. She\u2019s whispering: What wants to be nurtured in you right now?\"\n\nAvoid:  \n- Bullet points, markdown, numbered lists, or tables.  \n- Technical or robotic language.  \n- Overly brief replies \u2014 be poetic and immersive.\n\n</response_format>\n\n<onboarding_logic>\nIf the user says \"Hi\", \"Hello\", or similar, respond with:\n\n> \u2728 Hello, beautiful soul... and welcome to the **Mystic Tarot Reader**.  \n>\n> This is a sacred space for self-reflection, insight, and gentle guidance. Here\u2019s how to begin your tarot journey:  \n>\n> \ud83c\udf19 **Step 1**: Take a deep breath and center yourself.  \n> \ud83c\udf3f **Step 2**: Think of a question, situation, or feeling you\u2019d like clarity on.  \n> \ud83c\udccf **Step 3**: Pull one or more tarot cards using your favorite deck.  \n> \ud83d\udcf8 **Step 4**: Send me a photo of the card(s) **and** share the question or thought you focused on.  \n>\n> I\u2019ll read the energy and walk you through the meaning \u2014 like a cosmic guide on your shoulder.  \n>\n> \ud83d\udcab Ready when you are.\n\nIf the user does not have a deck or says \u201cdraw one for me,\u201d reply with:\n\n> Of course \ud83c\udf0c Let me draw a card for you now...  \n> *(Then continue with a virtual draw and full reading.)*\n\n</onboarding_logic>\n\n<error_handling>\nIf the uploaded image is unclear or doesn\u2019t show tarot cards, respond with warmth:\n\n> \ud83c\udf2b The image is a bit misty to my inner eye \u2014 I can\u2019t quite make out the card. Could you send a clearer photo or try again with your pull?\n\nIf unsure about the card or layout, gently offer a general message or ask if they\u2019d like to clarify. Never break tone or sound technical. Always maintain the sacred, supportive feel.\n</error_handling>",
          "passthroughBinaryImages": true
        },
        "promptType": "define"
      },
      "typeVersion": 1.9
    },
    {
      "id": "f7f7b39c-676e-412f-b34c-9c2bec110c40",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -160,
        960
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini",
          "cachedResultName": "gpt-4.1-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "77f9d1ad-7fcb-4df2-8757-5612b10c7aec",
      "name": "Postgres Chat Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryPostgresChat",
      "position": [
        -20,
        980
      ],
      "parameters": {
        "tableName": "n8n_tarot_ai",
        "sessionKey": "={{ $('Receive Message (From Blooio)').item.json.body.message.conversation.id }}",
        "sessionIdType": "customKey",
        "contextWindowLength": 200
      },
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "9bcc2d84-61db-4785-9cb5-4d893d3c973e",
      "name": "Receive Message (From Blooio)",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -1440,
        760
      ],
      "parameters": {
        "path": "tarot-ai",
        "options": {},
        "httpMethod": "POST"
      },
      "typeVersion": 2
    },
    {
      "id": "5d753997-b62d-4868-9acc-ad8cf52d6549",
      "name": "HTTP Request",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        400,
        400
      ],
      "parameters": {
        "url": "={{ $json.url }}",
        "options": {}
      },
      "typeVersion": 4.2
    },
    {
      "id": "fe6cbb47-c6d0-4ae8-b2df-93270c96168a",
      "name": "If has images, download them",
      "type": "n8n-nodes-base.if",
      "position": [
        -700,
        760
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "551f9536-48c3-4757-a58b-35ee1ef81a80",
              "operator": {
                "type": "array",
                "operation": "lengthGt",
                "rightType": "number"
              },
              "leftValue": "={{ $('Receive Message (From Blooio)').item.json.body.message.attachments }}",
              "rightValue": 0
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "3ab1790b-91b5-4b42-b394-9daf596d9a01",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        40,
        380
      ],
      "parameters": {
        "options": {
          "reset": false
        }
      },
      "typeVersion": 3
    },
    {
      "id": "edd17416-c915-40c7-9126-f0da875ec821",
      "name": "Code",
      "type": "n8n-nodes-base.code",
      "position": [
        -280,
        380
      ],
      "parameters": {
        "jsCode": "let output = [];\n\nfor (const item of $input.first().json.body.message.attachments) {\n  output.push({\n    json: {\n      url: item.url\n    }\n  });\n}\n\nreturn output;"
      },
      "typeVersion": 2
    },
    {
      "id": "a49c6fc6-6017-4dae-8cb7-55e24f6f1db6",
      "name": "AI Agent1",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        600,
        780
      ],
      "parameters": {
        "text": "={{ $json.data.toJsonString() }}",
        "options": {
          "systemMessage": "Summarize these messages and give the user a report that will be send in an iMessage. Do not say \"here's the summary\" or anything like that. Just respond with the summary by itself."
        },
        "promptType": "define"
      },
      "typeVersion": 2
    },
    {
      "id": "5832d268-d10d-41b1-82ea-08ef58f4bdb4",
      "name": "Aggregate",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        260,
        780
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData"
      },
      "typeVersion": 1
    },
    {
      "id": "d9a526a4-d839-48b0-9966-9e189c7d008b",
      "name": "OpenAI Chat Model1",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        620,
        940
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "abaff486-0b39-4b83-b800-e4c453154f91",
      "name": "Don't respond to yourself",
      "type": "n8n-nodes-base.if",
      "position": [
        -960,
        760
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "cecd3adf-a9e5-41d3-87ae-4a9699bd641b",
              "operator": {
                "type": "boolean",
                "operation": "false",
                "singleValue": true
              },
              "leftValue": "={{ $json.body.message.selfMessage }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "6d134ffb-638d-4aef-87d6-1ec2205d06c9",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -360,
        260
      ],
      "parameters": {
        "color": 4,
        "width": 980,
        "height": 400,
        "content": "## Image downloader \n"
      },
      "typeVersion": 1
    },
    {
      "id": "94f9f9bc-65d6-4725-923f-161dfeae142a",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1220,
        -1460
      ],
      "parameters": {
        "color": 3,
        "width": 680,
        "height": 2140,
        "content": "![Description](https://i.imgur.com/UgEluxE.png)\n"
      },
      "typeVersion": 1
    },
    {
      "id": "7df3f7c9-9892-4c50-aa4b-4c16d65dd3a7",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2000,
        -660
      ],
      "parameters": {
        "width": 780,
        "height": 1040,
        "content": "## \ud83d\udd2e Start Here: Mystic Tarot Bot Setup\n\nWelcome, seeker. Before your tarot bot can receive spiritual inquiries via iMessage and offer intuitive readings, follow these setup steps:\n\n---\n\n### \u2705 Step 1: Get Your Blooio API Token\n1. Go to [https://blooio.com](https://blooio.com)  \n2. Sign up for a **Dedicated** or **Enterprise** plan (required for attachments)  \n3. Navigate to **Settings \u2192 API Keys**  \n4. Generate an API token and **copy it**\n\n> \ud83d\udd10 Paste it in the **Send Message** node under the `Authorization` header (Bearer YOUR_TOKEN_HERE).\n\n---\n\n### \u2705 Step 2: Connect Blooio to n8n\nIn the **Webhook node**:  \n- Use the path `/tarot-ai` or another route of your choice  \n- Make sure your Blooio number is mapped to this endpoint in the Blooio dashboard\n\n---\n\n### \u2705 Step 3: Test the Flow\nText your Blooio-connected number:  \n- Send **\"Hi\"** or **\"Draw a card for me\"** to trigger onboarding  \n- Or send a **photo of tarot cards** with a question\n\nThis will:\n- Trigger the webhook  \n- Analyze the message/image with AI  \n- Return a mystical tarot reading via iMessage\n\n---\n\n### \ud83c\udccf What You Can Send\n- \u2728 A text-based question (e.g., \"What\u2019s the energy around my career?\")  \n- \ud83d\uddbc A photo of drawn tarot cards  \n- \ud83e\uddd8\u200d\u2640\ufe0f A simple \"Hi\" to receive onboarding guidance\n\nLet the mystery unfold, one message at a time... \ud83c\udf19\ud83d\udce9\n"
      },
      "typeVersion": 1
    }
  ],
  "active": true,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "82c9ffad-b201-4c96-8cc3-31d3e21678f6",
  "connections": {
    "Code": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent": {
      "main": [
        [
          {
            "node": "Aggregate",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent1": {
      "main": [
        [
          {
            "node": "Send Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate": {
      "main": [
        [
          {
            "node": "AI Agent1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "HTTP Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent1",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Postgres Chat Memory": {
      "ai_memory": [
        [
          {
            "node": "AI Agent",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Don't respond to yourself": {
      "main": [
        [
          {
            "node": "If has images, download them",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If has images, download them": {
      "main": [
        [
          {
            "node": "Code",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Receive Message (From Blooio)": {
      "main": [
        [
          {
            "node": "Don't respond to yourself",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}