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 →
{
"id": "TrackingMorePolling01",
"name": "HFD TrackingMore Polling \u2192 JONI WhatsApp",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "hours",
"hoursInterval": 2
}
]
}
},
"id": "node-schedule",
"name": "Every 2 Hours",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
240,
300
]
},
{
"parameters": {
"method": "POST",
"url": "https://api.monday.com/v2",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "eyJhbGciOiJIUzI1NiJ9.eyJ0aWQiOjU1OTAyMjM2MiwiYWFpIjoxMSwidWlkIjo2Mzc3NjA5NywiaWFkIjoiMjAyNS0wOS0wN1QxNTowMToxNy4wMDBaIiwicGVyIjoibWU6d3JpdGUiLCJhY3RpZCI6MjQ1MzIyMjcsInJnbiI6ImV1YzEifQ.d86GOnxc-RhtZND7Q7LIoIg3ShFUW0xImLCVjRlzXHQ"
},
{
"name": "Content-Type",
"value": "application/json"
},
{
"name": "API-Version",
"value": "2023-10"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={{ JSON.stringify({ query: '{ boards(ids: [2131896795]) { items_page(limit: 200) { items { id name column_values { id text } } } } }' }) }}",
"options": {}
},
"id": "node-get-monday",
"name": "Get Monday Orders",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
460,
300
]
},
{
"parameters": {
"jsCode": "// Parse Monday board items \u2014 extract tracking, phone, postal code\nconst data = $input.first().json.data || {};\nconst items = data.boards?.[0]?.items_page?.items || [];\n\nconst orders = [];\n\nfor (const item of items) {\n const cols = {};\n (item.column_values || []).forEach(c => { cols[c.id] = (c.text || '').trim(); });\n\n const trackingNumber = cols['text__1'];\n if (!trackingNumber) continue;\n\n const rawPhone = cols['phone__1'];\n if (!rawPhone) continue;\n const phone = rawPhone.replace(/[^0-9]/g, '');\n if (phone.length < 9) continue;\n\n // Extract 7-digit Israeli postal code from any column\n let postalCode = '';\n for (const text of Object.values(cols)) {\n const m = text.match(/\\b\\d{7}\\b/);\n if (m) { postalCode = m[0]; break; }\n }\n\n orders.push({\n item_id: item.id,\n customer_name: item.name,\n tracking_number: trackingNumber,\n phone,\n postal_code: postalCode\n });\n}\n\nreturn orders.map(o => ({ json: o }));"
},
"id": "node-parse-orders",
"name": "Parse Orders",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
680,
300
]
},
{
"parameters": {
"method": "POST",
"url": "https://api.trackingmore.com/v4/trackings/create",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Tracking-Api-Key",
"value": "yocbwatn-q6cl-f3o2-gpdi-5n7qdsd2xh5b"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={{ JSON.stringify({ tracking_number: $json.tracking_number, courier_code: 'hfd', tracking_postal_code: $json.postal_code || undefined }) }}",
"options": {
"response": {
"response": {
"neverError": true
}
}
}
},
"id": "node-register-tracking",
"name": "Register on TrackingMore",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
900,
300
]
},
{
"parameters": {
"url": "=https://api.trackingmore.com/v4/trackings/hfd/{{ $('Parse Orders').item.json.tracking_number }}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Tracking-Api-Key",
"value": "yocbwatn-q6cl-f3o2-gpdi-5n7qdsd2xh5b"
}
]
},
"options": {
"response": {
"response": {
"neverError": true
}
}
}
},
"id": "node-get-status",
"name": "Get TrackingMore Status",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1120,
300
]
},
{
"parameters": {
"jsCode": "// Check if status changed; update static data\nconst staticData = $getWorkflowStaticData('global');\nconst order = $('Parse Orders').item.json;\nconst tracking = order.tracking_number;\n\nconst tmResponse = $input.first().json;\nconst trackInfo = tmResponse.data?.[0]?.track_info || {};\nconst currentStatus = trackInfo.latest_status?.status || '';\n\n// Only act on meaningful statuses\nconst KEY_STATUSES = ['InTransit', 'OutForDelivery', 'Delivered', 'Exception', 'AvailableForPickup', 'Undelivered'];\nif (!currentStatus || !KEY_STATUSES.includes(currentStatus)) return [];\n\nconst lastKnown = staticData[tracking] || null;\nif (currentStatus === lastKnown) return []; // No change\n\n// Save new status\nstaticData[tracking] = currentStatus;\n\nconst lastEvent = trackInfo.latest_event || {};\nconst eta = trackInfo.time_metrics?.estimated_delivery_date || {};\n\nreturn [{ json: {\n phone: order.phone,\n customer_name: order.customer_name,\n tracking_number: tracking,\n status: currentStatus,\n sub_status: trackInfo.latest_status?.sub_status || '',\n last_message: lastEvent.description || '',\n last_location: lastEvent.location || '',\n eta_from: eta.from || '',\n eta_to: eta.to || ''\n}}];"
},
"id": "node-check-status",
"name": "Status Changed?",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1340,
300
]
},
{
"parameters": {
"jsCode": "const { status, last_message, last_location, eta_from, eta_to, phone, tracking_number, customer_name } = $input.first().json;\n\nconst warNotice = '\u05d1\u05e2\u05e7\u05d1\u05d5\u05ea \u05de\u05d1\u05e6\u05e2 \u05e9\u05d0\u05d2\u05ea \u05d4\u05d0\u05e8\u05d9 \u05e6\u05e4\u05d5\u05d9\u05d9\u05dd \u05e2\u05d9\u05db\u05d5\u05d1\u05d9\u05dd \u05e7\u05dc\u05d9\u05dd \u05d1\u05de\u05e9\u05dc\u05d5\u05d7\u05d9\u05dd, \u05d0\u05e0\u05d7\u05e0\u05d5 \u05e2\u05dd \u05d9\u05d3 \u05e2\u05dc \u05d4\u05d3\u05d5\u05e4\u05e7 \u05d5\u05d1\u05d5\u05d3\u05e7\u05d9\u05dd \u05de\u05d4 \u05e2\u05dd \u05d4\u05de\u05e9\u05dc\u05d5\u05d7 \u05e9\u05dc\u05da \u05d1\u05db\u05dc \u05d9\u05d5\u05dd \u05d5\u05d9\u05d5\u05dd.\\n\u05e0\u05d0 \u05dc\u05d4\u05d9\u05d5\u05ea \u05e1\u05d1\u05dc\u05e0\u05d9\u05d9\u05dd \ud83d\ude4f';\n\nconst statusMap = {\n InTransit: { headline: '\u05d1\u05d3\u05e8\u05db\u05d4 \u05dc\u05d0\u05e8\u05e5! \u2708\ufe0f', detail: '\u05d6\u05de\u05e0\u05d9 \u05d4\u05d0\u05e1\u05e4\u05e7\u05d4 \u05d4\u05dd 7-21 \u05d9\u05de\u05d9 \u05e2\u05e1\u05e7\u05d9\u05dd, \u05d0\u05e0\u05d5 \u05e0\u05e2\u05d3\u05db\u05df \u05d0\u05d5\u05ea\u05db\u05dd \u05d1\u05db\u05dc \u05e9\u05dc\u05d1 \u05d5\u05e9\u05dc\u05d1.' },\n OutForDelivery: { headline: '\u05d9\u05d5\u05e6\u05d0\u05ea \u05dc\u05de\u05e1\u05d9\u05e8\u05d4 \u05e2\u05db\u05e9\u05d9\u05d5! \ud83d\ude9a', detail: '\u05d4\u05e9\u05dc\u05d9\u05d7 \u05d1\u05d3\u05e8\u05db\u05d5 \u05d0\u05dc\u05d9\u05da \u05d4\u05d9\u05d5\u05dd \u2014 \u05e9\u05de\u05d5\u05e8 \u05e2\u05dc \u05d4\u05d8\u05dc\u05e4\u05d5\u05df \u05e4\u05ea\u05d5\u05d7!' },\n Delivered: { headline: '\u05e0\u05de\u05e1\u05e8\u05d4! \ud83c\udf89', detail: '\u05d4\u05d4\u05d6\u05de\u05e0\u05d4 \u05e9\u05dc\u05da \u05e0\u05de\u05e1\u05e8\u05d4 \u05d1\u05d4\u05e6\u05dc\u05d7\u05d4!\\n\u05e0\u05e9\u05de\u05d7 \u05dc\u05e9\u05de\u05d5\u05e2 \u05e9\u05d4\u05d2\u05d9\u05e2\u05d4 \u2014 \u05ea\u05d4\u05e0\u05d4 \u05de\u05d4\u05de\u05d5\u05e6\u05e8! \u26bd' },\n Exception: { headline: '\u05d1\u05e2\u05d9\u05d4 \u05d1\u05de\u05e9\u05dc\u05d5\u05d7 \u26a0\ufe0f', detail: '\u05d0\u05e0\u05d7\u05e0\u05d5 \u05d1\u05d5\u05d3\u05e7\u05d9\u05dd \u05de\u05d4 \u05e7\u05d5\u05e8\u05d4 \u05d5\u05e0\u05d7\u05d6\u05d5\u05e8 \u05d0\u05dc\u05d9\u05da \u05d1\u05d4\u05e7\u05d3\u05dd.' },\n AvailableForPickup: { headline: '\u05de\u05d7\u05db\u05d4 \u05dc\u05da \u05d1\u05e0\u05e7\u05d5\u05d3\u05ea \u05d7\u05dc\u05d5\u05e7\u05d4 \ud83d\udccd', detail: '\u05d4\u05d7\u05d1\u05d9\u05dc\u05d4 \u05e9\u05dc\u05da \u05de\u05d7\u05db\u05d4 \u05dc\u05d0\u05d9\u05e1\u05d5\u05e3 \u05d1\u05e0\u05e7\u05d5\u05d3\u05ea \u05d4\u05d7\u05dc\u05d5\u05e7\u05d4 \u05d4\u05e7\u05e8\u05d5\u05d1\u05d4 \u05d0\u05dc\u05d9\u05da.' },\n Undelivered: { headline: '\u05e0\u05d9\u05e1\u05d9\u05d5\u05df \u05de\u05e1\u05d9\u05e8\u05d4 \u05e0\u05db\u05e9\u05dc \u26a0\ufe0f', detail: '\u05dc\u05d0 \u05d4\u05e6\u05dc\u05d7\u05e0\u05d5 \u05dc\u05de\u05e1\u05d5\u05e8 \u05d0\u05ea \u05d4\u05d7\u05d1\u05d9\u05dc\u05d4. \u05e0\u05e0\u05e1\u05d4 \u05e9\u05d5\u05d1 \u05d1\u05d4\u05e7\u05d3\u05dd.' }\n};\n\nconst info = statusMap[status];\nif (!info) return [];\n\nlet etaLine = '';\nif (eta_from) {\n try {\n const d = new Date(eta_from);\n const formatted = d.toLocaleDateString('he-IL', { weekday: 'long', day: 'numeric', month: 'long' });\n etaLine = `\\n\u05e6\u05e4\u05d9 \u05d4\u05d2\u05e2\u05d4: ${formatted}`;\n } catch(e) {\n etaLine = `\\n\u05e6\u05e4\u05d9 \u05d4\u05d2\u05e2\u05d4: ${eta_from}`;\n }\n}\n\nconst firstName = (customer_name || '').split(' ')[0];\nconst greeting = firstName ? `\u05e9\u05dc\u05d5\u05dd ${firstName}! \ud83d\udc4b\\n\\n` : '';\nconst war = (status !== 'Delivered') ? `\\n\\n${warNotice}` : '';\nconst trackingLink = `\\n\\n\ud83d\udd0d *\u05dc\u05de\u05e2\u05e7\u05d1 \u05e2\u05e6\u05de\u05d0\u05d9 \u05d1\u05db\u05dc \u05e8\u05d2\u05e2:* https://www.hfd.co.il/\u05d0\u05d9\u05ea\u05d5\u05e8-\u05d7\u05d1\u05d9\u05dc\u05d4/\\n_(\u05d9\u05e9 \u05dc\u05d4\u05e7\u05dc\u05d9\u05d3 \u05d0\u05ea \u05de\u05e1\u05e4\u05e8 \u05d4\u05de\u05e2\u05e7\u05d1 \u05d9\u05d3\u05e0\u05d9\u05ea)_`;\n\nconst message = `*\u05e2\u05d3\u05db\u05d5\u05df \u05de\u05e9\u05dc\u05d5\u05d7 | OneZone* \ud83c\udfc6\\n\\n${greeting}*\u05e1\u05d8\u05d8\u05d5\u05e1:* ${info.headline}\\n\\n${info.detail}${etaLine}${war}\\n\\n*\u05de\u05e1\u05f3 \u05de\u05e2\u05e7\u05d1:* ${tracking_number}${trackingLink}\\n\\n_\u05dc\u05d4\u05e4\u05e1\u05e7\u05ea \u05e2\u05d3\u05db\u05d5\u05e0\u05d9\u05dd \u05e9\u05dc\u05d7 STOP_`;\n\nreturn [{ json: { phone, message } }];"
},
"id": "node-format-message",
"name": "Format Hebrew Message",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1560,
300
]
},
{
"parameters": {
"method": "POST",
"url": "https://joni-e746b-default-rtdb.europe-west1.firebasedatabase.app//joni/send.json",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={{ JSON.stringify({ to: $json.phone, text: $json.message }) }}",
"options": {}
},
"id": "node-send-joni",
"name": "Send via JONI",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1780,
300
]
}
],
"connections": {
"Every 2 Hours": {
"main": [
[
{
"node": "Get Monday Orders",
"type": "main",
"index": 0
}
]
]
},
"Get Monday Orders": {
"main": [
[
{
"node": "Parse Orders",
"type": "main",
"index": 0
}
]
]
},
"Parse Orders": {
"main": [
[
{
"node": "Register on TrackingMore",
"type": "main",
"index": 0
}
]
]
},
"Register on TrackingMore": {
"main": [
[
{
"node": "Get TrackingMore Status",
"type": "main",
"index": 0
}
]
]
},
"Get TrackingMore Status": {
"main": [
[
{
"node": "Status Changed?",
"type": "main",
"index": 0
}
]
]
},
"Status Changed?": {
"main": [
[
{
"node": "Format Hebrew Message",
"type": "main",
"index": 0
}
]
]
},
"Format Hebrew Message": {
"main": [
[
{
"node": "Send via JONI",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1",
"saveStaticData": true
},
"staticData": null,
"meta": {
"templateCredsSetupCompleted": true
},
"versionId": "1",
"triggerCount": 0,
"active": false
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
HFD TrackingMore Polling → JONI WhatsApp. Uses httpRequest. Scheduled trigger; 8 nodes.
Source: https://github.com/mirrorframestudio/amit-projects/blob/caed3818fa157d3059c4a053cd67b8caa8fb90d2/n8n/trackingmore-polling.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This workflow is an automated employee time tracking and reporting system that monitors weekly work hours via TMetric, then delivers personalized summaries directly to each team member on Slack. It co
Import Productboard Notes Companies And Features Into Snowflake. Uses stickyNote, httpRequest, splitOut, snowflake. Scheduled trigger; 35 nodes.
Import Productboard Notes, Companies and Features into Snowflake. Uses stickyNote, httpRequest, splitOut, snowflake. Scheduled trigger; 35 nodes.
This workflow imports Productboard data into Snowflake, automating data extraction, mapping, and updates for features, companies, and notes. It supports scheduled weekly updates, data cleansing, and S
Elevate your shopping experience with an AI-driven personal assistant that lives right in your WhatsApp. This template automates the entire lifecycle of a shopping list—from intelligent intake and liv