AutomationFlowsSlack & Telegram › Automated Discord SSH Attendance

Automated Discord SSH Attendance

Original n8n title: Absen Otomatis (discord)

Absen Otomatis. Uses discord, ssh, scheduleTrigger, executeWorkflowTrigger. Scheduled trigger; 16 nodes.

Cron / scheduled trigger★★★★☆ complexity16 nodesDiscordSshExecute Workflow Trigger
Slack & Telegram Trigger: Cron / scheduled Nodes: 16 Complexity: ★★★★☆ Added:

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 →

Download .json
{
  "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.

Pro

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 workers or students by simulating logins to a system via SSH at scheduled times, ensuring consistent check-ins without manual effort and reducing the risk of forgetting. It's ideal for individuals managing repetitive attendance tasks in educational or corporate environments where automated presence is required. The key step involves the cron-triggered schedule initiating an SSH connection to execute the attendance command, integrated seamlessly with Discord for notifications and code nodes for custom logic handling.

Use this workflow when you need reliable, hands-off attendance automation on a fixed schedule, such as daily office check-ins or class registrations, particularly if your system supports SSH access. Avoid it for real-time or irregular attendance needs, or when security policies prohibit automated logins, as it relies on predefined credentials. Common variations include adding email alerts instead of Discord messages or adjusting the cron timing for multiple daily sessions.

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 →

More Slack & Telegram workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Slack & Telegram

Automatically fetch existing domains from Notion's Database and verify the validity of SSL certificates through SSL-Checker. If the validity period is less than 14 days, send a Telegram message notifi

HTTP Request, Notion, Execute Workflow Trigger +2
Slack & Telegram

Absen Nami. Uses ssh, discord, scheduleTrigger. Scheduled trigger; 13 nodes.

Ssh, Discord
Slack & Telegram

Absen Nay. Uses ssh, discord, scheduleTrigger. Scheduled trigger; 13 nodes.

Ssh, Discord
Slack & Telegram

Absen Otomatis. Uses discord, ssh, executeWorkflowTrigger, scheduleTrigger. Event-driven trigger; 13 nodes.

Discord, Ssh, Execute Workflow Trigger
Slack & Telegram

HomeLab. Uses scheduleTrigger, discord, ssh. Scheduled trigger; 8 nodes.

Discord, Ssh