Changeset 3312791
- Timestamp:
- 06/16/2025 09:43:57 PM (10 months ago)
- Location:
- 800-com-call-tracking/trunk
- Files:
-
- 1 added
- 3 edited
-
admin-script.js (modified) (2 diffs)
-
admin-style.css (added)
-
eight-hundred-dni-injector.php (modified) (19 diffs)
-
readme.txt (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
800-com-call-tracking/trunk/admin-script.js
r3312730 r3312791 1 1 jQuery(document).ready(function($) { 2 $('#ehdi-refresh-script-button').on('click', function() {3 var $button = $(this);2 // Function to refresh the DNI script 3 function refreshDniScript() { 4 4 var $spinner = $('#ehdi-refresh-spinner'); 5 var $displayArea = $('#ehdi-dni-script-display'); 5 var $textarea = $('#ehdi-dni-script-textarea'); 6 var $companySelect = $('#ehdi_company_select_field'); 7 var $errorDiv = $('#ehdi-script-error'); 8 var $saveButton = $('#submit'); 6 9 7 // Show spinner and disable button10 // Show spinner and disable controls 8 11 $spinner.addClass('is-active'); 9 $button.prop('disabled', true); 12 $companySelect.prop('disabled', true); 13 $saveButton.prop('disabled', true); 10 14 11 // Clear previous script display / message and show loading text 12 $displayArea.html('<i>' + ehdi_ajax_object.loading_text + '</i>'); 15 // Clear previous error and show loading placeholder 16 $errorDiv.hide().empty(); 17 $textarea.attr('placeholder', 'Loading script...'); 13 18 14 19 // Get the currently selected company ID from the dropdown 15 var selectedCompanyId = $('#ehdi_company_select_field').val(); 20 var selectedCompanyId = $companySelect.val(); 21 22 // If no company is selected, clear the display and return 23 if (!selectedCompanyId) { 24 $textarea.val('').attr('placeholder', 'No script loaded. Select a company above to fetch the DNI script.'); 25 $spinner.removeClass('is-active'); 26 $companySelect.prop('disabled', false); 27 $saveButton.prop('disabled', false); 28 return; 29 } 16 30 17 31 $.ajax({ … … 24 38 }, 25 39 success: function(response) { 40 var $status = $('#ehdi-refresh-status'); 26 41 if (response.success) { 27 // Use text() to ensure script tags are displayed as text, not executed 28 $displayArea.text(response.data.script); 42 // Update textarea with the script content 43 $textarea.val(response.data.script).attr('placeholder', ''); 44 // Use smaller textarea size 45 $textarea.attr('rows', '6'); 46 // Hide any previous errors 47 $errorDiv.hide().empty(); 48 // Show success status briefly 49 $status.text('✓ Script loaded successfully').css('color', '#46b450'); 50 setTimeout(function() { 51 $status.text('').css('color', ''); 52 }, 2000); 29 53 } else { 30 // Display error message 31 $displayArea.html('<i style="color: red;">' + (response.data.message || ehdi_ajax_object.error_text) + '</i>'); 54 // Display error message in separate error div, NOT in textarea 55 var errorMsg = response.data.message || ehdi_ajax_object.error_text; 56 $errorDiv.html('<div class="notice notice-error"><p><strong>Error:</strong> ' + errorMsg + '</p></div>').show(); 57 // Clear textarea and reset placeholder 58 $textarea.val('').attr('placeholder', 'Error loading script. See error message above.'); 59 // Keep textarea small for errors 60 $textarea.attr('rows', '3'); 61 // Show error status 62 $status.text('✗ Failed to load script').css('color', '#dc3232'); 63 setTimeout(function() { 64 $status.text('').css('color', ''); 65 }, 3000); 32 66 } 33 67 }, 34 68 error: function(jqXHR, textStatus, errorThrown) { 35 // Display generic error message 69 // Display generic error message in error div 36 70 var errorMsg = ehdi_ajax_object.error_text; 37 71 if (jqXHR.responseJSON && jqXHR.responseJSON.data && jqXHR.responseJSON.data.message) { 38 72 errorMsg = jqXHR.responseJSON.data.message; 39 73 } 40 $displayArea.html('<i style="color: red;">' + errorMsg + ' (' + jqXHR.status + ')</i>'); 74 $errorDiv.html('<div class="notice notice-error"><p><strong>Error:</strong> ' + errorMsg + ' (' + jqXHR.status + ')</p></div>').show(); 75 $textarea.val('').attr('placeholder', 'Error loading script. See error message above.'); 41 76 }, 42 77 complete: function() { 43 // Hide spinner and re-enable button78 // Hide spinner and re-enable controls 44 79 $spinner.removeClass('is-active'); 45 $button.prop('disabled', false); 80 $companySelect.prop('disabled', false); 81 $saveButton.prop('disabled', false); 46 82 } 47 83 }); 84 } 85 86 // Auto-refresh when company selection changes 87 $('#ehdi_company_select_field').on('change', function() { 88 var $status = $('#ehdi-refresh-status'); 89 $status.text('Fetching script preview...'); 90 91 // Clear the status text after a delay 92 setTimeout(function() { 93 $status.text(''); 94 }, 3000); 95 96 refreshDniScript(); 48 97 }); 98 99 // Trigger initial load if a company is already selected 100 if ($('#ehdi_company_select_field').val()) { 101 refreshDniScript(); 102 } 49 103 }); -
800-com-call-tracking/trunk/eight-hundred-dni-injector.php
r3312730 r3312791 2 2 /** 3 3 * Plugin Name: 800.com Call Tracking 4 * Plugin URI: https:// 800.com/4 * Plugin URI: https://www.800.com/ 5 5 * Description: Seamlessly add 800.com dynamic number insertion to your WordPress site for enhanced call tracking and marketing attribution. 6 * Version: 1.0. 16 * Version: 1.0.2 7 7 * Requires at least: 5.2 8 8 * Requires PHP: 7.2 9 9 * License: GPL v2 or later 10 10 * License URI: https://www.gnu.org/licenses/gpl-2.0.html 11 * Text Domain: eight-hundred-dni-injector11 * Text Domain: 800-com-call-tracking 12 12 */ 13 13 … … 18 18 19 19 // Define plugin constants 20 define( 'EHDI_PLUGIN_VERSION', '1.0. 0' );20 define( 'EHDI_PLUGIN_VERSION', '1.0.2' ); 21 21 define( 'EHDI_PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); 22 22 define( 'EHDI_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); 23 24 23 25 24 /** … … 47 46 */ 48 47 function ehdi_sanitize_api_key($input) { 49 // Sanitize the API key - typically a string with no HTML50 48 return sanitize_text_field($input); 51 49 } … … 58 56 */ 59 57 function ehdi_sanitize_company_id($input) { 60 // Sanitize the company ID - typically a string with no HTML61 58 return sanitize_text_field($input); 62 59 } … … 73 70 ["sanitize_callback" => "ehdi_sanitize_company_id"] 74 71 ); 75 // Re-register ehdi_dni_script but use a sanitize callback to prevent form submission from overwriting it. 76 register_setting("ehdi_settings_group", "ehdi_dni_script", ["sanitize_callback" => "ehdi_prevent_save_via_form"]); 77 // Add option for script wrapping to prevent caching/optimization 78 register_setting("ehdi_settings_group", "ehdi_wrap_script", ["default" => 0, "sanitize_callback" => "absint"]); 72 register_setting("ehdi_settings_group", "ehdi_dni_script", [ 73 "sanitize_callback" => "ehdi_sanitize_dni_script" 74 ]); 75 register_setting("ehdi_settings_group", "ehdi_wrap_script", [ 76 "default" => 0, 77 "sanitize_callback" => "ehdi_sanitize_wrap_script" 78 ]); 79 79 80 80 // API Section … … 111 111 add_settings_section( 112 112 "ehdi_script_display_section", 113 "Fetched DNI Script Status",113 "Fetched DNI Script", 114 114 "ehdi_script_display_section_callback", 115 115 "eight_hundred_dni_injector" … … 181 181 182 182 if (is_wp_error($companies_result)) { 183 echo '<p style="color: red;">' . esc_html("Error fetching companies:") . ' ' . esc_html($companies_result->get_error_message()) . '</p>';183 echo '<p class="ehdi-error-message">' . esc_html("Error fetching companies:") . ' ' . esc_html($companies_result->get_error_message()) . '</p>'; 184 184 // Still show the currently selected ID if one exists 185 185 if ($selected_company_id) { … … 224 224 return; 225 225 } 226 227 // Check if API key exists to determine button text 228 $api_key = get_option('ehdi_api_key'); 229 $button_text = empty($api_key) ? 'Fetch Companies' : 'Save Settings'; 226 230 ?> 227 231 <div class="wrap"> … … 233 237 // Output setting sections and fields 234 238 do_settings_sections('eight_hundred_dni_injector'); 235 // Output save settings button 236 submit_button( 'Save Settings');239 // Output save settings button with dynamic text 240 submit_button($button_text); 237 241 ?> 238 242 </form> … … 241 245 } 242 246 243 244 247 // Define API Base URL constant (developer can change this) 245 248 define( 'EHDI_API_BASE_URL', 'https://api.800.com' ); 246 247 249 248 250 /** … … 305 307 return $body_data["data"]; // Assuming the script is in 'data' key 306 308 } 307 308 /**309 * Filter triggered just before the selected company ID option is updated.310 * Immediately fetches or clears the DNI script when the company ID changes.311 *312 * @param mixed $new_value The new option value.313 * @param mixed $old_value The old option value.314 * @param string $option The option name.315 * @return mixed The original $new_value to allow the option update to proceed.316 */317 function ehdi_handle_company_update_filter($new_value, $old_value, $option) {318 // Only proceed if the value actually changed319 if ($new_value !== $old_value) {320 if (!empty($new_value)) {321 // Fetch script immediately for the new company ID322 $api_key = get_option("ehdi_api_key");323 324 if (!empty($api_key)) {325 $script_result = ehdi_fetch_dni_script($new_value, $api_key);326 327 if (is_wp_error($script_result)) {328 // Clear the option on error329 delete_option("ehdi_dni_script");330 $error_message = sprintf(331 "Error fetching 800.com DNI script: %s",332 esc_html($script_result->get_error_message())333 );334 set_transient("ehdi_admin_notice", ["type" => "error", "message" => $error_message], 60);335 } else {336 // Force the script to be a string if it's not already337 if (!is_string($script_result)) {338 $script_result = (string)$script_result;339 }340 341 // Save the script to the database342 $update_result = update_option("ehdi_dni_script", $script_result, 'yes');343 344 // If update_option failed, try alternative approach345 if ($update_result === false) {346 // First try to delete the option if it exists347 delete_option('ehdi_dni_script');348 349 // Then add it fresh350 $add_result = add_option('ehdi_dni_script', $script_result, '', 'yes');351 352 // If that also fails, we've done our best353 // No need to log errors in production code354 }355 356 $success_message = "Successfully fetched and saved DNI script for the selected company.";357 set_transient("ehdi_admin_notice", ["type" => "success", "message" => $success_message], 60);358 }359 } else {360 // API key missing, cannot fetch361 delete_option("ehdi_dni_script");362 set_transient("ehdi_admin_notice", ["type" => "error", "message" => "API Key is missing. Cannot fetch DNI script."], 60);363 }364 } else {365 // Clear the script if company ID is empty366 delete_option("ehdi_dni_script");367 set_transient("ehdi_admin_notice", ["type" => "info", "message" => "Fetched company list. Please select your company to enable DNI."], 60);368 }369 }370 371 // IMPORTANT: Always return the original new value to allow the option update to proceed372 return $new_value;373 }374 // Use the pre_update_option filter375 add_filter("pre_update_option_ehdi_selected_company_id", "ehdi_handle_company_update_filter", 10, 3);376 309 377 310 /** … … 406 339 add_action("admin_notices", "ehdi_display_admin_notices"); 407 340 408 409 341 // Append the fetch companies function as well 410 342 /** … … 457 389 } 458 390 459 // Assuming the structure from pasted_content_2.txt is within a key, e.g., 'data'460 391 // Adjust this based on the actual API response structure 461 392 if (!isset($companies_data["data"]) || !is_array($companies_data["data"])) { 462 // If the structure is exactly like the text file (an array at the root)463 393 if (is_array($companies_data) && !empty($companies_data) && isset($companies_data[0]["id"])) { 464 // Assume the root is the array of companies465 394 return $companies_data; 466 395 } 467 // If it's paginated like { data: [...], meta: {...} }468 396 if (isset($companies_data["data"]) && is_array($companies_data["data"])) { 469 397 return $companies_data["data"]; 470 398 } 471 // Otherwise, unknown structure472 399 return new WP_Error("invalid_response_structure", "Unexpected API response structure."); 473 400 } … … 479 406 // Frontend Script Injection 480 407 /** 481 * Inject the stored DNI script into the wp_head action.482 */ 483 function ehdi_ inject_dni_script_in_head() {408 * Enqueue DNI script using WordPress proper methods. 409 */ 410 function ehdi_enqueue_dni_script() { 484 411 $dni_script = get_option("ehdi_dni_script"); 485 412 $wrap_script = get_option("ehdi_wrap_script"); 486 413 487 414 if (!empty($dni_script)) { 415 if ($wrap_script) { 416 417 // Register a dummy script handle for our inline script 418 wp_register_script( 419 'ehdi-dni-wrapper', // Unique handle for our script 420 false, // No external file 421 array(), // No dependencies needed 422 EHDI_PLUGIN_VERSION, // Use plugin version 423 true // Load in footer 424 ); 425 426 wp_enqueue_script('ehdi-dni-wrapper'); 427 428 // Create a dynamic wrapper script that bypasses optimization 429 $wrapper_script = ' 430 (function() { 431 // Wait for DOM to be ready 432 function injectScript() { 433 var scriptContent = ' . wp_json_encode($dni_script) . '; 434 var srcMatch = scriptContent.match(/src=[\'"]([^\'"]+)[\'"]/) || []; 435 var scriptSrc = srcMatch[1] || ""; 436 437 if (scriptSrc) { 438 var script = document.createElement("script"); 439 script.src = scriptSrc; 440 script.type = "text/javascript"; 441 442 // Extract and copy any other attributes from the original script 443 var attrMatch; 444 var attrRegex = /(\w+)=[\'"]([^\'"]+)[\'"](?:\s|>)/g; 445 while ((attrMatch = attrRegex.exec(scriptContent)) !== null) { 446 var attrName = attrMatch[1]; 447 var attrValue = attrMatch[2]; 448 if (attrName !== "src" && attrName !== "type") { 449 script.setAttribute(attrName, attrValue); 450 } 451 } 452 453 document.head.appendChild(script); 454 } 455 } 456 457 // Execute immediately or when DOM is ready 458 if (document.readyState === "loading") { 459 document.addEventListener("DOMContentLoaded", injectScript); 460 } else { 461 injectScript(); 462 } 463 })();'; 464 465 // Add the inline script, tied to our dummy handle 466 wp_add_inline_script('ehdi-dni-wrapper', $wrapper_script); 467 } 468 } 469 } 470 add_action('wp_enqueue_scripts', 'ehdi_enqueue_dni_script'); 471 472 /** 473 * Output DNI script directly in footer for non-wrapped mode. 474 */ 475 function ehdi_output_dni_script_direct() { 476 $dni_script = get_option("ehdi_dni_script"); 477 $wrap_script = get_option("ehdi_wrap_script"); 478 479 // Only output directly if wrap_script is disabled 480 if (!empty($dni_script) && !$wrap_script) { 488 481 echo "\n<!-- BEGIN 800.com Call Tracking Plugin -->\n"; 489 490 if ($wrap_script) { 491 // Wrap the script in a dynamic script injection to prevent caching/optimization 492 // This preserves query parameters needed for configuration 493 echo '<script> 494 (function() { 495 // Extract the script source from the original script tag 496 var scriptContent = ' . json_encode($dni_script) . '; 497 var srcMatch = scriptContent.match(/src=[\'"]([^\'"]+)[\'"]/) || []; 498 var scriptSrc = srcMatch[1] || ""; 499 500 if (scriptSrc) { 501 // Create a new script element 502 var script = document.createElement("script"); 503 script.src = scriptSrc; 504 505 // Extract and copy any other attributes from the original script 506 var attrMatch; 507 var attrRegex = /(\w+)=[\'"]([^\'"]+)[\'"](?:\s|>)/g; 508 while ((attrMatch = attrRegex.exec(scriptContent)) !== null) { 509 var attrName = attrMatch[1]; 510 var attrValue = attrMatch[2]; 511 if (attrName !== "src" && attrName !== "type") { 512 script.setAttribute(attrName, attrValue); 513 } 514 } 515 516 // Append the script to the document head 517 document.head.appendChild(script); 518 } 519 })(); 520 </script>'; 521 } else { 522 // Output the raw script content directly 523 echo wp_kses_post($dni_script); 524 } 525 482 // Output the script directly, but safely escaped 483 echo wp_kses($dni_script, array( 484 'script' => array( 485 'type' => array(), 486 'src' => array(), 487 'async' => array(), 488 'defer' => array(), 489 'id' => array(), 490 'class' => array(), 491 'data-*' => array() 492 ) 493 )); 526 494 echo "\n<!-- END 800.com Call Tracking Plugin -->\n"; 527 495 } 528 496 } 529 add_action( "wp_head", "ehdi_inject_dni_script_in_head");497 add_action('wp_footer', 'ehdi_output_dni_script_direct', 999); 530 498 531 499 /** … … 541 509 function ehdi_script_display_field_render() { 542 510 $dni_script = get_option("ehdi_dni_script"); 511 $has_script = !empty($dni_script); 512 543 513 echo 544 '<div id="ehdi-dni-script-wrapper"> 545 <p style="margin-bottom: 5px;"><strong>Current DNI Script:</strong></p>'; 546 547 // Always display using pre/code block, even if empty 548 echo "<pre><code id='ehdi-dni-script-display' style='display: block; white-space: pre-wrap; word-wrap: break-word; border: 1px solid #ccc; padding: 10px; background: #f9f9f9; margin-top: 0;'>"; 549 550 if (!empty($dni_script)) { 551 // Use esc_html to properly escape the script content 552 echo esc_html($dni_script); 553 } else { 554 echo "<i>" . esc_html("No DNI script has been fetched or saved yet. Please select a company and save settings, or use the Refresh button.") . "</i>"; 555 } 556 557 echo "</code></pre>"; 558 559 // Add Refresh button 514 '<div id="ehdi-dni-script-wrapper" class="ehdi-script-wrapper"> 515 <p class="ehdi-script-title"><strong>Current DNI Script:</strong></p>'; 516 517 // Add error display area (separate from textarea) 518 echo '<div id="ehdi-script-error" class="ehdi-script-error" style="display: none;"></div>'; 519 520 // Add a textarea for the actual form input with smaller, more reasonable sizing 521 $rows = $has_script ? '6' : '3'; 522 $placeholder = $has_script ? '' : 'No script loaded. Select a company above to fetch the DNI script.'; 523 524 echo '<textarea name="ehdi_dni_script" id="ehdi-dni-script-textarea" rows="' . esc_attr($rows) . '" cols="80" class="large-text code ehdi-script-textarea" readonly placeholder="' . esc_attr($placeholder) . '">'; 525 if ($has_script) { 526 echo esc_textarea($dni_script); 527 } 528 echo '</textarea>'; 529 530 // Add description 531 echo '<p class="description">' . esc_html('This script is automatically fetched when you select a company above. It will be injected into your website pages.') . '</p>'; 532 533 // Add spinner for auto-refresh functionality 560 534 echo 561 '<p>< button type="button" id="ehdi-refresh-script-button" class="button">' . esc_html("Refresh DNI Script") . '</button> <span id="ehdi-refresh-spinner" class="spinner" style="float: none; vertical-align: middle;"></span></p>';535 '<p><span id="ehdi-refresh-spinner" class="spinner ehdi-refresh-spinner"></span> <span id="ehdi-refresh-status" class="ehdi-refresh-status"></span></p>'; 562 536 563 537 echo '</div>'; // Close wrapper div … … 582 556 583 557 /** 584 * Prevent the 'ehdi_dni_script' option from being saved via the main settings form. 585 * It should only be updated via the update_option hook. 558 * Sanitize callback for DNI script. 586 559 * 587 * @param mixed $input The value submitted via the form (should be null/empty). 588 * @return mixed The existing value of the option, effectively preventing update. 589 */ 590 function ehdi_prevent_save_via_form($input) { 591 // Return the current value to prevent the submitted value (likely empty) from overwriting it. 592 // This ensures the value set by the update_option hook is preserved. 593 return get_option('ehdi_dni_script'); 560 * @param mixed $input The value submitted via the form. 561 * @return mixed The sanitized script content. 562 */ 563 function ehdi_sanitize_dni_script($input) { 564 // Since this is a script tag from a trusted API source (800.com), 565 // we use wp_kses with specifically allowed script attributes 566 // This preserves the script functionality while sanitizing against XSS 567 $allowed_html = array( 568 'script' => array( 569 'type' => array(), 570 'src' => array(), 571 'async' => array(), 572 'defer' => array(), 573 'id' => array(), 574 'class' => array(), 575 'data-*' => true, // Allow data attributes 576 'crossorigin' => array(), 577 'integrity' => array(), 578 'nonce' => array(), 579 ) 580 ); 581 582 return wp_kses($input, $allowed_html); 583 } 584 585 /** 586 * Sanitize callback for wrap script option. 587 * 588 * @param mixed $input The value submitted via the form. 589 * @return int The sanitized wrap script value. 590 */ 591 function ehdi_sanitize_wrap_script($input) { 592 return absint($input); 594 593 } 595 594 /** … … 638 637 ]); 639 638 640 wp_enqueue_style('wp-admin'); 639 // Enqueue admin styles 640 wp_enqueue_style( 641 'ehdi-admin-style', 642 plugin_dir_url(__FILE__) . 'admin-style.css', 643 [], // No dependencies 644 EHDI_PLUGIN_VERSION // Use defined version 645 ); 641 646 } 642 647 … … 675 680 676 681 if (is_wp_error($script_result)) { 677 // Clear the option on error678 delete_option('ehdi_dni_script');679 682 wp_send_json_error(['message' => $script_result->get_error_message()], 500); 680 683 } else { … … 684 687 } 685 688 686 // Try standard WordPress function first 687 $update_result = update_option('ehdi_dni_script', $script_result, 'yes'); 688 689 // If update_option failed, try alternative approach 690 if ($update_result === false) { 691 // First try to delete the option if it exists 692 delete_option('ehdi_dni_script'); 693 694 // Then add it fresh 695 $add_result = add_option('ehdi_dni_script', $script_result, '', 'yes'); 696 697 // If that also fails, we've done our best 698 // No need to log errors in production code 699 } 700 701 // Send success response with the script content 689 // Send success response with the script content for preview only 690 // Do not save to database - that will happen when user clicks "Save Settings" 702 691 wp_send_json_success(['script' => $script_result]); 703 692 } -
800-com-call-tracking/trunk/readme.txt
r3312730 r3312791 4 4 Requires at least: 5.2 5 5 Tested up to: 6.8 6 Stable tag: 1.0. 16 Stable tag: 1.0.2 7 7 Requires PHP: 7.2 8 8 License: GPLv2 or later … … 25 25 26 26 **How It Works:** 27 1. Sign up for an [800.com account](https:// 800.com/) to access dynamic number insertion features.27 1. Sign up for an [800.com account](https://www.800.com/) to access dynamic number insertion features. 28 28 2. Enter your 800.com API key in the plugin’s settings. 29 29 3. The plugin injects the 800.com JavaScript into your site’s `<head>`, enabling dynamic phone number swapping based on visitor data (e.g., referral source, campaign, or location). … … 59 59 60 60 = Where do I find my 800.com API key? = 61 Log in to your 800.com account and navigate to the API or Integrations section to generate or retrieve your API key.61 Log in to your 800.com account and navigate to the API or Integrations section to generate or retrieve your 62 62 63 = Does this plugin work with any WordPress theme? = 64 Yes, the plugin injects a JavaScript snippet into the `<head>` tag and is compatible with any properly coded WordPress theme. 65 66 = Is my 800.com API key secure? = 67 The plugin securely stores your API key using WordPress’s Options API and does not expose it in the frontend or source code. 68 69 = Can I customize the placement of the phone numbers? = 70 Phone number placement is managed by 800.com’s JavaScript. Refer to 800.com’s documentation for customizing number display. 71 72 == Screenshots == 63 **Requirements:** 64 - An active 800.com account with API access. 73 65 74 66 1. Plugin settings page where you enter your 800.com API key. 75 67 2. Example of a dynamic phone number displayed on a WordPress site. 76 68 3. 800.com dashboard showing call tracking analytics. 69 70 == External Services == 71 72 This plugin connects to 800.com's external services to provide call tracking functionality. The following information details what data is transmitted and how it is used: 73 74 **API Endpoints Used:** 75 - `https://api.800.com/companies/slim` - Retrieves a list of companies associated with your 800.com account for configuration purposes. 76 - `https://api.800.com/companies/{id}/trackingNumbers/script` - Fetches the JavaScript snippet required for dynamic number insertion on your website. 77 78 **Data Transmission:** 79 During plugin configuration, your 800.com API key is used to authenticate requests to the above endpoints. Once configured, the injected script communicates with 800.com servers on each page view to determine which phone numbers to display. 80 81 **Information Sent to 800.com:** 82 - Page location (URL) 83 - Referrer information 84 - 800.com session identifiers 85 - Browser information 86 87 **Data Usage:** 88 The transmitted data is used exclusively to determine which of your configured phone numbers to serve to website visitors based on your 800.com account settings. This enables accurate call tracking and marketing attribution. 89 90 **Transparency:** 91 800.com maintains transparency by keeping requests and variables human-readable. Additionally, source maps are published for DNI scripts, allowing users to understand exactly how the scripts interact with their websites. 92 93 **Service Links:** 94 - 800.com Terms of Service: https://www.800.com/terms 95 - 800.com Privacy Policy: https://www.800.com/privacy 96 97 **Note:** This plugin requires an active 800.com account and relies on their external services for all call tracking functionality. No call data is processed or stored locally by this plugin. 77 98 78 99 == Changelog == … … 87 108 = 1.0.1 = 88 109 This is the initial release. No upgrades available yet. 110 111 = 1.0.2 = 112 Minor changes requested due wordpress plugin review.
Note: See TracChangeset
for help on using the changeset viewer.