<!DOCTYPE html>
<html>
<head>
<meta charset=”UTF-8″>
<style>
.webhook-setup {
font-family: -apple-system, BlinkMacSystemFont, ‘Segoe UI’, Arial, sans-serif;
max-width: 900px;
margin: 20px auto;
padding: 20px;
}
.ws-container {
background: white;
padding: 30px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.ws-title {
color: #2c3e50;
margin-top: 0;
font-size: 28px;
}
.ws-step {
background: #f8f9fa;
padding: 20px;
margin: 20px 0;
border-radius: 6px;
border-left: 4px solid #007bff;
}
.ws-step h3 {
margin-top: 0;
color: #007bff;
}
.ws-info {
background: #d1ecf1;
border-left: 4px solid #0c5460;
padding: 15px;
margin: 15px 0;
border-radius: 4px;
color: #0c5460;
}
.ws-warning {
background: #fff3cd;
border-left: 4px solid #ffc107;
padding: 15px;
margin: 15px 0;
border-radius: 4px;
color: #856404;
}
.ws-success {
background: #d4edda;
border-left: 4px solid #28a745;
padding: 15px;
margin: 15px 0;
border-radius: 4px;
color: #155724;
}
.ws-input {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
margin: 10px 0;
box-sizing: border-box;
font-family: monospace;
}
.ws-button {
background: #007bff;
color: white;
border: none;
padding: 12px 24px;
border-radius: 6px;
font-size: 16px;
cursor: pointer;
font-weight: 500;
margin: 10px 5px 10px 0;
}
.ws-button:hover {
background: #0056b3;
}
.code-block {
background: #2c3e50;
color: #ecf0f1;
padding: 15px;
border-radius: 4px;
overflow-x: auto;
font-size: 13px;
font-family: ‘Courier New’, monospace;
margin: 10px 0;
position: relative;
}
.copy-btn {
position: absolute;
top: 10px;
right: 10px;
background: #007bff;
color: white;
border: none;
padding: 5px 10px;
border-radius: 4px;
cursor: pointer;
font-size: 12px;
}
.copy-btn:hover {
background: #0056b3;
}
.highlight {
background: #ffc107;
padding: 2px 4px;
border-radius: 3px;
font-weight: 600;
}
</style>
</head>
<body>
<div class=”webhook-setup”>
<div class=”ws-container”>
<h1 class=”ws-title”>🔗 NexHealth Webhook Setup for Postalytics</h1>
<div class=”ws-info”>
<strong>What this does:</strong><br>
Automatically sends direct mail via Postalytics when a <strong>Four Ever Smile Consultation</strong> is booked in NexHealth (from any source: website, phone, walk-in, etc.)
</div>
<!– STEP 1 –>
<div class=”ws-step”>
<h3>Step 1: Get Your Zapier Webhook URL</h3>
<ol>
<li>Go to <a href=”https://zapier.com/app/zaps” target=”_blank”>zapier.com</a></li>
<li>Click <strong>”Create Zap”</strong></li>
<li>Trigger: <strong>”Webhooks by Zapier”</strong> → <strong>”Catch Hook”</strong></li>
<li>Click <strong>”Continue”</strong></li>
<li>Copy the webhook URL (looks like: <code>https://hooks.zapier.com/hooks/catch/1234567/abcdefg/</code>)</li>
<li>Paste it below:</li>
</ol>
<input type=”text” id=”zapierUrl” class=”ws-input” placeholder=”Paste your Zapier webhook URL here”>
<button class=”ws-button” onclick=”generateCommands()”>Generate Setup Commands</button>
</div>
<!– COMMANDS OUTPUT –>
<div id=”commandsOutput” style=”display: none;”>
<!– STEP 2 –>
<div class=”ws-step”>
<h3>Step 2: Send These Commands to Your Developer</h3>
<div class=”ws-warning”>
<strong>⚠️ For Your Developer:</strong><br>
SSH into the server and run these two commands in order.
</div>
<h4>Command 1: Create Webhook Endpoint</h4>
<div class=”code-block”>
<button class=”copy-btn” onclick=”copyCode(‘cmd1’)”>Copy</button>
<pre id=”cmd1″></pre>
</div>
<div class=”ws-info”>
<strong>📝 After running Command 1:</strong><br>
Your developer will see output with an <span class=”highlight”>ID number</span> (e.g., <code>”id”: 123456</code>)<br>
<strong>SAVE THIS ID!</strong> You’ll need it for Command 2.
</div>
<h4>Command 2: Subscribe to appointment.created Event</h4>
<p>Replace <code>ENDPOINT_ID</code> with the ID from Command 1:</p>
<div class=”code-block”>
<button class=”copy-btn” onclick=”copyCode(‘cmd2’)”>Copy</button>
<pre id=”cmd2″></pre>
</div>
<div class=”ws-success”>
<strong>✅ After Command 2 succeeds:</strong><br>
The webhook is active! Move to Step 3.
</div>
</div>
<!– STEP 3 –>
<div class=”ws-step”>
<h3>Step 3: Configure Zapier Filter</h3>
<p>Back in your Zapier tab:</p>
<ol>
<li>Book a test appointment in NexHealth</li>
<li>Click <strong>”Test trigger”</strong> in Zapier</li>
<li>You should see appointment data appear</li>
<li>Click <strong>”+”</strong> to add a step</li>
<li>Select <strong>”Filter”</strong></li>
<li><strong>Only continue if:</strong>
<ul>
<li><code>appointment_type_id</code> <strong>Number Equals Exactly</strong> <code>11741</code></li>
<li><strong>OR</strong></li>
<li><code>appointment_type_id</code> <strong>Number Equals Exactly</strong> <code>1091202</code></li>
</ul>
</li>
</ol>
<div class=”ws-info”>
<strong>Why these IDs?</strong><br>
• <code>11741</code> = Four Ever Smile Consultation (NY locations)<br>
• <code>1091202</code> = Four Ever Smile Consultation (Totowa, NJ)<br><br>
This ensures ONLY consultation appointments trigger mailers.
</div>
</div>
<!– STEP 4 –>
<div class=”ws-step”>
<h3>Step 4: Connect Postalytics</h3>
<ol>
<li>Click <strong>”+”</strong> to add another step</li>
<li>Search for <strong>”Postalytics”</strong></li>
<li>Select <strong>”Send Direct Mail”</strong> or <strong>”Trigger Campaign”</strong></li>
<li>Connect your Postalytics account</li>
<li><strong>Map these fields:</strong></li>
</ol>
<table style=”width: 100%; border-collapse: collapse; margin: 10px 0;”>
<tr style=”background: #f8f9fa;”>
<th style=”padding: 10px; text-align: left; border: 1px solid #ddd;”>Postalytics Field</th>
<th style=”padding: 10px; text-align: left; border: 1px solid #ddd;”>Zapier Data (from webhook)</th>
</tr>
<tr>
<td style=”padding: 10px; border: 1px solid #ddd;”>First Name</td>
<td style=”padding: 10px; border: 1px solid #ddd;”><code>patient > first_name</code></td>
</tr>
<tr>
<td style=”padding: 10px; border: 1px solid #ddd;”>Last Name</td>
<td style=”padding: 10px; border: 1px solid #ddd;”><code>patient > last_name</code></td>
</tr>
<tr>
<td style=”padding: 10px; border: 1px solid #ddd;”>Street Address</td>
<td style=”padding: 10px; border: 1px solid #ddd;”><code>patient > bio > street_address</code></td>
</tr>
<tr>
<td style=”padding: 10px; border: 1px solid #ddd;”>City</td>
<td style=”padding: 10px; border: 1px solid #ddd;”><code>patient > bio > city</code></td>
</tr>
<tr>
<td style=”padding: 10px; border: 1px solid #ddd;”>State</td>
<td style=”padding: 10px; border: 1px solid #ddd;”><code>patient > bio > state</code></td>
</tr>
<tr>
<td style=”padding: 10px; border: 1px solid #ddd;”>Zip Code</td>
<td style=”padding: 10px; border: 1px solid #ddd;”><code>patient > bio > zip_code</code></td>
</tr>
<tr>
<td style=”padding: 10px; border: 1px solid #ddd;”>Email</td>
<td style=”padding: 10px; border: 1px solid #ddd;”><code>patient > email</code></td>
</tr>
<tr>
<td style=”padding: 10px; border: 1px solid #ddd;”>Phone</td>
<td style=”padding: 10px; border: 1px solid #ddd;”><code>patient > bio > phone_number</code></td>
</tr>
<tr>
<td style=”padding: 10px; border: 1px solid #ddd;”>Appointment Date</td>
<td style=”padding: 10px; border: 1px solid #ddd;”><code>appointment > start_time</code></td>
</tr>
<tr>
<td style=”padding: 10px; border: 1px solid #ddd;”>Location</td>
<td style=”padding: 10px; border: 1px solid #ddd;”><code>location > name</code></td>
</tr>
</table>
</div>
<!– STEP 5 –>
<div class=”ws-step”>
<h3>Step 5: Test & Activate</h3>
<ol>
<li>Click <strong>”Test action”</strong> in Zapier</li>
<li>Verify Postalytics received the data</li>
<li>Click <strong>”Publish”</strong> to turn on the Zap</li>
<li>Book a test <strong>Four Ever Smile Consultation</strong> in NexHealth</li>
<li>Check Zapier Zap History to confirm it triggered</li>
<li>Verify the filter passed (not blocked)</li>
<li>Confirm Postalytics is processing the mailer</li>
</ol>
<div class=”ws-success”>
<strong>🎉 You’re Done!</strong><br>
Every Four Ever Smile Consultation booked in NexHealth will now automatically trigger a Postalytics direct mail piece.
</div>
</div>
<!– TESTING CHECKLIST –>
<div class=”ws-step”>
<h3>Testing Checklist</h3>
<label style=”display: block; margin: 8px 0;”>
<input type=”checkbox”> Webhook endpoint created (Command 1 succeeded)
</label>
<label style=”display: block; margin: 8px 0;”>
<input type=”checkbox”> Subscription active (Command 2 succeeded)
</label>
<label style=”display: block; margin: 8px 0;”>
<input type=”checkbox”> Zapier catches test appointment data
</label>
<label style=”display: block; margin: 8px 0;”>
<input type=”checkbox”> Filter passes for Four Ever Smile (11741 or 1091202)
</label>
<label style=”display: block; margin: 8px 0;”>
<input type=”checkbox”> Filter blocks other appointment types
</label>
<label style=”display: block; margin: 8px 0;”>
<input type=”checkbox”> Postalytics receives correct patient data
</label>
<label style=”display: block; margin: 8px 0;”>
<input type=”checkbox”> Test mailer prints successfully
</label>
<label style=”display: block; margin: 8px 0;”>
<input type=”checkbox”> Zap is published and active
</label>
</div>
</div>
</div>
</div>
<script>
function generateCommands() {
const zapierUrl = document.getElementById(‘zapierUrl’).value.trim();
if (!zapierUrl) {
alert(‘Please paste your Zapier webhook URL first’);
return;
}
if (!zapierUrl.startsWith(‘https://hooks.zapier.com/’)) {
alert(‘Please enter a valid Zapier webhook URL (should start with https://hooks.zapier.com/)’);
return;
}
const cmd1 = `cd /var/www/html/wp-content/themes/hello-theme-child-master
php -r ”
require ‘nexhealth/nexhealth.php’;
\\$nh = new nexhealth();
\\$result = \\$nh->request([
‘request’ => ‘webhook_endpoints’,
‘type’ => ‘POST’,
‘get’ => [‘subdomain’ => ‘pure_dental’],
‘json’ => [
‘webhook_endpoint’ => [
‘name’ => ‘Four Ever Smile Consultation Mailer’,
‘url’ => ‘${zapierUrl}’,
‘description’ => ‘Triggers Postalytics for consultations (atid: 11741, 1091202)’
]
]
]);
echo ‘WEBHOOK ENDPOINT CREATED’ . PHP_EOL;
echo ‘SAVE THIS ID: ‘ . \\$result[‘data’][‘webhook_endpoint’][‘id’] . PHP_EOL;
echo json_encode(\\$result, JSON_PRETTY_PRINT) . PHP_EOL;
“`;
const cmd2 = `cd /var/www/html/wp-content/themes/hello-theme-child-master
php -r ”
require ‘nexhealth/nexhealth.php’;
\\$nh = new nexhealth();
\\$result = \\$nh->request([
‘request’ => ‘webhook_endpoints/ENDPOINT_ID/webhook_subscriptions’,
‘type’ => ‘POST’,
‘get’ => [‘subdomain’ => ‘pure_dental’],
‘json’ => [
‘webhook_subscription’ => [
‘event’ => ‘appointment.created’,
‘active’ => true
]
]
]);
echo ‘SUBSCRIPTION CREATED’ . PHP_EOL;
echo json_encode(\\$result, JSON_PRETTY_PRINT) . PHP_EOL;
“`;
document.getElementById(‘cmd1’).textContent = cmd1;
document.getElementById(‘cmd2’).textContent = cmd2;
document.getElementById(‘commandsOutput’).style.display = ‘block’;
// Scroll to commands
document.getElementById(‘commandsOutput’).scrollIntoView({ behavior: ‘smooth’ });
}
function copyCode(id) {
const code = document.getElementById(id).textContent;
navigator.clipboard.writeText(code).then(() => {
const btn = event.target;
const originalText = btn.textContent;
btn.textContent = ‘Copied!’;
btn.style.background = ‘#28a745’;
setTimeout(() => {
btn.textContent = originalText;
btn.style.background = ‘#007bff’;
}, 2000);
});
}
</script>
</body>
</html>