=== Revys ===
Contributors: revys
Tags: reviews, google reviews, testimonials, seo, schema
Requires at least: 6.0
Tested up to: 7.1
Requires PHP: 8.0
Stable tag: 1.4.2
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Show your Google reviews as server-rendered HTML that Google and AI search engines can read. Synced nightly by Revys. Requires a Revys account.

== Description ==

Revys is a review service (SaaS) published by OZAPP SRL (Belgium). It collects the **Google reviews** of your business through the official Google Business Profile API (you connect your profile with Google OAuth in your Revys dashboard), then **pushes them to your WordPress site every night** over a signed connection (HMAC SHA-256).

This plugin is the WordPress side of that connection. It receives the reviews, stores them in your WordPress database and **renders them on the server**: the reviews are part of the static HTML of your page, with no JavaScript needed to display them. Search engine crawlers and AI assistants that read pages without running JavaScript (Google, ChatGPT search, Google AI Overviews, Perplexity…) can therefore read your reviews, which is not the case with most review widgets loaded by JavaScript or in an iframe.

**A Revys account is required.** The plugin does nothing on its own: the reviews come from your Revys account. A free plan (one Google Business Profile) and a paid Pro plan are available on [revys.io](https://revys.io).

= Features =

* Google reviews shown as server-side HTML: author, rating, date and text, with the layout, theme and style chosen in your Revys dashboard (carousel, grid, list, badge, wall; light or dark).
* Compliant `schema.org` structured data: an `Organization` object (name, URL) only. The plugin never outputs `AggregateRating` or `Review` markup for your own business (see the FAQ).
* "Revys Reviews" block for the block editor, and the `[revys_reviews widget="ID"]` shortcode.
* Settings page (top-level "Revys" menu, also under Settings → Revys) to paste your connection secret, with an immediate check against Revys.
* Signed, push-based sync: Revys sends the reviews to a dedicated REST endpoint of your site; requests without a valid signature are rejected.
* The widget markup sent by Revys is filtered before output (strict allow-list of tags and attributes, stylesheet scoped to the widget, JSON-LD re-encoded). No JavaScript is added to your pages.
* Translation-ready (translations are managed on translate.wordpress.org).

= Supported review sources =

* **Google** (Google Business Profile): available.
* Facebook and Trustpilot: planned, **not available yet**.

= Free plan credit =

On the free Revys plan, the widget rendered by the Revys service ends with a small "Widget gratuit par Revys" credit linking to revys.io (`rel="nofollow sponsored"`). It is part of the service output, not added by the plugin, and it is removed on the paid plan.

= Source code =

The plugin ships with its full, human-readable source code (no build step, no minified or obfuscated file).

== Installation ==

1. In WordPress, go to Plugins → Add New, search for "Revys", then click Install Now and Activate. (Or upload the `revys` folder to `/wp-content/plugins/`.)
2. Create a Revys account on [revys.io](https://revys.io) and connect your Google Business Profile.
3. In your Revys dashboard, open My businesses › your business › On my website and click "Put on my website". Enter or confirm your site's address and follow the WordPress steps: click "Generate the secret" and copy the **connection secret** (it is shown only once).
4. In WordPress, open the "Revys" menu (or Settings → Revys), paste the secret and click Save. The plugin checks the secret with Revys; if it matches, Revys sends the first sync right away.
5. Add the "Revys Reviews" block, or the shortcode `[revys_reviews widget="YOUR_WIDGET_ID"]`, to a page or post. The last WordPress step in Revys shows the shortcode with the right widget ID.

== Frequently Asked Questions ==

= Do I need a Revys account? =

Yes. The reviews are collected by the Revys service and pushed to your site. Without a Revys account and a connection secret, the plugin shows nothing.

= Which review platforms are supported? =

Google reviews (Google Business Profile) only, for now. Facebook and Trustpilot are planned but not available yet.

= Where do I find my widget ID and my secret? =

In your Revys dashboard, open My businesses › your business › On my website, click "Put on my website" and follow the WordPress steps: "Generate the secret" shows the secret (only once), and the last step shows the shortcode with your public widget ID. The shortcode is also under "Embed code" on your widget's card, on the same page.

= Does the plugin send data to an external service? =

Only once, when you save the secret: the plugin asks Revys (revys.io) whether this secret matches your site's connection. It sends your site address, a timestamp and a signature computed with the secret, never the secret itself and never any data about your visitors. The rest of the time, Revys sends the reviews to your site (push-based): the plugin checks their signature, then stores and displays them. See "External services" below.

= Will I get review stars in Google search results? =

No, and no plugin can honestly promise that. Google's rules on review snippets do not allow "self-serving" reviews: star ratings that a business publishes about itself on its own website are not eligible, and neither is review markup copied from other platforms such as Google itself. That is why this plugin only outputs `Organization` structured data and never `AggregateRating` or `Review` markup. What the plugin does is make the review content visible in the HTML of your page, so search engines and AI assistants can read it.

= Does it add JavaScript to my pages? =

No. The reviews are rendered on the server. The only script file is the block editor script, loaded in the editor.

= Does it slow down my site? =

No external request is made when a page is displayed: the reviews are read from your WordPress database. The fallback stylesheet is only loaded on pages that need it.

= What happens to my data when I delete the plugin? =

Deleting the plugin from the Plugins screen removes its options: the connection secret, the sync timestamps and the stored reviews. Deactivating it keeps them.

== External services ==

This plugin connects to **Revys** (https://revys.io), a review service published by OZAPP SRL (Belgium). The service is required: it collects your Google reviews and provides the content the plugin displays.

**1. Secret check (request sent by your site to Revys)**

* What: a `POST` request to `https://revys.io/api/wordpress/verify`.
* When: only when an administrator saves a connection secret on the Revys settings page. Never on page views, never on a schedule.
* Data sent: your site's home URL, the current timestamp, and an HMAC SHA-256 signature of those two values computed with the secret (in the `X-Revys-Signature` header). The secret itself is not sent. No data about your visitors or users is sent.
* Why: to tell you right away whether the secret matches your site's connection in Revys and, if it does, to let Revys send the first sync.

**2. Review sync (requests sent by Revys to your site)**

* What: Revys calls the REST endpoint `POST /wp-json/revys/v1/sync` of your site.
* When: every night, right after a secret is successfully checked, and when you click "Sync now" in your Revys dashboard (My businesses › your business › On my website).
* Data received: the reviews of the connected Google Business Profile (author name, author picture URL, rating, text, language, date), the business name and URL, the display settings and the widget markup rendered by Revys. Requests without a valid signature are rejected. Your site answers with the widget ID and the number of reviews stored.

Author pictures, when present in the reviews, are image URLs served by Google; visitors' browsers load them when the reviews are displayed.

Developers can point the plugin to another Revys instance (for local testing) with the `REVYS_API_URL` constant or the `revys_api_url` filter.

The reviews themselves are retrieved by Revys from Google through the official Google Business Profile API, under your Google account's authorization; the plugin does not contact Google.

* Revys terms and conditions: https://revys.io/legal/cgv
* Revys privacy policy: https://revys.io/legal/confidentialite

== Changelog ==

= 1.4.2 =
* The widget stylesheet is now loaded through the WordPress styles API (printed in the page head when the widget is in the post content) instead of a `<style>` element inside the widget markup. The reviews and their structured data stay in the page HTML.
* Translations are now delivered by translate.wordpress.org language packs (bundled translation files removed).

= 1.4.1 =
* The instructions point to the new Revys dashboard path: My businesses › your business › On my website › "Put on my website" (WordPress) › "Generate the secret", and "Sync now" on the site's card.
* Clearer messages when the secret check fails: what to do when the secret is lost, when the site address differs, or when Revys cannot be reached (click Save again to retry).
* The settings page says where to find the widget ID for the shortcode.

= 1.4.0 =
* Ready for the WordPress.org plugin directory: English source strings, bundled French translation, translation-ready block editor script.
* The sync endpoint now checks the request signature in its REST permission callback (same protocol, same responses).
* Deleting the plugin now removes all its options (secret, sync timestamps, stored reviews), on every site of a multisite network.
* The fallback stylesheet is no longer loaded by the block when the Revys rendering is used.
* Structured data: the fallback JSON-LD is now encoded with `<`, `>` and `&` escaped.

= 1.3.2 =
* If you paste a Revys API key ("rv_…") instead of the WordPress connection secret, the plugin does not save it and explains where to find the right secret.
* The instructions point to the new Revys page "Afficher mes avis" (Show my reviews) → WordPress.

= 1.3.1 =
* The secret is checked as soon as it is saved: the plugin asks Revys whether it matches the site's connection and shows the result (verified, wrong secret, site unknown to Revys, Revys unreachable). If it is correct, Revys starts the first sync right away.
* The Revys page has its own menu in the admin sidebar (the Settings → Revys shortcut remains), and a "Settings" link appears on the Plugins screen.

= 1.3.0 =
* The widget looks exactly as in Revys: Revys now sends the ready-made rendering (styles, templates, buttons, "Read more"), still server-side and without JavaScript. The plugin filters it before output (tag allow-list, stylesheet limited to the widget, structured data re-encoded). New dashboard styles no longer require a plugin update.
* Compatibility: without this rendering (older Revys version), the previous plugin rendering is kept.

= 1.2.0 =
* Settings → Revys page: the "Connected" status only appears after a sync has actually been received with the current secret, with its date; otherwise "Waiting for the first sync".

= 1.1.0 =
* The rendering now follows the layout (carousel, grid, list, badge, wall), the theme (light/dark) and the style options (accent color, number of columns, corner radius, hiding the Google branding) chosen in the Revys dashboard.

= 1.0.0 =
* Initial release: secure REST endpoint, shortcode, Gutenberg block, settings page, server-side rendering + Organization structured data.

== Upgrade Notice ==

= 1.4.2 =
Widget styles loaded through the WordPress styles API; translations delivered by translate.wordpress.org. No change to your settings or reviews.

= 1.4.1 =
Instructions updated for the new Revys dashboard ("On my website"). No change to your settings or reviews.

= 1.4.0 =
English interface with bundled French translation, stricter sync endpoint permission check and full cleanup on uninstall. No change to your settings or reviews.
