The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"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"
}
]
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
discordWebhookApisshPassword
About this workflow
Absen Otomatis. Uses discord, ssh, scheduleTrigger, executeWorkflowTrigger. Scheduled trigger; 16 nodes.
Source: https://github.com/SamVivan1/n8n-Workflows-Backup/blob/main/absen-otomatis-JOwGA6XCfmsKkx5g.json — original creator credit. Request a take-down →