{
  "updatedAt": "2025-11-28T08:56:36.000Z",
  "createdAt": "2025-09-30T16:07:17.900Z",
  "id": "JOwGA6XCfmsKkx5g",
  "name": "Absen Otomatis",
  "active": true,
  "isArchived": false,
  "nodes": [
    {
      "parameters": {
        "authentication": "webhook",
        "content": "={{ $json.text }}\n-----------------------------------------",
        "options": {}
      },
      "type": "n8n-nodes-base.discord",
      "typeVersion": 2,
      "position": [
        1120,
        944
      ],
      "id": "e444a157-766f-4109-b8b3-58b092e69ade",
      "name": "Discord2",
      "credentials": {
        "discordWebhookApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// --- Mention User ---\nconst userId = \"664803448629493816\";\nconst mention = `<@${userId}>`;\n\n// --- Ambil output dari node sebelumnya (opsional) ---\nconst stdout = $input.first()?.json?.stdout || \"\u26a0 Tidak ada output dari script.\";\n\n// --- Ambil waktu sekarang ---\nconst now = new Date();\n\n// --- Hari dalam bahasa Inggris (Monday, Tuesday, ...) ---\nconst dayNames = [\"Sunday\",\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\"];\nconst rawDay = dayNames[now.getDay()];\n\n// --- Jam sekarang dalam HH:mm ---\nconst pad = (n) => String(n).padStart(2, \"0\");\nconst rawTime = `${pad(now.getHours())}:${pad(now.getMinutes())}`;\n\n// --- Normalisasi nama hari ---\nconst dayMap = {\n  'senin': 'Monday', 'selasa': 'Tuesday', 'rabu': 'Wednesday', 'kamis': 'Thursday', 'jumat': 'Friday', 'jum\\'at': 'Friday',\n  'mon': 'Monday', 'monday': 'Monday',\n  'tue': 'Tuesday', 'tues': 'Tuesday', 'tuesday': 'Tuesday',\n  'wed': 'Wednesday', 'wednesday': 'Wednesday',\n  'thu': 'Thursday', 'thur': 'Thursday', 'thursday': 'Thursday',\n  'fri': 'Friday', 'friday': 'Friday'\n};\nconst dayKey = dayMap[rawDay.toLowerCase()] || rawDay;\n\n// --- Jadwal kuliah ---\nconst schedule = {\n  Monday: [\n    { time: \"08:00\", end: \"09:40\", subject: \"Metodologi Penelitian\", lecturer: \"Dr. Maulisa Oktiana\", room: \"Lab Elektro IV\" }\n  ],\n  Tuesday: [\n    { time: \"10:45\", end: \"12:25\", subject: \"Artificial Inteligent\", lecturer: \"Ir. Yudha Nurdin, ST., MT\", room: \"A14-302\" }\n  ],\n  Wednesday: [\n    { time: \"10:40\", end: \"12:25\", subject: \"Sistem Terdistribusi\", lecturer: \"Ir. Yudha Nurdin, ST., MT\", room: \"A25-201\" },\n    { time: \"14:00\", end: \"15:40\", subject: \"Pengolahan Sinyal Multimedia\", lecturer: \"Dr. Maulisa Oktiana\", room: \"A12-302\" }\n  ],\n  Thursday: [\n    { time: \"08:00\", end: \"09:40\", subject: \"Keamanan Informasi\", lecturer: \"Ir. Sayed Muchalili, S.T., M.Sc., IPM\", room: \"A12-304\" },\n    { time: \"10:45\", end: \"13:15\", subject: \"Keamanan Jaringan\", lecturer: \"Prof. Dr. Ir. Teuku Yuliar Arif, S.T., M.Kom\", room: \"A24-102\" },\n    { time: \"14:00\", end: \"15:45\", subject: \"Sistem Embedded\", lecturer: \"Ir. Rahmad Dawood, S.Kom., M.Sc., IPM\", room: \"Lab Terpadu\" }\n  ],\n  Friday: [\n    { time: \"08:00\", end: \"09:40\", subject: \"Praktikum Distribusi\", lecturer: \"Pak Yudha\", room: \"A12-304\" },\n    { time: \"16:30\", end: \"18:15\", subject: \"Tata Tulis Ilmiah\", lecturer: \"Dr. Maulisa Oktiana\", room: \"A12-304\" }\n  ]\n};\n\n// --- Helper: parse HH:MM ke menit ---\nfunction parseTimeToMinutes(t) {\n  if (!t) return null;\n  t = String(t).trim().replace(/\\./g, ':');\n  const m = t.match(/(\\d{1,2}):(\\d{2})/);\n  if (!m) return null;\n  let hh = parseInt(m[1], 10);\n  let mm = parseInt(m[2], 10);\n  if (isNaN(hh) || isNaN(mm)) return null;\n  return hh * 60 + mm;\n}\n\nlet mataKuliah = \"\u2753 Tidak ada jadwal terdaftar.\";\nlet dosen = \"-\";\nlet ruangan = \"-\";\nlet jadwalWaktu = \"-\";\n\nconst nowMinutes = parseTimeToMinutes(rawTime);\n\n// --- Cari jadwal sesuai hari & waktu ---\nif (dayKey && schedule[dayKey]) {\n  const rows = schedule[dayKey];\n\n  if (nowMinutes !== null) {\n    // cek kelas yang sedang berlangsung\n    for (const r of rows) {\n      const start = parseTimeToMinutes(r.time);\n      const end = parseTimeToMinutes(r.end);\n      if (start !== null && end !== null && nowMinutes >= start && nowMinutes <= end) {\n        mataKuliah = r.subject;\n        dosen = r.lecturer;\n        ruangan = r.room;\n        jadwalWaktu = `${r.time} - ${r.end}`;\n        break;\n      }\n    }\n  }\n\n  // kalau belum ada kelas sekarang, ambil yang berikutnya\n  if (mataKuliah.startsWith(\"\u2753\") && nowMinutes !== null) {\n    const upcoming = rows\n      .map(r => ({ ...r, start: parseTimeToMinutes(r.time) }))\n      .filter(r => r.start !== null && r.start > nowMinutes)\n      .sort((a, b) => a.start - b.start);\n\n    if (upcoming.length > 0) {\n      const next = upcoming[0];\n      mataKuliah = `Tidak ada kelas sekarang. Berikutnya: ${next.subject}`;\n      dosen = next.lecturer;\n      ruangan = next.room;\n      jadwalWaktu = `${next.time} - ${next.end}`;\n    }\n  }\n} else {\n  mataKuliah = \"\u274c Hari ini tidak ada jadwal kuliah.\";\n}\n\n// --- Format pesan final ---\nconst finalMessage =\n  `\ud83d\udd5c **Absen Otomatis**\n${mention}\n\n\ud83d\udccc Status: ${stdout}\n\ud83d\udcc5 Hari: ${rawDay}\n\u23f0 Jam: ${rawTime}\n\ud83d\udcd6 Mata Kuliah: ${mataKuliah}\n\ud83d\udc68\u200d\ud83c\udfeb Dosen: ${dosen}\n\ud83c\udfeb Ruangan: ${ruangan}\n\ud83d\uddd3 Jadwal: ${jadwalWaktu}`;\n\nreturn [{ json: { text: finalMessage } }];\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        912,
        944
      ],
      "id": "48890e2d-4baf-4d3b-823c-92044c1f2d32",
      "name": "Code2"
    },
    {
      "parameters": {
        "command": ".env/bin/python3 absenproto.py",
        "cwd": "/home/n8nbot/absen/AbsenVersiAing"
      },
      "type": "n8n-nodes-base.ssh",
      "typeVersion": 1,
      "position": [
        688,
        944
      ],
      "id": "7d63c7e7-1d76-44cf-9dc0-cd7343f17482",
      "name": "Absen",
      "credentials": {
        "sshPassword": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtDay": [
                1
              ],
              "triggerAtHour": 8
            }
          ]
        }
      },
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        112,
        944
      ],
      "id": "c3c73250-da9b-4fd3-bc25-67c50ca50958",
      "name": "Metopen",
      "executeOnce": false
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtDay": [
                2
              ],
              "triggerAtHour": 10,
              "triggerAtMinute": 45
            }
          ]
        }
      },
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        -64,
        800
      ],
      "id": "90d05ecd-9dec-4059-b3f7-61ae7829b070",
      "name": "AI"
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtDay": [
                4
              ],
              "triggerAtHour": 8
            }
          ]
        }
      },
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        272,
        800
      ],
      "id": "2d668291-63c4-44a7-b40a-1497d9e3b82c",
      "name": "Informasi",
      "executeOnce": false
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtDay": [
                4
              ],
              "triggerAtHour": 10,
              "triggerAtMinute": 45
            }
          ]
        }
      },
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        112,
        800
      ],
      "id": "659ba427-9de4-46a6-9122-b7ba38ad58c9",
      "name": "Jaringan"
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtDay": [
                3
              ],
              "triggerAtHour": 10,
              "triggerAtMinute": 45
            }
          ]
        }
      },
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        288,
        1104
      ],
      "id": "f3e9d533-61ef-42ff-8b93-8e834f1a65d4",
      "name": "Distribusi"
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtDay": [
                4
              ],
              "triggerAtHour": 14
            }
          ]
        }
      },
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        -64,
        1104
      ],
      "id": "13eff02c-997c-4b3d-95a3-e73caf85296d",
      "name": "Embedded",
      "executeOnce": false
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtDay": [
                3
              ],
              "triggerAtHour": 14
            }
          ]
        }
      },
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        -64,
        960
      ],
      "id": "1df6c226-de7e-4a7d-be96-2c828ffb265e",
      "name": "Sinyal",
      "executeOnce": false
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtDay": [
                5
              ],
              "triggerAtHour": 16,
              "triggerAtMinute": 35
            }
          ]
        }
      },
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        272,
        944
      ],
      "id": "7677c4ed-003c-45d3-a932-5ecc79b18309",
      "name": "Tatul",
      "executeOnce": false
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtDay": [
                5
              ],
              "triggerAtHour": 8
            }
          ]
        }
      },
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        112,
        1104
      ],
      "id": "ae4f43d5-3cdd-4fd1-afae-ee4073198002",
      "name": "prak distribusi",
      "executeOnce": false
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtDay": [
                4
              ],
              "triggerAtHour": 14,
              "triggerAtMinute": 55
            }
          ]
        }
      },
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        -224,
        960
      ],
      "id": "8d058514-41a8-42ab-960f-acbbb8db97ce",
      "name": "PrakEmbedded",
      "executeOnce": false
    },
    {
      "parameters": {
        "inputSource": "passthrough"
      },
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "typeVersion": 1.1,
      "position": [
        496,
        784
      ],
      "id": "3815607b-2dc5-4b9f-b3c0-9ad0fda21a4b",
      "name": "When Executed by Another Workflow"
    },
    {
      "parameters": {
        "amount": "={{ Math.floor(Math.random() * (10 - 1 + 1) + 1) }}",
        "unit": "minutes"
      },
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1.1,
      "position": [
        496,
        944
      ],
      "id": "2247e0cc-745c-46ff-a6d5-575f4726e642",
      "name": "Wait",
      "alwaysOutputData": false
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "28a15265-0a35-41b8-a33d-d10594d08b60",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1,
      "position": [
        496,
        1104
      ],
      "id": "d1c54776-008b-4ca0-ac92-3ec7ab77a961",
      "name": "Webhook"
    }
  ],
  "connections": {
    "Code2": {
      "main": [
        [
          {
            "node": "Discord2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Absen": {
      "main": [
        [
          {
            "node": "Code2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Metopen": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Informasi": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Jaringan": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Distribusi": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Embedded": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sinyal": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Tatul": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "prak distribusi": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "PrakEmbedded": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When Executed by Another Workflow": {
      "main": [
        [
          {
            "node": "Absen",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait": {
      "main": [
        [
          {
            "node": "Absen",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook": {
      "main": [
        [
          {
            "node": "Absen",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "saveExecutionProgress": true,
    "callerPolicy": "workflowsFromSameOwner",
    "errorWorkflow": "AvhjGJdACMdnvIEn",
    "availableInMCP": false,
    "timeSavedPerExecution": 5
  },
  "staticData": {
    "node:Metopen": {
      "recurrenceRules": []
    },
    "node:AI": {
      "recurrenceRules": []
    },
    "node:Informasi": {
      "recurrenceRules": []
    },
    "node:Jaringan": {
      "recurrenceRules": []
    },
    "node:Distribusi": {
      "recurrenceRules": []
    },
    "node:Embedded": {
      "recurrenceRules": []
    },
    "node:Sinyal": {
      "recurrenceRules": []
    },
    "node:Tatul": {
      "recurrenceRules": []
    },
    "node:prak distribusi": {
      "recurrenceRules": []
    },
    "node:PrakEmbedded": {
      "recurrenceRules": []
    }
  },
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "versionId": "79885666-ddd3-4505-84f4-956f2e8d2ced",
  "triggerCount": 11,
  "shared": [
    {
      "updatedAt": "2025-09-30T16:07:17.908Z",
      "createdAt": "2025-09-30T16:07:17.908Z",
      "role": "workflow:owner",
      "workflowId": "JOwGA6XCfmsKkx5g",
      "projectId": "DiQC0tGxFhuiK9UM"
    }
  ],
  "tags": [
    {
      "updatedAt": "2025-10-01T17:10:43.185Z",
      "createdAt": "2025-10-01T17:10:43.185Z",
      "id": "kFo2wAHgXOGuNR0l",
      "name": "Absen"
    }
  ]
}