Currently, I am working on a small project wherein I want to try out PocketBase as a backend for comments. Not only should it accept comments by a simple HTML form but I also want to be able to quickly moderate them. The nice admin UI, provided by PocketBase out of the box, combined with the simple setup is what drew me to it in the first place. However, for the moderation process I aim for even less friction while not having to implement a dedicated frontend. The idea is to keep all the business logic in PocketBase and have the only UI in the form of a push notification which also provides the option to approve the comment. For these notifications I chose ntfy which conveniently has apps for Android and iOS.

Let’s start with PocketBase first: The comments are held in a collection with columns for the content, author, submission date and a boolean column approved. The create rule of this collection is set to @request.data.approved:isset = false to allow the submission of comments without authentication while ensuring that a comment can not skip moderation. Likewise the list and view rules are set to approved = true which makes only approved comments publicly accessible.1 From this API a website can easily pull the comments without having to authenticate because the approved comments will be public anyway.

Now, comments can be submitted using an HTML form which sends an HTTP POST request to the create API endpoint. Just don’t forget to set enctype=multipart/form-data on the <form>. Moderation is possible with admin access to the PocketBase UI but let’s see how we can send push notifications.

To get notified on comment submission, I am using the PocketBase event hook onRecordAfterCreateRequest which I scoped to the comments collection. Inside e.record we find the columns of interest for our notification. In addition, I included an ntfy action which allows us to approve comments on the go. However, to actually be able to change the approved column we need to authenticate to PocketBase. Thus we create an authentication token which later can be used when executing the approve action. Finally, the update rule for the comments collection needs to be set to @request.auth.username = "ntfy" and the corresponding ntfy user needs to be added to the auth collection users.

onRecordAfterCreateRequest((e) => {
  const authRecord = $app.dao().findAuthRecordByUsername("users", "ntfy");
  const token = $tokens.recordAuthToken($app, authRecord);

  const res = $http.send({
    method: "POST",
    url: "https://ntfy.sh/",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      topic: "SECRET_TOPIC",
      title: "New comment by " + e.record.getString("author"),
      message: e.record.getString("content"),
      actions: [{
        action: "http",
        label: "Approve",
        url: "https://pb.example.com/api/collections/comments/records/" + e.record.get("id"),
        method: "PATCH",
        headers: {
          "Authorization": token,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ approved: true })
      }]
    })
  })
}, "comments")

Note that depending on your database schemas you might want to add additional checks in the rules. An improvement would be to only allow changing approved in the update rule. Also be aware that ideally the authentication tokens should expire after a short period of time which is not the default because they are intended as normal login tokens. You can however configure their lifetime in the PocketBase admin interface but this is a global change.