{
  "id": "AyrKWvboPldzZPsM",
  "name": "🎬 Pompeo — Jellyfin Playback [Webhook]",
  "nodes": [
    {
      "id": "wh_jellyfin",
      "name": "Webhook Jellyfin",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "webhookId": "jellyfin-playback",
      "position": [
        0,
        300
      ],
      "parameters": {
        "httpMethod": "POST",
        "path": "jellyfin-playback",
        "responseMode": "onReceived",
        "options": {}
      }
    },
    {
      "id": "code_norm",
      "name": "🔀 Normalizza Evento",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        280,
        300
      ],
      "parameters": {
        "jsCode": "// Parse body: il plugin Jellyfin invia il payload come stringa JSON dentro il body\nconst rawBody = $json.body || $json;\nconst body = typeof rawBody === 'string' ? JSON.parse(rawBody) : rawBody;\n\nconst notifType = body.NotificationType || body.Event || '';\nconst isStart = /PlaybackStart|Play$/i.test(notifType);\nconst isStop = /PlaybackStop|PlaybackPause|Pause|Stop|Scrobble/i.test(notifType);\nif (!isStart && !isStop) return [];\n\n// Whitelist utenti\nconst ALLOWED = ['42369255a7c64917a28fc26d4c7f8265', 'martin'];\nconst jellyUser = String(body.UserId || body.User || '');\nif (jellyUser && !ALLOWED.some(u => jellyUser.toLowerCase().includes(u.toLowerCase()))) return [];\n\n// Campi Jellyfin reali (plugin v1)\nconst series = body.SeriesName || null;\nconst season = body.SeasonNumber || null;\nconst ep = body.EpisodeNumber || null;\nconst item = body.Name || body.ItemName || 'Sconosciuto';\nconst device = body.DeviceName || body.Client || 'Unknown';\nconst sid = body.SessionId || body.DeviceId || null;\nconst itemType = (body.ItemType || '').toLowerCase();\n\nconst subject = series\n  ? `${series} S${String(season||0).padStart(2,'0')}E${String(ep||0).padStart(2,'0')} - ${item}`\n  : item;\n\nreturn [{json:{\n  is_start: isStart,\n  is_stop: isStop,\n  subject,\n  item_name: item,\n  series_name: series,\n  item_type: itemType,\n  device,\n  session_id: sid,\n  user_id: 'martin',\n  jellyfin_user_id: jellyUser,\n  ts: new Date().toISOString()\n}}];"
      }
    },
    {
      "id": "sw_startstop",
      "name": "🔀 Start o Stop?",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3,
      "position": [
        560,
        300
      ],
      "parameters": {
        "mode": "rules",
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "loose"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "leftValue": "={{ $json.is_start }}",
                    "rightValue": true,
                    "operator": {
                      "type": "boolean",
                      "operation": "true"
                    }
                  }
                ]
              },
              "renameOutput": true,
              "outputKey": "start"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "loose"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "leftValue": "={{ $json.is_stop }}",
                    "rightValue": true,
                    "operator": {
                      "type": "boolean",
                      "operation": "true"
                    }
                  }
                ]
              },
              "renameOutput": true,
              "outputKey": "stop"
            }
          ]
        }
      }
    },
    {
      "id": "pg_start",
      "name": "💾 PG - Inizia Sessione",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2,
      "position": [
        840,
        180
      ],
      "parameters": {
        "operation": "executeQuery",
        "query": "INSERT INTO behavioral_context (user_id,event_type,start_at,do_not_disturb,home_presence_expected,notes) VALUES ('{{ $json.user_id }}','watching_media',now(),true,true,'{{ JSON.stringify({item:$json.subject,device:$json.device,item_type:$json.item_type,session_id:$json.session_id}) }}'::jsonb)",
        "options": {}
      },
      "credentials": {
        "postgres": {
          "id": "mRqzxhSboGscolqI",
          "name": "Pompeo — PostgreSQL"
        }
      }
    },
    {
      "id": "pg_msg_start",
      "name": "💬 PG - Msg Start",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2,
      "position": [
        1120,
        180
      ],
      "parameters": {
        "operation": "executeQuery",
        "query": "INSERT INTO agent_messages (agent,priority,event_type,user_id,subject,detail,expires_at) VALUES ('media','low','behavioral_observation','{{ $(\"🔀 Normalizza Evento\").item.json.user_id }}','▶️ {{ $(\"🔀 Normalizza Evento\").item.json.subject }} ({{ $(\"🔀 Normalizza Evento\").item.json.device }})','{{ JSON.stringify({event:\"watching_media_start\",item_type:$(\"🔀 Normalizza Evento\").item.json.item_type,device:$(\"🔀 Normalizza Evento\").item.json.device,ts:$(\"🔀 Normalizza Evento\").item.json.ts}) }}'::jsonb,now()+interval '4 hours')",
        "options": {}
      },
      "credentials": {
        "postgres": {
          "id": "mRqzxhSboGscolqI",
          "name": "Pompeo — PostgreSQL"
        }
      }
    },
    {
      "id": "pg_stop",
      "name": "💾 PG - Chiudi Sessione",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2,
      "position": [
        840,
        420
      ],
      "parameters": {
        "operation": "executeQuery",
        "query": "UPDATE behavioral_context SET end_at=now(),do_not_disturb=false WHERE id=(SELECT id FROM behavioral_context WHERE user_id='{{ $json.user_id }}' AND event_type='watching_media' AND end_at IS NULL ORDER BY start_at DESC LIMIT 1)",
        "options": {}
      },
      "credentials": {
        "postgres": {
          "id": "mRqzxhSboGscolqI",
          "name": "Pompeo — PostgreSQL"
        }
      }
    },
    {
      "id": "pg_msg_stop",
      "name": "💬 PG - Msg Stop",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2,
      "position": [
        1120,
        420
      ],
      "parameters": {
        "operation": "executeQuery",
        "query": "INSERT INTO agent_messages (agent,priority,event_type,user_id,subject,detail,expires_at) VALUES ('media','low','behavioral_observation','{{ $(\"🔀 Normalizza Evento\").item.json.user_id }}','⏹️ {{ $(\"🔀 Normalizza Evento\").item.json.subject }} ({{ $(\"🔀 Normalizza Evento\").item.json.device }})','{{ JSON.stringify({event:\"watching_media_stop\",device:$(\"🔀 Normalizza Evento\").item.json.device,ts:$(\"🔀 Normalizza Evento\").item.json.ts}) }}'::jsonb,now()+interval '1 hour')",
        "options": {}
      },
      "credentials": {
        "postgres": {
          "id": "mRqzxhSboGscolqI",
          "name": "Pompeo — PostgreSQL"
        }
      }
    }
  ],
  "connections": {
    "Webhook Jellyfin": {
      "main": [
        [
          {
            "node": "🔀 Normalizza Evento",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🔀 Normalizza Evento": {
      "main": [
        [
          {
            "node": "🔀 Start o Stop?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🔀 Start o Stop?": {
      "main": [
        [
          {
            "node": "💾 PG - Inizia Sessione",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "💾 PG - Chiudi Sessione",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "💾 PG - Inizia Sessione": {
      "main": [
        [
          {
            "node": "💬 PG - Msg Start",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "💾 PG - Chiudi Sessione": {
      "main": [
        [
          {
            "node": "💬 PG - Msg Stop",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "callerPolicy": "workflowsFromSameOwner",
    "availableInMCP": false
  },
  "triggerCount": 1,
  "versionId": "fe285311-5816-456e-bdf1-b7f85fcc1f7c",
  "owner": {
    "type": "personal",
    "projectId": "Hdttz401OqqtObPo",
    "projectName": "Martin Tahiraj <tahiraj.martin@gmail.com>",
    "personalEmail": "tahiraj.martin@gmail.com"
  },
  "parentFolderId": null,
  "isArchived": false
}