Managing tickets with discord forums and PHP

Table of contents

Almost every website has some kind of contact nowadays, usually forwarded to an email that is loosely checked every few days. Especially for communities, this can mean administrative overhead, because that email address then needs to be shared among all staff members and access updated every time roles change (people leaving, newly promoted moderators etc). Additionally, it is not easily visible who will take over which request, what state an inquiry is in and if one has been forgotten. Wouldn't it be nice if you could simply synchronize all that on a platform used for the community interactions already? Turns out that if you are using Discord, the new forum channels got you covered!

Setting up Discord

Next, we need a forum channel and a webhook in our Discord server. Start by creating a new channel:

Select "Forum" as the channel type and give it a name:

Once created, edit your new forum channel:

Select "Integrations" in the menu on the left and click the blue "Create webhook" button:

This will generate a new webhook with a random name, typically named "Spidey Bot" or "Captain Hook". Click on it to expand the details and copy the webhook url:

And that's all we need from discord! Paste your webhook url somewhere safe, you will need it in a moment.

Interacting with the webhook

The webhook is a really simple way to post content to a Discord channel without needing to worry about authentication or complex third-party libraries. To use it, simply send an HTTP POST request to the url and include the required form fields in the body.

For our use case, we will send the following POST parameters:

  • content - The message content to be posted. This cannot be empty.
  • thread_name - Name of the forum thread to create. Required to post to forum channels.
  • username - Sets the name of the posting user. Optional, but nice to have for our needs.

Webhooks allow many more optional parameters, like attached files, embedding images, setting custom avatar images etc. Have a look at the full documentation here.

Be sure to keep your webhook url safe: Anybody who has it can post to the channel it is created for!

A sample PHP application

Since not everyone will have a php server at hand, here is a quick docker one-liner to spin up a working server from the current directory:

docker run --rm -v $PWD:/var/www/html -p 8080:80 php:8.0-apache

Once started, you should now have a functional apache2 webserver with php enabled running at .

Now we can create a simple file as a demo form


   $webhookUrl = "";
   $submitted = false;
      $curl = curl_init($webhookUrl);
      curl_setopt($curl, CURLOPT_POST, true);
      curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query([
         "content" => "{$_POST['message']}",
         "thread_name" => $_POST["title"],
         "username" => "{$_POST["name"]} [{$_POST['email']}]"
      curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
      $response = curl_exec($curl);
      if($response != ""){
         die("Error sending message: {$response}");
      $submitted = true;
<!Doctype html>
      <title>Sample webpage</title>
            margin:0 auto;
         input, textarea{
            border-bottom:1px dashed #333;
            background: darkcyan;
            padding:5px 10px;
            padding:10px 40px;
            color: darkslategrey;
            background: darkseagreen;
      <div class="container">
         <?php if($submitted){ ?>
            <div class="alert">Thank you for your message. We will get in touch shortly!</div>
         <?php }else{ ?>
         <h1>If you have a problem, please fill out this form</h1>
         <form action="" method="POST">
            <input type="text" name="name" placeholder="Your name" required>
            <input type="email" name="email" placeholder="Your email (for answers)" required>
            <input type="text" name="title" placeholder="Title of your problem" required>
            <textarea name="message" rows="5" placeholder="Describe your problem" required></textarea>
            <div class="btn-holder">
               <button type="submit">Submit</button>
         <?php } ?>

Make sure to fill in your own webhook on the second line!

It's just a simple form with some basic styling. On form submission, we make a curl request to the webhook url with the contents, thread_name and username fields filled with the form inputs.

If the form is filled out and submitted, it will create a new thread in our forum channel:

This makes inquiries very easy to deal with for multiple staff members: Channel access can be restricted to specific roles, new messages will notify relevant people and staff members can simply comment on an open ticket to "claim" it, or discuss uncertainties. And when something is resolved, the thread can be locked, closed or deleted.

Going further

The sample application above is just one of many use cases for automation using Discord's forum channels. Here are some other ideas:

  • user-supplied application logs
  • crash dumps
  • performance metrics
  • server alerts
  • recurring analytics

... the list goes on.

Related considerations

If your discord server represents or is operated by a legal entity, make sure to read up on privacy laws before putting personal data into discord forums. For example the GDPR outlines specific rules about handling personal data like names, email addresses and other information that can identify a single person.

Additionally, the example above is very simplistic. When making something like this available to a broader audience, ensure you adhere to the Discord API rate limits and content size limits, sanitize the user input and escape markdown syntax if necessary.

More articles

Why bash shell aliases deserve your attention

A seriously underrated feature of the bash shell

Automating code quality in go

Exploring what code quality is, tools to maintain it in go and how to automate them

Managing packages with apt

How to find, install, update and remove packages - and everything inbetween

Setting up an nginx load balancer

Distributing requests to multiple servers

Simplifying terminal operations with python modules

Saving time with python builtin modules

A complete guide to running windows software on linux

Making windows programs behave like they were written for linux