{
  "name": "ST-03 Mining Controller",
  "active": true,
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "minutes",
              "minutesInterval": 2
            }
          ]
        }
      },
      "id": "74a1e64d",
      "name": "Every 2 min",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        100,
        300
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "https://api.spacetraders.io/v2/my/ships",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "httpHeaderAuth",
        "options": {
          "retries": 3,
          "retryDelay": 2000,
          "continueOnFail": true
        },
        "alwaysOutputData": true,
        "continueOnFail": true
      },
      "id": "6539db0b",
      "name": "List Ships",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        300,
        300
      ],
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "\nconst ships = $input.all().map(i => i.json);\nconst list = (Array.isArray(ships[0]?.data) ? ships[0].data : ships).filter(s =>\n  s.frame?.symbol?.includes('MINER') ||\n  (s.mounts || []).some(m => m.symbol?.includes('MINING_LASER'))\n);\nreturn list.map(s => ({json: s}));\n"
      },
      "id": "83290c04",
      "name": "Filter Miners",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        500,
        300
      ]
    },
    {
      "parameters": {
        "batchSize": 1,
        "options": {}
      },
      "id": "93267a26",
      "name": "Each Miner",
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        700,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "const s = $input.first().json;\nconst now = Date.now();\nconst cooldownExp = s.cooldown?.expiration ? new Date(s.cooldown.expiration).getTime() : 0;\nconst cargoPct = s.cargo?.capacity > 0 ? s.cargo.units / s.cargo.capacity : 0;\nconst status = s.nav?.status;\nconst wp = s.nav?.waypointSymbol;\nconst ASTEROID = 'X1-FY52-B8';\n\nif (status === 'IN_TRANSIT' || status === 'DOCKED') return [];\nif (cooldownExp > now) return [];\nif (status !== 'IN_ORBIT') return [];\nif (wp !== ASTEROID) return [];\n\nif (cargoPct >= 0.9) return [{json:{ship:s.symbol, action:'full_cargo', title:'Mining: Cargo Full', message:`${s.symbol} cargo at ${Math.round(cargoPct*100)}% \u2014 ready to sell`}}];\nreturn [{json:{ship:s.symbol, action:'extract'}}];\n"
      },
      "id": "c64f7f2d",
      "name": "Decide",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        900,
        300
      ]
    },
    {
      "parameters": {
        "mode": "rules",
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "560ee5d2",
                    "leftValue": "={{ $json.action }}",
                    "rightValue": "extract",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ]
              },
              "renameOutput": false
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "5fb52301",
                    "leftValue": "={{ $json.action }}",
                    "rightValue": "full_cargo",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ]
              },
              "renameOutput": false
            }
          ]
        },
        "fallbackOutput": "extra",
        "options": {}
      },
      "id": "783101f3",
      "name": "Switch",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.2,
      "position": [
        1100,
        300
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://api.spacetraders.io/v2/my/ships/{{$json.ship}}/extract",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "httpHeaderAuth",
        "continueOnFail": true,
        "options": {
          "retries": 3,
          "retryDelay": 2000,
          "continueOnFail": true
        }
      },
      "id": "08b913b5",
      "name": "Extract",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1300,
        200
      ],
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "http://localhost:5678/webhook/spaceship-notify",
        "sendBody": true,
        "options": {
          "continueOnFail": true
        },
        "specifyBody": "json",
        "jsonBody": "={\"title\":{{ JSON.stringify($json.title) }},\"message\":{{ JSON.stringify($json.message) }},\"severity\":\"info\"}"
      },
      "id": "34a8dc87",
      "name": "Notify Cargo Full",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1300,
        320
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "http://localhost:5678/webhook/spaceship-notify",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\"title\":\"\u26cf\ufe0f Mining Controller\",\"message\":\"{{ $json.action }}: {{ $json.ship }} ({{ $json.remainMs ? Math.round($json.remainMs/1000)+\"s cooldown\" : $json.action }})\",\"severity\":\"info\"}",
        "options": {
          "continueOnFail": true
        }
      },
      "id": "8238b29b",
      "name": "Skip",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1300,
        440
      ]
    }
  ],
  "connections": {
    "Every 2 min": {
      "main": [
        [
          {
            "node": "List Ships",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "List Ships": {
      "main": [
        [
          {
            "node": "Filter Miners",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter Miners": {
      "main": [
        [
          {
            "node": "Each Miner",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Each Miner": {
      "main": [
        [],
        [
          {
            "node": "Decide",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Decide": {
      "main": [
        [
          {
            "node": "Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch": {
      "main": [
        [
          {
            "node": "Extract",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Notify Cargo Full",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Skip",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "errorWorkflow": "UBBtoeMsOM2deZTM"
  }
}