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-10-06T02:58:29.000Z",
"createdAt": "2025-10-01T17:11:28.001Z",
"id": "rTKmxnxMu8ZarKG7",
"name": "Absen Nay",
"active": true,
"isArchived": false,
"nodes": [
{
"parameters": {
"command": "AbsenVersiAing/.env/bin/python3 absenNay.py",
"cwd": "/home/n8nbot/absen"
},
"type": "n8n-nodes-base.ssh",
"typeVersion": 1,
"position": [
448,
2288
],
"id": "8d052e46-d868-48be-87b5-eded5ddb1aef",
"name": "Absen2",
"credentials": {
"sshPassword": {
"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} Naila\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": [
656,
2288
],
"id": "87f16599-3276-48c6-9adf-6d2f3ac1d683",
"name": "Code4"
},
{
"parameters": {
"authentication": "webhook",
"content": "={{ $json.text }}\n-----------------------------------------",
"options": {}
},
"type": "n8n-nodes-base.discord",
"typeVersion": 2,
"position": [
848,
2288
],
"id": "e73f3dab-512b-4993-8069-da72fbaca526",
"name": "Discord4",
"credentials": {
"discordWebhookApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"rule": {
"interval": [
{
"field": "weeks",
"triggerAtDay": [
1
],
"triggerAtHour": 8,
"triggerAtMinute": 5
}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
48,
2288
],
"id": "c3d7023f-907c-4186-bfe6-50727c8c8c51",
"name": "Metopen",
"executeOnce": false
},
{
"parameters": {
"rule": {
"interval": [
{
"field": "weeks",
"triggerAtDay": [
2
],
"triggerAtHour": 10,
"triggerAtMinute": 50
}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
-128,
2144
],
"id": "e2e323b9-ad5a-4e92-ae62-f9000048f34f",
"name": "AI"
},
{
"parameters": {
"rule": {
"interval": [
{
"field": "weeks",
"triggerAtDay": [
4
],
"triggerAtHour": 8,
"triggerAtMinute": 5
}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
208,
2144
],
"id": "55e583a6-fe88-4239-8c52-9a32a4bd8a04",
"name": "Informasi",
"executeOnce": false
},
{
"parameters": {
"rule": {
"interval": [
{
"field": "weeks",
"triggerAtDay": [
4
],
"triggerAtHour": 10,
"triggerAtMinute": 50
}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
48,
2144
],
"id": "4efbf5be-eac5-4742-ab28-6b31a5572a71",
"name": "Jaringan"
},
{
"parameters": {
"rule": {
"interval": [
{
"field": "weeks",
"triggerAtDay": [
3
],
"triggerAtHour": 10,
"triggerAtMinute": 50
}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
224,
2448
],
"id": "b5b626a3-b1c2-403a-ae08-438dd78a248f",
"name": "Distribusi"
},
{
"parameters": {
"rule": {
"interval": [
{
"field": "weeks",
"triggerAtDay": [
4
],
"triggerAtHour": 14,
"triggerAtMinute": 5
}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
-128,
2448
],
"id": "c4716cd4-03ce-4c2e-bcf9-5fc108873207",
"name": "Embedded",
"executeOnce": false
},
{
"parameters": {
"rule": {
"interval": [
{
"field": "weeks",
"triggerAtDay": [
3
],
"triggerAtHour": 14,
"triggerAtMinute": 5
}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
-128,
2304
],
"id": "3acbd4e4-d161-410f-8e7f-edc18709264d",
"name": "Sinyal",
"executeOnce": false
},
{
"parameters": {
"rule": {
"interval": [
{
"field": "weeks",
"triggerAtDay": [
5
],
"triggerAtHour": 16,
"triggerAtMinute": 40
}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
208,
2288
],
"id": "276c8e3b-0b5f-4d90-8f84-b2366ddee708",
"name": "Tatul",
"executeOnce": false
},
{
"parameters": {
"rule": {
"interval": [
{
"field": "weeks",
"triggerAtDay": [
5
],
"triggerAtHour": 8,
"triggerAtMinute": 5
}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
48,
2448
],
"id": "6f758d30-1cfb-4bd2-b911-38c2ac205ca1",
"name": "prak distribusi",
"executeOnce": false
},
{
"parameters": {
"rule": {
"interval": [
{
"field": "weeks",
"triggerAtDay": [
4
],
"triggerAtHour": 15,
"triggerAtMinute": null
}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
-288,
2304
],
"id": "6fc263b4-c4ed-465d-90d3-edf7b191afd4",
"name": "PrakEmbedded",
"executeOnce": false
}
],
"connections": {
"Absen2": {
"main": [
[
{
"node": "Code4",
"type": "main",
"index": 0
}
]
]
},
"Code4": {
"main": [
[
{
"node": "Discord4",
"type": "main",
"index": 0
}
]
]
},
"Informasi": {
"main": [
[
{
"node": "Absen2",
"type": "main",
"index": 0
}
]
]
},
"Tatul": {
"main": [
[
{
"node": "Absen2",
"type": "main",
"index": 0
}
]
]
},
"Distribusi": {
"main": [
[
{
"node": "Absen2",
"type": "main",
"index": 0
}
]
]
},
"prak distribusi": {
"main": [
[
{
"node": "Absen2",
"type": "main",
"index": 0
}
]
]
},
"Metopen": {
"main": [
[
{
"node": "Absen2",
"type": "main",
"index": 0
}
]
]
},
"Jaringan": {
"main": [
[
{
"node": "Absen2",
"type": "main",
"index": 0
}
]
]
},
"AI": {
"main": [
[
{
"node": "Absen2",
"type": "main",
"index": 0
}
]
]
},
"Sinyal": {
"main": [
[
{
"node": "Absen2",
"type": "main",
"index": 0
}
]
]
},
"Embedded": {
"main": [
[
{
"node": "Absen2",
"type": "main",
"index": 0
}
]
]
},
"PrakEmbedded": {
"main": [
[
{
"node": "Absen2",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1",
"callerPolicy": "workflowsFromSameOwner",
"errorWorkflow": "AvhjGJdACMdnvIEn",
"saveExecutionProgress": true
},
"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": []
},
"node:Metopen2": {
"recurrenceRules": []
},
"node:AI2": {
"recurrenceRules": []
},
"node:Informasi2": {
"recurrenceRules": []
},
"node:Distribusi2": {
"recurrenceRules": []
},
"node:Embedded2": {
"recurrenceRules": []
},
"node:Sinyal2": {
"recurrenceRules": []
},
"node:Tatul2": {
"recurrenceRules": []
},
"node:prak distribusi2": {
"recurrenceRules": []
},
"node:PrakEmbedded2": {
"recurrenceRules": []
}
},
"meta": null,
"versionId": "b02c186b-d05c-4ca2-947d-71e3409c5af1",
"triggerCount": 10,
"shared": [
{
"updatedAt": "2025-10-01T17:11:28.007Z",
"createdAt": "2025-10-01T17:11:28.007Z",
"role": "workflow:owner",
"workflowId": "rTKmxnxMu8ZarKG7",
"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
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
How this works
This workflow automates attendance marking for remote teams by securely submitting entries via SSH to a central system, ensuring consistent records without manual effort. It's ideal for administrators or supervisors managing distributed staff who need reliable, scheduled check-ins to track presence and reduce administrative overhead. The key step involves the cron-triggered sequence that executes the SSH command for submission, followed by a Discord notification to confirm completion and alert any discrepancies, integrating seamlessly with these tools for effortless oversight.
Use this workflow for daily or periodic attendance automation in small to medium teams relying on SSH-accessible servers, particularly when compliance requires timestamped logs. Avoid it for large enterprises needing advanced authentication or real-time adjustments, as it suits fixed schedules without user input. Common variations include adjusting the cron interval for weekly reports or adding email alerts alongside Discord for broader notifications.
About this workflow
Absen Nay. Uses ssh, discord, scheduleTrigger. Scheduled trigger; 13 nodes.
Source: https://github.com/SamVivan1/n8n-Workflows-Backup/blob/main/absen-nay-rTKmxnxMu8ZarKG7.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Absen Otomatis. Uses discord, ssh, scheduleTrigger, executeWorkflowTrigger. Scheduled trigger; 16 nodes.
Absen Nami. Uses ssh, discord, scheduleTrigger. Scheduled trigger; 13 nodes.
Wait Schedule. Uses spotify, supabase, compareDatasets, noOp. Scheduled trigger; 54 nodes.
This n8n template demonstrates how to automatically monitor and track username and nickname changes across your Discord server members. Perfect for community moderation, security monitoring, and maint