Generate new topics, posts and PM via IFTTT

Want to use IFTTT to create new topics, posts and private messages? Let’s get started!

Using Maker Webhooks of IFTTT service we can make Discourse API calls. For that we must generate API keys first. It can be generated using the API admin tab.

Also we can generate user specific API keys through user admin pages.

Now create new applet on IFTTT and then choose your favorite trigger service. Now I am using Google Calendar service for example.

Then I am choosing Any new event added trigger.

To connect your trigger with Discourse choose Maker Webhooks as action service and Make a web request action.

Now fill the action fields as below.

  • URL (required): https://discourse.example.com/posts/?api_key=[YOUR_API_KEY]&api_username=[API_USERNAME]

  • Method (required): POST

  • Content Type: application/json

  • Body:

{
 "title": "{{Title}}",
 "raw": "{{Description}}\n\nPlace: {{Where}}\nAt: {{Starts}} - {{Ends}}",
 "category": 4,
 "created_at": "{{CreatedAt}}"
}

In body text you can see many fields with double brackets {{ }}. Those fields (content sources) will vary with every service triggers. Choose it from Ingredient button below.

You can edit title and raw fields in JSON body however you need with surrounded texts. Find category id from your site’s /site.json URL and put it on category field. Now click Create action button to create the applet. After the applet creation it may take some time to be live.

It’s done :sunglasses:. Now a new topic will be created whenever a new event created on your Google Calendar :calendar_spiral:.


To create a post reply to an existing topic instead of new topic creation the body text should be changed as below (topic_id instead of category)

{
 "title": "{{Title}}",
 "raw": "{{Description}}\n\nPlace: {{Where}}\nAt: {{Starts}} - {{Ends}}",
 "topic_id": 4,
 "created_at": "{{CreatedAt}}"
}

To create new private message

{
 "title": "{{Title}}",
 "raw": "{{Description}}\n\nPlace: {{Where}}\nAt: {{Starts}} - {{Ends}}",
 "target_usernames": "discourse1,discourse2",
 "archetype": "private_message",
 "created_at": "{{CreatedAt}}"
}

In this same method you can make Discourse API requests by any other IFTTT action services.

22 Likes

I wonder if this option is no longer free and only available as a premium for developers ?

1 Like

Based on the Discourse API documentation, the Api_username and Api_key must be sent over HTTP request headers. Sending them as a GET params won’t work.

I tried and it failed. Therefore, I had wasn’t able to use IFTTT as it was instructed here…

However, I ended up writing a simple custom PHP script that acts as a relay hook that will allow data to be sent to discourse with the proper configuration.

Code
<?php
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!'));
    die();
}

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

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

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

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

unset($payload['discourse_endpoint']);
unset($payload['api_key']);
unset($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;

?>

You can read more about it here: Generate new topics, posts and PM via Discourse Relay API Script - discourse - Jamaican Developers Community Forum

2 Likes

I am in the same boat here trying to set up an IFTTT applet to post items bookmarked a certain tag in Pinboard (I have other applets posting to Mastodon where I am able to pass a token as a header item rather than GET parameters).

My mediocre PHP chops fully see how your code works, my question being less knowledgable of the discourse server, is where can I place the script? Does it need to be on same server to avoid CORS issues?

Or should I be looking at some other integration middle platform than IFTTT?

It just needs to be hosted on a server that can accept the request from IFTTT and can talk to your Discourse instance via the curl functions. It just initiates the same type of request that the Dsicourse web interface would. :slight_smile:

1 Like

Thanks. Looks like I have access to Zapier which has better integrations.