{"id":"IYgbtNpyB4E6Jbxo","meta":{"instanceId":"workflow-170789c5","versionId":"1.0.0","createdAt":"2025-09-29T07:07:55.695000","updatedAt":"2025-09-29T07:07:55.695019","owner":"n8n-user","license":"MIT","category":"automation","status":"active","priority":"high","environment":"production"},"name":"2. Refresh Pipedrive tokens","nodes":[{"id":"2b66edcd-c71a-4dac-971f-deb1b09ef85b","name":"Stop and Error","type":"n8n-nodes-base.stopAndError","position":[1460,-80],"parameters":{"errorMessage":"Token refresh failed"},"typeVersion":1,"alwaysOutputData":false,"notes":"This stopAndError node performs automated tasks as part of the workflow."},{"id":"b48d6760-766e-4b39-be35-89de7dc3ab5e","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[60,-300],"parameters":{"color":5,"width":872,"height":97,"content":"## Step 2:\nCreate a workflow to refresh your access token when the access token requires a refresh."},"typeVersion":1,"notes":"This stickyNote node performs automated tasks as part of the workflow."},{"id":"6119eef3-9ffa-45a1-b238-412738e7529e","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[280,-80],"parameters":{"height":211,"content":"\n\n\n\n\n\n\n\nPost unique data to identify your row in Database and be able to fetch the existing access and refresh token"},"typeVersion":1,"notes":"This stickyNote node performs automated tasks as part of the workflow."},{"id":"2d76be21-95e1-4747-b761-126b133e8264","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[980,-220],"parameters":{"content":"## Get token from pipedrive"},"typeVersion":1,"notes":"This stickyNote node performs automated tasks as part of the workflow."},{"id":"9a44eb63-9d31-4b24-9171-1f9a828a5c52","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[100,-740],"parameters":{"color":5,"width":995,"height":82,"content":"## Step 1:\nSave Refresh token and Access token to DB when authenticated by user and installed.  "},"typeVersion":1,"notes":"This stickyNote node performs automated tasks as part of the workflow."},{"id":"f3247e6a-7c1c-4479-9f83-f3bc4146f254","name":"Insert","type":"n8n-nodes-base.supabase","position":[1600,-660],"parameters":{"tableId":"App_tok","fieldsUi":{"fieldValues":[{"fieldId":"ref_token","fieldValue":"={{ $node[\"Generate Refresh Token from authcode\"].json[\"body\"][\"refresh_token\"] }}"},{"fieldId":"acc_token","fieldValue":"={{ $node[\"Generate Refresh Token from authcode\"].json[\"body\"][\"access_token\"] }}"},{"fieldId":"Platform","fieldValue":"Pipedrive"},{"fieldId":"created_at","fieldValue":"={{$now.toUTC().toString()}}"},{"fieldId":"updated_at","fieldValue":"={{$now.toUTC().toString()}}"}]}},"credentials":{"supabaseApi":{"id":"tlmP1CXY3ExzjJDs","name":"Supabase Automation"}},"typeVersion":1,"notes":"This supabase node performs automated tasks as part of the workflow."},{"id":"f7ad45d0-7055-45f4-9971-031ffebfdbda","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[500,-640],"parameters":{"content":"You can also use SET NODE + tobase64 function as done in step 2"},"typeVersion":1,"notes":"This stickyNote node performs automated tasks as part of the workflow."},{"id":"e14e2dac-e84b-475f-a01b-14bb723eedc8","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[100,200],"parameters":{"color":5,"width":1644,"height":80,"content":"## Step 3:\nMake an actual API call. In this example, we are using search person API. Please refer to Pipedrive API documentation for your specific use case. "},"typeVersion":1,"notes":"This stickyNote node performs automated tasks as part of the workflow."},{"id":"b450c928-e0e4-4f49-829e-03b61828d4d9","name":"Get Pipedrive Token","type":"n8n-nodes-base.supabase","position":[600,660],"parameters":{"filters":{"conditions":[{"keyName":"YOUR_CREDENTIAL_HERE","keyValue":"YOUR_CREDENTIAL_HERE"},{"keyName":"YOUR_CREDENTIAL_HERE","keyValue":"YOUR_CREDENTIAL_HERE"}]},"tableId":"App_tok","operation":"get"},"credentials":{"supabaseApi":{"id":"tlmP1CXY3ExzjJDs","name":"Supabase Automation"}},"typeVersion":1,"notes":"This supabase node performs automated tasks as part of the workflow."},{"id":"f92a957a-d0ef-4037-8657-74e7fe74fe6d","name":"Get contact from Pipedrive","type":"n8n-nodes-base.httpRequest","position":[900,660],"parameters":{"url":"{{ $env.BASE_URL }}","options":{"response":{"response":{"fullResponse":true}}},"sendHeaders":true,"headerParameters":{"parameters":[{"name":"Accept","value":"application/json"},{"name":"Authorization","value":"=Bearer {{ $node[\"Get Pipedrive Token\"].json[\"acc_token\"] }}"}]}},"typeVersion":4,"continueOnFail":true,"alwaysOutputData":false,"notes":"This httpRequest node performs automated tasks as part of the workflow."},{"id":"bff21156-3da0-4cf3-b3de-c24d8abe7577","name":"Access Token Invalid","type":"n8n-nodes-base.if","position":[1160,700],"parameters":{"conditions":{"boolean":[{"value1":"={{ $json[\"error\"][\"message\"].includes(\"Invalid token: access token is invalid\") }}","value2":"={{ true }}"}]},"combineOperation":"any"},"typeVersion":1,"notes":"This if node performs automated tasks as part of the workflow."},{"id":"9fd832b1-2af9-48c2-9d57-86a9f34bdd78","name":"Success","type":"n8n-nodes-base.respondToWebhook","position":[1440,720],"parameters":{"options":{"responseCode":200},"respondWith":"json","responseBody":"={{ $node[\"Get contact from Pipedrive\"].json[\"body\"][\"data\"][\"items\"][\"0\"][\"item\"][\"name\"] }}"},"typeVersion":1,"notes":"This respondToWebhook node performs automated tasks as part of the workflow."},{"id":"daf33b32-ff7b-4d7e-8fd0-d54dfaddf405","name":"Refresh Access Token","type":"n8n-nodes-base.httpRequest","position":[1360,320],"parameters":{"url":"{{ $env.WEBHOOK_URL }}","method":"POST","options":{},"jsonBody":"{\n\n  \"appId\":\"57db0bab2932f657\"\n\n}","sendBody":true,"specifyBody":"json","authentication":"{{ $credentials.genericCredentialType }}","genericAuthType":"httpBasicAuth"},"credentials":{"httpBasicAuth":{"id":"E2RYFiR9PotuglZv","name":"PJ demo"}},"typeVersion":4.2,"notes":"This httpRequest node performs automated tasks as part of the workflow."},{"id":"6759a890-6c2a-4bb1-aae9-9b8723b9e143","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[580,420],"parameters":{"width":668,"content":"## Loop back to fecth the  refreshed Access Token\n### Note:\nYou can add further conditions and use Switch  statemen tinstead of IF to validate API response based on your use case."},"typeVersion":1,"notes":"This stickyNote node performs automated tasks as part of the workflow."},{"id":"d975ce9f-2ef2-46b1-9d30-4f6e06e19b7e","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[120,-960],"parameters":{"width":1413,"content":"## 1. This workflow helps you create your own Oauth 2.0 token refresh system. It helps you have better control of your oauth 2.0 auth process.\n## 2. I am using Pipedrive API here. However, you can re-use this for other similar applications. "},"typeVersion":1,"notes":"This stickyNote node performs automated tasks as part of the workflow."},{"id":"40d59a94-563d-459c-91d0-4206c2a19704","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[180,580],"parameters":{"height":248,"content":"A 3rd partyapplication posting the request to the webhook"},"typeVersion":1,"notes":"This stickyNote node performs automated tasks as part of the workflow."},{"id":"03945766-570c-47db-82c6-2c973e45106d","name":"convert clientId and secret to base64","type":"n8n-nodes-base.code","position":[560,-560],"parameters":{"jsCode":"// Loop over input items and add a new field called 'myNewField' to the JSON of each one\nconst client_id = \"57db0bab2932f657\";\nconst client_secret = \"edfaba095e9e7ddefe2e960ce2e98345230a016d\";\n\n// Combine client_id and client_secret with a colon\nconst combinedString = client_id+\":\"+client_secret;\n\n// Encode the combined string in Base64\nconst encodedString = Buffer.from(combinedString).toString('base64');\n\n// Create the Authorization header value\nconst authorizationHeader = `Basic ${encodedString}`;\n\nreturn {\"authheader\":authorizationHeader};"},"typeVersion":2,"notes":"This code node performs automated tasks as part of the workflow."},{"id":"8ca6eb93-6994-4536-b61e-d884c8515929","name":"Generate Refresh Token from authcode","type":"n8n-nodes-base.httpRequest","maxTries":2,"position":[820,-560],"parameters":{"url":"{{ $env.WEBHOOK_URL }}","method":"POST","options":{"response":{"response":{"fullResponse":true}}},"sendBody":true,"contentType":"form-urlencoded","sendHeaders":true,"bodyParameters":{"parameters":[{"name":"grant_type","value":"authorization_code"},{"name":"code","value":"={{$node[\"catch Auth code\"].json[\"query\"][\"code\"]}}"},{"name":"redirect_uri","value":"={{ $node[\"catch Auth code\"].json[\"webhookUrl\"] }}"}]},"headerParameters":{"parameters":[{"name":"Authorization","value":"={{$node[\"convert clientId and secret to base64\"].json[\"authheader\"]}}"}]}},"retryOnFail":false,"typeVersion":4,"alwaysOutputData":false,"notes":"This httpRequest node performs automated tasks as part of the workflow."},{"id":"9c1b22e1-fd50-4c70-91cf-f4ea8cc7d3ac","name":"Look for the related record in Supabase","type":"n8n-nodes-base.supabase","position":[1060,-540],"parameters":{"filters":{"conditions":[{"keyName":"YOUR_CREDENTIAL_HERE","keyValue":"YOUR_CREDENTIAL_HERE"}]},"tableId":"App_tok","operation":"get"},"credentials":{"supabaseApi":{"id":"tlmP1CXY3ExzjJDs","name":"Supabase Automation"}},"typeVersion":1,"alwaysOutputData":true,"notes":"This supabase node performs automated tasks as part of the workflow."},{"id":"53602a58-d47a-4133-b9ec-4ea421a75eea","name":"IF rec not found","type":"n8n-nodes-base.if","position":[1260,-540],"parameters":{"conditions":{"number":[{"value1":"={{ $json.values().length }}","operation":"equal"}]}},"typeVersion":1,"notes":"This if node performs automated tasks as part of the workflow."},{"id":"38e5d91c-1bea-4f7a-8336-98748005d02e","name":"Update tokns in the record","type":"n8n-nodes-base.supabase","position":[1600,-460],"parameters":{"filters":{"conditions":[{"keyName":"YOUR_CREDENTIAL_HERE","keyValue":"YOUR_CREDENTIAL_HERE","condition":"eq"}]},"tableId":"App_tok","fieldsUi":{"fieldValues":[{"fieldId":"acc_token","fieldValue":"={{ $node[\"Generate Refresh Token from authcode\"].json[\"body\"][\"access_token\"] }}"},{"fieldId":"ref_token","fieldValue":"={{ $node[\"Generate Refresh Token from authcode\"].json[\"body\"][\"refresh_token\"] }}"},{"fieldId":"updated_at","fieldValue":"={{$now.toUTC().toString()}}"}]},"matchType":"allFilters","operation":"update"},"credentials":{"supabaseApi":{"id":"tlmP1CXY3ExzjJDs","name":"Supabase Automation"}},"typeVersion":1,"notes":"This supabase node performs automated tasks as part of the workflow."},{"id":"43a2613d-7793-48c9-8934-57d9b713f5fe","name":"Supabase- look for the record","type":"n8n-nodes-base.supabase","position":[600,-140],"parameters":{"filters":{"conditions":[{"keyName":"YOUR_CREDENTIAL_HERE","keyValue":"YOUR_CREDENTIAL_HERE"},{"keyName":"YOUR_CREDENTIAL_HERE","keyValue":"YOUR_CREDENTIAL_HERE"}]},"tableId":"App_tok","operation":"get"},"credentials":{"supabaseApi":{"id":"tlmP1CXY3ExzjJDs","name":"Supabase Automation"}},"typeVersion":1,"notes":"This supabase node performs automated tasks as part of the workflow."},{"id":"366bd343-419c-4a77-b2ce-e6124a6cc291","name":"combine client id and secret","type":"n8n-nodes-base.set","position":[840,-140],"parameters":{"options":{},"assignments":{"assignments":[{"id":"4330b857-6184-4ad8-82dc-a8b806ab8077","name":"authheader","type":"string","value":"57db0bab2932f657:edfaba095e9e7ddefe2e960ce2e98345230a016d"}]}},"typeVersion":3.3,"notes":"This set node performs automated tasks as part of the workflow."},{"id":"156acb8f-3a23-40ec-b011-9db8bfa6d98b","name":"Get Pipedrive acess token","type":"n8n-nodes-base.httpRequest","position":[1060,-140],"parameters":{"url":"{{ $env.WEBHOOK_URL }}","method":"POST","options":{},"sendBody":true,"contentType":"form-urlencoded","sendHeaders":true,"bodyParameters":{"parameters":[{"name":"grant_type","value":"refresh_token"},{"name":"refresh_token","value":"={{ $node[\"Supabase- look for the record\"].json[\"ref_token\"] }}"}]},"headerParameters":{"parameters":[{"name":"Authorization","value":"=Basic {{ $json[\"authheader\"].base64Encode() }}"}]}},"typeVersion":4.2,"notes":"This httpRequest node performs automated tasks as part of the workflow."},{"id":"3e20309e-6d50-444c-b9e1-cf6d6982e546","name":"IF success","type":"n8n-nodes-base.if","position":[1240,-140],"parameters":{"conditions":{"string":[{"value1":"={{ Object.keys($input.first().json)[0]}}","value2":"access_token"}]}},"typeVersion":1,"notes":"This if node performs automated tasks as part of the workflow."},{"id":"1e991aa7-9888-404d-8f80-bb6ce0a3b777","name":"Update thr row with new access token","type":"n8n-nodes-base.supabase","position":[1420,-280],"parameters":{"filters":{"conditions":[{"keyName":"YOUR_CREDENTIAL_HERE","keyValue":"YOUR_CREDENTIAL_HERE","condition":"eq"}]},"tableId":"App_tok","fieldsUi":{"fieldValues":[{"fieldId":"acc_token","fieldValue":"={{ $node[\"Get Pipedrive acess token\"].json[\"access_token\"] }}"},{"fieldId":"ref_token","fieldValue":"={{ $node[\"Get Pipedrive acess token\"].json[\"refresh_token\"] }}"}]},"matchType":"allFilters","operation":"update"},"credentials":{"supabaseApi":{"id":"tlmP1CXY3ExzjJDs","name":"Supabase Automation"}},"typeVersion":1,"alwaysOutputData":true,"notes":"This supabase node performs automated tasks as part of the workflow."},{"id":"d0989bad-9176-44a2-86ce-db07a5e8a34c","name":"Webhook","type":"n8n-nodes-base.webhook","position":[340,-140],"webhookId":"937a8843-a28a-400a-b473-bdc598366fa0","parameters":{"path":"937a8843-a28a-400a-b473-bdc598366fa0","options":{},"httpMethod":"POST","responseMode":"lastNode","authentication":"{{ $credentials.basicAuth }}"},"credentials":{"httpBasicAuth":{"id":"E2RYFiR9PotuglZv","name":"PJ demo"}},"typeVersion":2,"notes":"This webhook node performs automated tasks as part of the workflow."},{"id":"108a2ea1-de2a-4df3-9d9f-0ce1b27a52e9","name":"Receive request","type":"n8n-nodes-base.webhook","position":[280,680],"webhookId":"47704458-bfa6-4d95-adf1-97fc78e35d8a","parameters":{"path":"47704458-bfa6-4d95-adf1-97fc78e35d8a","options":{},"httpMethod":"POST","responseMode":"responseNode","authentication":"{{ $credentials.basicAuth }}"},"credentials":{"httpBasicAuth":{"id":"E2RYFiR9PotuglZv","name":"PJ demo"}},"typeVersion":1,"notes":"This webhook node performs automated tasks as part of the workflow."},{"id":"f983cfd1-52db-4839-88af-6386ec7c7256","name":"catch Auth code","type":"n8n-nodes-base.webhook","position":[300,-560],"webhookId":"aae545fb-a69d-4e20-91ce-65f105d0ea2f","parameters":{"path":"aae545fb-a69d-4e20-91ce-65f105d0ea2f","options":{}},"typeVersion":1,"notes":"This webhook node performs automated tasks as part of the workflow."}],"active":false,"settings":{"callerPolicy":"workflowsFromSameOwner","executionOrder":"v1","saveManualExecutions":true,"errorWorkflow":null,"timezone":"UTC","executionTimeout":3600,"maxExecutions":1000,"retryOnFail":true,"retryCount":3,"retryDelay":1000},"versionId":"54499ed8-4677-400a-9e03-d0d84f8a97b5","connections":{"Get contact from Pipedrive":{"main":[[],[],[],[],[],[],[],[]]},"Success":{"main":[[],[],[],[],[],[],[],[]]},"Refresh Access Token":{"main":[[],[],[],[],[],[],[],[]]},"Generate Refresh Token from authcode":{"main":[[],[],[],[],[],[],[],[]]},"Get Pipedrive acess token":{"main":[[],[],[],[],[],[],[],[]]},"Webhook":{"main":[[],[],[],[],[],[],[],[]]},"Receive request":{"main":[[],[],[],[],[],[],[],[]]},"catch Auth code":{"main":[[],[],[],[],[],[],[],[]]}},"description":"Automated workflow: 2. Refresh Pipedrive tokens. This workflow integrates 9 different services: webhook, stickyNote, httpRequest, code, respondToWebhook. It contains 37 nodes and follows best practices for error handling and security.","notes":"Excellent quality workflow: 2. Refresh Pipedrive tokens. This workflow has been optimized for production use with comprehensive error handling, security, and documentation."}