{
  "name": "Movie Recommendation Bot",
  "nodes": [
    {
      "parameters": {
        "url": "https://api.themoviedb.org/3/discover/movie",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "with_genres",
              "value": "={{ $json.output[0].content[0].text.discover_params.with_genres }}"
            },
            {
              "name": "with_original_language",
              "value": "={{ $json.output[0].content[0].text.discover_params.with_original_language }}"
            },
            {
              "name": "region",
              "value": "={{ $json.output[0].content[0].text.discover_params.region }}"
            },
            {
              "name": "language",
              "value": "={{ $json.output[0].content[0].text.discover_params.language }}"
            },
            {
              "name": "include_adult",
              "value": "={{ $json.output[0].content[0].text.discover_params.include_adult }}"
            },
            {
              "name": "sort_by",
              "value": "={{ $json.output[0].content[0].text.discover_params.sort_by }}"
            },
            {
              "name": "vote_average.gte",
              "value": "={{ $json.output[0].content[0].text.discover_params.vote_average_gte }}"
            },
            {
              "name": "vote_count.gte",
              "value": "={{ $json.output[0].content[0].text.discover_params.vote_count_gte }}"
            },
            {
              "name": "primary_release_date.gte",
              "value": "={{ $json.output[0].content[0].text.discover_params.primary_release_date_gte }}"
            },
            {
              "name": "primary_release_date.lte",
              "value": "={{ $json.output[0].content[0].text.discover_params.primary_release_date_lte }}"
            }
          ]
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TMDB_API_KEY"
            }
          ]
        },
        "options": {
          "timeout": 10000
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.4,
      "position": [
        336,
        -16
      ],
      "id": "e4cc3c5f-e944-4772-80fc-1d67661649a1",
      "name": "HTTP Request"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "6ee17d62-4a19-4403-a6e8-c4a701190cbb",
              "name": "details_params",
              "value": "={{ $('Message a model').item.json.output[0].content[0].text.details_params }}",
              "type": "object"
            }
          ]
        },
        "includeOtherFields": true,
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        544,
        -16
      ],
      "id": "adb8b3fc-22e6-4b67-bb20-9dfdeb489354",
      "name": "Edit Fields"
    },
    {
      "parameters": {
        "fieldToSplitOut": "results",
        "options": {}
      },
      "type": "n8n-nodes-base.splitOut",
      "typeVersion": 1,
      "position": [
        752,
        -16
      ],
      "id": "e70f34d7-3998-4e26-896a-1fbacb33cf22",
      "name": "Split Out"
    },
    {
      "parameters": {
        "url": "=https://api.themoviedb.org/3/movie/{{ $json.id }}",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "language",
              "value": "={{ $('Edit Fields').item.json.details_params.language }}"
            },
            {
              "name": "append_to_response",
              "value": "={{ $('Edit Fields').item.json.details_params.append_to_response }}"
            }
          ]
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TMDB_API_KEY"
            }
          ]
        },
        "options": {
          "timeout": 10000
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.4,
      "position": [
        960,
        -16
      ],
      "id": "b21f688d-71ec-4501-85a4-73bfe0e2b3e6",
      "name": "HTTP Request1"
    },
    {
      "parameters": {
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.chatTrigger",
      "typeVersion": 1.4,
      "position": [
        -224,
        -16
      ],
      "id": "c5c9eacc-462a-4458-8aa0-3510afa5a850",
      "name": "When chat message received"
    },
    {
      "parameters": {
        "modelId": {
          "__rl": true,
          "value": "models/gemini-2.5-flash",
          "mode": "list",
          "cachedResultName": "models/gemini-2.5-flash"
        },
        "messages": {
          "values": [
            {
              "content": "=You will receive multiple movie objects.\n\ntitle: {{ $json.original_title }}\nreviews: {{ $json.reviews }}\ngenres: {{ $json.genres }}\nrelease date: {{ $json.release_date }}\nruntime: {{ $json.runtime }}\ncast and crews: {{ $json.credits }}\noverview: {{ $json.overview }}\nlang: {{ $json.spoken_languages }}\n\nFor each movie, display:\n\n\ud83c\udfac Movie Title (Year)\n\n\u2b50 X/10 | \ud83c\udfad Genre 1, Genre 2\n\ud83d\udcc5 Release Date | \u23f1\ufe0f Runtime min\n\ud83c\udf10 Language | \ud83d\udd1e Certification\n\n\ud83c\udf1f Cast: Actor 1, Actor 2, Actor 3\n\n\ud83d\udcdd One concise sentence describing the story.\n\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\nKeep each movie under 10 lines.\nPrioritize readability and avoid long descriptions.\n\nrules:\nShow only the fields above.\nUse only the top 3 cast members.\nKeep the story summary to a maximum of 2 lines.\nDo not mention missing fields.\nMake the output visually appealing and easy to scan.\nUse emojis consistently.\nSeparate movies with a divider line."
            }
          ]
        },
        "builtInTools": {},
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.googleGemini",
      "typeVersion": 1.2,
      "position": [
        1168,
        -16
      ],
      "id": "b37bd457-2c5a-4edf-9a96-db5b88c294bf",
      "name": "Message a model2",
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "modelId": {
          "__rl": true,
          "value": "gpt-4.1",
          "mode": "list",
          "cachedResultName": "GPT-4.1"
        },
        "responses": {
          "values": [
            {
              "content": "=You are a parameter builder for The Movie Database (TMDB) API.\n\nYour job is to take a natural language user query about movie recommendations and output two sets of parameters:\n\n1) discover_params: query parameters for GET https://api.themoviedb.org/3/discover/movie\n2) details_params: query parameters for GET https://api.themoviedb.org/3/movie/{movie_id}\n\nUser query: {{ $json.chatInput }}\n\nYou MUST reply with valid JSON only, with this structure:\n\n{\n  \"discover_params\": {\n    \"with_genres\": \"string or null\",\n    \"with_original_language\": \"string or null\",\n    \"region\": \"string or null\",\n    \"language\": \"string\", \n    \"include_adult\": boolean,\n    \"sort_by\": \"string\",\n    \"vote_average_gte\": number or null,\n    \"vote_count_gte\": number or null,\n    \"primary_release_date_gte\": \"YYYY-MM-DD or null\",\n    \"primary_release_date_lte\": \"YYYY-MM-DD or null\",\n    \"page\": number\n  },\n  \"details_params\": {\n    \"language\": \"string\",\n    \"append_to_response\": \"comma-separated list of sections\"\n  }\n}\n\nRules:\n\n- Never include an API key. The API key will be added separately in n8n.\n- Do NOT output URLs, only parameter values.\n- For all text queries from the user, assume:\n  - They want multiple recommendations, not just one movie.\n  - They want details: cast, crew, videos, reviews, release dates/certifications, keywords, recommendations.\n\nMappings:\n\nGENRES (TMDB movie genre IDs):\n- Action -> 28\n- Adventure -> 12\n- Animation -> 16\n- Comedy -> 35\n- Crime -> 80\n- Documentary -> 99\n- Drama -> 18\n- Family -> 10751\n- Fantasy -> 14\n- History -> 36\n- Horror -> 27\n- Music -> 10402\n- Mystery -> 9648\n- Romance -> 10749\n- Science Fiction -> 878\n- TV Movie -> 10770\n- Thriller -> 53\n- War -> 10752\n- Western -> 37\n\nLANGUAGES (ISO 639-1 examples):\n- \"hindi\", \"bollywood\" -> \"hi\"\n- \"english\" -> \"en\"\n- \"tamil\" -> \"ta\"\n- \"telugu\" -> \"te\"\n- \"malayalam\" -> \"ml\"\n- \"kannada\" -> \"kn\"\n- \"marathi\" -> \"mr\"\n- \"bengali\" -> \"bn\"\n\nRegions (ISO 3166-1 examples):\n- For Indian users, default region \"IN\" if user language is an Indian language or they mention India.\n- For English without region hints, leave region as null.\n\nRatings / age preferences:\n- If the user mentions things like \"family\", \"kids\", \"children\", \"no adult\", prefer more family-friendly by:\n  - include_adult: false\n  - vote_average_gte: 6.0\n- If the user mentions \"adult\", \"18+\", \"A rated\", set:\n  - include_adult: true\n- If the user explicitly says \"highly rated\", \"top rated\", \"best\", set:\n  - vote_average_gte: 7.0\n  - vote_count_gte: 1000\n\nDates:\n- If the user says \"recent\", \"latest\", \"new\", \"from last few years\":\n  - Set primary_release_date_gte to 5 years ago from today (approximate).\n- If no date constraint is mentioned:\n  - Set primary_release_date_gte and primary_release_date_lte to null.\n\nSorting:\n- If the user says \"top rated\", \"best rated\":\n  - sort_by: \"vote_average.desc\"\n- If the user says \"popular\", \"trending\", or does not specify:\n  - sort_by: \"popularity.desc\"\n\nPages:\n- Always set page to 1.\n\nLanguages in details:\n- For discover_params.language and details_params.language:\n  - If the user specifies a language like \"Hindi\", use \"<code>-IN\" when possible, for example:\n    - Hindi -> \"hi-IN\"\n    - English -> \"en-US\"\n  - If uncertain, use \"en-US\".\n\nAppend to response:\n- details_params.append_to_response MUST include:\n  - \"credits\" (for cast & crew)\n  - \"videos\" (for trailers/teasers)\n  - \"reviews\" (user reviews)\n  - \"release_dates\" (for certifications / age ratings)\n  - \"keywords\" (tags/keywords)\n  - \"recommendations\" (similar movies)\n\nHandle vague queries:\n- If the user does not mention a genre, set with_genres to null.\n- If the user does not mention a language, set with_original_language to null.\n\nExamples:\n\nUser: \"recommend comedy hindi movies\"\nOutput:\n{\n  \"discover_params\": {\n    \"with_genres\": \"35\",\n    \"with_original_language\": \"hi\",\n    \"region\": \"IN\",\n    \"language\": \"hi-IN\",\n    \"include_adult\": false,\n    \"sort_by\": \"popularity.desc\",\n    \"vote_average_gte\": null,\n    \"vote_count_gte\": null,\n    \"primary_release_date_gte\": null,\n    \"primary_release_date_lte\": null,\n    \"page\": 1\n  },\n  \"details_params\": {\n    \"language\": \"hi-IN\",\n    \"append_to_response\": \"credits,videos,reviews,release_dates,keywords,recommendations\"\n  }\n}\n\nReturn only the JSON object, no explanations. "
            }
          ]
        },
        "builtInTools": {},
        "options": {
          "textFormat": {
            "textOptions": {
              "type": "json_schema",
              "schema": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"discover_params\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"with_genres\": {\n          \"type\": [\"string\", \"null\"]\n        },\n        \"with_original_language\": {\n          \"type\": [\"string\", \"null\"]\n        },\n        \"region\": {\n          \"type\": [\"string\", \"null\"]\n        },\n        \"language\": {\n          \"type\": \"string\"\n        },\n        \"include_adult\": {\n          \"type\": \"boolean\"\n        },\n        \"sort_by\": {\n          \"type\": \"string\"\n        },\n        \"vote_average_gte\": {\n          \"type\": [\"number\", \"null\"]\n        },\n        \"vote_count_gte\": {\n          \"type\": [\"number\", \"null\"]\n        },\n        \"primary_release_date_gte\": {\n          \"type\": [\"string\", \"null\"]\n        },\n        \"primary_release_date_lte\": {\n          \"type\": [\"string\", \"null\"]\n        },\n        \"page\": {\n          \"type\": \"integer\"\n        }\n      },\n      \"required\": [\n        \"with_genres\",\n        \"with_original_language\",\n        \"region\",\n        \"language\",\n        \"include_adult\",\n        \"sort_by\",\n        \"vote_average_gte\",\n        \"vote_count_gte\",\n        \"primary_release_date_gte\",\n        \"primary_release_date_lte\",\n        \"page\"\n      ],\n      \"additionalProperties\": false\n    },\n    \"details_params\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"language\": {\n          \"type\": \"string\"\n        },\n        \"append_to_response\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\"language\", \"append_to_response\"],\n      \"additionalProperties\": false\n    }\n  },\n  \"required\": [\"discover_params\", \"details_params\"],\n  \"additionalProperties\": false\n}",
              "strict": true
            }
          }
        }
      },
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "typeVersion": 2.3,
      "position": [
        -16,
        -16
      ],
      "id": "4f5d9f62-2b3c-4c8e-9b61-0772830ae499",
      "name": "Message a model",
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "content": "Movie Recommendation TMDB API\n----\n\nYOUR_TMDB_API_KEY\n\n\nrequest send to:\n-----\nhttps://api.themoviedb.org/3/discover/movie\n\n\n----\nprompt\n-----\n\nYou are a parameter builder for The Movie Database (TMDB) API.\n\nYour job is to take a natural language user query about movie recommendations and output two sets of parameters:\n\n1) discover_params: query parameters for GET https://api.themoviedb.org/3/discover/movie\n2) details_params: query parameters for GET https://api.themoviedb.org/3/movie/{movie_id}\n\nYou MUST reply with valid JSON only, with this structure:\n\n{\n  \"discover_params\": {\n    \"with_genres\": \"string or null\",\n    \"with_original_language\": \"string or null\",\n    \"region\": \"string or null\",\n    \"language\": \"string\", \n    \"include_adult\": boolean,\n    \"sort_by\": \"string\",\n    \"vote_average_gte\": number or null,\n    \"vote_count_gte\": number or null,\n    \"primary_release_date_gte\": \"YYYY-MM-DD or null\",\n    \"primary_release_date_lte\": \"YYYY-MM-DD or null\",\n    \"page\": number\n  },\n  \"details_params\": {\n    \"language\": \"string\",\n    \"append_to_response\": \"comma-separated list of sections\"\n  }\n}\n\nRules:\n\n- Never include an API key. The API key will be added separately in n8n.\n- Do NOT output URLs, only parameter values.\n- For all text queries from the user, assume:\n  - They want multiple recommendations, not just one movie.\n  - They want details: cast, crew, videos, reviews, release dates/certifications, keywords, recommendations.\n\nMappings:\n\nGENRES (TMDB movie genre IDs):\n- Action -> 28\n- Adventure -> 12\n- Animation -> 16\n- Comedy -> 35\n- Crime -> 80\n- Documentary -> 99\n- Drama -> 18\n- Family -> 10751\n- Fantasy -> 14\n- History -> 36\n- Horror -> 27\n- Music -> 10402\n- Mystery -> 9648\n- Romance -> 10749\n- Science Fiction -> 878\n- TV Movie -> 10770\n- Thriller -> 53\n- War -> 10752\n- Western -> 37\n\nLANGUAGES (ISO 639-1 examples):\n- \"hindi\", \"bollywood\" -> \"hi\"\n- \"english\" -> \"en\"\n- \"tamil\" -> \"ta\"\n- \"telugu\" -> \"te\"\n- \"malayalam\" -> \"ml\"\n- \"kannada\" -> \"kn\"\n- \"marathi\" -> \"mr\"\n- \"bengali\" -> \"bn\"\n\nRegions (ISO 3166-1 examples):\n- For Indian users, default region \"IN\" if user language is an Indian language or they mention India.\n- For English without region hints, leave region as null.\n\nRatings / age preferences:\n- If the user mentions things like \"family\", \"kids\", \"children\", \"no adult\", prefer more family-friendly by:\n  - include_adult: false\n  - vote_average_gte: 6.0\n- If the user mentions \"adult\", \"18+\", \"A rated\", set:\n  - include_adult: true\n- If the user explicitly says \"highly rated\", \"top rated\", \"best\", set:\n  - vote_average_gte: 7.0\n  - vote_count_gte: 1000\n\nDates:\n- If the user says \"recent\", \"latest\", \"new\", \"from last few years\":\n  - Set primary_release_date_gte to 5 years ago from today (approximate).\n- If no date constraint is mentioned:\n  - Set primary_release_date_gte and primary_release_date_lte to null.\n\nSorting:\n- If the user says \"top rated\", \"best rated\":\n  - sort_by: \"vote_average.desc\"\n- If the user says \"popular\", \"trending\", or does not specify:\n  - sort_by: \"popularity.desc\"\n\nPages:\n- Always set page to 1.\n\nLanguages in details:\n- For discover_params.language and details_params.language:\n  - If the user specifies a language like \"Hindi\", use \"<code>-IN\" when possible, for example:\n    - Hindi -> \"hi-IN\"\n    - English -> \"en-US\"\n  - If uncertain, use \"en-US\".\n\nAppend to response:\n- details_params.append_to_response MUST include:\n  - \"credits\" (for cast & crew)\n  - \"videos\" (for trailers/teasers)\n  - \"reviews\" (user reviews)\n  - \"release_dates\" (for certifications / age ratings)\n  - \"keywords\" (tags/keywords)\n  - \"recommendations\" (similar movies)\n\nHandle vague queries:\n- If the user does not mention a genre, set with_genres to null.\n- If the user does not mention a language, set with_original_language to null.\n\nExamples:\n\nUser: \"recommend comedy hindi movies\"\nOutput:\n{\n  \"discover_params\": {\n    \"with_genres\": \"35\",\n    \"with_original_language\": \"hi\",\n    \"region\": \"IN\",\n    \"language\": \"hi-IN\",\n    \"include_adult\": false,\n    \"sort_by\": \"popularity.desc\",\n    \"vote_average_gte\": null,\n    \"vote_count_gte\": null,\n    \"primary_release_date_gte\": null,\n    \"primary_release_date_lte\": null,\n    \"page\": 1\n  },\n  \"details_params\": {\n    \"language\": \"hi-IN\",\n    \"append_to_response\": \"credits,videos,reviews,release_dates,keywords,recommendations\"\n  }\n}\n\nReturn only the JSON object, no explanations.\n\n\n\n\n-----\njson output sample\n----\n\n{\n  \"discover_params\": {\n    \"with_genres\": \"27\",\n    \"with_original_language\": \"hi\",\n    \"region\": \"IN\",\n    \"language\": \"hi-IN\",\n    \"include_adult\": false,\n    \"sort_by\": \"popularity.desc\",\n    \"vote_average_gte\": null,\n    \"vote_count_gte\": null,\n    \"primary_release_date_gte\": null,\n    \"primary_release_date_lte\": null,\n    \"page\": 1\n  },\n  \"details_params\": {\n    \"language\": \"hi-IN\",\n    \"append_to_response\": \"credits,videos,reviews,release_dates,keywords,recommendations\"\n  }\n}\n\n\n\n---\n\noutput schema\n----\n\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"discover_params\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"with_genres\": {\n          \"type\": [\"string\", \"null\"]\n        },\n        \"with_original_language\": {\n          \"type\": [\"string\", \"null\"]\n        },\n        \"region\": {\n          \"type\": [\"string\", \"null\"]\n        },\n        \"language\": {\n          \"type\": \"string\"\n        },\n        \"include_adult\": {\n          \"type\": \"boolean\"\n        },\n        \"sort_by\": {\n          \"type\": \"string\"\n        },\n        \"vote_average_gte\": {\n          \"type\": [\"number\", \"null\"]\n        },\n        \"vote_count_gte\": {\n          \"type\": [\"number\", \"null\"]\n        },\n        \"primary_release_date_gte\": {\n          \"type\": [\"string\", \"null\"]\n        },\n        \"primary_release_date_lte\": {\n          \"type\": [\"string\", \"null\"]\n        },\n        \"page\": {\n          \"type\": \"integer\"\n        }\n      },\n      \"required\": [\n        \"with_genres\",\n        \"with_original_language\",\n        \"region\",\n        \"language\",\n        \"include_adult\",\n        \"sort_by\",\n        \"vote_average_gte\",\n        \"vote_count_gte\",\n        \"primary_release_date_gte\",\n        \"primary_release_date_lte\",\n        \"page\"\n      ],\n      \"additionalProperties\": false\n    },\n    \"details_params\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"language\": {\n          \"type\": \"string\"\n        },\n        \"append_to_response\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\"language\", \"append_to_response\"],\n      \"additionalProperties\": false\n    }\n  },\n  \"required\": [\"discover_params\", \"details_params\"],\n  \"additionalProperties\": false\n}",
        "height": 272,
        "width": 416,
        "color": 5
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -240,
        208
      ],
      "typeVersion": 1,
      "id": "ad336667-3726-4502-875a-8242ff20fb29",
      "name": "Sticky Note"
    }
  ],
  "connections": {
    "HTTP Request": {
      "main": [
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields": {
      "main": [
        [
          {
            "node": "Split Out",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out": {
      "main": [
        [
          {
            "node": "HTTP Request1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request1": {
      "main": [
        [
          {
            "node": "Message a model2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When chat message received": {
      "main": [
        [
          {
            "node": "Message a model",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Message a model": {
      "main": [
        [
          {
            "node": "HTTP Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "binaryMode": "separate",
    "availableInMCP": false
  },
  "staticData": null,
  "triggerCount": 0,
  "meta": {
    "templateCredsSetupCompleted": true
  }
}