Wire feedback to IIS reverse-proxy -> Power Automate
- Set FEEDBACK_ENDPOINT to same-origin /api/feedback (no CORS, hides trigger URL) - Add web.config with ARR/URL-Rewrite proxy rule (placeholder trigger URL), HTTPS/POST/static-content setup - DEPLOYMENT.md: concrete IIS + Power Automate steps and the HTTP-trigger Request Body JSON Schema matching the app payload Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -78,12 +78,55 @@ app.listen(8080);
|
|||||||
Each line of `feedback.jsonl` is one submission; download it anytime. (PHP/
|
Each line of `feedback.jsonl` is one submission; download it anytime. (PHP/
|
||||||
Python/ASP.NET equivalents are a few lines too.)
|
Python/ASP.NET equivalents are a few lines too.)
|
||||||
|
|
||||||
#### Option B — Microsoft Power Automate → SharePoint / Excel (good fit for M365)
|
#### Option B — Internal IIS reverse proxy → Power Automate (the chosen setup)
|
||||||
|
|
||||||
|
The browser posts to a **same-origin** path `/api/feedback`; IIS forwards that to
|
||||||
|
the Power Automate trigger. This avoids CORS entirely and keeps the secret
|
||||||
|
trigger URL off the client. `FEEDBACK_ENDPOINT` is already set to
|
||||||
|
`/api/feedback`, and [`web.config`](web.config) contains the proxy rule.
|
||||||
|
|
||||||
|
**On the IIS box (one-time, server admin):**
|
||||||
|
1. Install the **URL Rewrite** and **Application Request Routing (ARR)** modules.
|
||||||
|
2. Enable the proxy: IIS Manager → server node → *Application Request Routing
|
||||||
|
Cache* → *Server Proxy Settings* → check **Enable proxy**.
|
||||||
|
3. Bind the site to **HTTPS** with an internal certificate.
|
||||||
|
4. In `web.config`, replace `POWER_AUTOMATE_TRIGGER_URL` with the real trigger
|
||||||
|
URL (write every `&` as `&`).
|
||||||
|
|
||||||
|
**In Power Automate:**
|
||||||
1. Create a flow with the **"When an HTTP request is received"** trigger.
|
1. Create a flow with the **"When an HTTP request is received"** trigger.
|
||||||
2. Paste its generated URL into `FEEDBACK_ENDPOINT`.
|
2. Set its **Request Body JSON Schema** to:
|
||||||
3. Add an action: **Add a row into a table** (Excel) or **Create item**
|
|
||||||
(SharePoint list), mapping the JSON fields (`type`, `name`/`author`, `text`,
|
```json
|
||||||
`submittedAt`, `page`, …).
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"app": { "type": "string" },
|
||||||
|
"page": { "type": "string" },
|
||||||
|
"submittedAt": { "type": "string" },
|
||||||
|
"type": { "type": "string" },
|
||||||
|
"name": { "type": "string" },
|
||||||
|
"author": { "type": "string" },
|
||||||
|
"text": { "type": "string" },
|
||||||
|
"step": { "type": "integer" },
|
||||||
|
"view": { "type": "string" },
|
||||||
|
"timestamp": { "type": "string" },
|
||||||
|
"ts": { "type": "string" },
|
||||||
|
"id": { "type": "string" },
|
||||||
|
"clientId": { "type": "string" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
> `name` is used by the home/SOP forms, `author` by the Work Package Creator.
|
||||||
|
> Map both into one "Submitted by" column with an expression like
|
||||||
|
> `coalesce(triggerBody()?['name'], triggerBody()?['author'])`.
|
||||||
|
3. Add an action — **Create item** (SharePoint list) or **Add a row into a
|
||||||
|
table** (Excel / Dataverse) — mapping the fields above.
|
||||||
|
4. Save; copy the generated **HTTP POST URL** into `web.config`
|
||||||
|
(`POWER_AUTOMATE_TRIGGER_URL`).
|
||||||
|
5. A Power App (or just the list/Excel) reads that store to show live comments.
|
||||||
|
|
||||||
|
Chain: `browser → /api/feedback (IIS proxy) → Power Automate → SharePoint/Dataverse → Power App`.
|
||||||
|
|
||||||
The "downloadable file" is then just the Excel/SharePoint list, viewable live or
|
The "downloadable file" is then just the Excel/SharePoint list, viewable live or
|
||||||
exported — all inside your corporate cloud.
|
exported — all inside your corporate cloud.
|
||||||
|
|||||||
@@ -15,8 +15,14 @@
|
|||||||
|
|
||||||
Leave it as an empty string to stay fully local (export/import only).
|
Leave it as an empty string to stay fully local (export/import only).
|
||||||
See DEPLOYMENT.md for setup details and sample receivers.
|
See DEPLOYMENT.md for setup details and sample receivers.
|
||||||
|
|
||||||
|
This is set to the same-origin path '/api/feedback', which the IIS reverse
|
||||||
|
proxy (see web.config) forwards to the Power Automate HTTP trigger. Keeping it
|
||||||
|
relative means no CORS and the secret trigger URL never appears in client
|
||||||
|
code. Locally (no proxy) the POST simply fails silently and feedback is still
|
||||||
|
saved/exported from the browser.
|
||||||
────────────────────────────────────────────────────────────────────────── */
|
────────────────────────────────────────────────────────────────────────── */
|
||||||
window.FEEDBACK_ENDPOINT = '';
|
window.FEEDBACK_ENDPOINT = '/api/feedback';
|
||||||
|
|
||||||
/* Best-effort send to the central endpoint. Never throws and never blocks the
|
/* Best-effort send to the central endpoint. Never throws and never blocks the
|
||||||
UI: feedback is always saved locally first by the caller, so a failed or
|
UI: feedback is always saved locally first by the caller, so a failed or
|
||||||
|
|||||||
62
web.config
Normal file
62
web.config
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
IIS configuration for the Work Package Suite (static site) + feedback proxy.
|
||||||
|
|
||||||
|
PREREQUISITES (one-time, done by the server admin in IIS Manager):
|
||||||
|
1. Install the "URL Rewrite" module.
|
||||||
|
2. Install "Application Request Routing" (ARR).
|
||||||
|
3. Enable the proxy: IIS Manager > (server node) >
|
||||||
|
Application Request Routing Cache > Server Proxy Settings >
|
||||||
|
check "Enable proxy". (This is server-level and cannot be set here.)
|
||||||
|
4. Bind the site to HTTPS with an internal certificate.
|
||||||
|
|
||||||
|
THEN: replace POWER_AUTOMATE_TRIGGER_URL below with the real "When an HTTP
|
||||||
|
request is received" URL from your flow. Remember every literal "&" in the URL
|
||||||
|
must be written as "&" inside this file.
|
||||||
|
-->
|
||||||
|
<configuration>
|
||||||
|
<system.webServer>
|
||||||
|
|
||||||
|
<!-- index.html is the entry point -->
|
||||||
|
<defaultDocument>
|
||||||
|
<files>
|
||||||
|
<clear />
|
||||||
|
<add value="index.html" />
|
||||||
|
</files>
|
||||||
|
</defaultDocument>
|
||||||
|
|
||||||
|
<!-- Don't list folder contents -->
|
||||||
|
<directoryBrowse enabled="false" />
|
||||||
|
|
||||||
|
<rewrite>
|
||||||
|
<rules>
|
||||||
|
<!-- Forward same-origin /api/feedback POSTs to the Power Automate flow.
|
||||||
|
The browser sees only /api/feedback; the secret trigger URL stays
|
||||||
|
on the server. Requires ARR proxy enabled (see prerequisites). -->
|
||||||
|
<rule name="Feedback proxy to Power Automate" stopProcessing="true">
|
||||||
|
<match url="^api/feedback/?$" />
|
||||||
|
<action type="Rewrite"
|
||||||
|
url="POWER_AUTOMATE_TRIGGER_URL" />
|
||||||
|
</rule>
|
||||||
|
</rules>
|
||||||
|
</rewrite>
|
||||||
|
|
||||||
|
<!-- Make sure POST is allowed and the JSON body isn't truncated -->
|
||||||
|
<security>
|
||||||
|
<requestFiltering>
|
||||||
|
<verbs>
|
||||||
|
<add verb="POST" allowed="true" />
|
||||||
|
</verbs>
|
||||||
|
<!-- 1 MB cap on a feedback body is plenty -->
|
||||||
|
<requestLimits maxAllowedContentLength="1048576" />
|
||||||
|
</requestFiltering>
|
||||||
|
</security>
|
||||||
|
|
||||||
|
<!-- Sensible static MIME types (most are built in; this is belt-and-braces) -->
|
||||||
|
<staticContent>
|
||||||
|
<remove fileExtension=".json" />
|
||||||
|
<mimeMap fileExtension=".json" mimeType="application/json" />
|
||||||
|
</staticContent>
|
||||||
|
|
||||||
|
</system.webServer>
|
||||||
|
</configuration>
|
||||||
Reference in New Issue
Block a user