Компонент для добавления пользовательского сообщения в Composer на основе ID пользователя и категорий

Сегодня я столкнулся с этой проблемой:

Но пока команда не займется этим (надеюсь), я решил попросить Claude помочь мне создать компонент, который позволит добавлять кастомное сообщение в композере, чтобы напоминать мне о необходимости добавить тег. Я могу указать одного или нескольких пользователей по ID, а также ограничить функционал определенными категориями, тоже по ID.

Если ID (пользователя и категорий) нет в списке, я вижу следующее:

Если ID есть в списке, я вижу сообщение:

Если это кому-то поможет, вот код (просто создайте компонент и добавьте скрипт во вкладку JS):

import { apiInitializer } from "discourse/lib/api";

export default apiInitializer("0.8.31", (api) => {
  // Конфигурация: добавьте сюда ID пользователей и ID категорий
  const TARGET_USER_IDS = [2]; // Замените на реальные ID пользователей
  const TARGET_CATEGORY_IDS = [4, 49]; // Замените на реальные ID категорий
  const REMINDER_MESSAGE = "🛑 Добавьте подходящий тег к этому посту!";
  
  let previousCategoryId = null;
  let checkInterval = null;
  
  function checkAndUpdateMessage() {
    const composer = api.container.lookup("controller:composer");
    if (!composer || !composer.model) {
      // Композер исчез, прекращаем проверку
      if (checkInterval) {
        clearInterval(checkInterval);
        checkInterval = null;
      }
      return;
    }
    
    const currentUser = api.getCurrentUser();
    if (!currentUser || !TARGET_USER_IDS.includes(currentUser.id)) return;
    
    const model = composer.model;
    const categoryId = model.categoryId;
    
    // Действуем только если категория изменилась
    if (categoryId === previousCategoryId) return;
    previousCategoryId = categoryId;
    
    const currentReply = model.reply || "";
    
    // Удаляем сообщение, если оно было добавлено
    if (currentReply.startsWith(REMINDER_MESSAGE)) {
      model.set("reply", currentReply.replace(REMINDER_MESSAGE, "").trim());
    }
    
    // Добавляем сообщение, если мы в целевой категории и композер пуст
    if (categoryId && TARGET_CATEGORY_IDS.includes(categoryId)) {
      const cleanReply = model.reply || "";
      if (cleanReply.trim().length === 0) {
        model.set("reply", REMINDER_MESSAGE);
      }
    }
  }
  
  // Проверка при открытии композера
  api.onAppEvent("composer:opened", () => {
    previousCategoryId = null;
    checkAndUpdateMessage();
    
    // Запускаем опрос изменений категории
    if (checkInterval) clearInterval(checkInterval);
    checkInterval = setInterval(checkAndUpdateMessage, 300);
  });
  
  // Прекращаем проверку при закрытии композера
  api.onAppEvent("composer:closed", () => {
    if (checkInterval) {
      clearInterval(checkInterval);
      checkInterval = null;
    }
    previousCategoryId = null;
  });
});
3 лайка