Move topics to subcategories automatically based on their tags

One small correction to my previous post is that the Tag Event webhook is not the correct webhook to use for this. To get details about a topic’s tags, you need to use the Topic Event webhook. That webhook is fired any time a topic is created, updated, or deleted. The relevant part of that webhook’s payload will look something like this:

{
  "topic": {
    "tags": [
      "docs"
    ],
    "id": 10365,
    "title": "Holiday calendar category test",
    "fancy_title": "Holiday calendar category test",
    "posts_count": 18,
    "created_at": "2021-03-11T20:11:12.227Z",
    "views": 10,
    "reply_count": 3,
    "like_count": 0,
    "last_posted_at": "2021-04-06T19:52:02.478Z",
    "visible": true,
    "closed": false,
    "archived": false,
    "archetype": "regular",
    "slug": "holiday-calendar-category-test",
    "category_id": 5,
    "word_count": 187,
    "deleted_at": null,
    "user_id": 1,
    "featured_link": null,
    "pinned_globally": true,
    "pinned_at": "2021-03-15T17:24:44.551Z",
    "pinned_until": "3021-03-15T15:00:00.000Z",
    "unpinned": null,
    "pinned": true,
    "highest_post_number": 18,
    "deleted_by": null,
    "has_deleted": false,
    "bookmarked": false,
    "participant_count": 1,
    "queued_posts_count": 0,
    "thumbnails": null,
    "tags_disable_ads": false,
    "event_starts_at": "2021-03-30 19:10:00",
    "event_ends_at": "2021-03-30 20:10:00",
    "can_vote": false,
    "vote_count": 0,
    "user_voted": false,
    "discourse_zendesk_plugin_zendesk_id": null,
    "discourse_zendesk_plugin_zendesk_url": "https://discoursedemo.zendesk.com/agent/tickets/",
    "created_by": {
      "id": 1,
      "username": "Simon_Cossar",
      "name": "Simon Cossar ",
      "avatar_template": "/letter_avatar_proxy/v4/letter/s/ed655f/{size}.png"
    },
    "last_poster": {
      "id": 1,
      "username": "Simon_Cossar",
      "name": "Simon Cossar ",
      "avatar_template": "/letter_avatar_proxy/v4/letter/s/ed655f/{size}.png"
    },
    "pending_posts": []
  }
}

You could then recategorize the topic based on the value of its tags property. To recategorize the topic, you would make a PUT request via the Discourse API to set the topic’s category_id to the ID of the category that you want to move it to. If you wanted to move the topic to a category that does not yet exist on your site, you would need to make two API calls. The first API call would be to create the new category. The second API call would be to move the topic to the new category.

The above method would allow you to automatically recategorize topics based on their tags.

A good approach for figuring out the API calls that are required for this is outlined here: How to reverse engineer the Discourse API. Let us know if you have any trouble figuring out how to structure the API calls.

You will need to figure out a way of saving your Discourse site’s category structure to your main application’s database so that you know which category IDs are available to move the topics to. For example, in the payload that I posted above, I might want to move a topic that’s been tagged with docs to my site’s “documentation” category. To do that, I’d need to be able to find the ID of my “documentation” category on my main application. There are a few ways that this could be accomplished. Our WordPress plugin does this by making periodic requests to the Discourse /site.json route, parses the categories that are returned from that route, and then caches the results for a period of 10 minutes.

1 Like