All message broker subscribers within Plato must implement the IBrokerSubscriber
interface. This interface exposes 2 methods "Subscribe" and "Unsubscribe". You can then use the IBroker
interface to create or destroy specific subscriptions.
You can see below a simple message broker subscriber from Plato.Discuss.Slack that will post a message to your Slack channel whenever a new topic is created within Plato.Discuss.
The example below hooks into the EntityCreated event exposed by the message broker to detect when an entity or in this specific case a topic has been created and perform some actions with that entity or topic - in this case posting to Slack.
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Logging;
using Plato.Discuss.Models;
using Plato.Entities.Extensions;
using Plato.Internal.Hosting.Abstractions;
using Plato.Internal.Messaging.Abstractions;
using Plato.Slack.Services;
namespace Plato.Discuss.Slack.Subscribers
{
public class EntitySubscriber : IBrokerSubscriber
{
private readonly ICapturedRouterUrlHelper _capturedRouterUrlHelper;
private readonly ILogger<EntitySubscriber> _logger;
private readonly ISlackService _slackService;
private readonly IBroker _broker;
public EntitySubscriber(
ICapturedRouterUrlHelper capturedRouterUrlHelper,
ILogger<EntitySubscriber> logger,
ISlackService slackService,
IBroker broker)
{
_capturedRouterUrlHelper = capturedRouterUrlHelper;
_slackService = slackService;
_broker = broker;
_logger = logger;
}
// Implementation
public void Subscribe()
{
// Subscribe to the EntityCreated event
_broker.Sub<Topic>(new MessageOptions()
{
Key = "EntityCreated"
}, async message => await EntityCreated(message.What));
}
public void Unsubscribe()
{
// Unsubscribe from the EntityCreated event
_broker.Unsub<Topic>(new MessageOptions()
{
Key = "EntityCreated"
}, async message => await EntityCreated(message.What));
}
// Private Methods
async Task<Topic> EntityCreated(Topic entity)
{
// If the created entity is hidden, no need to send notifications
// Entities can be hidden automatically, for example if they are detected as SPAM
if (entity.IsHidden())
{
return entity; ;
}
// Build url to topic
var baseUri = await _capturedRouterUrlHelper.GetBaseUrlAsync();
var url = _capturedRouterUrlHelper.GetRouteUrl(baseUri, new RouteValueDictionary()
{
["area"] = "Plato.Discuss",
["controller"] = "Home",
["action"] = "Display",
["opts.id"] = entity.Id,
["opts.alias"] = entity.Alias
});
// Build our message to post to our Slack channel
var sb = new StringBuilder();
sb
.Append(entity.Title)
.Append(" - ")
.Append(baseUri)
.Append(url);
// Finally post our message to Slack
var response = await _slackService.PostAsync(sb.ToString());
// Log any errors that may have occurred
if (!response.Success)
{
if (_logger.IsEnabled(LogLevel.Error))
{
_logger.LogError($"An error occurred whilst attempting to post to Slack. Response from POST request to Slack Webhook Url: {response.Error}");
}
}
// Continue processing the broker pipeline
return entity;
}
}
}
To browse the full code please visit Plato.Discuss.Slack on GitHub.