Sitemap
Sharif Bhuiyan

Sharif Bhuiyan

Founder of COR2TECT. A cogitator & procrastinator ... framework architect, IT startup expert & creative engineer to build ideas for what is important for us.

When ReviewPro’s Scheduled Reports Fell Short: Building a Fully Automated Workflow with Google Apps Script

3 min readJul 21, 2026

--

Press enter or click to view image in full size

I recently needed to automate the retrieval of guest review reports from ReviewPro. At first glance, the platform’s scheduled reporting feature looked like the perfect solution. However, after implementing it, I discovered two limitation(s).

  1. Instead of sending the actual Excel report as an attachment — or even providing a direct download URL — the scheduled report emails contain an HTML page with a download button. Since the download link is generated dynamically, the URL cannot simply be extracted and reused by an automation script.
  2. ReviewPro blocks the Google App Script UrlFetchApp request by returning the HTTP 403 code.

To make it automatic, I need to solve both of the above problems, right!

The scope of this article is to show the URL generation process and why use lightweight API if you are using google app script.

Lets talk about how I automated it completely!

Step 1 — Extract the Job ID

The initial ReviewPro report URL contains a jobId and two (2) other parameter(s).

Example:

...&jobId=120660963&lang=en&userId=...

Google App Script

var html = message.getBody();

// Find download link
var match = html.match(/<a\b[^>]*href="([^"]+)"[^>]*>\s*Download Your Report Now\s*<\/a>/i);
if (!match) return;
var downloadUrl = match[1];
var queryEndpointParam = getQueryParam_(downloadUrl, "endpoint");
var queryHashParam = getQueryParam_(downloadUrl, "hash");
var jobId = getQueryParam_(downloadUrl, "jobId");
Logger.log("jobId: " + jobId);
var newDownloadUrl = `https://app.reviewpro.com/api/report-server/download/anonymousReport/orm_tracking_xls/${jobId}?endpoint=${queryEndpointParam}&hash=${queryHashParam}&lang=en`;
var generatedReportId = fetchFromCloudRunAPI_(newDownloadUrl);
Logger.log(generatedReportId);
...
..
var your_file_name = "....";
var finalDownlodUrl = `https://app.reviewpro.com/api/report-server/download/${generatedReportId}?fileName=${your_file_name}

Step 2 — Generate the Anonymous Report URL

Using the Job ID, construct the anonymous download endpoint.

Get Sharif Bhuiyan’s stories in your inbox

Join Medium for free to get updates from this writer.

Structure:

https://app.reviewpro.com/api/report-server/download/anonymousReport/orm_tracking_xls/{JOB_ID}?endpoint=...&hash=...

This endpoint does not download the report. Instead, it creates a temporary report instance.

Step 3 — Generate the Report ID

Opening the anonymous URL returns a long identifier.

Example:

164324xxxxx_xxxxxxxxxxxxxxxx

This ID represents the actual generated report. Think of it as a temporary token used for downloading the final file.

Step 4 — Download the Report

Finally, use the generated Report ID.

Structure:

https://app.reviewpro.com/api/report-server/download/{REPORT_ID}?fileName=ABC_Reviews.xlsx

This URL immediately downloads the Excel report…boom! Now it is very easy to automate.

Why Google Apps Script Alone Wasn’t Enough

Initially, I planned to automate everything using Google Apps Script. However, there was another obstacle which is …

Google’s backend infrastructure acts as a forward proxy (X-Forwarded-For), appending the internal Google routing IP addresses to this header

and ReviewPro doesn’t like it. Hence it returns HTTP 403 error and to solve it, you need to use another API layer to call it.

Conclusion

Although ReviewPro provides scheduled reports, the existing workflow still requires manual interaction before the report can be downloaded.

By understanding the underlying request flow and reverse-engineering the report generation process, it was possible to build a fully automated solution using Google Apps Script and a lightweight API.

The result is an end-to-end automation pipeline that eliminates repetitive manual work while remaining flexible enough to adapt if the platform evolves!

--

--

Sharif Bhuiyan

Written by Sharif Bhuiyan

Founder of COR2TECT. A cogitator & procrastinator ... framework architect, IT startup expert & creative engineer to build ideas for what is important for us.