Marketing
Product reviews in Go
A Go package for what shoppers say about a product: a rating from one to five and some words. A review waits for an operator unless the store approves on sight, and it is marked verified when its email has bought the product. Nothing is required; two switches sit on the Plugins screen.
- Marketing module
- 3 settings
- 15 tests
- 8 API operations
- ext/reviews
What it does
In the package’s own words, a review is “a rating out of five and some words, moderated before it shows.” The storefront posts one to POST /x/reviews and reads a product’s approved reviews from GET /x/reviews?product_id=, with the count, the average to one decimal and the number at each star beside them. The reviewer’s email is kept for the store and never sent to the storefront.
A review is marked verified when its email has an order for the product in the confirmed, partial, shipped or delivered status: the store’s own definition of a sale. The Plugins screen can make that a condition of posting at all. On the Reviews screen an operator approves or rejects a review, writes a public reply under it, or deletes it.
Reviews also travel as a CSV file. The package names two jobs: a store moving in from another platform “arrives with a few thousand reviews in a CSV and no other way to get them here”, and a store already running moderates in bulk by exporting, sorting by rating, and pasting a column of statuses back.
Configuration
Nothing is required. Config holds two switches, which become the Plugins screen’s defaults; the screen holds the same two and wins.
| Setting | Environment variable | Required | What it does |
|---|---|---|---|
AutoApproveShow reviews without moderation | — | No | Shows a review the moment it is posted. Off by default, so every new review waits as pending. |
RequirePurchaseOnly buyers may review | — | No | Refuses a review from an email with no order for the product, and asks for the email the order was placed with. Public, so the storefront can say so on the form. |
promptForm heading | — | No | The review form’s heading, “Write a review” by default. Public. Panel only; there is no Config field for it. |
The module reads its Config struct, not the environment. The variable names are the ones the package’s own example or the reference binary uses; in your own main() you choose where each value comes from. Where a setting has a panel label, the admin’s settings drawer can hold it too, and a value typed there wins over Config.
Setting it up
- Install the modulePass reviews.New to gocommerce.New, as below, or start the reference binary with -reviews. It adds one table, and the plugin starts switched on.
- Choose the policyUnder Product reviews on the Plugins screen: approve on sight or moderate, and whether only buyers may review.
- Draw the form and the listThe storefront posts product_id, name, email, rating, title and body to POST /x/reviews, and reads GET /x/reviews?product_id= for the approved reviews and their summary.
- ModerateThe Reviews screen lists reviews by status. PATCH /api/admin/x/reviews/{id} sets the status or the reply; DELETE removes the review.
main.go
import (
"github.com/itswadesh/gocommerce/core"
"github.com/itswadesh/gocommerce/ext/reviews"
)
app, err := gocommerce.New(cfg, reviews.New(reviews.Config{})) The package doc has no example of its own; this is how the reference binary’s -reviews flag and examples/store/main.go install it. cfg is your gocommerce.Config. Import path github.com/itswadesh/gocommerce/ext/reviews.
How it works
-
Held, then shown
A new review is pending unless auto-approve is on. Only approved reviews reach the storefront and count toward the summary; a rejected one stays in the admin list.
-
Verified by the orders
The badge is set when the review is posted, from an order carrying the product under the reviewer’s email, compared lower-cased, in the confirmed, partial, shipped or delivered status.
-
No email on the storefront
The public list carries the name, rating, title, body, badge, reply and date. The email stays on the admin side, masked on a demo store or for an agent key, where search stops matching it.
-
A honeypot for bots
A hidden website field that a person never sees. A request that fills it is answered as if the review were accepted, and nothing is kept.
-
A file both ways
The export streams every review, newest first, with its product’s slug and title. On import a row with an id updates that review, and a blank cell leaves its column alone; a row without one is a new review, found by product_slug.
-
Row by row, with a rehearsal
Each imported row is its own transaction, so a row naming a product that is not here is a row error and the rest still land. ?dry_run=1 checks every row and rolls each back. A file is read up to 32 MB.
What it does not do
Read these before an order depends on it. No store is known to run GoCommerce in production yet, so these come from the code, not from anyone’s experience.
- A honeypot, nothing moreThe module has no captcha and no rate limit of its own, and does not stop one email posting several reviews of one product.
- Text and stars onlyNo photos and no helpful votes. A shopper cannot edit or withdraw a review after posting it; an operator can only change its status or reply, or delete it.
- Nobody is toldThe module sends no notice when a review is waiting. Pending reviews are found on the Reviews screen.
- An import is believedA file’s status is applied as written, so an approved row goes live without moderation; a row with no status is pending. A file with a verified column is taken at its word, because a store moving in carries verifications its orders here cannot show. Without the column, the store’s orders decide.
- Sample reviews show until erasedThe sample shop adds one approved review to each sample product, written by a sample customer whose sample order bought it. They are flagged as samples and erased with the rest of the sample shop, which the package says to do before opening.
- The file has no buttonExport and import are API routes, GET /api/admin/x/reviews/export and POST /api/admin/x/reviews/import. The Reviews screen does not offer them.
FAQ
Questions about the Product reviews module
Does the store ever show a review nobody wrote?
Only the sample shop’s. Its reviews are flagged as samples, and erasing the sample shop removes them and no shopper’s. In the package’s words, “a review nobody wrote is not one to show a real shopper.” The module adds no other reviews of its own.
What makes a review verified?
An order for the product placed with the reviewer’s email, in the confirmed, partial, shipped or delivered status. It is decided when the review is posted. An imported review takes the file’s verified column if it has one, and the orders’ answer if it does not.
Can I bring reviews from another platform?
Yes, as a CSV with the columns id, product_slug, product_title, name, email, rating, title, body, status, verified, reply and created_at. The product is named by its slug here; product_title is ignored on the way in. Run it with ?dry_run=1 first to see each row’s errors without writing anything.
Who can moderate?
Seeing reviews needs reviews.read, which managers and staff hold by default. Approving, rejecting, replying and deleting need reviews.moderate, which managers hold by default. The export needs data.export and the import data.import.
What does switching the plugin off do?
Both storefront routes answer 404. The Reviews screen and the admin routes keep working, so an operator can still read and moderate.
Source
Everything on this page is read from ext/reviews in the GoCommerce repository, MIT licensed. When this page and the code disagree, the code is right and this page is out of date.
Try it against a store of your own
The backend + admin quick start runs GoCommerce’s API and admin on your own machine, without a storefront. Add this module to it and try it on test orders before a real one depends on it.