Generate new topics, posts and PM via Discourse Relay API Script

Following Vinoth’s example on the official discourse server and the API documentation, I ended up writing a small PHP script that act as a relay script to generate posts on our discourse forum.

Why did I write the script when I could have used IFTTT?

  • The IFTTT webhook applet is running on someone else server and I’m not sure what it’s doing in the background.
  • I needed more control and flexibility
  • The API key and username variables are sent over HTTP Headers. I found this out when I realize that the application that is sending the data doesn’t support custom headers for webhooks.

What features does the script provide?

  • API CRUD functionalities for posts, topics, categories and other resources.
  • Trigger user invite for the discourse forum
header('Content-Type: application/json');

//Make sure that it is a POST request.
if (strcasecmp($_SERVER['REQUEST_METHOD'], 'POST') != 0) {
    echo json_encode(array("error" => 'Request method must be POST!'));

//Make sure that the content type of the POST request has been set to application/json
$contentType = isset($_SERVER["CONTENT_TYPE"]) ? trim($_SERVER["CONTENT_TYPE"]) : '';
if (strcasecmp($contentType, 'application/json') != 0) {
    echo json_encode(array("error" => 'Content type must be: application/json'));

//Receive the RAW post data.
$content = trim(file_get_contents("php://input"));

//Attempt to decode the incoming RAW post data from JSON.
$payload = json_decode($content, true);

//If json_decode failed, the JSON is invalid.
if (!is_array($payload)) {
    echo json_encode(array("error" => 'Received content contained invalid JSON!'));

if (empty($payload['discourse_endpoint'])) {
    echo json_encode(array("error" => 'Discourse endpoint must be provided in the json body!'));

if (empty($payload['api_key'])) {
    echo json_encode(array("error" => 'Discourse API Key must be provided in the json body!'));

if (empty($payload['api_username'])) {
    echo json_encode(array("error" => 'Discourse API User must be provided in the json body!'));

$discourse_endpoint = $payload['discourse_endpoint'];
$api_key = $payload['api_key'];
$api_user = $payload['api_username'];


$data_string = json_encode($payload);

$ch = curl_init($discourse_endpoint);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json',
    "Api-key: $api_key",
    "Api-username: $api_user",
    'Content-Length: ' . strlen($data_string)
$result = curl_exec($ch);

echo $result;


See the updated code here: