📞 (647) 474-4602

Mobile Tire Services in Toronto & GTA | Local Tire Quote

Mobile Tire Service GTA & Calgary — We Come To You | LocalTireQuote.ca
WE COME TO YOU HOME OR OFFICE ROADSIDE HELP 15 MIN RESPONSE GTA & CALGARY 100% FREE TO REQUEST VERIFIED TECHNICIANS WE COME TO YOU HOME OR OFFICE ROADSIDE HELP 15 MIN RESPONSE GTA & CALGARY 100% FREE TO REQUEST VERIFIED TECHNICIANS
Select your service

🔧 Mobile Tire Installation

We send a technician to your home, office, or any address

🚨 Emergency Roadside Repair

Flat tire on the road — we get help to you fast

📍 GTA & Calgary — Mobile Installation

Tires done
at your
location.

Tell us where you are and what you need. We match you with a verified mobile tire technician in your area. No need to drive anywhere — we come to you.

📍 We come to you 15 min response 🔒 Free to request Verified techs
Mobile tire installation — where should we come?
🚨 Emergency now
⚡ Today

    LocalTireQuote — Form Fix + Alex & Jordan Setup

    ① The Problem

    ② The Fix — CF7 Form

    ③ Google Apps Script

    ④ Alex — Driver AI

    ⑤ Jordan — Shop AI

    ⑥ Go Live Checklist

    Why Your Form Data Isn’t Reaching Google Sheets

    You have two separate forms that don’t know about each other. Here is exactly what is happening.

    ❌ What you have now

    Form A — Custom HTML form built into your page HTML. This is the form drivers see and fill in. When they click submit, it tries to submit but has nowhere to go — there’s no action URL connected to anything real.

    Form B — CF7 form is a completely separate WordPress form with its own fields and its own shortcode. It lives inside your HTML widget but it has different field names than your custom form.

    Result: Driver fills in Form A. Data goes nowhere. CF7 (Form B) sits there doing nothing because nobody filled it in.

    ✅ What we are building

    One unified CF7 form that replaces your custom HTML form completely. The CF7 form will look identical to your current design — dark theme, red accents, all the same fields.

    Google Apps Script webhook — completely free, no Make.com, no Zapier. A script that lives inside Google Sheets and receives the form data directly every time someone submits.

    Alex calls the driver within 2 minutes. Jordan calls the shop once Alex confirms. Both agents go live before you give out the pitch.

    The core issue in one line: Your custom HTML form fields (id="phone", id="vehicle" etc.) are not CF7 fields. CF7 only captures data from its own shortcode fields. You need to replace the custom form with a properly styled CF7 form so all data flows through CF7’s submission system.

    Replace Your Form With This CF7 Code

    Two parts: the CF7 form template (goes in the CF7 editor) and the CSS (goes in Additional CSS). Together they produce a form that looks exactly like your current design.

    Where to go: WordPress → Contact → Contact Forms → Edit your main form → replace the Form tab content with the code below.

    CF7 Form Tab — Replace Everything With This

    				
    				
    
    <div class="ltq-form-inner">
    
      <span class="ltq-form-label">How urgent is your need?</span>
      <div class="ltq-urgency-row">
        <label class="ltq-urgency-btn">
           
        </label>
        <label class="ltq-urgency-btn">
          
        </label>
      </div>
    
      <div class="ltq-field">
        <label>Service needed</label>
        
      </div>
    
      <div class="ltq-field">
        <label>Your vehicle</label>
        
      </div>
    
      <div class="ltq-field">
        <label>Tire size (optional)</label>
        
      </div>
    
      <div class="ltq-field">
        <label>Postal code</label>
        [text* postal-code placeholder "e.g. L5B 1M1 or T3K 4B8" maxlength:7 id:ltq-postal]
      </div>
    
      <div class="ltq-field">
        <label>Your city</label>
        
      </div>
    
      <div class="ltq-field">
        <label>Your name</label>
        
      </div>
    
      <div class="ltq-field">
        <label>Phone number</label>
        [tel* phone-number placeholder "(647) 555-0123" id:ltq-phone]
      </div>
    
      
    
      <p class="ltq-note">🔒 Free for drivers. Shared only with your matched shop. <a href="#disclaimer">Disclaimer</a></p>
    
    </div>
    				

    Email Notification Setup

    Click the Mail tab in CF7 and set these fields so you get emailed on every submission.

    CF7 Mail Tab — To field

    partners@localtirequote.ca
    				

    CF7 Mail Tab — Subject field

    🔔 [urgency] request — [your-name] in [city]
    				

    CF7 Mail Tab — Message Body

    NEW DRIVER REQUEST — LocalTireQuote.ca
    
    Name: [your-name]
    Phone: [phone-number]
    City: [city]
    Postal Code: [postal-code]
    Vehicle: [vehicle]
    Tire Size: [tire-size]
    Service: [service]
    Urgency: [urgency]
    Source Page: [ltq_source_page]
    Submitted: [ltq_timestamp]
    				

    Make the CF7 Form Look Like Your Design

    Appearance → Customize → Additional CSS → paste at the bottom.

    Additional CSS — CF7 Form Styling

    /* ── LTQ CF7 Form Styles ── */
    .ltq-form-inner { display:flex; flex-direction:column; gap:10px; width:100%; box-sizing:border-box; }
    .ltq-form-label { font-size:0.6rem; font-weight:700; letter-spacing:2px; text-transform:uppercase; color:#E8170A; margin-bottom:6px; display:block; }
    .ltq-field { display:flex; flex-direction:column; gap:4px; }
    .ltq-field label { font-size:0.6rem; font-weight:700; letter-spacing:1px; text-transform:uppercase; color:#888; }
    
    /* All inputs and selects */
    .ltq-form-inner input[type="text"],
    .ltq-form-inner input[type="tel"],
    .ltq-form-inner select {
      width:100% !important;
      max-width:100% !important;
      box-sizing:border-box !important;
      background:#242424 !important;
      border:1px solid #2a2a2a !important;
      border-radius:5px !important;
      padding:11px 13px !important;
      color:#f0f0f0 !important;
      font-family:'Barlow',sans-serif !important;
      font-size:0.86rem !important;
      outline:none !important;
      -webkit-appearance:none !important;
      appearance:none !important;
    }
    .ltq-form-inner input:focus,
    .ltq-form-inner select:focus {
      border-color:#E8170A !important;
      box-shadow:0 0 0 3px rgba(232,23,10,0.08) !important;
    }
    .ltq-form-inner input::placeholder { color:#555 !important; }
    .ltq-form-inner select option { background:#181818; }
    
    /* Urgency radio buttons */
    .ltq-urgency-row { display:flex; gap:8px; margin-bottom:4px; }
    .ltq-urgency-btn { flex:1; }
    .ltq-urgency-btn .wpcf7-radio { display:flex; }
    .ltq-urgency-btn label {
      flex:1;
      padding:10px 8px !important;
      border-radius:4px !important;
      font-size:0.74rem !important;
      font-weight:700 !important;
      text-align:center !important;
      cursor:pointer !important;
      border:1px solid #2a2a2a !important;
      background:#242424 !important;
      color:#888 !important;
      transition:all 0.2s !important;
      display:flex !important;
      align-items:center !important;
      justify-content:center !important;
    }
    .ltq-urgency-btn input[type="radio"] { display:none !important; }
    .ltq-urgency-btn input[type="radio"]:checked + span,
    .ltq-urgency-btn label:has(input:checked) {
      background:#E8170A !important;
      border-color:#E8170A !important;
      color:#fff !important;
    }
    
    /* Submit button */
    .ltq-submit, input.ltq-submit {
      width:100% !important;
      background:#E8170A !important;
      color:#fff !important;
      border:none !important;
      border-radius:5px !important;
      padding:14px !important;
      font-family:'Bebas Neue',sans-serif !important;
      font-size:1.1rem !important;
      letter-spacing:2px !important;
      cursor:pointer !important;
      margin-top:4px !important;
      transition:background 0.2s !important;
    }
    .ltq-submit:hover { background:#b81008 !important; }
    
    /* Note text */
    .ltq-note { font-size:0.62rem; color:#555; text-align:center; margin-top:6px; line-height:1.5; }
    .ltq-note a { color:#E8170A; text-decoration:none; }
    
    /* CF7 validation messages */
    .wpcf7-not-valid-tip { font-size:0.7rem; color:#E8170A !important; }
    .wpcf7-response-output { font-size:0.78rem !important; border-radius:5px !important; padding:10px 14px !important; }
    
    /* Fix CF7 overflow on mobile */
    .wpcf7 { width:100% !important; max-width:100% !important; overflow:hidden !important; }
    .wpcf7-form { width:100% !important; box-sizing:border-box !important; }
    				

    Auto-select city from postal code

    WPCode → Add Snippet → HTML → Footer location → paste this.

    Postal Code Auto-Select JS — WPCode Footer

    <script>
    document.addEventListener('DOMContentLoaded', function() {
    
      // Phone formatter — CF7 field
      var ph = document.getElementById('ltq-phone');
      if(ph) {
        ph.addEventListener('input', function() {
          var d = this.value.replace(/[^0-9]/g, '').slice(0, 10);
          if(d.length >= 7) this.value = '(' + d.slice(0,3) + ') ' + d.slice(3,6) + '-' + d.slice(6);
          else if(d.length >= 4) this.value = '(' + d.slice(0,3) + ') ' + d.slice(3);
          else this.value = d;
        });
      }
    
      // Postal code → city auto-select
      var postal = document.getElementById('ltq-postal');
      var city   = document.getElementById('ltq-city');
      if(postal && city) {
        postal.addEventListener('blur', function() {
          var p = this.value.toUpperCase().replace(/\s/g, '');
          var map = [
            ['M1', 'Scarborough'],
            ['M',  'Toronto'],
            ['L4', 'Mississauga'], ['L5', 'Mississauga'],
            ['L6', 'Brampton'],    ['L7', 'Brampton'],
            ['T3N','Calgary NW'],['T3K','Calgary NW'],['T3L','Calgary NW'],
            ['T2K','Calgary NW'],['T2L','Calgary NW'],['T2M','Calgary NW'],
            ['T2W','Calgary SW'],['T3H','Calgary SW'],['T3E','Calgary SW'],
            ['T2V','Calgary SW'],['T2T','Calgary SW'],['T2S','Calgary SW'],
            ['T2Z','Calgary SE'],['T2X','Calgary SE'],['T2Y','Calgary SE'],
            ['T3M','Calgary SE'],['T3J','Calgary SE'],['T2J','Calgary SE'],
            ['T3P','Calgary NE'],['T1Y','Calgary NE'],['T2A','Calgary NE'],
            ['T2B','Calgary NE'],['T2E','Calgary NE'],
            ['T2P','Calgary Downtown'],['T2R','Calgary Downtown'],
            ['T2G','Calgary Downtown'],['T2C','Calgary Downtown'],
          ];
          for(var i=0; i<map.length; i++) {
            if(p.startsWith(map[i][0])) {
              city.value = map[i][1];
              break;
            }
          }
        });
      }
    });
    </script>
    				

    Google Apps Script Webhook

    This replaces Make.com and Zapier entirely. A script that lives inside your Google Sheet and receives CF7 data directly. Free forever, no account limits, no expiry.

    Why Google Apps Script instead of Make.com? Make.com free tier limits you to 1,000 operations per month. Google Apps Script runs inside Google itself — unlimited free executions, no third-party account, no expiry, no rate limits for your volume.

    1

    Open your Google Sheet and create the Apps Script

    Open LocalTireQuote — Master in Google Sheets

    → Click Extensions → Apps Script

    → Delete everything in the editor

    → Paste the entire script below

    → Click Save (disk icon)

    Google Apps Script — Paste This Entire Script

    // LocalTireQuote — Google Apps Script Webhook
    // Receives CF7 form submissions and writes to Google Sheets + triggers VAPI
    // Deploy as web app — anyone can access, execute as me
    
    var SHEET_NAME = 'Driver Requests';
    var NOTIFY_EMAIL = 'partners@localtirequote.ca';
    var VAPI_API_KEY = 'YOUR_VAPI_API_KEY_HERE';
    var VAPI_ASSISTANT_ID = 'YOUR_VAPI_ASSISTANT_ID_HERE';
    var VAPI_PHONE_NUMBER_ID = 'YOUR_VAPI_PHONE_NUMBER_ID_HERE';
    
    // This runs when the form POSTs to this script URL
    function doPost(e) {
      try {
        var data = JSON.parse(e.postData.contents);
        writeToSheet(data);
        sendEmailAlert(data);
        triggerVapiCall(data);
        return ContentService
          .createTextOutput(JSON.stringify({status:'ok'}))
          .setMimeType(ContentService.MimeType.JSON);
      } catch(err) {
        return ContentService
          .createTextOutput(JSON.stringify({status:'error', message:err.message}))
          .setMimeType(ContentService.MimeType.JSON);
      }
    }
    
    // Also handle GET requests (for testing in browser)
    function doGet(e) {
      return ContentService
        .createTextOutput('LocalTireQuote webhook is live ✓')
        .setMimeType(ContentService.MimeType.TEXT);
    }
    
    function writeToSheet(data) {
      var ss    = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = ss.getSheetByName(SHEET_NAME);
      if(!sheet) sheet = ss.insertSheet(SHEET_NAME);
    
      // Auto-create headers if sheet is empty
      if(sheet.getLastRow() === 0) {
        sheet.appendRow([
          'Timestamp','Full Name','Phone','Email',
          'Postal Code','City','Vehicle','Tire Size',
          'Service','Urgency','Status','Source Page',
          'Confirmed Vehicle','Confirmed Service',
          'Call Outcome','Shop Assigned','Notes'
        ]);
      }
    
      // Append the new row
      sheet.appendRow([
        new Date().toLocaleString('en-CA', {timeZone:'America/Toronto'}),
        data['your-name']     || data['full-name'] || '',
        data['phone-number']  || data['tel']       || '',
        data['your-email']   || data['email']     || '',
        data['postal-code']  || '',
        data['city']         || '',
        data['vehicle']      || '',
        data['tire-size']    || '',
        data['service']      || '',
        data['urgency']      || '',
        'New',
        data['ltq_source_page'] || '',
        '','','','',''
      ]);
    }
    
    function sendEmailAlert(data) {
      var name    = data['your-name']    || 'Unknown';
      var phone   = data['phone-number'] || 'Not provided';
      var city    = data['city']         || 'Unknown';
      var service = data['service']      || 'Unknown';
      var urgency = data['urgency']      || 'Unknown';
    
      var subject = '🔔 ' + urgency + ' request — ' + name + ' in ' + city;
      var body = [
        'NEW DRIVER REQUEST — LocalTireQuote.ca\n',
        'Name:     ' + name,
        'Phone:    ' + phone,
        'City:     ' + city,
        'Vehicle:  ' + (data['vehicle'] || 'Not provided'),
        'Service:  ' + service,
        'Urgency:  ' + urgency,
        'Postal:   ' + (data['postal-code'] || ''),
        '\nAlex (VAPI) will call the driver within 2 minutes.',
      ].join('\n');
    
      MailApp.sendEmail(NOTIFY_EMAIL, subject, body);
    }
    
    function triggerVapiCall(data) {
      var phone = data['phone-number'] || '';
      if(!phone) return; // skip if no phone
    
      // Format phone to E.164 (+1XXXXXXXXXX)
      var digits = phone.replace(/\D/g, '');
      if(digits.length === 10) digits = '1' + digits;
      var e164 = '+' + digits;
    
      var payload = {
        assistantId: VAPI_ASSISTANT_ID,
        phoneNumberId: VAPI_PHONE_NUMBER_ID,
        customer: {
          number: e164,
          name: data['your-name'] || 'Driver'
        },
        assistantOverrides: {
          variableValues: {
            driver_name: data['your-name']   || 'there',
            vehicle:     data['vehicle']      || 'your vehicle',
            service:     data['service']      || 'tire service',
            city:        data['city']         || 'your area',
            urgency:     data['urgency']      || 'Today',
            tire_size:   data['tire-size']   || 'not provided',
            postal_code: data['postal-code'] || ''
          }
        }
      };
    
      var options = {
        method: 'post',
        contentType: 'application/json',
        headers: { Authorization: 'Bearer ' + VAPI_API_KEY },
        payload: JSON.stringify(payload),
        muteHttpExceptions: true
      };
    
      var resp = UrlFetchApp.fetch('https://api.vapi.ai/call/phone', options);
      Logger.log('VAPI response: ' + resp.getContentText());
    }
    
    // ── CF7 WEBHOOK HANDLER ──
    // CF7 sends data as form-encoded, not JSON.
    // This handles both formats automatically.
    function parseBody(e) {
      if(e.postData.type === 'application/json') {
        return JSON.parse(e.postData.contents);
      }
      // form-urlencoded
      var params = e.parameter;
      return params;
    }
    				

    2

    Deploy the script as a Web App

    In Apps Script → click Deploy → New Deployment

    → Select type: Web App

    → Description: LTQ Webhook v1

    → Execute as: Me

    → Who has access: Anyone

    → Click Deploy

    → Authorise the permissions when prompted (click Advanced → Go to LTQ Webhook → Allow)

    Copy the Web App URL — it looks like:

    https://script.google.com/macros/s/AKfyc.../exec

    Save that URL. This is your webhook endpoint. You will paste it into CF7 and into your site’s custom form action.

    3

    Add your VAPI credentials to the script

    At the top of the script, replace the three placeholder values:

    VAPI_API_KEY → from VAPI Dashboard → Account → API Keys

    VAPI_ASSISTANT_ID → from VAPI → Assistants → your assistant → copy ID from URL

    VAPI_PHONE_NUMBER_ID → from VAPI → Phone Numbers → click your number → copy ID

    Then click Save and Deploy → Manage Deployments → Edit → New Version → Deploy to update.

    4

    Connect CF7 to your Apps Script webhook

    Install the free plugin: Contact Form 7 – To – Webhook

    → WordPress → Plugins → Add New → search it → Install → Activate

    → Contact → Contact Forms → Edit your form → Webhooks tab

    → Paste your Apps Script URL

    → Method: POST

    → Save

    5

    Test it — submit the form and check the Sheet

    Go to your site → fill in the form → submit.

    Check Google Sheets — a new row should appear within 10 seconds.

    Check your email — you should receive the alert.

    Check your phone — VAPI should call within 2 minutes.

    Alex — Driver AI Agent

    Alex calls every driver within 2 minutes of form submission. Confirms their details, sets the 15-minute shop callback expectation, and ends warmly. Alex never sells. Alex solves.

    Alex

    Driver Confirmation Agent

    Calls drivers, confirms details, sets callback expectation

    Voice11Labs — Sarah (warm, clear)

    ModelGPT-4o

    Max duration5 minutes

    Avg call length90–120 seconds

    Triggers whenForm submitted → Apps Script fires

    StatusReady to deploy

    Jordan

    Shop Notification Agent

    Calls the partner shop after Alex confirms the driver

    Voice11Labs — Ash (professional)

    ModelGPT-4o

    Max duration3 minutes

    Avg call length45–60 seconds

    Triggers whenAlex call outcome = confirmed

    StatusReady to deploy

    VAPI System Prompt — ALEX (Driver Agent)

    You are Alex, a friendly and efficient booking assistant for LocalTireQuote.ca — Canada's tire service matching platform based in Toronto.
    
    Your ONLY job is to call a driver who just submitted a tire service request, confirm their details in under 2 minutes, and let them know a local shop will call them shortly.
    
    You never sell. You never upsell. You solve their problem fast.
    
    ## YOUR IDENTITY
    - Name: Alex
    - Company: LocalTireQuote.ca
    - Tone: Warm, calm, human, and quick. Like a helpful friend who works in customer service.
    - Never robotic. Never read from a script — have a conversation.
    
    ## WHAT YOU KNOW ABOUT THIS DRIVER
    You will receive these variables before the call:
    - {{driver_name}} — their name
    - {{vehicle}} — their vehicle (year make model)  
    - {{service}} — the service they need
    - {{city}} — their city
    - {{urgency}} — Emergency, Today, or Scheduled
    - {{tire_size}} — tire size if provided
    - {{postal_code}} — their postal code
    
    ## CALL STRUCTURE — FOLLOW THIS EXACTLY
    
    ### OPENING — First 15 seconds
    Say: "Hi, is this {{driver_name}}? Great — this is Alex from LocalTireQuote.ca. You just submitted a tire request and I am calling to quickly confirm your details. Takes about 90 seconds — is now okay?"
    
    If no or bad time: "No problem at all — we will follow up shortly. Have a great day." Then end the call.
    
    ### STEP 1 — CONFIRM VEHICLE
    "I have got {{vehicle}} on file — is that right?"
    - Yes → continue
    - No → "What is the correct vehicle?" → note it
    
    ### STEP 2 — CONFIRM SERVICE  
    "And you need {{service}} — still correct?"
    - Yes → continue
    - Changed → "Got it — what service do you need?" → note it
    
    ### STEP 3 — URGENCY HANDLING
    
    IF urgency is EMERGENCY:
    "I can see this is marked urgent. Are you dealing with a flat right now or is there another emergency situation?"
    
    If active flat tire: 
    "Stay safe — hazard lights on if you are on the road. Do not drive on the flat, it will damage your rim. We are treating this as a priority. A shop will call you in the next 10 to 15 minutes."
    
    If other emergency:
    "Understood — we are prioritising this. A shop will call you within 15 minutes."
    
    IF urgency is TODAY or SCHEDULED:
    "Perfect. We are matching you with the best available shop in {{city}} right now."
    
    ### STEP 4 — TIRE SIZE (only if not provided)
    If {{tire_size}} is blank or "not provided":
    "One quick thing — do you know your tire size by any chance? It is on a sticker inside your driver's door. Looks like 225/65R17. Totally fine if you do not have it — the shop can confirm it."
    
    ### STEP 5 — CLOSE EVERY CALL WITH THIS
    "Perfect — you are all set {{driver_name}}. A verified local shop in {{city}} will call you at this number within 15 to 20 minutes. Keep your phone close. Is there anything else before I let you go?"
    
    After they say no: "Great — the shop will call you soon. Thanks for using LocalTireQuote and have a great rest of your day!"
    
    ## COMMON QUESTIONS — ANSWER THESE
    
    Q: How much will it cost?
    A: "Pricing depends on your exact vehicle and tire size — the shop will give you a quote when they call. Our shops are vetted and offer fair competitive pricing."
    
    Q: Which shop is calling me?
    A: "We match based on your location and availability. The shop is local to {{city}}, vetted, and ready to help you today."
    
    Q: What if the shop does not call?
    A: "If you have not heard within 20 minutes, call or text us directly at 647 474 4602 and we will sort it out immediately."
    
    Q: Is this free?
    A: "Completely free for you. Shops pay a small referral fee — zero cost to you."
    
    ## RULES YOU MUST NEVER BREAK
    - Never give a specific price
    - Never name a specific shop
    - Never put the driver on hold
    - Never say "I don't know" — redirect to "the shop will confirm that"
    - Never end without setting the 15-minute callback expectation
    - If the driver goes off topic: "Great question — the shop will be able to help you with that. For now let me just confirm your details so we can get them to you quickly."
    
    ## CALL OUTCOMES — LOG ONE AT END
    Use the log_call_outcome function:
    - confirmed — driver confirmed, all good, shop will call
    - no_answer — did not pick up
    - voicemail — left voicemail
    - wrong_number — not the driver
    - cancelled — driver no longer needs service
    - callback_requested — driver asked to be called at a different time
    				

    VAPI First Message — ALEX (what Alex says the instant driver picks up)

    Hi, is this {{driver_name}}? This is Alex calling from LocalTireQuote.ca about your tire service request. I am just calling to quickly confirm your details — takes about 90 seconds. Is now okay?
    				

    VAPI Voicemail Message — ALEX

    Hi {{driver_name}}, this is Alex from LocalTireQuote.ca. You recently submitted a tire service request on our website. We are ready to match you with a local shop in {{city}}. Please call or text us back at 647 474 4602, or visit localtirequote.ca and resubmit your request. Thank you and have a great day!
    				

    VAPI Settings for Alex: Voice = 11Labs Sarah · Model = GPT-4o · Voice Speed = 0.95 · Max Duration = 300 seconds · Background Noise = Office · Voicemail Detection = Enabled · Silence Timeout = 10 seconds

    Jordan — Shop Notification Agent

    Jordan calls the partner shop immediately after Alex confirms the driver. Jordan gives the shop every detail they need and tells them to call the customer now. Fast, direct, no fluff.

    How Jordan is triggered: When Alex’s call ends with outcome = “confirmed”, the log_call_outcome VAPI function fires. Your Apps Script receives the confirmed data and calls the Jordan endpoint to call the assigned shop. You set the shop phone number per city in the script config below.

    VAPI System Prompt — JORDAN (Shop Notification Agent)

    You are Jordan, a professional dispatch coordinator for LocalTireQuote.ca.
    
    Your job is to call a partner tire shop and give them a confirmed customer request. You are fast, clear, and professional. This is a business-to-business call. You are not selling anything — you are delivering a confirmed customer who is waiting for their call right now.
    
    ## YOUR IDENTITY
    - Name: Jordan
    - Company: LocalTireQuote.ca
    - Tone: Professional, efficient, direct. Like a confident operations coordinator.
    - Keep it under 60 seconds. The shop needs to hang up and call the customer.
    
    ## WHAT YOU KNOW
    You will receive these variables:
    - {{shop_name}} — the name of the shop
    - {{driver_name}} — the customer's name
    - {{driver_phone}} — the customer's phone number
    - {{vehicle}} — confirmed vehicle
    - {{service}} — confirmed service needed
    - {{city}} — city/area
    - {{urgency}} — Emergency, Today, or Scheduled
    - {{tire_size}} — tire size (or "not provided")
    - {{call_time}} — what time the driver was confirmed
    
    ## CALL STRUCTURE — STAY ON THIS
    
    ### OPENING
    "Hi, is this {{shop_name}}? Great — this is Jordan from LocalTireQuote.ca. I have got a confirmed customer request for you in {{city}}. Do you have 30 seconds?"
    
    If no or busy: "No problem — I will send the details to your WhatsApp right now. The customer is expecting a call." Then end the call.
    
    ### DELIVER THE REQUEST — READ THIS OUT CLEARLY
    "Perfect. Here are the details:
    
    Customer name: {{driver_name}}
    Phone number: {{driver_phone}}
    Vehicle: {{vehicle}}
    Service needed: {{service}}
    Tire size: {{tire_size}}
    Urgency: {{urgency}}
    
    This customer has already been confirmed by our system. They are expecting a call from a local shop within the next 15 minutes. Their phone is ready."
    
    Then pause and say: "Do you have those details? Do you have any questions before you call them?"
    
    ### HANDLE QUESTIONS
    Q: Can we handle this job?
    A: "If you cannot take this one, let us know and we will reassign it. But the customer is ready right now."
    
    Q: When should we call?
    A: "Right now — they are expecting a call within 15 minutes. The sooner the better."
    
    Q: What about pricing?
    A: "That is between you and the customer — you quote them directly. We just handle the matching."
    
    Q: Is this the referral fee call?
    A: "No — referral fee applies after you confirm contact with the customer. Call them first, we will handle the billing separately."
    
    ### CLOSE
    "Great — {{driver_name}} is waiting at {{driver_phone}}. Call them now and let us know how it goes. Thanks {{shop_name}} — speak soon."
    
    ## RULES
    - Never stay on the call more than 90 seconds
    - Always read the customer phone number clearly — repeat it if needed
    - Never commit to a price on behalf of the shop
    - If the shop cannot take the job, note it and end the call
    - Always end with "call them now"
    
    ## CALL OUTCOMES — LOG ONE
    Use log_shop_outcome function:
    - notified — shop confirmed they received the details and will call
    - no_answer — shop did not pick up (send WhatsApp backup)
    - declined — shop cannot take this job (reassign)
    - voicemail — left voicemail with details
    				

    VAPI First Message — JORDAN

    Hi, is this {{shop_name}}? Great — this is Jordan from LocalTireQuote.ca. I have got a confirmed customer request for you right now in {{city}}. Do you have 30 seconds?
    				

    Apps Script — Add This Function to Trigger Jordan After Alex Confirms

    // Add this to your Google Apps Script
    // Called when VAPI sends back call outcome = "confirmed"
    // Configure your shop phone numbers per city below
    
    var JORDAN_ASSISTANT_ID = 'YOUR_JORDAN_ASSISTANT_ID';
    
    var SHOP_PHONES = {
      'Toronto':           '+1XXXXXXXXXX', // Replace with your shop's WhatsApp number
      'Mississauga':       '+1XXXXXXXXXX',
      'Brampton':          '+1XXXXXXXXXX',
      'Scarborough':       '+1XXXXXXXXXX',
      'Calgary NW':        '+1XXXXXXXXXX',
      'Calgary SW':        '+1XXXXXXXXXX',
      'Calgary SE':        '+1XXXXXXXXXX',
      'Calgary NE':        '+1XXXXXXXXXX',
      'Calgary Downtown':  '+1XXXXXXXXXX',
    };
    
    function triggerJordan(confirmedData) {
      var city = confirmedData.city || '';
      var shopPhone = SHOP_PHONES[city] || SHOP_PHONES['Toronto'];
    
      if(!shopPhone || shopPhone.includes('XXXXXXXXXX')) {
        Logger.log('No shop phone configured for city: ' + city);
        return;
      }
    
      var payload = {
        assistantId: JORDAN_ASSISTANT_ID,
        phoneNumberId: VAPI_PHONE_NUMBER_ID,
        customer: { number: shopPhone, name: 'Partner Shop' },
        assistantOverrides: {
          variableValues: {
            shop_name:    confirmedData.shopName    || 'Partner Shop',
            driver_name:  confirmedData.driverName  || 'the customer',
            driver_phone: confirmedData.driverPhone || '',
            vehicle:      confirmedData.vehicle     || 'not provided',
            service:      confirmedData.service     || 'tire service',
            city:         city,
            urgency:      confirmedData.urgency     || 'Today',
            tire_size:    confirmedData.tireSize    || 'not provided',
            call_time:    new Date().toLocaleTimeString('en-CA')
          }
        }
      };
    
      var options = {
        method: 'post',
        contentType: 'application/json',
        headers: { Authorization: 'Bearer ' + VAPI_API_KEY },
        payload: JSON.stringify(payload),
        muteHttpExceptions: true
      };
    
      UrlFetchApp.fetch('https://api.vapi.ai/call/phone', options);
      Logger.log('Jordan dispatched to shop in ' + city);
    }
    
    // This endpoint receives Alex's end-of-call data from VAPI
    function receiveCallOutcome(e) {
      var data = JSON.parse(e.postData.contents);
      if(data.call_outcome === 'confirmed') {
        triggerJordan(data);
        updateSheetWithOutcome(data); // Update Google Sheet row
      }
    }
    
    function updateSheetWithOutcome(data) {
      var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME);
      var values = sheet.getDataRange().getValues();
      for(var i = 1; i < values.length; i++) {
        if(values[i][2] === data.driverPhone) { // Match by phone (column C)
          sheet.getRange(i+1, 11).setValue('AI Confirmed');   // Status
          sheet.getRange(i+1, 13).setValue(data.confirmedVehicle  || '');
          sheet.getRange(i+1, 14).setValue(data.confirmedService  || '');
          sheet.getRange(i+1, 15).setValue(data.call_outcome || '');
          break;
        }
      }
    }
    				

    Jordan’s VAPI Settings: Create a SECOND assistant in VAPI called “LTQ Jordan — Shop Dispatch”. Voice = 11Labs Ash (professional male) · Model = GPT-4o · Max Duration = 180 seconds · Speed = 1.0. Copy the Jordan Assistant ID and put it in JORDAN_ASSISTANT_ID above.

    Go Live Checklist

    Complete every item in this order. Check them off as you go. Do not give out the pitch until all are green.

    🔒 Free to request. Shared only with your matched technician. Disclaimer

    Request received!

    We are matching you with a mobile technician in your area.
    Expect a call within 15–30 minutes to confirm.
    Stay with your vehicle if you are roadside.

    The process
    How mobile tire service works
    01

    Submit your request

    Tell us your location, vehicle, service needed, and best time. Under 90 seconds.

    02

    We match a technician

    Our system finds the nearest available verified mobile tire technician in your area.

    03

    We call you in 15 min

    Confirm details, time slot, and get an ETA. You know exactly when help is arriving.

    04

    Technician comes to you

    At your home, office, parking lot, or roadside. Tires sorted. Done.

    Our services
    Two mobile services — one request
    🚨

    Emergency Roadside Repair

    Flat tire on the highway or a side street? We dispatch a mobile technician to your exact location. Fastest possible response for emergency situations.

    • Flat tire repair or replacement on the spot
    • Emergency spare tire installation
    • Roadside on the 401, 403, 410, Gardiner (GTA)
    • Roadside on Deerfoot, Stoney Trail (Calgary)
    • Priority emergency dispatch
    • Stay safe — wait in your vehicle
    Get roadside help →
    Coverage
    GTA & Calgary mobile coverage

    We cover all major areas of the GTA and Calgary. If you are unsure whether we reach your location, submit a request and we will confirm coverage when we call.

    Greater Toronto Area

    GTA
    Toronto

    Downtown, North York, Etobicoke, East York, Rexdale

    GTA
    Mississauga

    City Centre, Meadowvale, Erin Mills, Port Credit, Cooksville

    GTA
    Brampton

    Downtown, Bramalea, Mount Pleasant, Springdale, Castlemore

    GTA
    Scarborough

    Wexford, Agincourt, Malvern, Highland Creek, Rouge

    Calgary, Alberta

    Calgary
    Calgary NW

    Tuscany, Kincora, Evanston, Sage Hill, Rocky Ridge

    Calgary
    Calgary SW

    Signal Hill, Aspen Woods, Evergreen, Coach Hill

    Calgary
    Calgary SE

    Mahogany, Auburn Bay, McKenzie Towne, Cranston

    Calgary
    Calgary NE & Downtown

    Martindale, Saddle Ridge, Beltline, Centre Street

    Why choose mobile
    No waiting rooms. No wasted time.
    🏠

    At your home or office

    Get tires changed while you work, sleep, or cook dinner. The technician handles everything in your driveway or parking spot.

    15-minute response

    We call you within 15 minutes of your request to confirm the technician and give you an ETA. No waiting in the dark.

    🚗

    No need to drive on a flat

    Driving on a flat ruins your rim. Stay where you are — we bring the service to you and protect your vehicle.

    🔒

    Free to request

    Submitting a request costs nothing. Shops pay us a referral fee. You get the convenience at zero cost.

    Verified technicians

    Every mobile technician in our network is vetted before they receive any requests from us.

    🌨️

    Winter-ready in Calgary

    Calgary winters are brutal. Mobile seasonal swaps mean you never have to drive on summer tires in a snowstorm.

    ⚖️

    Disclaimer — Important information about our service

    LocalTireQuote is a customer matching and referral service only. We are not a tire shop, mobile tire service provider, or mechanical repair business. Our role is solely to connect drivers with independent local tire professionals and mobile technicians in their area.

    LocalTireQuote does not employ, supervise, or control the mobile technicians or service providers in our network. All tire services are performed solely by independent partner technicians. LocalTireQuote is not responsible for the quality, safety, pricing, timeliness, or outcome of any service provided.

    By submitting a request, you agree your contact information and location details will be shared with one or more local partner technicians. We do not sell your information. Questions: [email protected] · (647) 474-4602