{
  "name": "LineOA",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "request",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1,
      "position": [
        -2832,
        1712
      ],
      "id": "2a282af4-c352-41e0-81e0-c16f8034bc77",
      "name": "Webhook"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.line.me/v2/bot/message/reply",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer dfb5VjlLp060/Co+K/KvfL3JRM8qGYag5hbDOvqyfXuMMZ0auDMU3RQ0CC3XJCbt/5sXYsbfO51+5dIt6Xq3WD48lxkTxubVv5Yps4NMkL6SnVvuieSq86Qyo3ZugeYbz0OkGv25DxMUN/aheZpANwdB04t89/1O/w1cDnyilFU="
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"replyToken\": \"{{ $('Webhook').first().json.body.events[0].replyToken }}\",\n  \"messages\": [\n    {\n      \"type\": \"text\",\n      \"text\": \"{{ $json.output.replaceAll('\\t',' ').replaceAll('\\\"','\\\\\\\"').replaceAll('\\n','\\\\n').trim() || 'An error occurred, please try again.' }}\"\n    }\n  ]\n}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        336,
        1632
      ],
      "id": "c206c062-ebbb-47df-b861-fbe43cb7ede1",
      "name": "HTTP Request"
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "={{ $('message').item.json.message }}",
        "options": {
          "systemMessage": "=\u0e04\u0e38\u0e13\u0e04\u0e37\u0e2d SME FoodMate AI \u0e1c\u0e39\u0e49\u0e40\u0e0a\u0e35\u0e48\u0e22\u0e27\u0e0a\u0e32\u0e0d\u0e41\u0e25\u0e30\u0e1c\u0e39\u0e49\u0e0a\u0e48\u0e27\u0e22\u0e2a\u0e33\u0e2b\u0e23\u0e31\u0e1a\u0e40\u0e08\u0e49\u0e32\u0e02\u0e2d\u0e07\u0e18\u0e38\u0e23\u0e01\u0e34\u0e08\u0e23\u0e49\u0e32\u0e19\u0e2d\u0e32\u0e2b\u0e32\u0e23\u0e41\u0e25\u0e30\u0e04\u0e32\u0e40\u0e1f\u0e48 (SME) \u0e43\u0e19\u0e44\u0e17\u0e22\n\n\u0e40\u0e1b\u0e49\u0e32\u0e2b\u0e21\u0e32\u0e22\u0e2b\u0e25\u0e31\u0e01\u0e02\u0e2d\u0e07\u0e04\u0e38\u0e13\u0e04\u0e37\u0e2d\u0e01\u0e32\u0e23\u0e43\u0e2b\u0e49\u0e04\u0e33\u0e41\u0e19\u0e30\u0e19\u0e33\u0e17\u0e35\u0e48\u0e19\u0e33\u0e44\u0e1b\u0e43\u0e0a\u0e49\u0e44\u0e14\u0e49\u0e08\u0e23\u0e34\u0e07\u0e41\u0e25\u0e30\u0e40\u0e02\u0e49\u0e32\u0e43\u0e08\u0e07\u0e48\u0e32\u0e22 \u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e0a\u0e48\u0e27\u0e22\u0e43\u0e2b\u0e49\u0e1e\u0e27\u0e01\u0e40\u0e02\u0e32 \u0e25\u0e14\u0e15\u0e49\u0e19\u0e17\u0e38\u0e19, \u0e40\u0e1e\u0e34\u0e48\u0e21\u0e22\u0e2d\u0e14\u0e02\u0e32\u0e22, \u0e41\u0e25\u0e30\u0e1a\u0e23\u0e34\u0e2b\u0e32\u0e23\u0e18\u0e38\u0e23\u0e01\u0e34\u0e08 \u0e44\u0e14\u0e49\u0e2d\u0e22\u0e48\u0e32\u0e07\u0e21\u0e35\u0e1b\u0e23\u0e30\u0e2a\u0e34\u0e17\u0e18\u0e34\u0e20\u0e32\u0e1e\n\n\u0e02\u0e2d\u0e1a\u0e40\u0e02\u0e15\u0e04\u0e27\u0e32\u0e21\u0e40\u0e0a\u0e35\u0e48\u0e22\u0e27\u0e0a\u0e32\u0e0d\n\u0e04\u0e38\u0e13\u0e08\u0e30\u0e15\u0e2d\u0e1a\u0e40\u0e09\u0e1e\u0e32\u0e30\u0e04\u0e33\u0e16\u0e32\u0e21\u0e17\u0e35\u0e48\u0e40\u0e01\u0e35\u0e48\u0e22\u0e27\u0e01\u0e31\u0e1a 4 \u0e14\u0e49\u0e32\u0e19\u0e19\u0e35\u0e49\u0e40\u0e17\u0e48\u0e32\u0e19\u0e31\u0e49\u0e19:\n\n\ud83d\udca1 \u0e01\u0e32\u0e23\u0e15\u0e25\u0e32\u0e14: \u0e01\u0e25\u0e22\u0e38\u0e17\u0e18\u0e4c\u0e42\u0e0b\u0e40\u0e0a\u0e35\u0e22\u0e25\u0e21\u0e35\u0e40\u0e14\u0e35\u0e22\u0e15\u0e49\u0e19\u0e17\u0e38\u0e19\u0e15\u0e48\u0e33, \u0e42\u0e1b\u0e23\u0e42\u0e21\u0e0a\u0e31\u0e19, \u0e01\u0e32\u0e23\u0e23\u0e31\u0e01\u0e29\u0e32\u0e25\u0e39\u0e01\u0e04\u0e49\u0e32, \u0e01\u0e32\u0e23\u0e2d\u0e2d\u0e01\u0e41\u0e1a\u0e1a\u0e40\u0e21\u0e19\u0e39\u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e01\u0e32\u0e23\u0e02\u0e32\u0e22\n\ud83d\udcb0 \u0e01\u0e32\u0e23\u0e08\u0e31\u0e14\u0e01\u0e32\u0e23\u0e15\u0e49\u0e19\u0e17\u0e38\u0e19: \u0e01\u0e32\u0e23\u0e2b\u0e32\u0e41\u0e2b\u0e25\u0e48\u0e07\u0e27\u0e31\u0e15\u0e16\u0e38\u0e14\u0e34\u0e1a, \u0e01\u0e32\u0e23\u0e25\u0e14\u0e02\u0e22\u0e30, \u0e01\u0e32\u0e23\u0e04\u0e27\u0e1a\u0e04\u0e38\u0e21\u0e2a\u0e15\u0e47\u0e2d\u0e01, \u0e01\u0e32\u0e23\u0e04\u0e33\u0e19\u0e27\u0e13\u0e15\u0e49\u0e19\u0e17\u0e38\u0e19\u0e2d\u0e32\u0e2b\u0e32\u0e23\n\ud83d\udcc8 \u0e01\u0e32\u0e23\u0e14\u0e33\u0e40\u0e19\u0e34\u0e19\u0e07\u0e32\u0e19: \u0e40\u0e17\u0e04\u0e19\u0e34\u0e04\u0e08\u0e31\u0e14\u0e01\u0e32\u0e23\u0e2a\u0e15\u0e47\u0e2d\u0e01 (\u0e40\u0e0a\u0e48\u0e19 FIFO), \u0e01\u0e32\u0e23\u0e2b\u0e32\u0e0b\u0e31\u0e1e\u0e1e\u0e25\u0e32\u0e22\u0e40\u0e2d\u0e2d\u0e23\u0e4c\u0e43\u0e19\u0e1e\u0e37\u0e49\u0e19\u0e17\u0e35\u0e48, \u0e01\u0e32\u0e23\u0e40\u0e1e\u0e34\u0e48\u0e21\u0e1b\u0e23\u0e30\u0e2a\u0e34\u0e17\u0e18\u0e34\u0e20\u0e32\u0e1e\u0e01\u0e32\u0e23\u0e08\u0e31\u0e14\u0e2a\u0e48\u0e07\n\ud83d\uded2 \u0e01\u0e32\u0e23\u0e40\u0e07\u0e34\u0e19\u0e40\u0e1a\u0e37\u0e49\u0e2d\u0e07\u0e15\u0e49\u0e19: \u0e01\u0e32\u0e23\u0e27\u0e34\u0e40\u0e04\u0e23\u0e32\u0e30\u0e2b\u0e4c\u0e01\u0e33\u0e44\u0e23\u0e02\u0e32\u0e14\u0e17\u0e38\u0e19\u0e40\u0e1a\u0e37\u0e49\u0e2d\u0e07\u0e15\u0e49\u0e19, \u0e40\u0e04\u0e25\u0e47\u0e14\u0e25\u0e31\u0e1a\u0e01\u0e32\u0e23\u0e40\u0e1e\u0e34\u0e48\u0e21\u0e2a\u0e20\u0e32\u0e1e\u0e04\u0e25\u0e48\u0e2d\u0e07\u0e17\u0e32\u0e07\u0e01\u0e32\u0e23\u0e40\u0e07\u0e34\u0e19\n\n\u0e01\u0e0e\u0e01\u0e32\u0e23\u0e15\u0e2d\u0e1a\u0e01\u0e25\u0e31\u0e1a\n[\u0e20\u0e32\u0e29\u0e32\u0e41\u0e25\u0e30\u0e19\u0e49\u0e33\u0e40\u0e2a\u0e35\u0e22\u0e07]\n\u0e15\u0e2d\u0e1a\u0e40\u0e1b\u0e47\u0e19\u0e20\u0e32\u0e29\u0e32\u0e44\u0e17\u0e22\u0e40\u0e2a\u0e21\u0e2d \u0e14\u0e49\u0e27\u0e22\u0e19\u0e49\u0e33\u0e40\u0e2a\u0e35\u0e22\u0e07\u0e17\u0e35\u0e48\u0e40\u0e1b\u0e47\u0e19\u0e21\u0e34\u0e15\u0e23 \u0e43\u0e2b\u0e49\u0e01\u0e33\u0e25\u0e31\u0e07\u0e43\u0e08 \u0e40\u0e2b\u0e21\u0e37\u0e2d\u0e19\u0e40\u0e1b\u0e47\u0e19\u0e17\u0e35\u0e48\u0e1b\u0e23\u0e36\u0e01\u0e29\u0e32 \u0e41\u0e15\u0e48\u0e22\u0e31\u0e07\u0e04\u0e07\u0e04\u0e27\u0e32\u0e21\u0e40\u0e1b\u0e47\u0e19\u0e21\u0e37\u0e2d\u0e2d\u0e32\u0e0a\u0e35\u0e1e \u0e2b\u0e25\u0e35\u0e01\u0e40\u0e25\u0e35\u0e48\u0e22\u0e07\u0e28\u0e31\u0e1e\u0e17\u0e4c\u0e40\u0e17\u0e04\u0e19\u0e34\u0e04\u0e17\u0e35\u0e48\u0e0b\u0e31\u0e1a\u0e0b\u0e49\u0e2d\u0e19\u0e40\u0e01\u0e34\u0e19\u0e44\u0e1b\n\n[\u0e42\u0e04\u0e23\u0e07\u0e2a\u0e23\u0e49\u0e32\u0e07\u0e41\u0e25\u0e30\u0e01\u0e32\u0e23\u0e08\u0e31\u0e14\u0e23\u0e39\u0e1b\u0e41\u0e1a\u0e1a\u0e2a\u0e33\u0e2b\u0e23\u0e31\u0e1a LINE]\n\u0e17\u0e38\u0e01\u0e04\u0e33\u0e15\u0e2d\u0e1a\u0e15\u0e49\u0e2d\u0e07\u0e08\u0e31\u0e14\u0e23\u0e39\u0e1b\u0e41\u0e1a\u0e1a\u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e43\u0e2b\u0e49\u0e2d\u0e48\u0e32\u0e19\u0e07\u0e48\u0e32\u0e22\u0e1a\u0e19\u0e21\u0e37\u0e2d\u0e16\u0e37\u0e2d:\n\ud83d\udd38 \u0e02\u0e36\u0e49\u0e19\u0e15\u0e49\u0e19\u0e14\u0e49\u0e27\u0e22\u0e2b\u0e31\u0e27\u0e02\u0e49\u0e2d\u0e2b\u0e25\u0e31\u0e01\u0e43\u0e19\u0e27\u0e07\u0e40\u0e25\u0e47\u0e1a \u0e40\u0e0a\u0e48\u0e19 [\u0e2b\u0e31\u0e27\u0e02\u0e49\u0e2d]\n\ud83d\udd38 \u0e43\u0e0a\u0e49 Emoji \ud83d\udca1\ud83d\udcb0\ud83d\udcc8\ud83d\uded2 \u0e19\u0e33\u0e2b\u0e19\u0e49\u0e32\u0e1b\u0e23\u0e30\u0e40\u0e14\u0e47\u0e19\u0e22\u0e48\u0e2d\u0e22\n\ud83d\udd38 \u0e43\u0e0a\u0e49\u0e22\u0e48\u0e2d\u0e2b\u0e19\u0e49\u0e32\u0e2a\u0e31\u0e49\u0e19\u0e46 (\u0e44\u0e21\u0e48\u0e40\u0e01\u0e34\u0e19 2-3 \u0e1b\u0e23\u0e30\u0e42\u0e22\u0e04) \u0e41\u0e25\u0e30\u0e02\u0e36\u0e49\u0e19\u0e1a\u0e23\u0e23\u0e17\u0e31\u0e14\u0e43\u0e2b\u0e21\u0e48\u0e1a\u0e48\u0e2d\u0e22\u0e46\n\ud83d\udd38 \u0e08\u0e1a\u0e14\u0e49\u0e27\u0e22\u0e01\u0e32\u0e23\u0e2a\u0e23\u0e38\u0e1b\u0e43\u0e2b\u0e49\u0e01\u0e33\u0e25\u0e31\u0e07\u0e43\u0e08\u0e2b\u0e23\u0e37\u0e2d\u0e04\u0e33\u0e16\u0e32\u0e21\u0e2a\u0e31\u0e49\u0e19\u0e46 \u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e01\u0e23\u0e30\u0e15\u0e38\u0e49\u0e19\u0e01\u0e32\u0e23\u0e2a\u0e19\u0e17\u0e19\u0e32\n- \u0e44\u0e21\u0e48\u0e15\u0e49\u0e2d\u0e07\u0e43\u0e2a\u0e48 '*' \u0e43\u0e19\u0e02\u0e49\u0e2d\u0e04\u0e27\u0e32\u0e21\n\n[\u0e02\u0e49\u0e2d\u0e08\u0e33\u0e01\u0e31\u0e14\u0e2a\u0e33\u0e04\u0e31\u0e0d]\n\ud83d\udd38 \u0e2b\u0e32\u0e01\u0e04\u0e33\u0e16\u0e32\u0e21\u0e2d\u0e22\u0e39\u0e48\u0e19\u0e2d\u0e01\u0e02\u0e2d\u0e1a\u0e40\u0e02\u0e15\u0e04\u0e27\u0e32\u0e21\u0e40\u0e0a\u0e35\u0e48\u0e22\u0e27\u0e0a\u0e32\u0e0d 4 \u0e14\u0e49\u0e32\u0e19\u0e02\u0e49\u0e32\u0e07\u0e15\u0e49\u0e19 \u0e43\u0e2b\u0e49\u0e1b\u0e0f\u0e34\u0e40\u0e2a\u0e18\u0e2d\u0e22\u0e48\u0e32\u0e07\u0e2a\u0e38\u0e20\u0e32\u0e1e\u0e27\u0e48\u0e32 \"\u0e40\u0e23\u0e37\u0e48\u0e2d\u0e07\u0e19\u0e35\u0e49\u0e2d\u0e22\u0e39\u0e48\u0e19\u0e2d\u0e01\u0e40\u0e2b\u0e19\u0e37\u0e2d\u0e04\u0e27\u0e32\u0e21\u0e40\u0e0a\u0e35\u0e48\u0e22\u0e27\u0e0a\u0e32\u0e0d\u0e02\u0e2d\u0e07 Co-Pilot AI \u0e04\u0e23\u0e31\u0e1a\" \u0e41\u0e25\u0e30\u0e41\u0e19\u0e30\u0e19\u0e33\u0e43\u0e2b\u0e49\u0e1b\u0e23\u0e36\u0e01\u0e29\u0e32\u0e1c\u0e39\u0e49\u0e40\u0e0a\u0e35\u0e48\u0e22\u0e27\u0e0a\u0e32\u0e0d\u0e42\u0e14\u0e22\u0e15\u0e23\u0e07\n\ud83d\udd38 \u0e2b\u0e49\u0e32\u0e21 \u0e43\u0e2b\u0e49\u0e04\u0e33\u0e41\u0e19\u0e30\u0e19\u0e33\u0e17\u0e32\u0e07\u0e01\u0e32\u0e23\u0e41\u0e1e\u0e17\u0e22\u0e4c, \u0e01\u0e0e\u0e2b\u0e21\u0e32\u0e22, \u0e2b\u0e23\u0e37\u0e2d\u0e01\u0e32\u0e23\u0e25\u0e07\u0e17\u0e38\u0e19\u0e17\u0e32\u0e07\u0e01\u0e32\u0e23\u0e40\u0e07\u0e34\u0e19\u0e40\u0e14\u0e47\u0e14\u0e02\u0e32\u0e14"
        }
      },
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 2.2,
      "position": [
        -224,
        1632
      ],
      "id": "374785c9-9b45-4757-b0d9-5962123bcb7b",
      "name": "AI Agent"
    },
    {
      "parameters": {
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "typeVersion": 1,
      "position": [
        -224,
        1824
      ],
      "id": "2ba03ead-b7e6-46bf-a3ed-4a9318f36859",
      "name": "Google Gemini Chat Model",
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "typeVersion": 1,
      "position": [
        -1600,
        2080
      ],
      "id": "7000dd9b-ae5f-42b8-a301-f18590bbaefe",
      "name": "Google Gemini Chat Model1",
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "dcee9191-38b1-4b95-8f2b-c1606569f942",
                    "leftValue": "={{ $json.output.intent }}",
                    "rightValue": "GREETING",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              }
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "ce6452f8-f0a3-4554-ade4-a56c180b0c59",
                    "leftValue": "={{ $json.output.intent }}",
                    "rightValue": "AI_CONSULT",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              }
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "2faeb9d7-6108-4881-aad6-c9ac06927d96",
                    "leftValue": "={{ $json.output.intent }}",
                    "rightValue": "FAQ",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              }
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.output.intent }}",
                    "rightValue": "OTHER",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "id": "f5751c45-db5b-4d50-b078-acac5d6d4db1"
                  }
                ],
                "combinator": "and"
              }
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.3,
      "position": [
        -1168,
        1680
      ],
      "id": "b30d1d2e-0b57-4156-8e47-4972fa4407c6",
      "name": "Switch"
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=You are an expert intent classifier for a business assistant chatbot for F&B SMEs named 'F&B SME Co-Pilot'.\nYour task is to analyze the user's message and classify it into one of the following categories.\nRespond ONLY with a JSON object containing the determined intent.\n\nHere are the possible intents and their definitions:\n\n- AI_CONSULT: User is asking for **in-depth, personalized business advice** that requires analysis of their specific situation. This is for questions that cannot be answered with a general guide.\n\n- FAQ: User is asking a general question about the service itself, **OR a common, general business question** that could likely be answered from a knowledge base.\n\n- GREETING: User is saying hello, thank you, or other pleasantries.\n\n- OTHER: The user's request does not fit into any of the above categories.\n\n**Decision-making examples to guide you:**\n- If the user asks \"How do I do marketing online?\", classify as **FAQ**. (This is a general question)\n- If the user asks \"Can you give me a marketing plan for my new fried chicken shop in Ari?\", classify as **AI_CONSULT**. (This is a personalized request)\n- If the user asks \"What are some ways to reduce costs?\", classify as **FAQ**. (This is a general question)\n- If the user asks \"My ingredient cost is 35%, how can I lower it?\", classify as **AI_CONSULT**. (This requires analysis of specific data)\n\nUser's message: \"{{ $json.message }}\"\n\nJSON Response:",
        "hasOutputParser": true,
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 2.2,
      "position": [
        -1552,
        1696
      ],
      "id": "e672ece6-0865-47d1-90d7-51d4a091b54a",
      "name": "filter intent"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "a2b94504-d596-4368-94ed-1e5974ef89ad",
              "name": "replyMessage",
              "value": "\u0e2a\u0e27\u0e31\u0e2a\u0e14\u0e35\u0e04\u0e23\u0e31\u0e1a SME FoodMate  \u0e22\u0e34\u0e19\u0e14\u0e35\u0e43\u0e2b\u0e49\u0e1a\u0e23\u0e34\u0e01\u0e32\u0e23 \u0e21\u0e35\u0e2d\u0e30\u0e44\u0e23\u0e43\u0e2b\u0e49\u0e0a\u0e48\u0e27\u0e22\u0e2a\u0e2d\u0e1a\u0e16\u0e32\u0e21\u0e44\u0e14\u0e49\u0e40\u0e25\u0e22\u0e04\u0e23\u0e31\u0e1a \ud83d\ude0a",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -896,
        1328
      ],
      "id": "2d8714f9-0a98-46d5-b402-24a9f6bd9c39",
      "name": "Edit Fields1"
    },
    {
      "parameters": {
        "jsonSchemaExample": "{\n\t\"intent\": \"The classified intent of the user's message. Must be one of: AI_CONSULT, FAQ, GREETING, OTHER.\"\n}"
      },
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "typeVersion": 1.3,
      "position": [
        -1408,
        2000
      ],
      "id": "f37ec9cf-9059-4464-8c67-c5b7ef347c9b",
      "name": "Structured Output Parser"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.line.me/v2/bot/message/reply",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer dfb5VjlLp060/Co+K/KvfL3JRM8qGYag5hbDOvqyfXuMMZ0auDMU3RQ0CC3XJCbt/5sXYsbfO51+5dIt6Xq3WD48lxkTxubVv5Yps4NMkL6SnVvuieSq86Qyo3ZugeYbz0OkGv25DxMUN/aheZpANwdB04t89/1O/w1cDnyilFU="
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"replyToken\": \"{{ $('Webhook').first().json.body.events[0].replyToken }}\",\n  \"messages\": [\n    {\n      \"type\": \"text\",\n      \"text\": \"{{ $json.Answer.replaceAll('\\t',' ').replaceAll('\\\"','\\\\\\\"').replaceAll('\\n','\\\\n').trim() }}\"\n    }\n  ]\n}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -32,
        2192
      ],
      "id": "018e5b63-c6cd-45bf-a64f-2e5f601a02b7",
      "name": "HTTP Request2"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.line.me/v2/bot/message/reply",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer dfb5VjlLp060/Co+K/KvfL3JRM8qGYag5hbDOvqyfXuMMZ0auDMU3RQ0CC3XJCbt/5sXYsbfO51+5dIt6Xq3WD48lxkTxubVv5Yps4NMkL6SnVvuieSq86Qyo3ZugeYbz0OkGv25DxMUN/aheZpANwdB04t89/1O/w1cDnyilFU="
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"replyToken\": \"{{ $('Webhook').first().json.body.events[0].replyToken }}\",\n  \"messages\": [\n    {\n      \"type\": \"text\",\n      \"text\": \"\u0e01\u0e33\u0e25\u0e31\u0e07\u0e08\u0e30\u0e04\u0e49\u0e19\u0e2b\u0e32\u0e23\u0e49\u0e32\u0e19\u0e04\u0e49\u0e32\u0e43\u0e01\u0e25\u0e49\u0e40\u0e04\u0e35\u0e22\u0e07\u0e43\u0e2b\u0e49\u0e04\u0e23\u0e31\u0e1a \ud83e\uddd0\\n\\n\u0e01\u0e23\u0e38\u0e13\u0e32\u0e01\u0e14\u0e1b\u0e38\u0e48\u0e21\u0e14\u0e49\u0e32\u0e19\u0e25\u0e48\u0e32\u0e07 \u0e2b\u0e23\u0e37\u0e2d\u0e41\u0e0a\u0e23\u0e4c\u0e15\u0e33\u0e41\u0e2b\u0e19\u0e48\u0e07\u0e17\u0e35\u0e48\u0e15\u0e31\u0e49\u0e07 (Location) \u0e02\u0e2d\u0e07\u0e04\u0e38\u0e13\u0e44\u0e14\u0e49\u0e40\u0e25\u0e22\u0e04\u0e23\u0e31\u0e1a\",\n      \"quickReply\": {\n        \"items\": [\n          {\n            \"type\": \"action\",\n            \"action\": {\n              \"type\": \"location\",\n              \"label\": \"\ud83d\udccd \u0e2a\u0e48\u0e07\u0e15\u0e33\u0e41\u0e2b\u0e19\u0e48\u0e07\u0e17\u0e35\u0e48\u0e15\u0e31\u0e49\u0e07\u0e1b\u0e31\u0e08\u0e08\u0e38\u0e1a\u0e31\u0e19\"\n            }\n          }\n        ]\n      }\n    }\n  ]\n}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -576,
        400
      ],
      "id": "53157b4e-e0b5-49c6-beb1-f4ce48615d5a",
      "name": "request location"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "76da3b8c-e07f-4204-97d3-93ca015f8b5f",
              "leftValue": "={{ $node[\"Get row by uid3\"].json.isEmpty() }}",
              "rightValue": "",
              "operator": {
                "type": "boolean",
                "operation": "false",
                "singleValue": true
              }
            }
          ],
          "combinator": "or"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        -1072,
        144
      ],
      "id": "1c98cb09-3203-467c-bb98-5ff4eefea7b8",
      "name": "information"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "b4f15148-7ac6-4d91-a685-9aee41e250f1",
              "leftValue": "={{ parseFloat($json.lat) }}",
              "rightValue": 0,
              "operator": {
                "type": "number",
                "operation": "gt"
              }
            },
            {
              "id": "ef591cfe-55c7-400e-be24-45e459774211",
              "leftValue": "={{ parseFloat($json.lon) }}",
              "rightValue": 0,
              "operator": {
                "type": "number",
                "operation": "gt"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        -736,
        128
      ],
      "id": "984a8ebf-2c23-4433-83ce-193dca0008c8",
      "name": "location"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.line.me/v2/bot/message/reply",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer dfb5VjlLp060/Co+K/KvfL3JRM8qGYag5hbDOvqyfXuMMZ0auDMU3RQ0CC3XJCbt/5sXYsbfO51+5dIt6Xq3WD48lxkTxubVv5Yps4NMkL6SnVvuieSq86Qyo3ZugeYbz0OkGv25DxMUN/aheZpANwdB04t89/1O/w1cDnyilFU="
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"replyToken\": \"{{ $('Webhook').first().json.body.events[0].replyToken }}\",\n  \"messages\": [\n    {\n      \"type\": \"text\",\n      \"text\": \"\u0e22\u0e34\u0e19\u0e14\u0e35\u0e15\u0e49\u0e2d\u0e19\u0e23\u0e31\u0e1a\u0e2a\u0e39\u0e48 F&B Co-Pilot \u0e04\u0e23\u0e31\u0e1a! \ud83d\ude0a\\n\\n\u0e01\u0e48\u0e2d\u0e19\u0e40\u0e23\u0e34\u0e48\u0e21\u0e43\u0e0a\u0e49\u0e07\u0e32\u0e19\u0e1f\u0e35\u0e40\u0e08\u0e2d\u0e23\u0e4c\u0e23\u0e27\u0e21\u0e01\u0e25\u0e38\u0e48\u0e21\u0e0b\u0e37\u0e49\u0e2d \u0e02\u0e2d\u0e23\u0e1a\u0e01\u0e27\u0e19\u0e04\u0e38\u0e13\u0e25\u0e07\u0e17\u0e30\u0e40\u0e1a\u0e35\u0e22\u0e19\u0e23\u0e49\u0e32\u0e19\u0e04\u0e49\u0e32\u0e2a\u0e31\u0e49\u0e19\u0e46 \u0e01\u0e48\u0e2d\u0e19\u0e19\u0e30\u0e04\u0e23\u0e31\u0e1a\"\n    },\n    {\n      \"type\": \"text\",\n      \"text\": \"\u0e01\u0e23\u0e38\u0e13\u0e32\u0e1e\u0e34\u0e21\u0e1e\u0e4c\u0e15\u0e2d\u0e1a\u0e01\u0e25\u0e31\u0e1a\u0e21\u0e32\u0e43\u0e19\u0e23\u0e39\u0e1b\u0e41\u0e1a\u0e1a\u0e19\u0e35\u0e49\u0e04\u0e23\u0e31\u0e1a:\\n#\u0e25\u0e07\u0e17\u0e30\u0e40\u0e1a\u0e35\u0e22\u0e19 \u0e0a\u0e37\u0e48\u0e2d\u0e23\u0e49\u0e32\u0e19\u0e02\u0e2d\u0e07\u0e04\u0e38\u0e13, \u0e1b\u0e23\u0e30\u0e40\u0e20\u0e17\u0e23\u0e49\u0e32\u0e19\\n\\n\u0e15\u0e31\u0e27\u0e2d\u0e22\u0e48\u0e32\u0e07:\\n#\u0e25\u0e07\u0e17\u0e30\u0e40\u0e1a\u0e35\u0e22\u0e19 \u0e23\u0e49\u0e32\u0e19\u0e40\u0e08\u0e4a\u0e44\u0e1d\u0e42\u0e2d\u0e21\u0e32\u0e01\u0e32\u0e40\u0e2a\u0e30, \u0e2d\u0e32\u0e2b\u0e32\u0e23\u0e15\u0e32\u0e21\u0e2a\u0e31\u0e48\u0e07\"\n    }\n  ]\n}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -1152,
        464
      ],
      "id": "dd7e77e6-35d4-4c41-8831-9260b91f1ae1",
      "name": "request location1"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "2732ac41-6df2-4362-8600-a0f1e5a65934",
              "name": "userId",
              "value": "={{ $json.body.events[0].source.userId }}",
              "type": "string"
            },
            {
              "id": "97361a7c-d326-4f64-8c53-10a155007553",
              "name": "message",
              "value": "={{ $json.body.events[0].message.text }}",
              "type": "string"
            },
            {
              "id": "2872dd3e-180c-498a-93df-36b503fa4d09",
              "name": "replyToken",
              "value": "={{ $json.body.events[0].replyToken }}",
              "type": "string"
            },
            {
              "id": "b46ac446-d02e-4e2a-bbff-3e7a7c21e2e0",
              "name": "body.events[0].postback.data",
              "value": "={{ $json.body.events[0].postback.data }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -2528,
        1712
      ],
      "id": "c66ba1b6-b128-44f3-a30a-1d7982d62e52",
      "name": "message"
    },
    {
      "parameters": {
        "jsCode": "\n// 1. \u0e14\u0e36\u0e07\u0e02\u0e49\u0e2d\u0e04\u0e27\u0e32\u0e21\u0e40\u0e15\u0e47\u0e21\u0e46 \u0e08\u0e32\u0e01 Webhook Trigger\n// (\u0e43\u0e0a\u0e49 $('Webhook') \u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e04\u0e27\u0e32\u0e21\u0e41\u0e19\u0e48\u0e19\u0e2d\u0e19\u0e27\u0e48\u0e32\u0e08\u0e30\u0e44\u0e14\u0e49\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e08\u0e32\u0e01\u0e08\u0e38\u0e14\u0e40\u0e23\u0e34\u0e48\u0e21\u0e15\u0e49\u0e19\u0e40\u0e2a\u0e21\u0e2d)\nconst fullMessage = $input.first().json.message\n\n// 2. \u0e15\u0e31\u0e14\u0e04\u0e33\u0e27\u0e48\u0e32 \"#\u0e25\u0e07\u0e17\u0e30\u0e40\u0e1a\u0e35\u0e22\u0e19\" \u0e41\u0e25\u0e30\u0e0a\u0e48\u0e2d\u0e07\u0e27\u0e48\u0e32\u0e07\u0e02\u0e49\u0e32\u0e07\u0e2b\u0e19\u0e49\u0e32\u0e2d\u0e2d\u0e01\u0e44\u0e1b\nconst dataString = fullMessage.replace('#\u0e25\u0e07\u0e17\u0e30\u0e40\u0e1a\u0e35\u0e22\u0e19', '').trim();\n\n// 3. \u0e41\u0e22\u0e01\u0e02\u0e49\u0e2d\u0e04\u0e27\u0e32\u0e21\u0e14\u0e49\u0e27\u0e22\u0e40\u0e04\u0e23\u0e37\u0e48\u0e2d\u0e07\u0e2b\u0e21\u0e32\u0e22 \",\"\nconst parts = dataString.split(',');\n\n// 4. \u0e15\u0e23\u0e27\u0e08\u0e2a\u0e2d\u0e1a\u0e27\u0e48\u0e32\u0e1c\u0e39\u0e49\u0e43\u0e0a\u0e49\u0e1e\u0e34\u0e21\u0e1e\u0e4c\u0e21\u0e32\u0e16\u0e39\u0e01\u0e23\u0e39\u0e1b\u0e41\u0e1a\u0e1a\u0e2b\u0e23\u0e37\u0e2d\u0e44\u0e21\u0e48 (\u0e04\u0e27\u0e23\u0e08\u0e30\u0e21\u0e35 2 \u0e2a\u0e48\u0e27\u0e19)\nif (parts.length !== 2) {\n  // \u0e16\u0e49\u0e32\u0e44\u0e21\u0e48\u0e16\u0e39\u0e01\u0e23\u0e39\u0e1b\u0e41\u0e1a\u0e1a \u0e43\u0e2b\u0e49\u0e2a\u0e48\u0e07\u0e04\u0e48\u0e32\u0e27\u0e48\u0e32\u0e07\u0e2d\u0e2d\u0e01\u0e44\u0e1b \u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e43\u0e2b\u0e49 Workflow \u0e2b\u0e22\u0e38\u0e14\u0e17\u0e33\u0e07\u0e32\u0e19\u0e17\u0e35\u0e48\u0e19\u0e35\u0e48\n  // \u0e1b\u0e49\u0e2d\u0e07\u0e01\u0e31\u0e19\u0e01\u0e32\u0e23\u0e1a\u0e31\u0e19\u0e17\u0e36\u0e01\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e1c\u0e34\u0e14\u0e46 \u0e25\u0e07 Database\n  return null; \n}\n\n// 5. \u0e17\u0e33\u0e04\u0e27\u0e32\u0e21\u0e2a\u0e30\u0e2d\u0e32\u0e14\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e41\u0e15\u0e48\u0e25\u0e30\u0e2a\u0e48\u0e27\u0e19 (\u0e15\u0e31\u0e14\u0e0a\u0e48\u0e2d\u0e07\u0e27\u0e48\u0e32\u0e07) \u0e41\u0e25\u0e30\u0e01\u0e33\u0e2b\u0e19\u0e14\u0e04\u0e48\u0e32\u0e43\u0e2b\u0e49\u0e15\u0e31\u0e27\u0e41\u0e1b\u0e23\nconst storeName = parts[0].trim();\nconst storeType = parts[1].trim();\n\n// 6. \u0e2a\u0e23\u0e49\u0e32\u0e07 Object \u0e43\u0e2b\u0e21\u0e48\u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e2a\u0e48\u0e07\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e2d\u0e2d\u0e01\u0e44\u0e1b\u0e43\u0e2b\u0e49 Node \u0e16\u0e31\u0e14\u0e44\u0e1b\u0e43\u0e0a\u0e49\nconst item = {};\nitem.store_name = storeName;\nitem.store_type = storeType;\n\n// \u0e2a\u0e48\u0e07\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e2d\u0e2d\u0e01\u0e44\u0e1b\nreturn item;"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -2128,
        1280
      ],
      "id": "2e761b03-61cb-4f34-9b44-637213694cfb",
      "name": "Code in JavaScript1"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "45d8ff4f-e876-49cd-9a0f-ec6004a3e910",
              "leftValue": "={{ $json.message }}",
              "rightValue": "Group Purchase Function",
              "operator": {
                "type": "string",
                "operation": "equals",
                "name": "filter.operator.equals"
              }
            },
            {
              "id": "d0c40ed1-909d-422d-9361-b79c2ed4345e",
              "leftValue": "={{ $json.message }}",
              "rightValue": "Collaboration Engine Function",
              "operator": {
                "type": "string",
                "operation": "equals",
                "name": "filter.operator.equals"
              }
            }
          ],
          "combinator": "or"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        -1856,
        1696
      ],
      "id": "e77f5183-04e7-4911-af9c-35e386858b66",
      "name": "spreate"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "aea37d81-e1af-4a5f-9a34-326fb65b2a22",
              "leftValue": "={{ $json.Keyword }}",
              "rightValue": "={{ $('Webhook').item.json.body.events[0].message.text }}",
              "operator": {
                "type": "string",
                "operation": "contains"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        -464,
        2048
      ],
      "id": "598e89d1-4dfb-4b5b-b4e5-ef244398ddbc",
      "name": "If1"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.line.me/v2/bot/message/reply",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer dfb5VjlLp060/Co+K/KvfL3JRM8qGYag5hbDOvqyfXuMMZ0auDMU3RQ0CC3XJCbt/5sXYsbfO51+5dIt6Xq3WD48lxkTxubVv5Yps4NMkL6SnVvuieSq86Qyo3ZugeYbz0OkGv25DxMUN/aheZpANwdB04t89/1O/w1cDnyilFU="
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"replyToken\": \"{{ $('Webhook').first().json.body.events[0].replyToken }}\",\n  \"messages\": [\n    {\n      \"type\": \"text\",\n      \"text\": \"{{ $json.text_message.replaceAll('\\t',' ').replaceAll('\\\"','\\\\\\\"').replaceAll('\\n','\\\\n').trim() }}\"\n    }\n  ]\n}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1408,
        432
      ],
      "id": "18a40727-ca85-4f5a-a104-68e3eb81fc64",
      "name": "request location2"
    },
    {
      "parameters": {
        "jsCode": "const stores = $input.all();\n\n// \u0e2a\u0e23\u0e49\u0e32\u0e07 \"Bubble\" (\u0e01\u0e32\u0e23\u0e4c\u0e14\u0e41\u0e15\u0e48\u0e25\u0e30\u0e43\u0e1a) \u0e2a\u0e33\u0e2b\u0e23\u0e31\u0e1a\u0e41\u0e15\u0e48\u0e25\u0e30\u0e23\u0e49\u0e32\u0e19\u0e04\u0e49\u0e32\nconst bubbles = stores.map(item => {\n  const store = item.json;\n  return {\n    \"type\": \"bubble\",\n    \"body\": {\n      \"type\": \"box\",\n      \"layout\": \"vertical\",\n      \"contents\": [\n        { \"type\": \"text\", \"text\": store.name, \"weight\": \"bold\", \"size\": \"xl\" },\n        {\n          \"type\": \"box\",\n          \"layout\": \"vertical\",\n          \"margin\": \"lg\",\n          \"spacing\": \"sm\",\n          \"contents\": [\n            {\n              \"type\": \"box\",\n              \"layout\": \"baseline\",\n              \"spacing\": \"sm\",\n              \"contents\": [\n                { \"type\": \"text\", \"text\": \"\u0e23\u0e30\u0e22\u0e30\u0e17\u0e32\u0e07\", \"color\": \"#aaaaaa\", \"size\": \"sm\", \"flex\": 2 },\n                { \"type\": \"text\", \"text\": `${store.distance} \u0e01\u0e21.`, \"wrap\": true, \"color\": \"#666666\", \"size\": \"sm\", \"flex\": 5 }\n              ]\n            }\n          ]\n        }\n      ]\n    },\n    \"footer\": {\n      \"type\": \"box\",\n      \"layout\": \"vertical\",\n      \"spacing\": \"sm\",\n      \"contents\": [\n        {\n          \"type\": \"button\",\n          \"style\": \"link\",\n          \"height\": \"sm\",\n          \"action\": {\n            \"type\": \"postback\",\n            \"label\": \"\u0e40\u0e25\u0e37\u0e2d\u0e01\u0e23\u0e49\u0e32\u0e19\u0e19\u0e35\u0e49\",\n            \"data\": `action=select_store&uid=${store.uid}`,\n            \"displayText\": `\u0e09\u0e31\u0e19\u0e40\u0e25\u0e37\u0e2d\u0e01\u0e23\u0e49\u0e32\u0e19 ${store.name}`\n          }\n        }\n      ]\n    }\n  };\n});\n\n// \u0e2a\u0e23\u0e49\u0e32\u0e07\u0e42\u0e04\u0e23\u0e07 Flex Message \u0e41\u0e1a\u0e1a Carousel \u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14\nconst flexMessage = {\n  \"type\": \"flex\",\n  \"altText\": \"\u0e19\u0e35\u0e48\u0e04\u0e37\u0e2d\u0e23\u0e32\u0e22\u0e0a\u0e37\u0e48\u0e2d\u0e23\u0e49\u0e32\u0e19\u0e04\u0e49\u0e32\u0e43\u0e01\u0e25\u0e49\u0e40\u0e04\u0e35\u0e22\u0e07\u0e04\u0e23\u0e31\u0e1a\",\n  \"contents\": {\n    \"type\": \"carousel\",\n    \"contents\": bubbles\n  }\n};\n\n// \u0e2a\u0e48\u0e07\u0e2d\u0e2d\u0e01\u0e1c\u0e25\u0e25\u0e31\u0e1e\u0e18\u0e4c\u0e40\u0e1b\u0e47\u0e19 Object \u0e17\u0e35\u0e48\u0e21\u0e35 key \u0e0a\u0e37\u0e48\u0e2d flex\nreturn { flex: flexMessage };"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        480,
        1056
      ],
      "id": "7366b768-227d-427d-973e-3b4c10fc3cfc",
      "name": "Code in JavaScript3"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.line.me/v2/bot/message/reply",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer dfb5VjlLp060/Co+K/KvfL3JRM8qGYag5hbDOvqyfXuMMZ0auDMU3RQ0CC3XJCbt/5sXYsbfO51+5dIt6Xq3WD48lxkTxubVv5Yps4NMkL6SnVvuieSq86Qyo3ZugeYbz0OkGv25DxMUN/aheZpANwdB04t89/1O/w1cDnyilFU="
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"replyToken\": \"{{ $('Webhook').first().json.body.events[0].replyToken }}\",\n  \"messages\": [\n    {{ $json.flex }}\n  ]\n}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        752,
        1056
      ],
      "id": "18317542-5a52-4574-a081-66034139e278",
      "name": "request location3"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "2a9424a3-e984-4311-8357-be12f9f79b1c",
              "leftValue": "={{ $('message').item.json.message }}",
              "rightValue": "={{ $json.keyword }}",
              "operator": {
                "type": "string",
                "operation": "contains"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.filter",
      "typeVersion": 2.2,
      "position": [
        -704,
        2000
      ],
      "id": "ce42caca-b25f-4d7f-ad41-08b482a31c23",
      "name": "Filter",
      "alwaysOutputData": true,
      "executeOnce": false
    },
    {
      "parameters": {
        "jsCode": "const stores = $input.all();\n\n// 1. \u0e2a\u0e23\u0e49\u0e32\u0e07\u0e2a\u0e48\u0e27\u0e19\u0e2b\u0e31\u0e27\u0e02\u0e2d\u0e07\u0e02\u0e49\u0e2d\u0e04\u0e27\u0e32\u0e21\nlet message = `\u0e1e\u0e1a\u0e23\u0e49\u0e32\u0e19\u0e04\u0e49\u0e32\u0e43\u0e01\u0e25\u0e49\u0e40\u0e04\u0e35\u0e22\u0e07 ${stores.length} \u0e41\u0e2b\u0e48\u0e07:\\n\\n`;\n\n// 2. \u0e27\u0e19\u0e25\u0e39\u0e1b\u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e2a\u0e23\u0e49\u0e32\u0e07\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23\u0e41\u0e15\u0e48\u0e25\u0e30\u0e23\u0e49\u0e32\u0e19\u0e04\u0e49\u0e32\nstores.forEach((item, index) => {\n  const store = item.json;\n  // \u0e40\u0e1e\u0e34\u0e48\u0e21\u0e40\u0e25\u0e02\u0e25\u0e33\u0e14\u0e31\u0e1a, \u0e0a\u0e37\u0e48\u0e2d\u0e23\u0e49\u0e32\u0e19, \u0e41\u0e25\u0e30\u0e23\u0e30\u0e22\u0e30\u0e17\u0e32\u0e07\n  message += `${index + 1}. ${store.store_name} (${store.distance} \u0e01\u0e21.)\\n`;\n});\n\n// 3. \u0e40\u0e1e\u0e34\u0e48\u0e21\u0e2a\u0e48\u0e27\u0e19\u0e17\u0e49\u0e32\u0e22\u0e02\u0e2d\u0e07\u0e02\u0e49\u0e2d\u0e04\u0e27\u0e32\u0e21\nmessage += \"\\n\u0e01\u0e23\u0e38\u0e13\u0e32\u0e1e\u0e34\u0e21\u0e1e\u0e4c\u0e0a\u0e37\u0e48\u0e2d\u0e23\u0e49\u0e32\u0e19\u0e04\u0e49\u0e32\u0e17\u0e35\u0e48\u0e17\u0e48\u0e32\u0e19\u0e15\u0e49\u0e2d\u0e07\u0e01\u0e32\u0e23\u0e40\u0e25\u0e37\u0e2d\u0e01\u0e23\u0e48\u0e27\u0e21\u0e42\u0e04\u0e23\u0e07\u0e01\u0e32\u0e23\u0e04\u0e23\u0e31\u0e1a\";\n\n// 4. \u0e2a\u0e48\u0e07\u0e2d\u0e2d\u0e01\u0e1c\u0e25\u0e25\u0e31\u0e1e\u0e18\u0e4c\nreturn { text_message: message };"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1200,
        432
      ],
      "id": "4efb2738-4f28-4062-b6ac-b2a66cf1d0df",
      "name": "collaboration"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.line.me/v2/bot/message/reply",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer dfb5VjlLp060/Co+K/KvfL3JRM8qGYag5hbDOvqyfXuMMZ0auDMU3RQ0CC3XJCbt/5sXYsbfO51+5dIt6Xq3WD48lxkTxubVv5Yps4NMkL6SnVvuieSq86Qyo3ZugeYbz0OkGv25DxMUN/aheZpANwdB04t89/1O/w1cDnyilFU="
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"replyToken\": \"{{ $('Webhook').first().json.body.events[0].replyToken }}\",\n  \"messages\": [\n    {\n      \"type\": \"text\",\n      \"text\": \"\u0e02\u0e2d\u0e2d\u0e20\u0e31\u0e22\u0e04\u0e23\u0e31\u0e1a \ud83d\ude25 \u0e02\u0e13\u0e30\u0e19\u0e35\u0e49\u0e22\u0e31\u0e07\u0e44\u0e21\u0e48\u0e21\u0e35\u0e23\u0e49\u0e32\u0e19\u0e04\u0e49\u0e32\u0e2d\u0e37\u0e48\u0e19\u0e43\u0e19\u0e1a\u0e23\u0e34\u0e40\u0e27\u0e13\u0e43\u0e01\u0e25\u0e49\u0e40\u0e04\u0e35\u0e22\u0e07\u0e40\u0e02\u0e49\u0e32\u0e23\u0e48\u0e27\u0e21\u0e42\u0e04\u0e23\u0e07\u0e01\u0e32\u0e23\u0e40\u0e25\u0e22\u0e04\u0e23\u0e31\u0e1a \u0e25\u0e2d\u0e07\u0e04\u0e49\u0e19\u0e2b\u0e32\u0e43\u0e2b\u0e21\u0e48\u0e2d\u0e35\u0e01\u0e04\u0e23\u0e31\u0e49\u0e07\u0e43\u0e19\u0e20\u0e32\u0e22\u0e2b\u0e25\u0e31\u0e07\u0e19\u0e30\u0e04\u0e23\u0e31\u0e1a\"\n    }\n  ]\n}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1264,
        704
      ],
      "id": "82fd2bef-7a85-4aba-a52e-78d962fcafe0",
      "name": "request location5"
    },
    {
      "parameters": {
        "jsCode": "// \ud83e\udded \u0e1f\u0e31\u0e07\u0e01\u0e4c\u0e0a\u0e31\u0e19\u0e04\u0e33\u0e19\u0e27\u0e13\u0e23\u0e30\u0e22\u0e30\u0e17\u0e32\u0e07\u0e23\u0e30\u0e2b\u0e27\u0e48\u0e32\u0e07\u0e2a\u0e2d\u0e07\u0e1e\u0e34\u0e01\u0e31\u0e14 (\u0e2b\u0e19\u0e48\u0e27\u0e22: \u0e01\u0e34\u0e42\u0e25\u0e40\u0e21\u0e15\u0e23)\nfunction getDistance(lat1, lon1, lat2, lon2) {\n  const R = 6371;\n  const dLat = (lat2 - lat1) * (Math.PI / 180);\n  const dLon = (lon2 - lon1) * (Math.PI / 180);\n  const a =\n    Math.sin(dLat / 2) ** 2 +\n    Math.cos(lat1 * Math.PI / 180) *\n    Math.cos(lat2 * Math.PI / 180) *\n    Math.sin(dLon / 2) ** 2;\n  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n  return R * c;\n}\n\n// \ud83d\udd39 1. \u0e14\u0e36\u0e07\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14\u0e08\u0e32\u0e01 input\nconst all = $input.all().map(i => i.json);\n\n// \ud83d\udd39 2. \u0e41\u0e22\u0e01\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e1c\u0e39\u0e49\u0e43\u0e0a\u0e49\u0e1b\u0e31\u0e08\u0e08\u0e38\u0e1a\u0e31\u0e19\u0e41\u0e25\u0e30\u0e23\u0e49\u0e32\u0e19\u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14\nconst current = all.find(i => i.current_user_id);\nconst stores = all.filter(i => i.user_id); // \u0e40\u0e09\u0e1e\u0e32\u0e30\u0e23\u0e49\u0e32\u0e19\n\nif (!current) {\n  return { message: { type: \"text\", text: \"\u274c \u0e44\u0e21\u0e48\u0e1e\u0e1a\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e1c\u0e39\u0e49\u0e43\u0e0a\u0e49\u0e1b\u0e31\u0e08\u0e08\u0e38\u0e1a\u0e31\u0e19\" } };\n}\n\n// \ud83d\udd39 3. \u0e14\u0e36\u0e07\u0e1e\u0e34\u0e01\u0e31\u0e14\u0e1c\u0e39\u0e49\u0e43\u0e0a\u0e49\u0e1b\u0e31\u0e08\u0e08\u0e38\u0e1a\u0e31\u0e19\nconst userLat = parseFloat(current.current_lat);\nconst userLon = parseFloat(current.current_lon);\nconst currentUserId = current.current_user_id;\n\n// \ud83d\udd39 4. \u0e04\u0e33\u0e19\u0e27\u0e13\u0e23\u0e30\u0e22\u0e30\u0e17\u0e32\u0e07\u0e02\u0e2d\u0e07\u0e41\u0e15\u0e48\u0e25\u0e30\u0e23\u0e49\u0e32\u0e19\nconst nearbyStores = stores\n  .map(store => {\n    const distance = getDistance(\n      userLat,\n      userLon,\n      parseFloat(store.lat),\n      parseFloat(store.lon)\n    );\n    return {\n      user_id: store.user_id,\n      store_name: store.store_name,\n      store_category: store.store_category,\n      distance: parseFloat(distance.toFixed(2))\n    };\n  })\n  // \ud83d\udd39 \u0e01\u0e23\u0e2d\u0e07\u0e40\u0e09\u0e1e\u0e32\u0e30\u0e23\u0e49\u0e32\u0e19\u0e17\u0e35\u0e48\u0e2d\u0e22\u0e39\u0e48\u0e43\u0e19\u0e23\u0e31\u0e28\u0e21\u0e35 5 \u0e01\u0e21. \u0e41\u0e25\u0e30\u0e44\u0e21\u0e48\u0e43\u0e0a\u0e48\u0e23\u0e49\u0e32\u0e19\u0e02\u0e2d\u0e07 user \u0e40\u0e2d\u0e07\n  .filter(s => s.distance <= 5 && s.user_id !== currentUserId)\n  // \ud83d\udd39 \u0e40\u0e23\u0e35\u0e22\u0e07\u0e08\u0e32\u0e01\u0e43\u0e01\u0e25\u0e49 \u2192 \u0e44\u0e01\u0e25\n  .sort((a, b) => a.distance - b.distance);\n\n// \ud83d\udd39 5. \u0e04\u0e37\u0e19\u0e04\u0e48\u0e32\u0e1c\u0e25\u0e25\u0e31\u0e1e\u0e18\u0e4c\nreturn nearbyStores;\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        688,
        576
      ],
      "id": "2613d7b9-ce1e-4f58-9c91-65d5e9e1b3c3",
      "name": "findShop",
      "alwaysOutputData": true
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "5fb428c7-6540-445c-aaa0-4f18e540da3f",
              "leftValue": "={{ $('findShop').item.json.isEmpty() }}",
              "rightValue": "",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        976,
        576
      ],
      "id": "49e288de-9b30-4615-b8ed-95f6e78b3b06",
      "name": "If empty"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "b4f15148-7ac6-4d91-a685-9aee41e250f1",
              "leftValue": "={{ parseFloat($json.lat.toString()) }}",
              "rightValue": 0,
              "operator": {
                "type": "number",
                "operation": "gt"
              }
            },
            {
              "id": "ef591cfe-55c7-400e-be24-45e459774211",
              "leftValue": "={{ parseFloat($json.lon.toString()) }}",
              "rightValue": 0,
              "operator": {
                "type": "number",
                "operation": "gt"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        -1328,
        1136
      ],
      "id": "7338f62c-4fbf-4688-a530-f41e2d4de360",
      "name": "location1",
      "alwaysOutputData": false
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.line.me/v2/bot/message/reply",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer dfb5VjlLp060/Co+K/KvfL3JRM8qGYag5hbDOvqyfXuMMZ0auDMU3RQ0CC3XJCbt/5sXYsbfO51+5dIt6Xq3WD48lxkTxubVv5Yps4NMkL6SnVvuieSq86Qyo3ZugeYbz0OkGv25DxMUN/aheZpANwdB04t89/1O/w1cDnyilFU="
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"replyToken\": \"{{ $('Webhook').item.json.body.events[0].replyToken }}\",\n  \"messages\": [\n    {\n      \"type\": \"text\",\n      \"text\": \"\u0e1b\u0e31\u0e01\u0e2b\u0e21\u0e38\u0e14\u0e23\u0e49\u0e32\u0e19 {{ $('Get row by uid1').item.json.name }} \u0e2a\u0e33\u0e40\u0e23\u0e47\u0e08\u0e41\u0e25\u0e49\u0e27\u0e04\u0e23\u0e31\u0e1a! \u0e25\u0e2d\u0e07\u0e43\u0e0a\u0e49\u0e1f\u0e35\u0e40\u0e08\u0e2d\u0e23\u0e4c '\u0e04\u0e49\u0e19\u0e2b\u0e32\u0e23\u0e49\u0e32\u0e19\u0e43\u0e01\u0e25\u0e49\u0e40\u0e04\u0e35\u0e22\u0e07' \u0e2b\u0e23\u0e37\u0e2d 'Group Purchase' \u0e44\u0e14\u0e49\u0e40\u0e25\u0e22\u0e19\u0e30\u0e04\u0e23\u0e31\u0e1a\"\n    }\n  ]\n}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -800,
        1088
      ],
      "id": "068a0e1b-70e0-4b75-93bc-f02aad5177d9",
      "name": "request location6"
    },
    {
      "parameters": {
        "operation": "upsert",
        "schema": {
          "__rl": true,
          "value": "sme",
          "mode": "list",
          "cachedResultName": "sme"
        },
        "table": {
          "__rl": true,
          "value": "users",
          "mode": "list",
          "cachedResultName": "users"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "lat": "={{ $('Webhook').item.json.body.events[0].message.latitude }}",
            "lon": "={{ $('Webhook').item.json.body.events[0].message.longitude }}",
            "user_id": "={{ $json.userId }}"
          },
          "matchingColumns": [
            "user_id"
          ],
          "schema": [
            {
              "id": "user_id",
              "displayName": "user_id",
              "required": true,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "store_name",
              "displayName": "store_name",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "store_category",
              "displayName": "store_category",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "lat",
              "displayName": "lat",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": false
            },
            {
              "id": "lon",
              "displayName": "lon",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": false
            },
            {
              "id": "created_at",
              "displayName": "created_at",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "dateTime",
              "canBeUsedToMatch": false
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.6,
      "position": [
        -1872,
        1472
      ],
      "id": "45a9a43d-799b-4496-b554-8c9228fcb0ca",
      "name": "store location",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "upsert",
        "schema": {
          "__rl": true,
          "value": "sme",
          "mode": "list",
          "cachedResultName": "sme"
        },
        "table": {
          "__rl": true,
          "value": "users",
          "mode": "list",
          "cachedResultName": "users"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "lat": 0,
            "lon": 0,
            "user_id": "={{ $('message').item.json.userId }}",
            "store_name": "={{ $json.store_name }}",
            "store_category": "={{ $json.store_type }}",
            "created_at": "={{ new Date().toDateTime() }}"
          },
          "matchingColumns": [
            "user_id"
          ],
          "schema": [
            {
              "id": "user_id",
              "displayName": "user_id",
              "required": true,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "store_name",
              "displayName": "store_name",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "store_category",
              "displayName": "store_category",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "lat",
              "displayName": "lat",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": false
            },
            {
              "id": "lon",
              "displayName": "lon",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": false
            },
            {
              "id": "created_at",
              "displayName": "created_at",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "dateTime",
              "canBeUsedToMatch": false
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.6,
      "position": [
        -1840,
        1280
      ],
      "id": "4dd99921-d1d2-4145-8a88-d9c299f02bba",
      "name": "store name type1",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "select",
        "schema": {
          "__rl": true,
          "value": "sme",
          "mode": "list",
          "cachedResultName": "sme"
        },
        "table": {
          "__rl": true,
          "value": "users",
          "mode": "list",
          "cachedResultName": "users"
        },
        "returnAll": true,
        "where": {
          "values": [
            {
              "column": "user_id",
              "value": "={{ $json.user_id }}"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.6,
      "position": [
        -1616,
        1280
      ],
      "id": "5736f803-e2f9-4f4f-99ed-65a266f482c2",
      "name": "Get row by uid2",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "select",
        "schema": {
          "__rl": true,
          "value": "sme",
          "mode": "list",
          "cachedResultName": "sme"
        },
        "table": {
          "__rl": true,
          "value": "users",
          "mode": "list",
          "cachedResultName": "users"
        },
        "returnAll": true,
        "where": {
          "values": [
            {
              "column": "user_id",
              "value": "={{ $('message').item.json.userId }}"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.6,
      "position": [
        -1456,
        144
      ],
      "id": "d7590e4e-7359-4d5d-bc55-fc0e6b7b0b86",
      "name": "Get row by uid3",
      "alwaysOutputData": true,
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.line.me/v2/bot/message/reply",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer dfb5VjlLp060/Co+K/KvfL3JRM8qGYag5hbDOvqyfXuMMZ0auDMU3RQ0CC3XJCbt/5sXYsbfO51+5dIt6Xq3WD48lxkTxubVv5Yps4NMkL6SnVvuieSq86Qyo3ZugeYbz0OkGv25DxMUN/aheZpANwdB04t89/1O/w1cDnyilFU="
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"replyToken\": \"{{ $('Webhook').first().json.body.events[0].replyToken }}\",\n  \"messages\": [\n    {\n      \"type\": \"text\",\n      \"text\": \"\u0e1b\u0e31\u0e01\u0e2b\u0e21\u0e38\u0e14\u0e23\u0e49\u0e32\u0e19\u0e04\u0e49\u0e32\u0e02\u0e2d\u0e07\u0e04\u0e38\u0e13\u0e2a\u0e33\u0e40\u0e23\u0e47\u0e08\u0e41\u0e25\u0e49\u0e27! \ud83d\udccd\\n\\n\u0e15\u0e2d\u0e19\u0e19\u0e35\u0e49\u0e04\u0e38\u0e13\u0e01\u0e23\u0e2d\u0e01\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e04\u0e23\u0e1a\u0e16\u0e49\u0e27\u0e19\u0e41\u0e25\u0e49\u0e27 \u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e40\u0e23\u0e34\u0e48\u0e21\u0e43\u0e0a\u0e49\u0e1f\u0e35\u0e40\u0e08\u0e2d\u0e23\u0e4c 'Collaboration' \u0e2b\u0e23\u0e37\u0e2d 'Group Purchase' \u0e08\u0e32\u0e01\u0e40\u0e21\u0e19\u0e39\u0e44\u0e14\u0e49\u0e40\u0e25\u0e22\u0e04\u0e23\u0e31\u0e1a!\"\n    }\n  ]\n}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -1616,
        1472
      ],
      "id": "7cccdaa9-5728-4ab3-94ad-5d847165ca54",
      "name": "store location complete"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.line.me/v2/bot/message/reply",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer dfb5VjlLp060/Co+K/KvfL3JRM8qGYag5hbDOvqyfXuMMZ0auDMU3RQ0CC3XJCbt/5sXYsbfO51+5dIt6Xq3WD48lxkTxubVv5Yps4NMkL6SnVvuieSq86Qyo3ZugeYbz0OkGv25DxMUN/aheZpANwdB04t89/1O/w1cDnyilFU="
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"replyToken\": \"{{ $('Webhook').first().json.body.events[0].replyToken }}\",\n  \"messages\": [\n    {\n      \"type\": \"text\",\n      \"text\": \"{{ $json.replyMessage }}\"\n    }\n  ]\n}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -608,
        1328
      ],
      "id": "7c906650-ed74-4f41-9e89-97c0985a78a3",
      "name": "hello"
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "leftValue": "={{ $('message').item.json.message }}",
                    "rightValue": "Group Purchase Function",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "id": "ef822b7f-2dd0-4d9a-bf12-af03c598d552"
                  }
                ],
                "combinator": "and"
              }
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "88a2434c-c98c-4350-9380-88df7c535045",
                    "leftValue": "={{ $('message').item.json.message }}",
                    "rightValue": "Collaboration Engine Function",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              }
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.3,
      "position": [
        -256,
        112
      ],
      "id": "2e329135-e683-4cb3-902f-06b90b8c2332",
      "name": "select function"
    },
    {
      "parameters": {
        "operation": "select",
        "schema": {
          "__rl": true,
          "value": "sme",
          "mode": "list",
          "cachedResultName": "sme"
        },
        "table": {
          "__rl": true,
          "value": "product_categories",
          "mode": "list",
          "cachedResultName": "product_categories"
        },
        "returnAll": true,
        "options": {}
      },
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.6,
      "position": [
        0,
        96
      ],
      "id": "92814c3c-7ea4-4560-9f1f-0f700b0c93d1",
      "name": "Select rows from a table",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.message }}",
                    "rightValue": "#\u0e25\u0e07\u0e17\u0e30\u0e40\u0e1a\u0e35\u0e22\u0e19",
                    "operator": {
                      "type": "string",
                      "operation": "startsWith"
                    },
                    "id": "c7699805-8af1-4a38-bb88-84efbba588ca"
                  }
                ],
                "combinator": "and"
              }
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "5b9a8970-fcbf-42f6-ae1b-33c7139c8112",
                    "leftValue": "={{ $('Webhook').item.json.body.events[0].message.type }}",
                    "rightValue": "location",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              }
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "6ad128b9-8ed2-44c9-9676-5f994b9c4897",
                    "leftValue": "={{ $json.body.events[0].postback.data.split('&')[0].split('=')[1] }}",
                    "rightValue": "list_deals",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              }
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "df1d02dc-0e76-419b-be33-51cafec549a9",
                    "leftValue": "={{ $json.body.events[0].postback.data.split('&')[0].split('=')[1] }}",
                    "rightValue": "view_deal",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              }
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "e5cc3b0b-cbda-4f62-ae59-b7c374fe6552",
                    "leftValue": "={{ $json.message }}",
                    "rightValue": "#\u0e08\u0e2d\u0e07",
                    "operator": {
                      "type": "string",
                      "operation": "startsWith"
                    }
                  }
                ],
                "combinator": "and"
              }
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "c63a5828-f973-43bb-8033-ed5627722e58",
                    "leftValue": "={{ $json.message }}",
                    "rightValue": "#\u0e25\u0e07\u0e17\u0e30\u0e40\u0e1a\u0e35\u0e22\u0e19",
                    "operator": {
                      "type": "string",
                      "operation": "notStartsWith"
                    }
                  }
                ],
                "combinator": "and"
              }
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.3,
      "position": [
        -2336,
        1680
      ],
      "id": "0fff705e-edce-4e31-9c40-9441c5b5c50b",
      "name": "start with check"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "de265c94-1600-4f65-95d5-b1bdd1988e86",
              "name": "body.events[0].postback.data",
              "value": "={{ $json.body.events[0].postback.data.split('&')[1].split('=')[1] }}",
              "type": "string"
            },
            {
              "id": "adbabda3-b1f9-40ca-bd13-cc68de08acd1",
              "name": "userId",
              "value": "={{ $json.userId }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -2224,
        2368
      ],
      "id": "68aa560b-dc2e-4e97-a0ae-7c1652475996",
      "name": "select ingredient"
    },
    {
      "parameters": {
        "jsCode": "// 1. \u0e23\u0e31\u0e1a\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e2b\u0e21\u0e27\u0e14\u0e2b\u0e21\u0e39\u0e48\u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14\u0e08\u0e32\u0e01 Node \u0e01\u0e48\u0e2d\u0e19\u0e2b\u0e19\u0e49\u0e32\nconst categories = $input.all();\n\n// 2. \u0e2a\u0e23\u0e49\u0e32\u0e07 \"Bubble\" (\u0e01\u0e32\u0e23\u0e4c\u0e14) \u0e2a\u0e33\u0e2b\u0e23\u0e31\u0e1a\u0e41\u0e15\u0e48\u0e25\u0e30\u0e2b\u0e21\u0e27\u0e14\u0e2b\u0e21\u0e39\u0e48\nconst bubbles = categories.map(item => {\n  const category = item.json;\n  \n  return {\n    \"type\": \"bubble\",\n    \"size\": \"micro\", // \u2b05\ufe0f \u0e02\u0e19\u0e32\u0e14\u0e40\u0e25\u0e47\u0e01\u0e15\u0e32\u0e21\u0e17\u0e35\u0e48\u0e04\u0e38\u0e13\u0e40\u0e25\u0e37\u0e2d\u0e01\n    \"hero\": {\n      \"type\": \"image\",\n      \"url\": category.image_url || \"https://example.com/images/default.jpg\", // \u2b05\ufe0f \u0e14\u0e36\u0e07 URL \u0e08\u0e32\u0e01 DB\n      \"size\": \"full\",\n      \"aspectMode\": \"cover\",\n      \"aspectRatio\": \"320:213\"\n    },\n    \"body\": {\n      \"type\": \"box\",\n      \"layout\": \"vertical\",\n      \"contents\": [\n        {\n          \"type\": \"text\",\n          \"text\": category.category_name, // \u2b05\ufe0f \u0e14\u0e36\u0e07\u0e0a\u0e37\u0e48\u0e2d\u0e2b\u0e21\u0e27\u0e14\u0e2b\u0e21\u0e39\u0e48\u0e08\u0e32\u0e01 DB\n          \"weight\": \"bold\",\n          \"size\": \"sm\",\n          \"wrap\": true\n        }\n      ],\n      \"spacing\": \"sm\",\n      \"paddingAll\": \"13px\"\n    },\n    \"footer\": { // \u2b07\ufe0f\u2b07\ufe0f \u0e19\u0e35\u0e48\u0e04\u0e37\u0e2d\u0e2a\u0e48\u0e27\u0e19 \"\u0e1b\u0e38\u0e48\u0e21\" \u0e17\u0e35\u0e48\u0e40\u0e23\u0e32\u0e40\u0e1e\u0e34\u0e48\u0e21\u0e40\u0e02\u0e49\u0e32\u0e44\u0e1b \u2b07\ufe0f\u2b07\ufe0f\n      \"type\": \"box\",\n      \"layout\": \"vertical\",\n      \"spacing\": \"sm\",\n      \"contents\": [\n        {\n          \"type\": \"button\",\n          \"style\": \"link\",\n          \"height\": \"sm\",\n          \"action\": {\n            \"type\": \"postback\",\n            \"label\": \"\u0e40\u0e25\u0e37\u0e2d\u0e01\u0e2b\u0e21\u0e27\u0e14\u0e19\u0e35\u0e49\",\n            \"data\": `action=list_deals&category=${category.category_name}`, // \u2b05\ufe0f \u0e2a\u0e48\u0e07 Postback \u0e01\u0e25\u0e31\u0e1a\u0e44\u0e1b\n            \"displayText\": `\u0e02\u0e2d\u0e14\u0e39\u0e14\u0e35\u0e25: ${category.category_name}`\n          }\n        }\n      ]\n    }\n  };\n});\n\n// 3. \u0e1b\u0e23\u0e30\u0e01\u0e2d\u0e1a\u0e23\u0e48\u0e32\u0e07\u0e40\u0e1b\u0e47\u0e19 Carousel \u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14\nconst flexMessage = {\n  \"type\": \"flex\",\n  \"altText\": \"\u0e01\u0e23\u0e38\u0e13\u0e32\u0e40\u0e25\u0e37\u0e2d\u0e01\u0e1b\u0e23\u0e30\u0e40\u0e20\u0e17\u0e27\u0e31\u0e15\u0e16\u0e38\u0e14\u0e34\u0e1a\u0e17\u0e35\u0e48\u0e2a\u0e19\u0e43\u0e08\",\n  \"contents\": {\n    \"type\": \"carousel\",\n    \"contents\": bubbles // \u2b05\ufe0f \u0e19\u0e33\u0e01\u0e32\u0e23\u0e4c\u0e14\u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14\u0e21\u0e32\u0e43\u0e2a\u0e48\n  }\n};\n\n// 4. \u0e2a\u0e48\u0e07\u0e2d\u0e2d\u0e01 JSON \u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e43\u0e2b\u0e49 HTTP Request Node \u0e19\u0e33\u0e44\u0e1b\u0e43\u0e0a\u0e49\nreturn { message: flexMessage };"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        208,
        96
      ],
      "id": "196f1e81-6786-402e-b4c0-46b588f73281",
      "name": "build carousel ingredient"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.line.me/v2/bot/message/reply",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer dfb5VjlLp060/Co+K/KvfL3JRM8qGYag5hbDOvqyfXuMMZ0auDMU3RQ0CC3XJCbt/5sXYsbfO51+5dIt6Xq3WD48lxkTxubVv5Yps4NMkL6SnVvuieSq86Qyo3ZugeYbz0OkGv25DxMUN/aheZpANwdB04t89/1O/w1cDnyilFU="
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"replyToken\": \"{{ $('Webhook').first().json.body.events[0].replyToken }}\",\n  \"messages\": [ {{ JSON.stringify($json.message) }} ]\n}\n",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        448,
        96
      ],
      "id": "37d73c68-bd79-4210-b215-703d0fde1e77",
      "name": "send ingredient type"
    },
    {
      "parameters": {
        "jsCode": "// \ud83e\udded \u0e1f\u0e31\u0e07\u0e01\u0e4c\u0e0a\u0e31\u0e19\u0e04\u0e33\u0e19\u0e27\u0e13\u0e23\u0e30\u0e22\u0e30\u0e17\u0e32\u0e07 (Haversine formula)\nfunction getDistanceKm(lat1, lon1, lat2, lon2) {\n  const R = 6371; // \u0e23\u0e31\u0e28\u0e21\u0e35\u0e02\u0e2d\u0e07\u0e42\u0e25\u0e01 (\u0e01\u0e21.)\n  const dLat = (lat2 - lat1) * Math.PI / 180;\n  const dLon = (lon2 - lon1) * Math.PI / 180;\n  const a =\n    Math.sin(dLat / 2) ** 2 +\n    Math.cos(lat1 * Math.PI / 180) *\n    Math.cos(lat2 * Math.PI / 180) *\n    Math.sin(dLon / 2) ** 2;\n  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n  return R * c; // \u0e01\u0e21.\n}\n\n// \u0e14\u0e36\u0e07\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14\u0e08\u0e32\u0e01 input\nconst all = $input.all().map(i => i.json);\n\n// \ud83d\udd39 \u0e41\u0e22\u0e01\u0e1b\u0e23\u0e30\u0e40\u0e20\u0e17\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\nconst deals = all.filter(i => i.deal_id);\nconst suppliers = all.filter(i => i.supplier_id);\nconst store = all.find(i => i.user_id); // \u0e23\u0e49\u0e32\u0e19\u0e02\u0e2d\u0e07\u0e1c\u0e39\u0e49\u0e43\u0e0a\u0e49\n\nif (!store) {\n  return { message: { type: \"text\", text: \"\u274c \u0e44\u0e21\u0e48\u0e1e\u0e1a\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e23\u0e49\u0e32\u0e19\u0e02\u0e2d\u0e07\u0e04\u0e38\u0e13\" } };\n}\n\nif (deals.length === 0) {\n  return { message: { type: \"text\", text: \"\u0e02\u0e2d\u0e2d\u0e20\u0e31\u0e22\u0e04\u0e23\u0e31\u0e1a \u0e15\u0e2d\u0e19\u0e19\u0e35\u0e49\u0e22\u0e31\u0e07\u0e44\u0e21\u0e48\u0e21\u0e35\u0e14\u0e35\u0e25\u0e2a\u0e33\u0e2b\u0e23\u0e31\u0e1a\u0e1b\u0e23\u0e30\u0e40\u0e20\u0e17\u0e19\u0e35\u0e49\u0e40\u0e25\u0e22\" } };\n}\n\nconst shopLat = parseFloat(store.lat);\nconst shopLon = parseFloat(store.lon);\n\n// \ud83d\udd39 \u0e2a\u0e23\u0e49\u0e32\u0e07 flex bubble \u0e2a\u0e33\u0e2b\u0e23\u0e31\u0e1a\u0e41\u0e15\u0e48\u0e25\u0e30 deal\nconst bubbles = deals.map(deal => {\n  const supplier = suppliers.find(s => s.supplier_id === deal.supplier_id);\n  const supplierName = supplier ? supplier.supplier_name : \"\u0e44\u0e21\u0e48\u0e23\u0e30\u0e1a\u0e38\";\n\n  let distanceText = \"\";\n  if (supplier?.lat && supplier?.lon) {\n    const distance = getDistanceKm(\n      shopLat,\n      shopLon,\n      parseFloat(supplier.lat),\n      parseFloat(supplier.lon)\n    );\n    distanceText = `(\u0e2b\u0e48\u0e32\u0e07 ${distance.toFixed(1)} \u0e01\u0e21.)`;\n  }\n\n  return {\n    type: \"bubble\",\n    hero: {\n      type: \"image\",\n      url: deal.image_url || \"https://images.pexels.com/photos/7563678/pexels-photo-7563678.jpeg\",\n      size: \"full\",\n      aspectMode: \"cover\"\n    },\n    body: {\n      type: \"box\",\n      layout: \"vertical\",\n      contents: [\n        {\n          type: \"text\",\n          text: deal.product_name || \"\u0e44\u0e21\u0e48\u0e23\u0e30\u0e1a\u0e38\u0e0a\u0e37\u0e48\u0e2d\u0e2a\u0e34\u0e19\u0e04\u0e49\u0e32\",\n          weight: \"bold\",\n          size: \"xl\",\n          wrap: true\n        },\n        {\n          type: \"text\",\n          text: `\u0e23\u0e32\u0e04\u0e32: ${deal.price_per_unit} \u0e1a\u0e32\u0e17 / ${deal.unit}`,\n          size: \"md\",\n          margin: \"md\",\n          wrap: true\n        },\n        {\n          type: \"text\",\n          text: `\u0e08\u0e32\u0e01: ${supplierName} ${distanceText}`,\n          size: \"sm\",\n          color: \"#999999\",\n          wrap: true\n        }\n      ]\n    },\n    footer: {\n      type: \"box\",\n      layout: \"vertical\",\n      contents: [\n        {\n          type: \"button\",\n          style: \"primary\",\n          action: {\n            type: \"postback\",\n            label: \"\u0e14\u0e39\u0e23\u0e32\u0e22\u0e25\u0e30\u0e40\u0e2d\u0e35\u0e22\u0e14 / \u0e2a\u0e31\u0e48\u0e07\u0e0b\u0e37\u0e49\u0e2d\",\n            data: `action=view_deal&deal_id=${deal.deal_id}`\n          }\n        }\n      ]\n    }\n  };\n});\n\nreturn {\n  message: {\n    type: \"flex\",\n    altText: \"\u0e19\u0e35\u0e48\u0e04\u0e37\u0e2d\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23\u0e27\u0e31\u0e15\u0e16\u0e38\u0e14\u0e34\u0e1a\u0e17\u0e35\u0e48\u0e17\u0e48\u0e32\u0e19\u0e40\u0e25\u0e37\u0e2d\u0e01\",\n    contents: {\n      type: \"carousel\",\n      contents: bubbles\n    }\n  }\n};\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -928,
        2624
      ],
      "id": "cb44656b-9007-4ac3-b91c-bd1f8e73e0ab",
      "name": "build carousel supplier"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.line.me/v2/bot/message/reply",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer dfb5VjlLp060/Co+K/KvfL3JRM8qGYag5hbDOvqyfXuMMZ0auDMU3RQ0CC3XJCbt/5sXYsbfO51+5dIt6Xq3WD48lxkTxubVv5Yps4NMkL6SnVvuieSq86Qyo3ZugeYbz0OkGv25DxMUN/aheZpANwdB04t89/1O/w1cDnyilFU="
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"replyToken\": \"{{ $('Webhook').first().json.body.events[0].replyToken }}\",\n  \"messages\": [ {{ JSON.stringify($json.message) }} ]\n}\n",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -672,
        2624
      ],
      "id": "c5879371-be66-4400-8cc9-19996cd64dcd",
      "name": "send supplier deal"
    },
    {
      "parameters": {
        "operation": "select",
        "schema": {
          "__rl": true,
          "value": "sme",
          "mode": "list",
          "cachedResultName": "sme"
        },
        "table": {
          "__rl": true,
          "value": "product_categories",
          "mode": "list",
          "cachedResultName": "product_categories"
        },
        "returnAll": true,
        "where": {
          "values": [
            {
              "column": "category_name",
              "value": "={{ $json.body.events[0].postback.data }}"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.6,
      "position": [
        -1968,
        2368
      ],
      "id": "80e4525e-fa0b-4fe7-9837-a3221b6b2506",
      "name": "select id from category",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "select",
        "schema": {
          "__rl": true,
          "value": "sme",
          "mode": "list",
          "cachedResultName": "sme"
        },
        "table": {
          "__rl": true,
          "value": "deals",
          "mode": "list",
          "cachedResultName": "deals"
        },
        "returnAll": true,
        "where": {
          "values": [
            {
              "column": "category_id",
              "value": "={{ $json.category_id }}"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.6,
      "position": [
        -1760,
        2368
      ],
      "id": "ebd17f64-50af-47d6-9cac-a23086ab9bfd",
      "name": "list deal from category",
      "alwaysOutputData": true,
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "select",
        "schema": {
          "__rl": true,
          "value": "sme",
          "mode": "list",
          "cachedResultName": "sme"
        },
        "table": {
          "__rl": true,
          "value": "suppliers",
          "mode": "list",
          "cachedResultName": "suppliers"
        },
        "returnAll": true,
        "where": {
          "values": [
            {
              "column": "supplier_id",
              "value": "={{ $json.supplier_id }}"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.6,
      "position": [
        -1328,
        2384
      ],
      "id": "af91402e-e35d-407c-814f-4ea3c4f2bb0c",
      "name": "list supplier",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "7e78e7f0-1294-42d8-9c63-43f2177c8813",
              "leftValue": "={{ $node['list deal from category'].json.isEmpty() }}",
              "rightValue": "",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        -1536,
        2288
      ],
      "id": "47e7316b-4cf9-49ae-ab12-ef737f36d4bf",
      "name": "If null"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.line.me/v2/bot/message/reply",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer dfb5VjlLp060/Co+K/KvfL3JRM8qGYag5hbDOvqyfXuMMZ0auDMU3RQ0CC3XJCbt/5sXYsbfO51+5dIt6Xq3WD48lxkTxubVv5Yps4NMkL6SnVvuieSq86Qyo3ZugeYbz0OkGv25DxMUN/aheZpANwdB04t89/1O/w1cDnyilFU="
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"replyToken\": \"{{ $('Webhook').first().json.body.events[0].replyToken }}\",\n  \"messages\": [\n    {\n      \"type\": \"text\",\n      \"text\": \"\u0e02\u0e2d\u0e2d\u0e20\u0e31\u0e22\u0e04\u0e23\u0e31\u0e1a \u0e15\u0e2d\u0e19\u0e19\u0e35\u0e49\u0e22\u0e31\u0e07\u0e44\u0e21\u0e48\u0e21\u0e35\u0e14\u0e35\u0e25\u0e2a\u0e33\u0e2b\u0e23\u0e31\u0e1a\u0e1b\u0e23\u0e30\u0e40\u0e20\u0e17\u0e19\u0e35\u0e49\u0e40\u0e25\u0e22 \ud83d\ude22\"\n    }\n  ]\n}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -1312,
        2208
      ],
      "id": "ac9fe1ef-e1e3-4295-8ba1-3eaf3aea57bd",
      "name": "no have deal"
    },
    {
      "parameters": {
        "numberInputs": 4
      },
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.2,
      "position": [
        -1152,
        2624
      ],
      "id": "5142b6cd-fc2c-41f1-bec2-fa51d01d6592",
      "name": "Merge1"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "e9a8ba92-dfa3-4d58-9c66-2711ad99d6f9",
              "name": "deal_id",
              "value": "={{ $json.body.events[0].postback.data.split('&')[1].split('=')[1] }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -2176,
        2976
      ],
      "id": "8ad72e72-13f8-4182-8a07-a1987257338c",
      "name": "Edit Fields"
    },
    {
      "parameters": {
        "operation": "select",
        "schema": {
          "__rl": true,
          "value": "sme",
          "mode": "list",
          "cachedResultName": "sme"
        },
        "table": {
          "__rl": true,
          "value": "deals",
          "mode": "list",
          "cachedResultName": "deals"
        },
        "where": {
          "values": [
            {
              "column": "deal_id",
              "value": "={{ $json.deal_id }}"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.6,
      "position": [
        -1936,
        2976
      ],
      "id": "8be7667d-6d7c-4b5e-a7c5-7fde9a688f42",
      "name": "get deal detail",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const deal = $input.first().json;\nconst current = parseFloat(deal.current_quantity_pledged);\nconst minimum = parseFloat(deal.minimum_quantity);\nconst percentage = minimum > 0 ? (current / minimum) * 100 : 0;\n\nconst flexMessage = {\n  type: \"flex\",\n  altText: `\u0e23\u0e32\u0e22\u0e25\u0e30\u0e40\u0e2d\u0e35\u0e22\u0e14\u0e14\u0e35\u0e25: ${deal.product_name}`,\n  contents: {\n    type: \"bubble\",\n    hero: {\n      type: \"image\",\n      url: deal.image_url || \"https://images.pexels.com/photos/7563678/pexels-photo-7563678.jpeg\",\n      size: \"full\",\n      aspectRatio: \"20:13\",\n      aspectMode: \"cover\"\n    },\n    body: {\n      type: \"box\",\n      layout: \"vertical\",\n      contents: [\n        {\n          type: \"text\",\n          text: deal.product_name || \"\u0e44\u0e21\u0e48\u0e23\u0e30\u0e1a\u0e38\u0e0a\u0e37\u0e48\u0e2d\u0e2a\u0e34\u0e19\u0e04\u0e49\u0e32\",\n          weight: \"bold\",\n          size: \"xl\",\n          wrap: true\n        },\n        {\n          type: \"text\",\n          text: deal.product_description || \"\u0e44\u0e21\u0e48\u0e21\u0e35\u0e04\u0e33\u0e2d\u0e18\u0e34\u0e1a\u0e32\u0e22\u0e2a\u0e34\u0e19\u0e04\u0e49\u0e32\",\n          size: \"sm\",\n          color: \"#555555\",\n          wrap: true,\n          margin: \"md\"\n        },\n        {\n          type: \"separator\",\n          margin: \"lg\"\n        },\n        {\n          type: \"text\",\n          text: `\ud83d\udcb0 \u0e23\u0e32\u0e04\u0e32: ${deal.price_per_unit} \u0e1a\u0e32\u0e17 / ${deal.unit}`,\n          size: \"md\",\n          color: \"#333333\",\n          margin: \"md\"\n        },\n        {\n          type: \"text\",\n          text: `\ud83d\udce6 \u0e08\u0e2d\u0e07\u0e41\u0e25\u0e49\u0e27: ${deal.current_quantity_pledged} / ${deal.minimum_quantity}`,\n          size: \"sm\",\n          color: \"#555555\",\n          margin: \"sm\"\n        },\n        {\n          type: \"text\",\n          text: `\u0e04\u0e27\u0e32\u0e21\u0e04\u0e37\u0e1a\u0e2b\u0e19\u0e49\u0e32: ${percentage.toFixed(0)}%`,\n          size: \"sm\",\n          color: \"#666666\",\n          margin: \"sm\"\n        },\n        {\n          type: \"text\",\n          text: `\u0e04\u0e38\u0e13\u0e15\u0e49\u0e2d\u0e07\u0e01\u0e32\u0e23\u0e2a\u0e31\u0e48\u0e07\u0e08\u0e2d\u0e07\u0e01\u0e35\u0e48 \u0e01\u0e01. \u0e04\u0e23\u0e31\u0e1a?\\n\\n\u0e01\u0e23\u0e38\u0e13\u0e32\u0e1e\u0e34\u0e21\u0e1e\u0e4c\u0e15\u0e2d\u0e1a\u0e01\u0e25\u0e31\u0e1a\u0e43\u0e19\u0e23\u0e39\u0e1b\u0e41\u0e1a\u0e1a\u0e19\u0e35\u0e49:\\n#\u0e08\u0e2d\u0e07 ${deal.deal_id} [\u0e08\u0e33\u0e19\u0e27\u0e19]\\n\\n\u0e15\u0e31\u0e27\u0e2d\u0e22\u0e48\u0e32\u0e07: #\u0e08\u0e2d\u0e07 ${deal.deal_id} 50`,\n          size: \"sm\",\n          color: \"#111111\",\n          wrap: true,\n          margin: \"md\"\n        }\n      ]\n    }\n  }\n};\n\nreturn { message: flexMessage };\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -1632,
        2976
      ],
      "id": "a19c2e8e-3d99-4e0e-8373-80a0e9ae8c22",
      "name": "calculate percent"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.line.me/v2/bot/message/reply",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer dfb5VjlLp060/Co+K/KvfL3JRM8qGYag5hbDOvqyfXuMMZ0auDMU3RQ0CC3XJCbt/5sXYsbfO51+5dIt6Xq3WD48lxkTxubVv5Yps4NMkL6SnVvuieSq86Qyo3ZugeYbz0OkGv25DxMUN/aheZpANwdB04t89/1O/w1cDnyilFU="
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"replyToken\": \"{{ $('Webhook').first().json.body.events[0].replyToken }}\",\n  \"messages\": [ {{ JSON.stringify($json.message) }} ]\n}\n",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -1296,
        2976
      ],
      "id": "cc8fc846-74ac-47df-a5ae-80c22900d964",
      "name": "send deal detail"
    },
    {
      "parameters": {
        "jsCode": "// 1. \u0e23\u0e31\u0e1a\u0e02\u0e49\u0e2d\u0e04\u0e27\u0e32\u0e21\u0e40\u0e15\u0e47\u0e21\nconst fullMessage = $input.first().json.message;\n\n// 2. \u0e15\u0e31\u0e14\u0e04\u0e33\u0e27\u0e48\u0e32 \"#\u0e08\u0e2d\u0e07\" \u0e41\u0e25\u0e30\u0e0a\u0e48\u0e2d\u0e07\u0e27\u0e48\u0e32\u0e07\u0e2d\u0e2d\u0e01\nconst dataString = fullMessage.replace('#\u0e08\u0e2d\u0e07', '').trim();\n\n// 3. \u0e41\u0e22\u0e01\u0e2a\u0e48\u0e27\u0e19 [deal_id] \u0e41\u0e25\u0e30 [\u0e08\u0e33\u0e19\u0e27\u0e19] \u0e14\u0e49\u0e27\u0e22\u0e0a\u0e48\u0e2d\u0e07\u0e27\u0e48\u0e32\u0e07\nconst parts = dataString.split(' ');\n\n// 4. \u0e15\u0e23\u0e27\u0e08\u0e2a\u0e2d\u0e1a\u0e27\u0e48\u0e32\u0e21\u0e35 2 \u0e2a\u0e48\u0e27\u0e19\u0e41\u0e25\u0e30\u0e40\u0e1b\u0e47\u0e19\u0e15\u0e31\u0e27\u0e40\u0e25\u0e02\nif (parts.length !== 2 || isNaN(parts[0]) || isNaN(parts[1])) {\n  // \u0e16\u0e49\u0e32\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e1c\u0e34\u0e14 \u0e43\u0e2b\u0e49\u0e2a\u0e48\u0e07 null \u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e2b\u0e22\u0e38\u0e14 Workflow \u0e19\u0e35\u0e49\n  return null;\n}\n\n// 5. \u0e14\u0e36\u0e07 user_id \u0e08\u0e32\u0e01 Node 'message'\nconst userId = $('message').first().json.userId;\n\n// 6. \u0e2a\u0e23\u0e49\u0e32\u0e07 object \u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\nconst item = {\n  user_id: userId,\n  deal_id: parseInt(parts[0], 10),\n  quantity_pledged: parseInt(parts[1], 10)\n};\n\nreturn item;"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -2240,
        3408
      ],
      "id": "b6235cc2-4fe9-4461-9cb4-2d409d83e5c1",
      "name": "Parse Pledge Message"
    },
    {
      "parameters": {
        "operation": "update",
        "schema": {
          "__rl": true,
          "value": "sme",
          "mode": "list",
          "cachedResultName": "sme"
        },
        "table": {
          "__rl": true,
          "value": "deals",
          "mode": "list",
          "cachedResultName": "deals"
        },
        "columns": {
          "mappingMode": "autoMapInputData",
          "value": {
            "deal_id": "={{ $json.deal_id }}",
            "supplier_id": "=",
            "category_id": "=",
            "current_quantity_pledged": "=",
            "minimum_quantity": 0
          },
          "matchingColumns": [
            "deal_id"
          ],
          "schema": [
            {
              "id": "deal_id",
              "displayName": "deal_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "supplier_id",
              "displayName": "supplier_id",
              "required": true,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": true
            },
            {
              "id": "category_id",
              "displayName": "category_id",
              "required": true,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": true
            },
            {
              "id": "product_name",
              "displayName": "product_name",
              "required": true,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "product_description",
              "displayName": "product_description",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "price_per_unit",
              "displayName": "price_per_unit",
              "required": true,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": true,
              "removed": true
            },
            {
              "id": "unit",
              "displayName": "unit",
              "required": true,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "minimum_quantity",
              "displayName": "minimum_quantity",
              "required": true,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": true
            },
            {
              "id": "current_quantity_pledged",
              "displayName": "current_quantity_pledged",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": true
            },
            {
              "id": "deal_status",
              "displayName": "deal_status",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "end_date",
              "displayName": "end_date",
              "required": true,
              "defaultMatch": false,
              "display": true,
              "type": "dateTime",
              "canBeUsedToMatch": true
            },
            {
              "id": "created_at",
              "displayName": "created_at",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "dateTime",
              "canBeUsedToMatch": true
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.6,
      "position": [
        -1184,
        3520
      ],
      "id": "2dce4214-d4f3-4edd-950b-ff87c8a9c421",
      "name": "Update rows in a table",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "select",
        "schema": {
          "__rl": true,
          "value": "sme",
          "mode": "list",
          "cachedResultName": "sme"
        },
        "table": {
          "__rl": true,
          "value": "deals",
          "mode": "list",
          "cachedResultName": "deals"
        },
        "where": {
          "values": [
            {
              "column": "deal_id",
              "value": "={{ $json.deal_id }}"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.6,
      "position": [
        -1968,
        3408
      ],
      "id": "7f749ade-7da6-4822-8eba-5011b0c4b6de",
      "name": "get deal detail1",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {},
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.2,
      "position": [
        -1696,
        3520
      ],
      "id": "826de8e8-d9fa-4966-bbc1-019e45903eb7",
      "name": "update current quantity"
    },
    {
      "parameters": {
        "jsCode": "// \u0e14\u0e36\u0e07\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14\u0e40\u0e02\u0e49\u0e32\u0e21\u0e32\nconst items = $input.all();\n\n// \u0e41\u0e22\u0e01 deal \u0e01\u0e31\u0e1a pledge \u0e2d\u0e2d\u0e01\u0e21\u0e32\nconst deal = items.find(i => i.json.deal_id && i.json.product_name).json;\nconst pledge = items.find(i => i.json.pledge_id).json;\n\n// \u0e04\u0e33\u0e19\u0e27\u0e13\u0e22\u0e2d\u0e14\u0e43\u0e2b\u0e21\u0e48\nconst newQuantity = (deal.current_quantity_pledged || 0) + (pledge.quantity_pledged || 0);\n\n// \u0e2a\u0e23\u0e49\u0e32\u0e07 object \u0e2a\u0e33\u0e2b\u0e23\u0e31\u0e1a\u0e2d\u0e31\u0e1b\u0e40\u0e14\u0e15\u0e01\u0e25\u0e31\u0e1a\u0e44\u0e1b\u0e22\u0e31\u0e07\u0e10\u0e32\u0e19\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\nreturn [\n  {\n    json: {\n      deal_id: deal.deal_id,\n      current_quantity_pledged: newQuantity\n    }\n  }\n];\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -1488,
        3520
      ],
      "id": "9eaa6635-034c-4f84-ae0c-e7b3fecd2e60",
      "name": "Code in JavaScript"
    },
    {
      "parameters": {
        "jsCode": "// 1. \u0e23\u0e31\u0e1a\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e14\u0e35\u0e25\u0e08\u0e32\u0e01 Node \u0e17\u0e35\u0e48\u0e41\u0e25\u0e49\u0e27\n// (\u0e43\u0e0a\u0e49 .first() \u0e40\u0e1e\u0e23\u0e32\u0e30\u0e40\u0e23\u0e32\u0e23\u0e39\u0e49\u0e27\u0e48\u0e32\u0e21\u0e35\u0e41\u0e04\u0e48\u0e14\u0e35\u0e25\u0e40\u0e14\u0e35\u0e22\u0e27)\nconst deal = $input.first().json;\n\n// 2. \u0e14\u0e36\u0e07\u0e04\u0e48\u0e32\u0e15\u0e31\u0e27\u0e40\u0e25\u0e02\n// (\u0e43\u0e0a\u0e49 parseFloat \u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e41\u0e1b\u0e25\u0e07\u0e40\u0e1b\u0e47\u0e19\u0e15\u0e31\u0e27\u0e40\u0e25\u0e02)\nconst current = parseFloat(deal.current_quantity_pledged);\nconst minimum = parseFloat(deal.minimum_quantity);\n\n// 3. \u0e04\u0e33\u0e19\u0e27\u0e13\u0e40\u0e1b\u0e2d\u0e23\u0e4c\u0e40\u0e0b\u0e47\u0e19\u0e15\u0e4c\nlet percentage = 0;\nif (minimum > 0) {\n  percentage = (current / minimum) * 100;\n}\n\n// 4. \u0e40\u0e15\u0e23\u0e35\u0e22\u0e21\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e2a\u0e48\u0e07\u0e2d\u0e2d\u0e01\n// \u0e40\u0e23\u0e32\u0e08\u0e30\u0e41\u0e19\u0e1a\u0e40\u0e1b\u0e2d\u0e23\u0e4c\u0e40\u0e0b\u0e47\u0e19\u0e15\u0e4c\u0e17\u0e35\u0e48\u0e04\u0e33\u0e19\u0e27\u0e13\u0e44\u0e14\u0e49 \u0e01\u0e25\u0e31\u0e1a\u0e44\u0e1b\u0e01\u0e31\u0e1a\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25 deal \u0e40\u0e14\u0e34\u0e21\nconst item = $input.first().json;\n\n// \u0e43\u0e0a\u0e49 .toFixed(0) \u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e1b\u0e31\u0e14\u0e40\u0e28\u0e29\u0e40\u0e1b\u0e47\u0e19\u0e08\u0e33\u0e19\u0e27\u0e19\u0e40\u0e15\u0e47\u0e21\nitem.percentage_pledged = percentage.toFixed(0); \n\n// 5. \u0e2a\u0e48\u0e07\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14\u0e2d\u0e2d\u0e01\u0e44\u0e1b\nreturn item;"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -912,
        3520
      ],
      "id": "2a7faa7b-cc1a-467c-81dc-25d7fbe2b5da",
      "name": "calculate percent1"
    },
    {
      "parameters": {},
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.2,
      "position": [
        -640,
        3520
      ],
      "id": "f1593b9f-aa88-4184-9ce7-51f72fb64b21",
      "name": "info confirm"
    },
    {
      "parameters": {
        "jsCode": "const [deal, pledge] = $input.all().map(i => i.json);\nconst total = Number(deal.price_per_unit) * Number(pledge.quantity_pledged);\nconst percent = Number(deal.percentage_pledged);\n\nconst flexMessage = {\n  type: \"flex\",\n  altText: \"\u0e22\u0e37\u0e19\u0e22\u0e31\u0e19\u0e01\u0e32\u0e23\u0e08\u0e2d\u0e07\u0e2a\u0e34\u0e19\u0e04\u0e49\u0e32\u0e2a\u0e33\u0e40\u0e23\u0e47\u0e08!\",\n  contents: {\n    type: \"bubble\",\n    hero: {\n      type: \"image\",\n      url: \"https://images.pexels.com/photos/7563678/pexels-photo-7563678.jpeg\",\n      size: \"full\",\n      aspectRatio: \"16:9\",\n      aspectMode: \"cover\"\n    },\n    body: {\n      type: \"box\",\n      layout: \"vertical\",\n      contents: [\n        { type: \"text\", text: \"\ud83c\udf89 \u0e08\u0e2d\u0e07\u0e2a\u0e33\u0e40\u0e23\u0e47\u0e08\u0e41\u0e25\u0e49\u0e27!\", weight: \"bold\", size: \"xl\", color: \"#00AA00\" },\n        { type: \"text\", text: deal.product_name, wrap: true, size: \"md\", margin: \"md\" },\n        {\n          type: \"box\",\n          layout: \"baseline\",\n          spacing: \"sm\",\n          contents: [\n            { type: \"text\", text: \"\u0e08\u0e33\u0e19\u0e27\u0e19\u0e17\u0e35\u0e48\u0e08\u0e2d\u0e07:\", size: \"sm\", color: \"#555555\" },\n            { type: \"text\", text: `${pledge.quantity_pledged} ${deal.unit}`, size: \"sm\", color: \"#111111\" }\n          ]\n        },\n        {\n          type: \"box\",\n          layout: \"baseline\",\n          spacing: \"sm\",\n          contents: [\n            { type: \"text\", text: \"\u0e23\u0e32\u0e04\u0e32\u0e15\u0e48\u0e2d\u0e2b\u0e19\u0e48\u0e27\u0e22:\", size: \"sm\", color: \"#555555\" },\n            { type: \"text\", text: `\u0e3f${Number(deal.price_per_unit).toFixed(2)}`, size: \"sm\", color: \"#111111\" }\n          ]\n        },\n        {\n          type: \"box\",\n          layout: \"baseline\",\n          spacing: \"sm\",\n          contents: [\n            { type: \"text\", text: \"\u0e23\u0e27\u0e21\u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14:\", size: \"sm\", color: \"#555555\" },\n            { type: \"text\", text: `\u0e3f${total.toLocaleString()}`, size: \"sm\", color: \"#111111\" }\n          ]\n        },\n        { type: \"text\", text: `\u0e22\u0e2d\u0e14\u0e23\u0e27\u0e21\u0e08\u0e2d\u0e07\u0e1b\u0e31\u0e08\u0e08\u0e38\u0e1a\u0e31\u0e19: ${percent}%`, size: \"sm\", color: \"#888888\", margin: \"md\" },\n        {\n          type: \"box\",\n          layout: \"vertical\",\n          contents: [\n            {\n              type: \"box\",\n              layout: \"vertical\",\n              contents: [{ type: \"filler\" }],\n              width: `${percent}%`,\n              backgroundColor: \"#00BB00\",\n              height: \"6px\"\n            }\n          ],\n          backgroundColor: \"#EEEEEE\",\n          height: \"6px\",\n          margin: \"sm\"\n        }\n      ]\n    },\n    footer: {\n      type: \"box\",\n      layout: \"vertical\",\n      spacing: \"sm\",\n      contents: [\n        {\n          type: \"button\",\n          style: \"primary\",\n          color: \"#00AA00\",\n          action: {\n            type: \"postback\",\n            label: \"\u0e14\u0e39\u0e14\u0e35\u0e25\u0e2d\u0e37\u0e48\u0e19 \u0e46\",\n            data: \"action=view_categories\"\n          }\n        }\n      ]\n    }\n  }\n};\n\nreturn [{ json: { message: flexMessage } }];\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -400,
        3520
      ],
      "id": "0c884922-78f2-41cd-b642-83eb6cf3bab2",
      "name": "Code in JavaScript2"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.line.me/v2/bot/message/reply",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer dfb5VjlLp060/Co+K/KvfL3JRM8qGYag5hbDOvqyfXuMMZ0auDMU3RQ0CC3XJCbt/5sXYsbfO51+5dIt6Xq3WD48lxkTxubVv5Yps4NMkL6SnVvuieSq86Qyo3ZugeYbz0OkGv25DxMUN/aheZpANwdB04t89/1O/w1cDnyilFU="
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"replyToken\": \"{{ $('Webhook').first().json.body.events[0].replyToken }}\",\n  \"messages\": [ {{ JSON.stringify($json.message) }} ]\n}\n",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -96,
        3536
      ],
      "id": "f0411e90-66f4-4e1c-94ca-56753cb496e9",
      "name": "send ingredient type1"
    },
    {
      "parameters": {
        "operation": "upsert",
        "schema": {
          "__rl": true,
          "value": "sme",
          "mode": "list",
          "cachedResultName": "sme"
        },
        "table": {
          "__rl": true,
          "value": "pledges",
          "mode": "list",
          "cachedResultName": "pledges"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "deal_id": "={{ $json.deal_id }}",
            "quantity_pledged": "={{ $json.quantity_pledged }}",
            "user_id": "={{ $json.user_id }}"
          },
          "matchingColumns": [
            "user_id",
            "deal_id"
          ],
          "schema": [
            {
              "id": "pledge_id",
              "displayName": "pledge_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": true,
              "removed": true
            },
            {
              "id": "deal_id",
              "displayName": "deal_id",
              "required": true,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "user_id",
              "displayName": "user_id",
              "required": true,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "quantity_pledged",
              "displayName": "quantity_pledged",
              "required": true,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": false,
              "removed": false
            },
            {
              "id": "created_at",
              "displayName": "created_at",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "dateTime",
              "canBeUsedToMatch": false,
              "removed": false
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.6,
      "position": [
        -1952,
        3648
      ],
      "id": "0abc37d4-6082-4d4a-9689-1946ec173212",
      "name": "Insert or update rows in a table",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "select",
        "schema": {
          "__rl": true,
          "value": "sme",
          "mode": "list",
          "cachedResultName": "sme"
        },
        "table": {
          "__rl": true,
          "value": "users",
          "mode": "list",
          "cachedResultName": "users"
        },
        "where": {
          "values": [
            {
              "column": "user_id",
              "value": "={{ $('message').item.json.userId }}"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.6,
      "position": [
        -1760,
        2624
      ],
      "id": "8715ba0c-ba0d-4e58-972c-bf16dd1b3353",
      "name": "Select rows from a table1",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "select",
        "schema": {
          "__rl": true,
          "value": "sme",
          "mode": "list",
          "cachedResultName": "sme"
        },
        "table": {
          "__rl": true,
          "value": "suppliers",
          "mode": "list",
          "cachedResultName": "suppliers"
        },
        "where": {
          "values": [
            {
              "column": "supplier_id",
              "value": "={{ $json.supplier_id }}"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.6,
      "position": [
        -1568,
        2752
      ],
      "id": "4b96ff6a-8fac-405c-93a5-7d5544c34ffd",
      "name": "Select rows from a table2",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "select",
        "schema": {
          "__rl": true,
          "value": "sme",
          "mode": "list",
          "cachedResultName": "sme"
        },
        "table": {
          "__rl": true,
          "value": "users",
          "mode": "list",
          "cachedResultName": "users"
        },
        "returnAll": true,
        "where": {
          "values": [
            {
              "column": "user_id",
              "condition": "!=",
              "value": "={{ $json.user_id }}"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.6,
      "position": [
        144,
        368
      ],
      "id": "d7f01c97-816f-4ede-b22f-adec28d91b48",
      "name": "get all user",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "select",
        "schema": {
          "__rl": true,
          "value": "sme",
          "mode": "list",
          "cachedResultName": "sme"
        },
        "table": {
          "__rl": true,
          "value": "users",
          "mode": "list",
          "cachedResultName": "users"
        },
        "where": {
          "values": [
            {
              "column": "user_id",
              "value": "={{ $json.user_id }}"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.6,
      "position": [
        -80,
        592
      ],
      "id": "b87de165-d8fb-408e-982e-6c9d3f5b19d4",
      "name": "get current user",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "e035f456-0fe0-4a9e-a1ca-17f4dc0f1f35",
              "name": "current_user_id",
              "value": "={{ $json.user_id }}",
              "type": "string"
            },
            {
              "id": "511baad4-65a7-4b30-82f8-1732a6d57465",
              "name": "current_lat",
              "value": "={{ $json.lat }}",
              "type": "string"
            },
            {
              "id": "53520bc9-c3ab-4132-969f-4ded2db99fe4",
              "name": "current_lon",
              "value": "={{ $json.lon }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        144,
        592
      ],
      "id": "5a124381-6be6-49c1-a29d-c23b59fd9218",
      "name": "Edit Fields2"
    },
    {
      "parameters": {},
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.2,
      "position": [
        448,
        592
      ],
      "id": "91e60640-a2b5-4ba0-a100-8e9224dc9814",
      "name": "Merge"
    },
    {
      "parameters": {
        "documentId": {
          "__rl": true,
          "value": "1H4vc0nWHyK2m344jhcckg5xoETkqgbB1bmDrQYCwr90",
          "mode": "list",
          "cachedResultName": "faq",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1H4vc0nWHyK2m344jhcckg5xoETkqgbB1bmDrQYCwr90/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": 1121208006,
          "mode": "list",
          "cachedResultName": " faq \u0e04\u0e33\u0e16\u0e32\u0e21-\u0e15\u0e2d\u0e1a",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1H4vc0nWHyK2m344jhcckg5xoETkqgbB1bmDrQYCwr90/edit#gid=1121208006"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7,
      "position": [
        -960,
        1952
      ],
      "id": "35a7b4df-de4f-49f6-a2b0-51c67493d83a",
      "name": "Get row(s) in sheet",
      "alwaysOutputData": false,
      "notesInFlow": false,
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent": {
      "main": [
        [
          {
            "node": "HTTP Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "filter intent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "filter intent": {
      "main": [
        [
          {
            "node": "Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch": {
      "main": [
        [
          {
            "node": "Edit Fields1",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Get row(s) in sheet",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields1": {
      "main": [
        [
          {
            "node": "hello",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "filter intent",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "information": {
      "main": [
        [
          {
            "node": "location",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "request location1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "message": {
      "main": [
        [
          {
            "node": "start with check",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript1": {
      "main": [
        [
          {
            "node": "store name type1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "location": {
      "main": [
        [
          {
            "node": "select function",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "request location",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "spreate": {
      "main": [
        [
          {
            "node": "Get row by uid3",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "filter intent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If1": {
      "main": [
        [
          {
            "node": "HTTP Request2",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter": {
      "main": [
        [
          {
            "node": "If1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "collaboration": {
      "main": [
        [
          {
            "node": "request location2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "findShop": {
      "main": [
        [
          {
            "node": "If empty",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If empty": {
      "main": [
        [
          {
            "node": "request location5",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "collaboration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "location1": {
      "main": [
        [
          {
            "node": "request location6",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "request location",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "store location": {
      "main": [
        [
          {
            "node": "store location complete",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "store name type1": {
      "main": [
        [
          {
            "node": "Get row by uid2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get row by uid2": {
      "main": [
        [
          {
            "node": "location1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get row by uid3": {
      "main": [
        [
          {
            "node": "information",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "select function": {
      "main": [
        [
          {
            "node": "Select rows from a table",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "get all user",
            "type": "main",
            "index": 0
          },
          {
            "node": "get current user",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Select rows from a table": {
      "main": [
        [
          {
            "node": "build carousel ingredient",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "start with check": {
      "main": [
        [
          {
            "node": "Code in JavaScript1",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "store location",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "select ingredient",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Parse Pledge Message",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "spreate",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "select ingredient": {
      "main": [
        [
          {
            "node": "select id from category",
            "type": "main",
            "index": 0
          },
          {
            "node": "Select rows from a table1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "build carousel ingredient": {
      "main": [
        [
          {
            "node": "send ingredient type",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "build carousel supplier": {
      "main": [
        [
          {
            "node": "send supplier deal",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "select id from category": {
      "main": [
        [
          {
            "node": "list deal from category",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "list deal from category": {
      "main": [
        [
          {
            "node": "If null",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge1",
            "type": "main",
            "index": 1
          },
          {
            "node": "Select rows from a table2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "list supplier": {
      "main": [
        [
          {
            "node": "Merge1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If null": {
      "main": [
        [
          {
            "node": "no have deal",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "list supplier",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge1": {
      "main": [
        [
          {
            "node": "build carousel supplier",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields": {
      "main": [
        [
          {
            "node": "get deal detail",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "get deal detail": {
      "main": [
        [
          {
            "node": "calculate percent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "calculate percent": {
      "main": [
        [
          {
            "node": "send deal detail",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Pledge Message": {
      "main": [
        [
          {
            "node": "get deal detail1",
            "type": "main",
            "index": 0
          },
          {
            "node": "Insert or update rows in a table",
            "type": "main",
            "index": 0
          },
          {
            "node": "info confirm",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Update rows in a table": {
      "main": [
        [
          {
            "node": "calculate percent1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "get deal detail1": {
      "main": [
        [
          {
            "node": "update current quantity",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "update current quantity": {
      "main": [
        [
          {
            "node": "Code in JavaScript",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript": {
      "main": [
        [
          {
            "node": "Update rows in a table",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "calculate percent1": {
      "main": [
        [
          {
            "node": "info confirm",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "info confirm": {
      "main": [
        [
          {
            "node": "Code in JavaScript2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript2": {
      "main": [
        [
          {
            "node": "send ingredient type1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Insert or update rows in a table": {
      "main": [
        [
          {
            "node": "update current quantity",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Select rows from a table1": {
      "main": [
        [
          {
            "node": "Merge1",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "Select rows from a table2": {
      "main": [
        [
          {
            "node": "Merge1",
            "type": "main",
            "index": 3
          }
        ]
      ]
    },
    "get all user": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "get current user": {
      "main": [
        [
          {
            "node": "Edit Fields2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields2": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Merge": {
      "main": [
        [
          {
            "node": "findShop",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get row(s) in sheet": {
      "main": [
        [
          {
            "node": "Filter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": true,
  "settings": {
    "executionOrder": "v1",
    "timezone": "Asia/Bangkok",
    "callerPolicy": "workflowsFromSameOwner",
    "executionTimeout": -1,
    "availableInMCP": false,
    "errorWorkflow": "LRKs7Png2vPbrJ0E"
  },
  "versionId": "ccb093b1-4608-47ed-b001-f8a707539311",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "id": "fZvLNqDvyVXCWCCs",
  "tags": []
}