Engineering

Working with Hooks

Jul 15, 2021

What is a hook?

working with hooks

A hook, or webhook, is an event handler, a mechanism by which an application can intercept events. With Weavy, hooks can be triggered in response to one, or more, system events. The triggered application can act on each event it receives, and can control the behavior of those events. This means that you get information in real-time inside those triggered applications, meaning you get data immediately. This is different from your typical API, where you have to frequently poll for data to get it in the best time.

Why should one use hooks?

Hooks can help you monitor as well as modify or discard events immediately. For example, you might want to avoid receiving notifications from a certain group of users, you can place a hook at Weavy’s AfterInsertNotification  event, and trash the event if the user belongs to your list of avoided users. Likewise, there are a lot of events on which hooks can be placed.

An Example Scenario

Take, for instance; a developer would love notifications by email of any new comment that is created in their Weavy app. This will be implemented using the related event class. Instead of polling every 3 to 5 minutes (which means you periodically hit an API to look for new comments created),  a hook is set up in the app to send an email whenever a comment is created. This gives room for real-time notification of email and removes the stress of continually checking for changes in the Weavy app. Needless to say, busy polling is resource intensive and if the time required to complete a single request becomes greater than the period of polling, you will end up stacking a lot of requests, which can make your system unavailable in no time.

Events that are supported

With Weavy, the hook extension is only triggered in response to the available system events. Each hook is created to receive every update related to a specific event in the Weavy app. See Weavy.Core.Events for a comprehensive list of available and supported events.

Adding a hook to Weavy

Adding hooks to your Weavy App is very easy and with few lines of code, you are all set up. To begin with, you first add a class which inherits from class  Hook, which is our base class for hooks. This class must also inherit the IHook<TEvent> interface for events that you wish to handle. Furthermore, it is good practice to always place your class in the “Models” folder. 

Each hook class must have a unique GUID (globally unique identifier), this will let Weavy know about your hook class. Your hook class should also have a Serializable attribute.

Optionally, Weavy provides support to add plugin attribute to your hooks. This attribute must be added only once to your class. It can be used to decorate your class with optional metadata such as description etc 

The following example shows how we add a hook that listens to the AfterInsertComment event and trashes comments that contain certain keywords.

using NLog;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Weavy.Core.Events;
using Weavy.Core.Models;
using Weavy.Core.Services;

Namespace Weavy.Models {
    [Serializable]
    [Guid("CF2303B5-A8B1-4F91-8029-9F464338A8DC")]
    [Plugin(Description = "A hook that automatically trashes comments with certain keywords.")]
    public class CommentFilterHook : Hook, IHook {
        private static readonly Logger _log = LogManager.GetCurrentClassLogger();
        [Required]
        [DataType("Tags")]
        [Display(Name = "Keywords", Description = "A list of keywords to look for.")]
        public List Keywords { get; set; }

        ///
        /// Trash comment if it contains one of the specified keywords.
        /// 
        ///
        /// 
        public Task HandleAsync(AfterInsertComment e) {
            if (Keywords != null) {
                foreach (var keyword in Keywords) {
                    if (e.Inserted.Text.IndexOf(keyword, StringComparison.OrdinalIgnoreCase) >= 0) {
                        var trashed = CommentService.Trash(e.Inserted.Id);
                        _log.Warn($"Trashed comment '{trashed.Text}' with keyword '{keyword}'");
                        break;
                    }
                }
            }
            return Task.CompletedTask;
        }
    }
}

From the above example, we can see that hooks must be decorated with the [Serialized] and [Guid] attribute. Also, you must give your class a unique Guid attribute; otherwise, Weavy will not recognize your Class. 

Apart from this, you can also decorate using the [plugin] attribute. Properties you can set for this include.

  • Icon – the name of an icon to use when displaying the daemon 
  • Color – the color to be used for the icon
  • Name – this attribute displays names for the content item, e.g., "Comment filter."
  • Description – Description is used for the daemon.

 

Hook fields

Hook Fields are pieces of information that can be added to a hook. This can be important if your hook requires some form of configuration. Fields have a name and a type. In the example given above, we added a field for storing the keywords not permitted in comments. Thus, Keywords in the above example is a Hook Field. 

For a property to be considered a field, it must be declared as public read-write, i.e., the property has the public access modifier and has both a get and a set accessor.

Fields must also have one of the following supported types:

enum
byte
short
int
long
bool
double
float
string
Guid
DateTime
TimeSpan

Nullables and Lists of the above types are also supported, e.g. int?, List<string> and List<DateTime?>

In the example above, the field Keywords has type  List<string> and is a public access modifier with both a get and a set accessor. We can have multiple hook fields in a single class. For example, we may also want to send a warning email to the user if the comment gets trashed. For that we can use a bool field to keep a flag which can be set to True if comment is trashed.


Configuration

If a hook requires some settings, like the Keywords property in our CommentFilterHook, you can navigate to /manage/hooks/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX where the last segment should be replaced with the Guid of your Hook, in this case, CF2303B5-A8B1-4F91-8029-9F464338A8DC for the CommentFilterHook.

Summary

By now, you have realised how easy it is to set up hooks for your Weavy App. Let us quickly summarise the important steps:

  • List down the events for which you wish to set up hook from Weavy.Core.Events
  • Create your Hook class, which must inherit from Hook.
  • It must also inherit from IHook<TEvent> for all events that you wish to handle
  • The class should be serializable and have unique GUID
  • You can set [Plugin] attribute to decorate your hook
  • You can use Hook Fields to configure data that you require
  • Each Hook Field must be a public access modifier and should have a get and a set accessor. Field must also have a valid type.

You can also decorate your fields using attributes listed here

Learn more at our docs site

Weavy

Share this post