DIGIPIN の生成と復号化を行う
中級
これはEngineering分野の自動化ワークフローで、12個のノードを含みます。主にCode, Switch, Webhook, RespondToWebhookなどのノードを使用。 INDIA 向けの高精細位置マッピングを目のとした、オフライン DIGIPIN マイクロサービス API を作成
前提条件
- •HTTP Webhookエンドポイント(n8nが自動生成)
カテゴリー
ワークフロープレビュー
ノード接続関係を可視化、ズームとパンをサポート
ワークフローをエクスポート
以下の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": "エンコードWebhook",
"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": "デコードWebhook",
"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通知)
CSVからJSONへの変換ツール(エラーハンドリングとSlack通知機能付き)
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のデプロイメント
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 デプロイ
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で表示 →
このワークフローを共有