跳到主要内容

Enable User Feedback in Writerside Using TiDB Cloud and Cloudflare Pages

· 阅读需 8 分钟

I am currently using Writerside, a new Integrated Development Environment (IDE) designed for technical writers, to create and develop the documentation website for my side project, PingCAP Docsite Preview. Throughout my experience with Writerside, I discovered an undocumented feature: a feedback module. I have utilized Cloudflare Pages Functions and TiDB Cloud Data Service to process the feedback received through this module and store it in the database.

This guide provides step-by-step instructions for integrating a feedback module into your website. It utilizes Writerside, Cloudflare Pages Functions, and TiDB Cloud Data Service for this integration. This will enable you to collect valuable user feedback directly through your website.

View the demo code: writerside-feedback-example

Try the feedback widget: Feedback example page

Prerequisites

1. Set up a Writerside project and deploy to Cloudflare Pages

Code example: commit/10a7107

  1. Create a new project in Writerside from the Playground option:

    img_2.png

    For easy deployment, I upload this project to GitHub and then use GitHub Actions to build and deploy the website to Cloudflare Pages.

  2. Configure GitHub Action workflow:

The newly created project includes two instances: hi and si. The following workflow only deploys the hi instance to Cloudflare Pages.

.github/workflows/deploy.yml
name: Build documentation

on:
push:
branches: ["main"]
workflow_dispatch:

env:
INSTANCE: writerside-feedback/hi
ARTIFACT: webHelpHI2-all.zip
DOCKER_VERSION: 233.14272

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Build Writerside docs using Docker
uses: JetBrains/writerside-github-action@v4
with:
instance: ${{ env.INSTANCE }}
artifact: ${{ env.ARTIFACT }}
docker-version: ${{ env.DOCKER_VERSION }}

- name: Upload documentation
uses: actions/upload-artifact@v4
with:
name: docs
path: |
artifacts/${{ env.ARTIFACT }}
artifacts/report.json
retention-days: 7

deploy:
needs: build
runs-on: ubuntu-latest
permissions:
contents: read
deployments: write
name: Deploy to Cloudflare Pages
steps:
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: docs
- name: Unzip artifact
run: |
unzip -O UTF-8 ${{ env.ARTIFACT }} -d public
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
- name: Publish
run: |
cd public
npx wrangler@3 pages deploy . --project-name writerside-feedback-example
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}

This workflow first builds the Writerside project using JetBrains/writerside-github-action. It then deploys the documentation website to Cloudflare Pages using wrangler.

Note that you need to configure CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID in your GitHub repository secrets. For more information, refer to Create secrets for a repository, Create an API token, and Find zone and account IDs.

  1. Trigger deployment:

After configuring CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID, you can trigger the deploy.yml workflow. The website will become accessible within a few minutes. You can find the URL of your website on the Cloudflare Pages project page.

2. Enable the feedback widget in Writerside

Code example: https://github.com/Oreoxmt/writerside-feedback-example/commit/25d63e0dda916b655a8c1cf869b3ed6d9d6e82d9

Configuration

To enable the feedback widget, modify the cfg/buildprofiles.xml file as follows:

cfg/buildprofiles.xml
<?xml version="1.0" encoding="UTF-8"?>
<buildprofiles xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/build-profiles.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<variables>
<feedback-widget>true</feedback-widget>
<feedback-url>https://www.test.com</feedback-url>
</variables>
</buildprofiles>

Then, you can trigger the deploy.yml workflow once more. After the deployment is completed, the feedback widget appears at the bottom of each page in your website.

Feedback widget behavior

Given that this feature is not officially documented, you can monitor the feedback widget's behavior in your browser's developer mode. For example, you can submit a feedback as follows:

img_2.png

After clicking Send feedback, you will notice that a request is sent to the feedback URL https://www.test.com with the feedback information in the request payload.

{
"articleId": "Default-topic",
"content":"Tell us what you think would make this page better",
"name":"Name",
"email":"[email protected]",
"title":"This is the first topic",
"url":"https://writerside-feedback-example.pages.dev/default-topic.html#feedback-and-support"
}

Additionally, you might notice a prompt Feedback wasn't sent. Please try again later.. This occurs because the feedback URL https://www.test.com is not available.

In conclusion, the feedback module sends a POST request to the specified feedback URL, containing the feedback information in the request payload as follows:

{
"articleId":"starter-topic",
"content":"Feedback content",
"name":"(Optional) Feedback user name",
"email":"(Optional) Feedback user email",
"title":"Page title",
"url":"Page URL"
}

Therefore, it is necessary to have a server in place to receive this request and store the feedback information in a database. TiDB Cloud Data Service is an excellent option for this purpose.

3. Configure TiDB Cloud Data Service for feedback storage

  1. Create a TiDB Serverless cluster and initialize the database as follows. For convenience, you can use Chat2Query in the TiDB Cloud console.
CREATE DATABASE demo;

USE demo;

CREATE TABLE
feedback (
id INT PRIMARY KEY AUTO_INCREMENT,
articleId TEXT,
content TEXT,
email TEXT,
name TEXT,
title TEXT,
url TEXT
);

Init database schema

  1. Navigate to the Data Service page and create a new Data App.

tidb_cloud_create_data_app.png

  1. Create an endpoint in the newly created Data App:
  • Set the Path, for example, /feedback.

  • Select POST as the Request Method.

  • Input the following SQL statements into the editor:

    USE demo;
    INSERT INTO feedback (
    articleId, content, email, name, title, url
    )
    VALUES (
    ${articleId}, ${content}, ${email}, ${name}, ${title}, ${url}
    );
  • Configure the parameters as follows:

    ParameterTypeDescription
    articleIdStringThe article ID.
    contentStringThe feedback content.
    emailStringThe feedback user email.
    nameStringThe feedback user name.
    titleStringThe page title.
    urlStringThe page URL.

img_3.png

  1. Click Deploy in the upper-right corner to deploy the endpoint.

  2. Copy the Endpoint URL from the Properties tab. Then, update this URL in the cfg/buildprofiles.xml file:

cfg/buildprofiles.xml
<?xml version="1.0" encoding="UTF-8"?>
<buildprofiles xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/build-profiles.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<variables>
<feedback-widget>true</feedback-widget>
<feedback-url>https://{YOUR_DOMAIN}/feedback</feedback-url>
</variables>
</buildprofiles>
  1. Trigger the deploy.yml workflow again. After the deployment is completed, you can submit a feedback and observe its response using the developer mode of your browser.

You will notice that the feedback submission results in a 401 response. This happens because the endpoint lacks authentication. To make your API keys secure, consider using Cloudflare Pages Functions to send the request, as it enables you to keep the token secret.

4. Configure Cloudflare Pages Functions to forward the feedback request

Code example: https://github.com/Oreoxmt/writerside-feedback-example/commit/dd61bd4157c34f50308ef085e8d5b424dc79bb82

  1. Create the functions/feedback.js file to forward the feedback request:
export async function onRequest(context) {
const resp = await fetch(context.env.API_HOST, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': context.env.API_AUTH
},
body: context.request.body
});
return new Response("Hi there!");
}

This function forwards the feedback request to TiDB Cloud Data Service, which is configured in the API_HOST and API_AUTH environment variables.

  1. Incorporate the Add function folder to output file step in the deploy.yml workflow. After building the documentation, this step adds the functions folder to the output file, facilitating the deployment of the function to Cloudflare Pages.
.github/workflows/deploy.yml
name: Build documentation

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
...
- name: Build Writerside docs using Docker
...
- name: Add function folder to output file
run: sudo zip -r "artifacts/${{ env.ARTIFACT }}" functions/
- name: Upload documentation
...
deploy:
...
  1. Navigate to your TiDB Cloud Data App and create an API key with ReadAndWrite role.

  2. Convert the public key and private key into a base64 encoded string. For example, if your public key is public_key and your private key is private_key, you can encode them as follows:

    echo -n "public_key:private_key" | base64
    # cHVibGljX2tleTpwcml2YXRlX2tleQ==
  3. In your Cloudflare Pages project (writerside-feedback-example in this example), configure the following environment variables:

    • API_HOST: The endpoint URL.
    • API_AUTH: The base64 encoded API key. For example, Basic cHVibGljX2tleTpwcml2YXRlX2tleQ==.

    cloudflare_pages_config_env.png

  4. Trigger the deploy.yml workflow once more. After the deployment is completed, you can submit a feedback and verify that it is successfully stored in the database.

tidb_cloud_query_feedback.png

Conclusion

When you submit a feedback on this page, the following process occurs:

  1. The feedback widget sends a POST request to the feedback URL (Cloudflare Pages Functions) with the feedback information in the request payload.
  2. The function receives the request and forwards it to the endpoint URL (TiDB Cloud Data Service) with the API token.
  3. TiDB Cloud Data Service receives the request and stores the feedback information in the database.