=== SowTrack Conversion Tracking ===
Contributors: leadseed
Tags: google tag manager, gtm, analytics, conversion tracking, lead tracking
Requires at least: 5.7
Tested up to: 7.1
Requires PHP: 7.2
Stable tag: 1.7.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Connects your site to LeadSeed, which sets up Google Tag Manager and conversion tracking for you. No theme editing; survives theme updates.

== Description ==

LeadSeed sets up Google Analytics and Google Tag Manager for small businesses, so they can see
which ads bring them leads. This plugin is how your WordPress site turns that tracking on.

1. Install and activate this plugin.
2. Tap **Connect to LeadSeed** (on the Plugins screen, or under **LeadSeed** in your WordPress
   menu), then tap **Approve** in LeadSeed. You land back in your LeadSeed setup, connected.
   Prefer a token? Open **LeadSeed** in your WordPress menu, choose "Have a connection token
   instead? Paste it", paste the token from your LeadSeed onboarding ("Turn on tracking" step), and
   click **Save & check connection**.
3. That's it. The plugin fetches your Google Tag Manager container from LeadSeed and adds the
   snippet to every page for you. The settings page shows whether your connection is live, and
   **Disconnect this site** turns it off.

What the plugin does on your site:

* Adds your Google Tag Manager snippet to every page (in the `<head>`, plus the standard
  `<noscript>` fallback), once your LeadSeed setup is ready.
* Remembers ad click IDs (such as `gclid` and `fbclid`) and UTM tags from the page a visitor lands
  on, in a first-party cookie, so a later form submission can be credited to the ad that brought
  them.
* Sends each contact-form submission (Contact Form 7, Gravity Forms, WPForms, SureForms,
  Elementor Pro, Fluent Forms, Ninja Forms or Jetpack Forms) to the lead sheet in **your own**
  Google account. How it gets there depends on how your LeadSeed account is set up:
  * **Through LeadSeed** (the newer setup, from version 1.6.0): the plugin sends the lead to LeadSeed,
    which adds it as a row in your lead sheet and keeps no copy. Each lead is first saved in a small
    table in your own WordPress database, and deleted from it as soon as LeadSeed confirms the row
    was written, so a lead is never lost if LeadSeed or Google is briefly unreachable. It is sent
    after your visitor's page has finished, so visitors never wait. The LeadSeed settings page shows
    how many leads are waiting, if any (never their details).
  * **Directly** (the older Apps Script setup): the lead goes from your site straight to your own
    Google Apps Script and never passes through LeadSeed.

The plugin holds no credentials to your LeadSeed account beyond the connection token, which only
lets it fetch your own tracking settings. It never gives LeadSeed access to your WordPress admin.

A LeadSeed account is required. Until you tap Connect to LeadSeed or paste a connection token, the
plugin only remembers ad click IDs in a first-party cookie; it contacts no outside service.

== External services ==

This plugin connects to the services below. None of them is contacted until an administrator taps
**Connect to LeadSeed** or saves a LeadSeed connection token on the plugin's settings page.

= LeadSeed =

LeadSeed (https://myleadseed.com) provides your tracking configuration.

* Connecting with the button: only when an administrator taps **Connect to LeadSeed** (or **Try
  again** or **Reconnect**), the plugin sends that administrator's browser to
  `https://myleadseed.com/connect/wordpress`. The address carries your site's address, the address
  of the plugin's settings page (where LeadSeed sends the browser back), a random one-time value, a
  one-way fingerprint of a second random value that stays on your site, and the time of the tap.
  Nothing else is sent, and no request leaves your server at this point. Before showing **Approve**,
  LeadSeed checks this site's `/wp-json/leadseed/v1/connect-check` to confirm the request came from
  your site; that endpoint answers only whether the attempt is real, with the one-way fingerprint
  above, and nothing else.
* After you tap **Approve** in LeadSeed: your server sends the one-time code LeadSeed returned, the
  second random value, your site's address and the plugin version to
  `https://myleadseed.com/api/connectors/wordpress/connect/exchange`, once, and receives your
  connection token in reply. The token is never put in a web address.
* Disconnecting: only when an administrator taps **Disconnect this site**, the plugin sends the
  connection token to `https://myleadseed.com/api/connectors/wordpress/disconnect` so LeadSeed marks
  the site as disconnected. The plugin then deletes the token and your tracking settings from your
  site, whether or not LeadSeed answered. If LeadSeed couldn't be reached, the plugin keeps the
  token only to repeat that one call (on its five-minute scheduled task and when wp-admin loads)
  until LeadSeed confirms; it is never used for anything else.
* Fetching your settings: once a connection token is saved, the plugin sends that token to
  `https://myleadseed.com/api/connectors/wordpress/pull` as soon as it is saved, every five minutes on a
  WordPress scheduled task, and at most once every five minutes when wp-admin (including WordPress's
  admin-ajax requests) is loaded. The request also carries your site's address and WordPress
  version, as every WordPress HTTP request does. (LeadSeed support can point the plugin at a
  different LeadSeed address for testing, through the "LeadSeed URL" setting or a
  `LEADSEED_API_BASE` constant in wp-config.php; leave both unset unless support asks. On a
  production site an address that isn't https is ignored unless it points at the site's own machine.)
  From version 1.6.0 the request also carries two numbers: how many leads are waiting on your site
  to be sent to LeadSeed, and how many could not be saved for sending. Never any lead's details.
* What comes back: your Google Tag Manager container ID, how your leads should be delivered
  (through LeadSeed, or directly to your own Apps Script) and, for the direct way, the address and
  shared secret of your own lead sheet.
* Sending your leads (only if your LeadSeed account delivers leads through LeadSeed): each time a
  visitor submits a supported contact form, the plugin sends what they entered in the form (name,
  email, phone number and message), the address of the page, any ad click IDs and UTM tags, the
  time, a random lead ID, which form plugin it came from, whether it was your own test enquiry, and
  the plugin version to `https://myleadseed.com/api/leads/ingest`, with your connection token.
  LeadSeed adds the lead to your own Google Sheet and does not keep it. If LeadSeed can't take it
  straight away, the plugin keeps it on your site and sends it again later (on its five-minute
  scheduled task, when wp-admin loads, or when LeadSeed signals it is ready), until LeadSeed
  confirms it.
* "Ready" signal: LeadSeed may call this plugin's public `/wp-json/leadseed/v1/flush` address to
  say "try sending waiting leads now". That call carries no data and the answer contains none; the
  plugin acts on it at most once a minute, and only does what its scheduled task would do anyway.
* LeadSeed also reads this plugin's public status endpoint
  (`/wp-json/leadseed/v1/status`) to confirm your tracking is installed. That endpoint reports only
  whether the snippet is installed, the container ID, the plugin version, whether a lead sheet
  is configured (yes/no), and whether leads are delivered through LeadSeed or directly.
* Terms of service: https://myleadseed.com/terms
* Privacy policy: https://myleadseed.com/privacy

= Google Tag Manager =

Google Tag Manager is what records visits and conversions for your Google Analytics and ad
accounts. Once your LeadSeed setup is ready, every page of your site loads Google's tag script from
`https://www.googletagmanager.com` in each visitor's browser. What is collected then depends on
the tags in your container, which LeadSeed sets up for you in your own Google account. Those tags
can include ones for ad platforms you connect (for example Google Ads or Meta), which send visit and
conversion data to that platform under its own terms.

* Terms of service: https://marketingplatform.google.com/about/analytics/tag-manager/use-policy/
* Privacy policy: https://policies.google.com/privacy

= Google Apps Script (your lead sheet) =

Only if you connected a lead sheet with LeadSeed's older Apps Script setup: when a visitor submits a supported contact form, the
plugin sends the submission's name, email, phone, message, page address, any ad click IDs and UTM
tags, a timestamp, a random lead ID, and a shared secret to your own Google Apps Script web app at
`https://script.google.com/macros/s/.../exec`, which writes the lead into your Google Sheet. This
script runs in your own Google account; LeadSeed does not receive the lead.

* Terms of service: https://developers.google.com/apps-script/terms
* Privacy policy: https://policies.google.com/privacy

== Privacy ==

This plugin sets one first-party cookie, `leadseed_clk`, only when a visitor arrives from a link
carrying ad click IDs or UTM tags. It stores those values for 90 days so a form submission can be
credited to the right ad. If your site uses a cookie-consent tool, configure it to cover this
cookie and Google Tag Manager as your local rules require.

A second cookie, `leadseed_test`, is set for one hour only when someone opens your site through
LeadSeed's test link (an address ending in `?leadseed_test=1`). It marks that person's enquiries
as tests, so they are labelled in your sheet and never counted as sales.

When your leads are delivered through LeadSeed, each one waits in a table in your own WordPress
database (`wp_leadseed_lead_queue`, with your site's table prefix) only until LeadSeed confirms it.
Disconnecting the site or deleting the plugin removes the table, with any lead still in it.

== Frequently Asked Questions ==

= Do I need a LeadSeed account? =

Yes. The plugin connects your site to LeadSeed; without an account it cannot add any tracking.
Sign up at https://myleadseed.com.

= Do I need a connection token? =

Not usually. Tap **Connect to LeadSeed** and approve in LeadSeed instead. If the button can't
finish on your site (a security or caching plugin can block the link back), the plugin says so and
offers the paste box.

= Where do I get the connection token? =

From your LeadSeed onboarding, on the "Turn on tracking" step. It starts with `ls_`.

= How do I disconnect my site? =

Open **LeadSeed** in your WordPress menu and tap **Disconnect this site**. Tracking stops on your
pages straight away. If any leads haven't reached your lead sheet yet, the page tells you how many
first: disconnecting deletes them from your site.

= The settings page says leads are waiting to be sent. =

Nothing to do: they are safe on your site and the plugin keeps trying until LeadSeed confirms each
one. If the number keeps growing for more than a day, or the page says leads could not be saved on
this site, check your LeadSeed connection or contact LeadSeed support.

= It says "Token rejected". =

Re-copy the token from LeadSeed and paste it exactly (no extra spaces), then click Save & check
connection again. If you have lost the token, generate a new one in LeadSeed; the new one replaces
the old.

= Does this edit my theme? =

No. The snippet is added by the plugin when each page is built, so it survives theme updates.

= What happens if I deactivate or delete the plugin? =

Deactivating stops the snippet and the scheduled check straight away. Leads still waiting to be
sent stay saved and are sent after you reactivate it. Deleting the plugin also removes everything it
stored, including your connection token and any leads still waiting to be sent.

== Changelog ==

= 1.7.0 =
* Renamed to SowTrack Conversion Tracking; no functional change. The plugin still connects your
  site to LeadSeed, and its LeadSeed menu, settings and connection are unchanged.
* The plugin's folder is now `sowtrack`.

= 1.6.0 =
* Leads can now be delivered through LeadSeed, which writes them into the lead sheet in your own
  Google account — no Apps Script to paste or deploy. LeadSeed tells the plugin which way your
  account works; sites on the older Apps Script setup keep working exactly as before.
* Every lead sent through LeadSeed is saved on your own site first and kept until LeadSeed confirms
  it, so a lead is never lost to a brief outage. Sending happens after the visitor's page has
  finished, so forms are never slowed down.
* The settings page shows how many leads are waiting to be sent, if any. Disconnecting tells you
  first if waiting leads would be deleted.
* Opening your site through LeadSeed's test link marks your own test enquiry as a test.

= 1.5.0 =
* New **Connect to LeadSeed** button: tap it, approve in LeadSeed, and you're connected. No token to
  copy. Your site and LeadSeed swap the connection token directly, server to server.
* New **Disconnect this site** button on the LeadSeed settings page.
* Until the site is connected, the Plugins screen shows a reminder to connect, which you can dismiss.
* The paste-a-token form still works exactly as before. Sites already connected with a token stay
  connected when they update.

= 1.4.0 =
* Prepared for the WordPress.org plugin directory: the plugin's folder is now `leadseed`, scripts
  are printed with WordPress's own script helpers, and the readme documents every external service
  the plugin uses.
* Requires WordPress 5.7 or later.
* If you installed an earlier version from a .zip file, deactivate and delete it before installing
  this one, then paste your connection token again (deleting the old copy removes its settings).
  While an older copy is still active, WordPress will refuse to activate this version.

= 1.3.0 =
* Lead capture now also covers SureForms, Elementor Pro forms, Fluent Forms, Ninja Forms and
  Jetpack Forms — alongside Contact Form 7, Gravity Forms and WPForms. Same direct site-to-Google
  flow: your leads go straight to your own Google Sheet and are never routed through LeadSeed.
* The connection status endpoint now reports whether a lead destination is configured, so LeadSeed
  support can tell "not connected yet" apart from "connected but not working" without asking you to
  dig through wp-admin. Only a yes/no is exposed — never your sheet URL or your secret.

= 1.2.0 =
* Lead capture now also forwards WPForms submissions (Lite and Pro, AJAX and native) to your
  connected Google Sheet — same direct site-to-Google flow as Contact Form 7 and Gravity Forms.

= 1.1.0 =
* Lead capture: forwards Contact Form 7 and Gravity Forms submissions (with ad click-IDs) straight
  to the Google Sheet you connect in LeadSeed. Lead data flows directly into that sheet — it is never
  routed through LeadSeed.

= 1.0.0 =
* Initial release: pull-based GTM snippet injection + connection status endpoint.

== Upgrade Notice ==

= 1.7.0 =
Renamed to SowTrack Conversion Tracking; no functional change. The folder is now `sowtrack`: if you
installed the LeadSeed plugin from a .zip file, deactivate and delete it first, then connect again.

= 1.6.0 =
Adds lead delivery through LeadSeed (no Apps Script needed). Existing setups keep working unchanged.

= 1.5.0 =
Adds the Connect to LeadSeed button and Disconnect this site. Sites already connected stay connected.

= 1.4.0 =
The plugin's folder is now `leadseed`. If you installed an earlier version from a .zip file,
deactivate and delete it first, then paste your connection token again.
