AutomationFlowsWeb Scraping › Automated Employee Offboarding: Lock Redmine & Gitlab Accounts Using Odoo 18

Automated Employee Offboarding: Lock Redmine & Gitlab Accounts Using Odoo 18

ByBHSoft @bhsoft on n8n.io

IT Ops, HR, and Security teams automating employee offboarding. Zero manual work: Disable access to Redmine, GitLab, and more- right after their last day. Boost security, cut risks, and stay compliant.

Cron / scheduled trigger★★★★★ complexity37 nodesHTTP Request
Web Scraping Trigger: Cron / scheduled Nodes: 37 Complexity: ★★★★★ Added:

This workflow corresponds to n8n.io template #11941 — we link there as the canonical source.

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
{
  "id": "EnNQafbUKMybv70w",
  "name": "Automatically lock Redmine, Gitlab accounts for employees after their last shift",
  "tags": [
    {
      "id": "HyLSX6V7QZs5MrZy",
      "name": "Odoo",
      "createdAt": "2025-03-24T01:54:27.030Z",
      "updatedAt": "2025-03-24T01:54:27.030Z"
    },
    {
      "id": "ROlM2EPm0TCikpBv",
      "name": "Redmine 6",
      "createdAt": "2025-03-26T07:11:53.633Z",
      "updatedAt": "2025-03-26T07:11:53.633Z"
    }
  ],
  "nodes": [
    {
      "id": "29e11f4a-6af3-4fcb-ac2f-0e287ce1f036",
      "name": "END",
      "type": "n8n-nodes-base.noOp",
      "position": [
        224,
        912
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "365d76e7-f556-4a20-9f30-9060b42fe747",
      "name": "Step2: Handle get today",
      "type": "n8n-nodes-base.code",
      "position": [
        -224,
        672
      ],
      "parameters": {
        "jsCode": "const today = new Date();\n\nconst formatDate = (date) => {\n  const year = date.getFullYear();\n  const month = String(date.getMonth() + 1).padStart(2, '0');\n  const day = String(date.getDate()).padStart(2, '0');\n  return `${year}-${month}-${day}`;\n};\nconst getDayOfWeek = (date) => {\n  const days = [\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\", \"Sunday\"];\n  return days[date.getDay()];\n};\n\nreturn [\n  {\n    date: formatDate(today),\n    dayOfWeek: getDayOfWeek(today)\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "b388dae5-6b64-4f90-a24d-ebcec5639469",
      "name": "Step3: Set Variables",
      "type": "n8n-nodes-base.set",
      "position": [
        -432,
        912
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "={\n  \"redmine6_Url\": \"\",\n  \"odooUrl\": \"\",\n  \"limit\": 100,\n  \"web_search_read_api\": \"\",\n  \"web_read_api\": \"\",\n  \"gitlab_Url\": \"\"\n}"
      },
      "typeVersion": 3.4
    },
    {
      "id": "d2a4f72b-e694-4604-b3b3-f21eaf13a177",
      "name": "Step5: If total_count is not equal to 0 = true",
      "type": "n8n-nodes-base.if",
      "position": [
        -16,
        784
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "40359ca9-0845-423c-9a96-58f06c9155df",
              "operator": {
                "type": "number",
                "operation": "notEquals"
              },
              "leftValue": "={{ $json.result.length }}",
              "rightValue": "={{ 0 }}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "8a870043-42f4-4f41-b7de-d4f98e990b6e",
      "name": "Step6: Check if there is a valid record.",
      "type": "n8n-nodes-base.code",
      "position": [
        224,
        672
      ],
      "parameters": {
        "jsCode": "const inputData = $input.all();\nconst records = inputData[0].json.result.records;\n\nconst today = new Date().toISOString().split('T')[0]; // YYYY-MM-DD\n\nconst filteredRecords = records.filter(record => record.state !== \"draft\" && record.state !== \"cancel\");\n\nconst result = filteredRecords\n  .filter(record => record.expected_revealing_date === today)\n  .map(record => ({ id: record.employee_id.id }));\n\nreturn result;\n"
      },
      "typeVersion": 2,
      "alwaysOutputData": true
    },
    {
      "id": "8228a302-6dff-4216-b043-b41656fcce68",
      "name": "Step7: If hasRecords is empty==> true",
      "type": "n8n-nodes-base.if",
      "position": [
        432,
        784
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "49b970b3-6c1f-4e8d-b165-6abdcb8b0079",
              "operator": {
                "type": "object",
                "operation": "empty",
                "singleValue": true
              },
              "leftValue": "={{ $json }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "2630d71f-971b-416f-bd38-6fe61a6fb8eb",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -496,
        512
      ],
      "parameters": {
        "width": 1068,
        "height": 584,
        "content": "## Step 1 --> 4: The flow will automatically run daily at 17:00 and check if any members are working their last shift on the current day.\n* Step 5: If there are no records, the flow will end. If there are records, it will filter the records that are NOT in draft or canceled state."
      },
      "typeVersion": 1
    },
    {
      "id": "73449f33-b4c1-4c5e-b3ae-4fd8da50bce7",
      "name": "Step1: Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -432,
        672
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtDay": [
                1,
                2,
                3,
                4,
                5
              ],
              "triggerAtHour": "={{ 17 }}",
              "triggerAtMinute": "={{ 0 }}"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "2d3de564-bb63-4765-9663-5586c908b4f8",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        656,
        400
      ],
      "parameters": {
        "color": 4,
        "width": 832,
        "height": 488,
        "content": "## Loop Over Items\n- Get the information of that member on Odoo, then extract their work email.\n- Use that email to find that user on RM6.\n  + If found, take the user's ID and lock the user."
      },
      "typeVersion": 1
    },
    {
      "id": "d79b45c4-1f2a-40b9-b472-9d32123423ac",
      "name": "Step8: Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        672,
        688
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "9a50191b-a20a-4cdb-a461-47da8b8baafa",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1616,
        448
      ],
      "parameters": {
        "color": 5,
        "width": 1308,
        "height": 672,
        "content": "## Lock, remove all group, delete membership in project on RM6"
      },
      "typeVersion": 1
    },
    {
      "id": "245da7d1-8cf3-44f7-b56e-009c1087012d",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1632,
        1232
      ],
      "parameters": {
        "color": 2,
        "width": 1224,
        "height": 320,
        "content": "## Check block a user on Gitlab"
      },
      "typeVersion": 1
    },
    {
      "id": "71fc8048-ea59-4e1c-a6c5-73627aaa5205",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -272,
        1168
      ],
      "parameters": {
        "height": 80,
        "content": "## Use APIkey Odoo 18"
      },
      "typeVersion": 1
    },
    {
      "id": "3dbbadf8-4d27-49ef-afa4-bef8f35d63a6",
      "name": "END1",
      "type": "n8n-nodes-base.noOp",
      "position": [
        672,
        528
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "68681c9a-ae82-4b60-b9c5-5aab983cc712",
      "name": "Step11: Get user info in RM6",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1328,
        688
      ],
      "parameters": {
        "url": "={{ $node['Step3: Set Variables'].json.redmine6_Url}}users.json?name={{ $node['Step10: Handle work_email'].json.work_email }}",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "executeOnce": true,
      "typeVersion": 4.2
    },
    {
      "id": "cafcc135-283d-4d3b-ae21-6e9005637625",
      "name": "Step12:  Check if there is a record or not?",
      "type": "n8n-nodes-base.if",
      "position": [
        1568,
        688
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "557ae5fd-116a-4bc5-aac2-7343bc7e3eb8",
              "operator": {
                "type": "number",
                "operation": "equals"
              },
              "leftValue": "={{ $json.total_count }}",
              "rightValue": "={{ 1 }}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "288bec11-508c-4ecb-8c9a-d319b595e496",
      "name": "Step13: Update the user's status to \"locked\" on RM6",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1792,
        608
      ],
      "parameters": {
        "url": "={{ $node['Step3: Set Variables'].json.redmine6_Url}}users/{{ $node['Step12:  Check if there is a record or not?'].json.users[0].id }}.json",
        "method": "PUT",
        "options": {},
        "jsonBody": "={\"user\": {\"status\": 3}}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "0dcb4fcd-c5ab-45bc-90e2-292b032af1b0",
      "name": "Step14: Remove the user from all groups in RM 6",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2000,
        608
      ],
      "parameters": {
        "url": "={{ $node['Step3: Set Variables'].json.redmine6_Url}}users/{{ $node['Step12:  Check if there is a record or not?'].json.users[0].id }}.json",
        "method": "PUT",
        "options": {},
        "jsonBody": "={\n  \"user\": {\n    \"group_ids\": []\n  }\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "executeOnce": true,
      "typeVersion": 4.2
    },
    {
      "id": "b30b26f1-5e2e-4d30-924e-6a0dca67456a",
      "name": "Step15: Get membership list of user in RM 6",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2224,
        608
      ],
      "parameters": {
        "url": "={{ $node['Step3: Set Variables'].json.redmine6_Url}}users/{{ $node['Step12:  Check if there is a record or not?'].json.users[0].id }}.json?include=memberships",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "executeOnce": true,
      "typeVersion": 4.2
    },
    {
      "id": "07847913-2ab6-4082-b804-e6d5cbe6e5f0",
      "name": "Step16: Get memberships_id",
      "type": "n8n-nodes-base.code",
      "position": [
        2432,
        608
      ],
      "parameters": {
        "jsCode": "const inputData = $input.all();\nconst membershipsProject = inputData[0].json.user.memberships;\nconst result = membershipsProject\n  .map(record => ({ id: record.id }));\n\nreturn result;\n"
      },
      "typeVersion": 2,
      "alwaysOutputData": true
    },
    {
      "id": "bb6be057-56e8-46d2-b1ee-092116f2f652",
      "name": "Step17: Loop Over memberships_id",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        2624,
        608
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "958a44fd-f6d6-4462-9d1a-97287532ec6f",
      "name": "Step18: Delete membership in project on RM 6",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueRegularOutput",
      "position": [
        2800,
        704
      ],
      "parameters": {
        "url": "={{ $node['Step3: Set Variables'].json.redmine6_Url}}memberships/{{ $json.id }}.json",
        "method": "DELETE",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "executeOnce": true,
      "typeVersion": 4.2,
      "alwaysOutputData": true
    },
    {
      "id": "c82a9c18-1419-44bb-be44-ac216633fd73",
      "name": "Step19: Get user information in Gitlab",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1664,
        1344
      ],
      "parameters": {
        "url": "={{ $node['Step3: Set Variables'].json.gitlab_Url}}api/v4/users?search={{ $node['Step10: Handle work_email'].json.username }}",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2,
      "alwaysOutputData": true
    },
    {
      "id": "fe50b2d0-7437-4272-97de-08f99ec45cd3",
      "name": "Step20:  Check if there is a record = true",
      "type": "n8n-nodes-base.if",
      "position": [
        1920,
        1328
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "557ae5fd-116a-4bc5-aac2-7343bc7e3eb8",
              "operator": {
                "type": "object",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $node['Step19: Get user information in Gitlab'].json }}",
              "rightValue": "={{ 1 }}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "3ba6b5e4-a344-4021-89f0-59e2318dc557",
      "name": "Step21: Check if the user is not blocked = true",
      "type": "n8n-nodes-base.if",
      "position": [
        2160,
        1296
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "08948f8d-0661-4106-86a0-3f0b07214e94",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $node['Step19: Get user information in Gitlab'].json.state}}",
              "rightValue": "=blocked"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "eff03657-4a4a-467c-8a6c-87e78b85fc1a",
      "name": "Step22: Check if the user is not deactivate = true",
      "type": "n8n-nodes-base.if",
      "position": [
        2384,
        1280
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "abf4625d-6a78-4da6-a704-82fb8b83f152",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $node['Step19: Get user information in Gitlab'].json.state}}",
              "rightValue": "=banned"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "12ef1a30-ecba-4e4a-9d72-8eeaa2f442a5",
      "name": "Step23: Block a user in Gitlab",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2688,
        1328
      ],
      "parameters": {
        "url": "={{ $node['Step3: Set Variables'].json.gitlab_Url}}api/v4/users/{{ $node['Step20:  Check if there is a record = true'].json.id}}/block",
        "method": "POST",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2,
      "alwaysOutputData": true
    },
    {
      "id": "e28de410-2e4a-47a0-8ac2-43e95049b077",
      "name": "Step24: Get user information in Gitlab",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1792,
        784
      ],
      "parameters": {
        "url": "={{ $node['Step3: Set Variables'].json.gitlab_Url}}api/v4/users?search={{ $node['Step10: Handle work_email'].json.username }}",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2,
      "alwaysOutputData": true
    },
    {
      "id": "bda33ccf-b67b-4c09-996d-e86db238c771",
      "name": "Step25:  Check if there is a record = true",
      "type": "n8n-nodes-base.if",
      "position": [
        2000,
        784
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "557ae5fd-116a-4bc5-aac2-7343bc7e3eb8",
              "operator": {
                "type": "object",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $node['Step24: Get user information in Gitlab'].json }}",
              "rightValue": "={{ 1 }}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "37324328-c131-4f3f-a8a3-4b635f580bd9",
      "name": "Step26: Check if the user is not blocked = true",
      "type": "n8n-nodes-base.if",
      "position": [
        2224,
        864
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "08948f8d-0661-4106-86a0-3f0b07214e94",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $node['Step24: Get user information in Gitlab'].json.state}}",
              "rightValue": "=blocked"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "2250c2c1-dfc1-4873-8600-51e829b2f688",
      "name": "Step27: Check if the user is not deactivate = true",
      "type": "n8n-nodes-base.if",
      "position": [
        2432,
        912
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "abf4625d-6a78-4da6-a704-82fb8b83f152",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $node['Step24: Get user information in Gitlab'].json.state}}",
              "rightValue": "=banned"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "1380048c-2981-4d07-9e63-3d6bf62f9e37",
      "name": "Step28: Block a user in Gitlab",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2688,
        960
      ],
      "parameters": {
        "url": "={{ $node['Step3: Set Variables'].json.gitlab_Url}}api/v4/users/{{ $node['Step25:  Check if there is a record = true'].json.id}}/block",
        "method": "POST",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2,
      "alwaysOutputData": true
    },
    {
      "id": "b218ac6d-1695-4e22-99f0-b8e93f52f368",
      "name": "Code",
      "type": "n8n-nodes-base.code",
      "position": [
        2800,
        480
      ],
      "parameters": {
        "jsCode": "return [\n  {}\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "87ad0556-fde3-47f6-b07a-ea545209db3e",
      "name": "Step9: Get employee information in Odoo 18",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        912,
        688
      ],
      "parameters": {
        "url": "={{ $node['Step3: Set Variables'].json.web_read_api}}",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"id\": 26,\n  \"jsonrpc\": \"2.0\",\n  \"method\": \"call\",\n  \"params\": {\n    \"model\": \"hr.employee\",\n    \"method\": \"web_read\",\n    \"args\": [\n      [\n        {{ $json.id }}\n      ]\n    ],\n    \"kwargs\": {\n      \"context\": {\n        \"lang\": \"en_US\",\n        \"tz\": \"Asia/Bangkok\",\n        \"allowed_company_ids\": [\n          1\n        ],\n        \"bin_size\": true,\n        \"params\": {\n          \"action\": \"employees\",\n          \"actionStack\": [\n            {\n              \"action\": \"employees\"\n            }\n          ]\n        },\n        \"chat_icon\": true\n      },\n      \"specification\": {\n        \"active\": {},\n        \"user_id\": {\n          \"fields\": {\n            \"display_name\": {}\n          }\n        },\n\n        \"work_email\": {}\n      }\n    }\n  }\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "executeOnce": true,
      "typeVersion": 4.2,
      "alwaysOutputData": false
    },
    {
      "id": "274c6f67-bfd6-4c2d-8ff5-a48dda3ed130",
      "name": "Step4: Get Employee Resignation in Odoo 18",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -224,
        912
      ],
      "parameters": {
        "url": "={{ $node['Step3: Set Variables'].json.web_search_read_api}}",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"id\": 6,\n  \"jsonrpc\": \"2.0\",\n  \"method\": \"call\",\n  \"params\": {\n    \"model\": \"hr.resignation\",\n    \"method\": \"web_search_read\",\n    \"args\": [],\n    \"kwargs\": {\n      \"specification\": {\n        \"employee_id\": {\n          \"fields\": {\n            \"display_name\": {}\n          }\n        },\n        \"department_id\": {\n          \"fields\": {\n            \"display_name\": {}\n          }\n        },\n        \"employee_contract\": {},\n        \"joined_date\": {},\n        \"expected_revealing_date\": {},\n        \"approved_revealing_date\": {},\n        \"resignation_type\": {},\n        \"notice_period\": {},\n        \"state\": {}\n      },\n      \"offset\": 0,\n      \"order\": \"\",\n      \"limit\": {{ $node['Step3: Set Variables'].json.limit }},\n      \"context\": {\n        \"lang\": \"en_US\",\n        \"tz\": \"Asia/Bangkok\",\n        \"allowed_company_ids\": [\n          1\n        ],\n        \"bin_size\": true,\n        \"params\": {\n          \"action\": \"resignation\",\n          \"actionStack\": [\n            {\n              \"action\": \"resignation\"\n            }\n          ]\n        },\n        \"current_company_id\": 1\n      },\n      \"count_limit\": 10001,\n      \"domain\": [\n        [\n          \"state\",\n          \"in\",\n          [\n            \"draft\",\n            \"confirm\",\n            \"manager_approved\",\n            \"handed_over\",\n            \"cancel\"\n          ]\n        ]\n      ]\n    }\n  }\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "executeOnce": true,
      "typeVersion": 4.2,
      "alwaysOutputData": false
    },
    {
      "id": "ece600ac-63a2-4eef-9d6d-649110803be1",
      "name": "Step10: Handle work_email",
      "type": "n8n-nodes-base.code",
      "position": [
        1104,
        688
      ],
      "parameters": {
        "jsCode": "const inputData = $input.all();\nconst work_email = inputData[0].json.result[0].work_email.split('@')[0];\nconst username = work_email.split('.')[0];\nreturn {work_email, username};\n"
      },
      "executeOnce": false,
      "typeVersion": 2,
      "alwaysOutputData": true
    },
    {
      "id": "d39321ea-115d-4351-b8c0-4302668a3457",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1328,
        368
      ],
      "parameters": {
        "width": 800,
        "height": 1056,
        "content": "## Automatically lock Redmine, Gitlab accounts for employees after their last shift\nThis workflow is designed for IT Ops, HR, and Security teams automating employee offboarding. Zero manual work: Disable access to Redmine, GitLab, and more- right after their last day. Boost security, cut risks, and stay compliant.\n\n### \ud83d\udccc The Problem It Solves\nOffboarding is messy and slow:\n- HR flags ending contracts.\n- IT hunts down accounts manually (Redmine, GitLab, etc.).\n- Misses happen, risks linger.\n\nThis n8n workflow queries Odoo 18 daily, spots offboardees, and locks accounts automatically.\n\n### \ud83d\udccc What It Does\n- **Triggers** daily (e.g., 5 PM weekdays).\n- **Queries** Odoo 18 for employees ending today.\n- **Filters** active users needing offboarding.\n- **Checks & Locks** Redmine accounts via API.\n- **Checks & Revokes** GitLab access via API.\n- **Notifies** via Slack/Teams/email with summary.\n- **Handles Errors**: Retries failures, logs issues.\n\n### \ud83d\udccc Quick setup\n1. Odoo 18 API (read employee end dates/last shifts).\n2. Redmine Admin API key.\n3. GitLab Admin token (for locking users).\n4. Slack/Teams webhook or SMTP for alerts.\n5. Cron schedule (e.g., daily 5 PM weekdays, skip weekends).\n\n### \ud83d\udccc Customize It\n- **Add Systems**: Jira, Confluence, LDAP\u2014easy toggles.\n- **Notification**: Full reports or alerts-only.\n- **Error Rules**: Retries, escalations.\n- **Audit Logs**: Save to DB, S3, Sheets, or dashboard.\n\n### \ud83d\udccc Results\n100% automated: Accounts locked on exit day. No orphans, no workload, full compliance.\n\n### \ud83d\udccc Workflow in Action\n1. Schedule trigger fires.\n2. Pull Odoo offboardees.\n3. API checks & disables Redmine/GitLab.\n4. Logs + summary notification."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "c77edf40-edd5-45ae-bd93-ee3796cb3c58",
  "connections": {
    "END": {
      "main": [
        []
      ]
    },
    "Code": {
      "main": [
        [
          {
            "node": "Step19: Get user information in Gitlab",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Step3: Set Variables": {
      "main": [
        [
          {
            "node": "Step4: Get Employee Resignation in Odoo 18",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Step8: Loop Over Items": {
      "main": [
        [],
        [
          {
            "node": "Step9: Get employee information in Odoo 18",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Step1: Schedule Trigger": {
      "main": [
        [
          {
            "node": "Step2: Handle get today",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Step2: Handle get today": {
      "main": [
        [
          {
            "node": "Step3: Set Variables",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Step10: Handle work_email": {
      "main": [
        [
          {
            "node": "Step11: Get user info in RM6",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Step16: Get memberships_id": {
      "main": [
        [
          {
            "node": "Step17: Loop Over memberships_id",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Step11: Get user info in RM6": {
      "main": [
        [
          {
            "node": "Step12:  Check if there is a record or not?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Step23: Block a user in Gitlab": {
      "main": [
        [
          {
            "node": "Step8: Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Step28: Block a user in Gitlab": {
      "main": [
        [
          {
            "node": "Step8: Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Step17: Loop Over memberships_id": {
      "main": [
        [
          {
            "node": "Code",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Step18: Delete membership in project on RM 6",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Step7: If hasRecords is empty==> true": {
      "main": [
        [
          {
            "node": "END1",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Step8: Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Step19: Get user information in Gitlab": {
      "main": [
        [
          {
            "node": "Step20:  Check if there is a record = true",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Step24: Get user information in Gitlab": {
      "main": [
        [
          {
            "node": "Step25:  Check if there is a record = true",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Step6: Check if there is a valid record.": {
      "main": [
        [
          {
            "node": "Step7: If hasRecords is empty==> true",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Step20:  Check if there is a record = true": {
      "main": [
        [
          {
            "node": "Step21: Check if the user is not blocked = true",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Step8: Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Step25:  Check if there is a record = true": {
      "main": [
        [
          {
            "node": "Step26: Check if the user is not blocked = true",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Step8: Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Step4: Get Employee Resignation in Odoo 18": {
      "main": [
        [
          {
            "node": "Step5: If total_count is not equal to 0 = true",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Step9: Get employee information in Odoo 18": {
      "main": [
        [
          {
            "node": "Step10: Handle work_email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Step12:  Check if there is a record or not?": {
      "main": [
        [
          {
            "node": "Step13: Update the user's status to \"locked\" on RM6",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Step24: Get user information in Gitlab",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Step15: Get membership list of user in RM 6": {
      "main": [
        [
          {
            "node": "Step16: Get memberships_id",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Step18: Delete membership in project on RM 6": {
      "main": [
        [
          {
            "node": "Step17: Loop Over memberships_id",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Step5: If total_count is not equal to 0 = true": {
      "main": [
        [
          {
            "node": "Step6: Check if there is a valid record.",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "END",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Step14: Remove the user from all groups in RM 6": {
      "main": [
        [
          {
            "node": "Step15: Get membership list of user in RM 6",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Step21: Check if the user is not blocked = true": {
      "main": [
        [
          {
            "node": "Step22: Check if the user is not deactivate = true",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Step8: Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Step26: Check if the user is not blocked = true": {
      "main": [
        [
          {
            "node": "Step27: Check if the user is not deactivate = true",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Step8: Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Step22: Check if the user is not deactivate = true": {
      "main": [
        [
          {
            "node": "Step23: Block a user in Gitlab",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Step8: Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Step27: Check if the user is not deactivate = true": {
      "main": [
        [
          {
            "node": "Step28: Block a user in Gitlab",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Step8: Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Step13: Update the user's status to \"locked\" on RM6": {
      "main": [
        [
          {
            "node": "Step14: Remove the user from all groups in RM 6",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

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

About this workflow

IT Ops, HR, and Security teams automating employee offboarding. Zero manual work: Disable access to Redmine, GitLab, and more- right after their last day. Boost security, cut risks, and stay compliant.

Source: https://n8n.io/workflows/11941/ — original creator credit. Request a take-down →

More Web Scraping workflows → · Browse all categories →

Related workflows

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

Web Scraping

Xiaobot Article Harvester v2. Uses httpRequest, readWriteFile, executeCommand. Event-driven trigger; 16 nodes.

HTTP Request, Read Write File, Execute Command
Web Scraping

&gt; Watch the full Youtube Video Tutorial [](https://youtu.be/Y-wUr2-UYZk)

Data Table, HTTP Request, Google Sheets +1
Web Scraping

As n8n instances scale, teams often lose track of sub-workflows—who uses them, where they are referenced, and whether they can be safely updated. This leads to inefficiencies like unnecessary copies o

HTTP Request, n8n, N8N Trigger +1
Web Scraping

This workflow is an improvement of this workflow by Greg Brzezinka.

HTTP Request, Email Send, XML +1
Web Scraping

N8N-Workflow-Github-Manager. Uses github, httpRequest, n8n. Scheduled trigger; 38 nodes.

GitHub, HTTP Request, n8n