AutomationFlowsSlack & Telegram › Batch Create Encrypted Payroll PDFs

Batch Create Encrypted Payroll PDFs

Original n8n title: 批量建立加密薪資單

批量建立加密薪資單. Uses httpRequest, googleDrive, googleSheets, discord. Event-driven trigger; 14 nodes.

Event trigger★★★★☆ complexity14 nodesHTTP RequestGoogle DriveGoogle SheetsDiscord
Slack & Telegram Trigger: Event Nodes: 14 Complexity: ★★★★☆ Added:

This workflow follows the Discord → HTTP Request recipe pattern — see all workflows that pair these two integrations.

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
{
  "name": "\u6279\u91cf\u5efa\u7acb\u52a0\u5bc6\u85aa\u8cc7\u55ae",
  "nodes": [
    {
      "parameters": {},
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        -336,
        -288
      ],
      "id": "155340d2-c9ab-4a4a-8a48-ed48836daac9",
      "name": "When clicking \u2018Execute workflow\u2019"
    },
    {
      "parameters": {
        "options": {}
      },
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        192,
        -288
      ],
      "id": "05409cd6-ae7b-4cab-a61b-6a77252528f4",
      "name": "Loop Over Items"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://docs.googleapis.com/v1/documents/{{ $('\u5f9e\u6a21\u677f\u8907\u88fd\u65b0\u7684 Doc').first().json.id }}:batchUpdate",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "googleDocsOAuth2Api",
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "requests",
              "value": "={{ $json.data }}"
            }
          ]
        },
        "options": {}
      },
      "id": "b9f5c918-e803-4e46-8ebf-ccad743978a6",
      "name": "Replace data in Google Doc",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        944,
        -272
      ],
      "typeVersion": 4.2,
      "credentials": {
        "googleDocsOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "download",
        "fileId": {
          "__rl": true,
          "value": "={{ $('\u5f9e\u6a21\u677f\u8907\u88fd\u65b0\u7684 Doc').item.json.id }}",
          "mode": "id"
        },
        "options": {
          "googleFileConversion": {
            "conversion": {
              "docsToFormat": "application/pdf"
            }
          }
        }
      },
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        1120,
        -272
      ],
      "id": "7fa46966-6dcf-4be5-8ae3-ff2b748907e8",
      "name": "\u4e0b\u8f09\u4e26\u8f49\u6210 PDF",
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "ae84fd5a-483b-4296-a17e-366eea5939a5",
              "name": "current_year_month",
              "value": "={{ $now.extract('year') - 1911 }}.{{ $now.format('MM') }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -176,
        -288
      ],
      "id": "921679f8-26ef-4c80-a59c-a7a17ebf585e",
      "name": "\u53d6\u5f97\u5e74\u6708"
    },
    {
      "parameters": {
        "documentId": {
          "__rl": true,
          "value": "https://docs.google.com/spreadsheets/d/1_rzBaHawoW8RNehQLyJ12j3pHfZfB5TmPjPHOPaoMQA/edit?gid=0#gid=0",
          "mode": "url"
        },
        "sheetName": {
          "__rl": true,
          "value": "gid=0",
          "mode": "list",
          "cachedResultName": "\u5de5\u4f5c\u88681",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1_rzBaHawoW8RNehQLyJ12j3pHfZfB5TmPjPHOPaoMQA/edit#gid=0"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7,
      "position": [
        -16,
        -288
      ],
      "id": "021ae9ad-b630-4c50-bb61-930049281816",
      "name": "\u8b80\u53d6\u54e1\u5de5\u8cc7\u6599",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "content": "## \u5efa\u7acb\u52a0\u5bc6\u85aa\u8cc7\u55ae",
        "height": 208,
        "width": 1408
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        368,
        -320
      ],
      "typeVersion": 1,
      "id": "1c9b79b0-6bd5-458d-86eb-c7b4163dfde4",
      "name": "Sticky Note2"
    },
    {
      "parameters": {
        "authentication": "webhook",
        "content": "PDF\u5efa\u7acb\u5b8c\u7562",
        "options": {
          "username": "\u85aa\u8cc7\u55ae\u5c0f\u52a9\u624b",
          "wait": true
        }
      },
      "type": "n8n-nodes-base.discord",
      "typeVersion": 2,
      "position": [
        416,
        -512
      ],
      "id": "fbd5734c-6b1b-4067-95a2-30ff0c655bbf",
      "name": "Discord \u901a\u77e5",
      "credentials": {
        "discordWebhookApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const data = [];\nconst allItems = $('Loop Over Items').all();\n\nallItems.forEach((item) => {\n  Object.keys(item.json).forEach((bodyProperty) => {\n    data.push({\n      key: bodyProperty,\n      value: item.json[bodyProperty],\n    });\n  });\n});\n\n// \u52a0\u4e0a\u5e74\u6708\ndata.push({\n  key: \"current_year_month\",\n  value: $('\u53d6\u5f97\u5e74\u6708').item.json.current_year_month\n})\n\nreturn {\n  webhook_data: data,\n  pairedItem: 0,\n};"
      },
      "id": "a280da65-4211-415d-85d8-024b2264324b",
      "name": "\u5efa\u7acb\u5c0d\u7167\u8868",
      "type": "n8n-nodes-base.code",
      "position": [
        592,
        -272
      ],
      "typeVersion": 2
    },
    {
      "parameters": {
        "jsCode": "const result = [];\n\n$('\u5efa\u7acb\u5c0d\u7167\u8868').all().map((item) => {\n  item.json.webhook_data.map((data) => {\n    if (\"submittedAt\" !== data.key && \"formMode\" !== data.key) {\n      result.push({\n        \"replaceAllText\": {\n            \"containsText\": {\n              \"text\": `{{${data.key}}}`, \n              \"matchCase\": true\n            },\n            \"replaceText\": `${data.value}`\n        },\n      });\n    }\n  });\n})\n\nreturn {\n  data: result,\n  pairedItem: 0,\n};"
      },
      "id": "24a3ddc4-4f58-4e79-a9fe-93ead64e674f",
      "name": "\u5efa\u7acb API \u6240\u9700\u683c\u5f0f",
      "type": "n8n-nodes-base.code",
      "position": [
        768,
        -272
      ],
      "typeVersion": 2
    },
    {
      "parameters": {
        "jsCode": "const muhammara = require(\"muhammara\");\nconst { PDFWStreamForBuffer, PDFRStreamForBuffer } = require(\"muhammara\");\n\nfunction encryptPDF(source, password) {\n  return new Promise(function (resolve, reject) {\n    try {\n      let input = new PDFRStreamForBuffer(source);\n      let output = new PDFWStreamForBuffer();\n      muhammara.recrypt(input, output, {\n          password: password,\n          userPassword: password,\n          ownerPassword: password,\n          userProtectionFlag: 4\n      });\n      resolve(output.buffer);\n    } catch (e) {\n      reject(e);\n    }\n  });\n}\n\n// 1. \u7372\u53d6\u524d\u4e00\u500b\u7bc0\u9ede\u7684\u4e8c\u9032\u4f4d\u8cc7\u6599\nconst inputBuffer = await this.helpers.getBinaryDataBuffer(0, 'data');\n\n// 2. \u52a0\u5bc6\nconst encryptedPDF = await encryptPDF(inputBuffer, $('Loop Over Items').first().json['\u8eab\u5206\u8b49\u5b57\u865f'])\n\n// 3. \u5c07\u7d50\u679c\u56de\u50b3\u7d66 n8n\nconst filename = `${$('Loop Over Items').first().json['\u54e1\u5de5\u7de8\u865f']}_${$('\u53d6\u5f97\u5e74\u6708').first().json.current_year_month}.pdf`\nreturn [\n  {\n    binary: {\n      data: {\n        data: encryptedPDF.toString('base64'),\n        mimeType: 'application/pdf',\n        fileName: filename,\n        fileExtension: 'pdf'\n      }\n    }\n  }\n];\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1296,
        -272
      ],
      "id": "a8978e42-d9fc-4ed2-a930-50c4de01c1ac",
      "name": "\u52a0\u5bc6 PDF"
    },
    {
      "parameters": {
        "inputDataFieldName": "=data",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "folderId": {
          "__rl": true,
          "value": "1yVM9-7dnVoUOfEmDMud1YVX7b7GAhy5L",
          "mode": "list",
          "cachedResultName": "n8n\u6e2c\u8a66",
          "cachedResultUrl": "https://drive.google.com/drive/folders/1yVM9-7dnVoUOfEmDMud1YVX7b7GAhy5L"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        1472,
        -272
      ],
      "id": "1f893b0b-87af-4735-b5c1-5e73a4a39b2a",
      "name": "\u4e0a\u50b3\u52a0\u5bc6\u5f8c\u7684 PDF",
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "copy",
        "fileId": {
          "__rl": true,
          "value": "1HShlA0nnLMacCtel5W6JAOUqx1GdySEgFuGv4f5kb5M",
          "mode": "list",
          "cachedResultName": "\u85aa\u8cc7\u660e\u7d30\u6a21\u677f",
          "cachedResultUrl": "https://docs.google.com/document/d/1HShlA0nnLMacCtel5W6JAOUqx1GdySEgFuGv4f5kb5M/edit?usp=drivesdk"
        },
        "name": "={{ $json['\u54e1\u5de5\u7de8\u865f'] }}_{{ $now.extract('year') - 1911 }}.{{ $now.format('MM') }}_{{ $json['\u8eab\u5206\u8b49\u5b57\u865f'] }}",
        "options": {}
      },
      "id": "ecdc29f6-165c-42e7-97b0-beb33a0b1b8f",
      "name": "\u5f9e\u6a21\u677f\u8907\u88fd\u65b0\u7684 Doc",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        416,
        -272
      ],
      "typeVersion": 3,
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "deleteFile",
        "fileId": {
          "__rl": true,
          "value": "={{ $('\u5f9e\u6a21\u677f\u8907\u88fd\u65b0\u7684 Doc').item.json.id }}",
          "mode": "id"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        1648,
        -272
      ],
      "id": "7a877a88-3f61-463d-91fd-f278b8dc2ee5",
      "name": "\u79fb\u9664 Doc",
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "When clicking \u2018Execute workflow\u2019": {
      "main": [
        [
          {
            "node": "\u53d6\u5f97\u5e74\u6708",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [
          {
            "node": "Discord \u901a\u77e5",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "\u5f9e\u6a21\u677f\u8907\u88fd\u65b0\u7684 Doc",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Replace data in Google Doc": {
      "main": [
        [
          {
            "node": "\u4e0b\u8f09\u4e26\u8f49\u6210 PDF",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u4e0b\u8f09\u4e26\u8f49\u6210 PDF": {
      "main": [
        [
          {
            "node": "\u52a0\u5bc6 PDF",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u53d6\u5f97\u5e74\u6708": {
      "main": [
        [
          {
            "node": "\u8b80\u53d6\u54e1\u5de5\u8cc7\u6599",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u8b80\u53d6\u54e1\u5de5\u8cc7\u6599": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Discord \u901a\u77e5": {
      "main": [
        []
      ]
    },
    "\u5efa\u7acb\u5c0d\u7167\u8868": {
      "main": [
        [
          {
            "node": "\u5efa\u7acb API \u6240\u9700\u683c\u5f0f",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u5efa\u7acb API \u6240\u9700\u683c\u5f0f": {
      "main": [
        [
          {
            "node": "Replace data in Google Doc",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u52a0\u5bc6 PDF": {
      "main": [
        [
          {
            "node": "\u4e0a\u50b3\u52a0\u5bc6\u5f8c\u7684 PDF",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u4e0a\u50b3\u52a0\u5bc6\u5f8c\u7684 PDF": {
      "main": [
        [
          {
            "node": "\u79fb\u9664 Doc",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u5f9e\u6a21\u677f\u8907\u88fd\u65b0\u7684 Doc": {
      "main": [
        [
          {
            "node": "\u5efa\u7acb\u5c0d\u7167\u8868",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u79fb\u9664 Doc": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "availableInMCP": false
  },
  "versionId": "7eb0c014-71cb-4140-9d79-19fc44b19a44",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "id": "xGjdkGqc3SAQX5Lh",
  "tags": []
}

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

批量建立加密薪資單. Uses httpRequest, googleDrive, googleSheets, discord. Event-driven trigger; 14 nodes.

Source: https://github.com/CK642509/n8n-workflows/blob/782d3533f66813882acf3db166fb86d483cde352/workflows/1_Batch_Encrypted_Payroll_Generator.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

Type in Slack. Walk away. Get a professional PDF report and a structured Excel fix sheet delivered to Google Drive and posted back in your Slack thread — fully automated, zero manual work.

Compression, HTTP Request, Google Drive +3
Slack & Telegram

This template monitors Google Drive folder for new files, extracts text from PDFs, images, text files, CSVs, and Google Docs., reads images with meta/llama-3.2-11b-vision-instruct, structures the resu

Google Drive Trigger, Google Drive, Google Docs +3
Slack & Telegram

Automatically transform any website URL into a complete portfolio entry with professional screenshots and AI-generated Upwork project descriptions. Freelancers building their Upwork/portfolio from pas

HTTP Request, Google Drive, Google Sheets +2
Slack & Telegram

Expenses Tracker (video). Uses httpRequest, splitInBatches, googleSheets, googleDrive. Event-driven trigger; 21 nodes.

HTTP Request, Google Sheets, Google Drive +2
Slack & Telegram

AI-Powered Short-Form Video Generator with OpenAI, Flux, Kling, and ElevenLabs and upload to all social networks. Uses httpRequest, openAi, stickyNote, googleDrive. Scheduled trigger; 51 nodes.

HTTP Request, OpenAI, Google Drive +4