DIGIPIN 생성 및 디코딩
중급
이것은Engineering분야의자동화 워크플로우로, 12개의 노드를 포함합니다.주로 Code, Switch, Webhook, RespondToWebhook 등의 노드를 사용하며. 인도 정확한 위치 맵핑을 위한 오프라인 DIGIPIN 미니서비스 API를 만듭니다.
사전 요구사항
- •HTTP Webhook 엔드포인트(n8n이 자동으로 생성)
사용된 노드 (12)
카테고리
워크플로우 미리보기
노드 연결 관계를 시각적으로 표시하며, 확대/축소 및 이동을 지원합니다
워크플로우 내보내기
다음 JSON 구성을 복사하여 n8n에 가져오면 이 워크플로우를 사용할 수 있습니다
{
"id": "OcAQrF91wzWH3rOw",
"meta": {
"instanceId": "97cf5417030d41ab2642f97a3d99e6a9359587b310a5d986917e2d084e12ce17"
},
"name": "Generate and Decode DIGIPIN",
"tags": [],
"nodes": [
{
"id": "882aa556-8ea2-4582-8230-7b0e13ad2fd1",
"name": "Webhook 응답 - 성공",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
340,
-140
],
"parameters": {
"options": {
"responseCode": 200
},
"respondWith": "json",
"responseBody": "={\n \"status\": \"Success\",\n \"lat\": \"{{ $json.query.lat }}\",\n \"lon\": \"{{ $json.query.lon }}\",\n \"digipin\": \"{{ $json.digipin }}\"\n} "
},
"typeVersion": 1.4
},
{
"id": "368240b0-cecf-46e7-9509-bfcb1afe7610",
"name": "Webhook 응답 - 오류",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
340,
60
],
"parameters": {
"options": {
"responseCode": 422
},
"respondWith": "json",
"responseBody": "={\n \"status\": \"Failed\",\n \"lat\": \"{{ $json.query.lat }}\",\n \"lon\": \"{{ $json.query.lon }}\",\n \"error\": \"{{ $json.error }}\"\n} "
},
"typeVersion": 1.4
},
{
"id": "b6c70cd6-3d5f-4215-989c-8a5e6a896564",
"name": "스위치 - 성공 확인",
"type": "n8n-nodes-base.switch",
"position": [
120,
-40
],
"parameters": {
"rules": {
"values": [
{
"outputKey": "digipin",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "3656e246-523a-4611-b563-8e66ae078d67",
"operator": {
"type": "string",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json.digipin }}",
"rightValue": ""
}
]
},
"renameOutput": true
},
{
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "9b5ef11d-7833-41c3-8611-56cf11df2dcc",
"operator": {
"type": "string",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json.error }}",
"rightValue": ""
}
]
}
}
]
},
"options": {}
},
"typeVersion": 3.2
},
{
"id": "3a7dc7a2-9d19-467c-b651-143187d852d9",
"name": "DIGIPIN_생성_코드",
"type": "n8n-nodes-base.code",
"position": [
-100,
-40
],
"parameters": {
"jsCode": "// --- DIGIPIN Generation Logic ---\n\n// Constants for DIGIPIN generation\nconst DIGIPIN_GRID = [\n ['F', 'C', '9', '8'],\n ['J', '3', '2', '7'],\n ['K', '4', '5', '6'],\n ['L', 'M', 'P', 'T']\n];\n\nconst BOUNDS = {\n minLat: 2.5,\n maxLat: 38.5,\n minLon: 63.5,\n maxLon: 99.5\n};\n\n/**\n * Encodes latitude and longitude into a DIGIPIN.\n * @param {number} lat The latitude.\n * @param {number} lon The longitude.\n * @returns {string} The generated DIGIPIN.\n * @throws {Error} If coordinates are out of bounds.\n */\nfunction generateDigiPin(lat, lon) {\n if (lat < BOUNDS.minLat || lat > BOUNDS.maxLat || lon < BOUNDS.minLon || lon > BOUNDS.maxLon) {\n throw new Error(`Coordinates (Lat: ${lat}, Lon: ${lon}) are out of the valid range.`);\n }\n\n let minLat = BOUNDS.minLat, maxLat = BOUNDS.maxLat;\n let minLon = BOUNDS.minLon, maxLon = BOUNDS.maxLon;\n let digiPin = '';\n\n for (let level = 1; level <= 10; level++) {\n const latDiv = (maxLat - minLat) / 4;\n const lonDiv = (maxLon - minLon) / 4;\n let row = 3 - Math.floor((lat - minLat) / latDiv);\n let col = Math.floor((lon - minLon) / lonDiv);\n row = Math.max(0, Math.min(row, 3));\n col = Math.max(0, Math.min(col, 3));\n digiPin += DIGIPIN_GRID[row][col];\n if (level === 3 || level === 6) {\n digiPin += '-';\n }\n maxLat = minLat + latDiv * (4 - row);\n minLat = minLat + latDiv * (3 - row);\n minLon = minLon + lonDiv * col;\n maxLon = minLon + lonDiv;\n }\n return digiPin;\n}\n\n\n// --- n8n Item Processing ---\n// Loop through each input item provided to the node.\nfor (const item of items) {\n try {\n // Get latitude and longitude from the input item's JSON data.\n // Assumes the previous node provides these fields.\n const lat = $input.first().json.query.lat;\n const lon = $input.first().json.query.lon;\n\n if (lat === undefined || lon === undefined) {\n throw new Error(\"Input item is missing 'latitude' or 'longitude' field.\");\n }\n\n // Generate the DIGIPIN.\n const digipinResult = generateDigiPin(lat, lon);\n\n // Add the result to a new field called 'digipin' in the item's JSON.\n item.json.digipin = digipinResult;\n\n } catch (error) {\n // If an error occurs, add an 'error' field to the item.\n // This helps with debugging in the n8n UI.\n item.json.error = error.message;\n }\n}\n\n// Return all the modified items to the next node in the workflow.\nreturn items;\n"
},
"typeVersion": 2
},
{
"id": "33aab4da-4b77-44fa-85c4-0ed165b416d3",
"name": "DIGIPIN_디코드_코드",
"type": "n8n-nodes-base.code",
"position": [
-100,
420
],
"parameters": {
"jsCode": "/**\n * Decodes a DIGIPIN into latitude and longitude coordinates.\n * @param {string} digiPin The DIGIPIN to decode.\n * @returns {{latitude: string, longitude: string}} An object containing the latitude and longitude,\n * each formatted to 6 decimal places.\n * @throws {Error} If the DIGIPIN is invalid or contains invalid characters.\n */\nconst DIGIPIN_GRID = [\n ['F', 'C', '9', '8'],\n ['J', '3', '2', '7'],\n ['K', '4', '5', '6'],\n ['L', 'M', 'P', 'T']\n];\n\n\nconst BOUNDS = {\n minLat: 2.5,\n maxLat: 38.5,\n minLon: 63.5,\n maxLon: 99.5\n};\nfunction getLatLngFromDigiPin(digiPin) {\n const pin = digiPin.replace(/-/g, ''); // Remove hyphens for processing\n if (pin.length !== 10) throw new Error('Invalid DIGIPIN: Must be 10 characters long after removing hyphens.');\n\n let minLat = BOUNDS.minLat;\n let maxLat = BOUNDS.maxLat;\n let minLon = BOUNDS.minLon;\n let maxLon = BOUNDS.minLon; // Corrected initial value here, should be BOUNDS.minLon\n\n // Recalculate maxLon for accurate initial bounds\n // Based on the original DIGIPIN generation, it should cover the whole range initially.\n maxLon = BOUNDS.maxLon;\n\n\n for (let i = 0; i < 10; i++) {\n const char = pin[i];\n let found = false;\n let ri = -1, ci = -1;\n\n for (let r = 0; r < 4; r++) {\n for (let c = 0; c < 4; c++) {\n if (DIGIPIN_GRID[r][c] === char) {\n ri = r;\n ci = c;\n found = true;\n break;\n }\n }\n if (found) break;\n }\n\n if (!found) throw new Error(`Invalid character '${char}' in DIGIPIN.`);\n\n const latDiv = (maxLat - minLat) / 4;\n const lonDiv = (maxLon - minLon) / 4;\n\n const lat1 = maxLat - latDiv * (ri + 1);\n const lat2 = maxLat - latDiv * ri;\n const lon1 = minLon + lonDiv * ci;\n const lon2 = minLon + lonDiv * (ci + 1);\n\n minLat = lat1;\n maxLat = lat2;\n minLon = lon1;\n maxLon = lon2;\n }\n\n const centerLat = (minLat + maxLat) / 2;\n const centerLon = (minLon + maxLon) / 2;\n\n return {\n latitude: centerLat.toFixed(6),\n longitude: centerLon.toFixed(6)\n };\n}\n\n\nconst MY_DIGIPIN = $input.first().json.query.digipin; // <--- REPLACE THIS with your desired DIGIPIN\n\n// Ensure there's at least one item to process, or create a dummy one\nlet outputItems = [];\nif (items.length === 0) {\n // If no items come into the node, create a blank one to attach results to\n outputItems.push({ json: {} });\n} else {\n // If items exist, clone them to add results\n outputItems = JSON.parse(JSON.stringify(items));\n}\n\nfor (const item of outputItems) {\n try {\n const digipinToProcess = MY_DIGIPIN;\n\n if (!digipinToProcess) {\n throw new Error(\"No DIGIPIN specified for processing.\");\n }\n\n // Decode the DIGIPIN\n const decodedCoords = getLatLngFromDigiPin(digipinToProcess);\n\n // Add the result to new fields in the item's JSON\n item.json.processedDigipin = digipinToProcess; // Optional: To see which digipin was processed\n item.json.decodedLatitude = decodedCoords.latitude;\n item.json.decodedLongitude = decodedCoords.longitude;\n\n } catch (error) {\n // If an error occurs, add an 'error' field to the item.\n item.json.error = error.message;\n }\n}\n\n// Return all the modified items to the next node in the workflow.\nreturn outputItems;"
},
"typeVersion": 2
},
{
"id": "6da5b090-caf7-4a8b-a254-a90ac9b97610",
"name": "인코드_웹훅",
"type": "n8n-nodes-base.webhook",
"position": [
-320,
-40
],
"webhookId": "8f08f857-3a7e-4b46-97fb-7de6812e9204",
"parameters": {
"path": "generate-digipin",
"options": {},
"responseMode": "responseNode"
},
"typeVersion": 2
},
{
"id": "99a30d16-696a-4c2c-941d-7b66a6591d54",
"name": "디코드_웹훅",
"type": "n8n-nodes-base.webhook",
"position": [
-320,
420
],
"webhookId": "8f08f857-3a7e-4b46-97fb-7de6812e9204",
"parameters": {
"path": "decode-digipin",
"options": {},
"responseMode": "responseNode"
},
"typeVersion": 2
},
{
"id": "ab871baf-aae7-4060-83af-7794974dce18",
"name": "스위치 2 - 성공 확인1",
"type": "n8n-nodes-base.switch",
"position": [
120,
420
],
"parameters": {
"rules": {
"values": [
{
"outputKey": "coordinates",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "3656e246-523a-4611-b563-8e66ae078d67",
"operator": {
"type": "string",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json.decodedLatitude }}",
"rightValue": ""
}
]
},
"renameOutput": true
},
{
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "9b5ef11d-7833-41c3-8611-56cf11df2dcc",
"operator": {
"type": "string",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json.error }}",
"rightValue": ""
}
]
}
}
]
},
"options": {}
},
"typeVersion": 3.2
},
{
"id": "64409e6c-e4aa-41b2-abcf-a016e729ea37",
"name": "Webhook 응답 - 성공 2",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
340,
320
],
"parameters": {
"options": {
"responseCode": 200
},
"respondWith": "json",
"responseBody": "={\n \"status\": \"Success\",\n \"digipin\": \"{{ $json.query.digipin }}\",\n \"lat\": \"{{ $json.decodedLatitude }}\",\n \"lon\": \"{{ $json.decodedLongitude }}\"\n} "
},
"typeVersion": 1.4
},
{
"id": "d37184ce-7060-4d06-b039-dd8572e7d3e8",
"name": "Webhook 응답 - 오류 2",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
340,
520
],
"parameters": {
"options": {
"responseCode": 422
},
"respondWith": "json",
"responseBody": "={\n \"status\": \"Failed\",\n \"digipin\": \"{{ $json.query.digipin }}\",\n \"error\": \"{{ $json.error }}\"\n} "
},
"typeVersion": 1.4
},
{
"id": "8d745b4f-f993-4865-a96f-e3f1e28a0cc2",
"name": "스티키 노트",
"type": "n8n-nodes-base.stickyNote",
"position": [
660,
360
],
"parameters": {
"color": 4,
"width": 920,
"height": 320,
"content": "## Example usage \n\nGenerate a DIGIPIN:\n```\ncurl --request GET \\\n --url 'https://n8n.example.in/webhook/generate-digipin?lat=27.175063&lon=78.042169'\n```\n\nDecode a DIGIPIN:\n```\ncurl --request GET \\\n --url 'https://n8n.example.in/webhook/decode-digipin?digipin=32C-849-5CJ6'\n```"
},
"typeVersion": 1
},
{
"id": "3cb47a09-ce41-4d2d-a413-885510ebda96",
"name": "스티키 노트1",
"type": "n8n-nodes-base.stickyNote",
"position": [
660,
-160
],
"parameters": {
"width": 920,
"height": 440,
"content": "## DIGIPIN Generator and Decoder\n\nThis n8n workflow lets you **generate and decode DIGIPINs** using only JavaScript - no external APIs involved.\n\nDIGIPIN is India Post’s geolocation code system that encodes latitude and longitude into a 10-character alphanumeric string, like `32C-849-5CJ6`. It helps simplify precise location sharing across India.\n\n### 🔧 What it does\n- `/generate-digipin?lat=...&lon=...` → returns the DIGIPIN for given coordinates\n- `/decode-digipin?digipin=...` → returns the coordinates for a given DIGIPIN\n\nUseful for: check-in systems, last-mile delivery, digital address verification, or simple location sharing.\n\n### ⚙️ How to use\n- Add your own webhook URLs or run locally\n- Pass query parameters to trigger either route\n- Both encode/decode logic is handled inside Function nodes\n\nNo credentials, APIs, or setup required.\n"
},
"typeVersion": 1
}
],
"active": true,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "9226c009-d942-4f3c-b982-9f7dbb73d710",
"connections": {
"99a30d16-696a-4c2c-941d-7b66a6591d54": {
"main": [
[
{
"node": "33aab4da-4b77-44fa-85c4-0ed165b416d3",
"type": "main",
"index": 0
}
]
]
},
"6da5b090-caf7-4a8b-a254-a90ac9b97610": {
"main": [
[
{
"node": "3a7dc7a2-9d19-467c-b651-143187d852d9",
"type": "main",
"index": 0
}
]
]
},
"33aab4da-4b77-44fa-85c4-0ed165b416d3": {
"main": [
[
{
"node": "ab871baf-aae7-4060-83af-7794974dce18",
"type": "main",
"index": 0
}
]
]
},
"3a7dc7a2-9d19-467c-b651-143187d852d9": {
"main": [
[
{
"node": "b6c70cd6-3d5f-4215-989c-8a5e6a896564",
"type": "main",
"index": 0
}
]
]
},
"b6c70cd6-3d5f-4215-989c-8a5e6a896564": {
"main": [
[
{
"node": "882aa556-8ea2-4582-8230-7b0e13ad2fd1",
"type": "main",
"index": 0
}
],
[
{
"node": "368240b0-cecf-46e7-9509-bfcb1afe7610",
"type": "main",
"index": 0
}
]
]
},
"ab871baf-aae7-4060-83af-7794974dce18": {
"main": [
[
{
"node": "64409e6c-e4aa-41b2-abcf-a016e729ea37",
"type": "main",
"index": 0
}
],
[
{
"node": "d37184ce-7060-4d06-b039-dd8572e7d3e8",
"type": "main",
"index": 0
}
]
]
}
}
}자주 묻는 질문
이 워크플로우를 어떻게 사용하나요?
위의 JSON 구성 코드를 복사하여 n8n 인스턴스에서 새 워크플로우를 생성하고 "JSON에서 가져오기"를 선택한 후, 구성을 붙여넣고 필요에 따라 인증 설정을 수정하세요.
이 워크플로우는 어떤 시나리오에 적합한가요?
중급 - 엔지니어링
유료인가요?
이 워크플로우는 완전히 무료이며 직접 가져와 사용할 수 있습니다. 다만, 워크플로우에서 사용하는 타사 서비스(예: OpenAI API)는 사용자 직접 비용을 지불해야 할 수 있습니다.
관련 워크플로우 추천
CSV를 JSON으로 변환기 (에러 처리 및 Slack 알림)
에러 처리 및 Slack 알림 기능을 포함한 CSV에서 JSON 변환기
If
Set
Code
+
If
Set
Code
18 노드n8n Team
엔지니어링
WhatsApp Flows를 사용하여 종단加密된 보안 인터랙션 애플리케이션 생성
WhatsApp Flows에서 끝까지 암호화된 안전한 상호작용 애플리케이션을 만들기
Code
Switch
Webhook
+
Code
Switch
Webhook
12 노드Flavio Angeleu
엔지니어링
puq-docker-immich-deploy
Docker Immich, WHMCS/WISECP API 백엔드 배포
If
Set
Ssh
+
If
Set
Ssh
35 노드PUQcloud
엔지니어링
puq-docker-influxdb-deploy
Docker InfluxDB, WHMCS/WISECP API 백엔드 배포
If
Set
Ssh
+
If
Set
Ssh
33 노드PUQcloud
엔지니어링
puq-docker-minio-deploy
Docker MinIO, WHMCS/WISECP API 백엔드 배포
If
Set
Ssh
+
If
Set
Ssh
33 노드PUQcloud
엔지니어링
PUQ Docker NextCloud 배포
Docker NextCloud, WHMCS/WISECP API 백엔드 배포
If
Set
Ssh
+
If
Set
Ssh
44 노드PUQcloud
엔지니어링
워크플로우 정보
난이도
중급
노드 수12
카테고리1
노드 유형5
저자
Srinivasan KB
@srinivasankbProduct Manager in B2B SaaS product focused on CX management. Interested in building AI powered workflows that can automate or simplify the routine and complex tasks.
외부 링크
n8n.io에서 보기 →
이 워크플로우 공유