Cadey is coffee
<Cadey> Hello! Thank you for visiting my website. You seem to be using an ad-blocker. I understand why you do this, but I'd really appreciate if it you would turn it off for my website. These ads help pay for running the website and are done by Ethical Ads. I do not receive detailed analytics on the ads and from what I understand neither does Ethical Ads. If you don't want to disable your ad blocker, please consider donating on Patreon or sending some extra cash to xeiaso.eth or 0xeA223Ca8968Ca59e0Bc79Ba331c2F6f636A3fB82. It helps fund the website's hosting bills and pay for the expensive technical editor that I use for my longer articles. Thanks and be well!

Discord Webhooks via NixOS and Systemd Timers

Read time in minutes: 5

Recently I needed to set up a Discord message on a cronjob as a part of moderating a guild I've been in for years. I've done this before using cronjobs, however this time we will be using NixOS and systemd timers. Here's what you will need to follow along:

  • A machine running NixOS
  • A Discord account
  • A webhook configured for a channel
  • A message you want to send to Discord

Mara is hacker
<Mara> If you don't have moderation permissions in any guilds, make your own for testing! You will need the "Manage Webhooks" permission to create a webhook.

Setting Up Timers

systemd timers are like cronjobs, except they trigger systemd services instead of shell commands. For this example, let's create a daily webhook reminder to check on your Animal Crossing island at 9 am.

Let's create the systemd service at the end of the machine's configuration.nix:

systemd.services.acnh-island-check-reminder = {
  serviceConfig.Type = "oneshot";
  script = ''
    MESSAGE="It's time to check on your island! Check those stonks!"
    WEBHOOK="${builtins.readFile /home/cadey/prefix/secrets/acnh-webhook-secret}"
    USERNAME="Domo"
    
    ${pkgs.curl}/bin/curl \
      -X POST \
      -F "content=$MESSAGE" \
      -F "username=$USERNAME" \
      "$WEBHOOK"
  '';
};

Mara is hacker
<Mara> This service is a oneshot unit, meaning systemd will launch this once and not expect it to always stay running.

Now let's create a timer for this service. We need to do the following:

  • Associate the timer with that service
  • Assign a schedule to the timer

Add this to the end of your configuration.nix:

systemd.timers.acnh-island-check-reminder = {
  wantedBy = [ "timers.target" ];
  partOf = [ "acnh-island-check-reminder.service" ];
  timerConfig.OnCalendar = "TODO(Xe): this";
};

Before we mentioned that we want to trigger this reminder every morning at 9 am. systemd timers specify their calendar config in the following format:

DayOfWeek Year-Month-Day Hour:Minute:Second

So for something that triggers every day at 9 AM, it would look like this:

*-*-* 8:00:00

Mara is hacker
<Mara> You can ignore the day of the week if it's not relevant!

So our final timer definition would look like this:

systemd.timers.acnh-island-check-reminder = {
  wantedBy = [ "timers.target" ];
  partOf = [ "acnh-island-check-reminder.service" ];
  timerConfig.OnCalendar = "*-*-* 8:00:00";
};

Deployment and Testing

Now we can deploy this with nixos-rebuild:

$ sudo nixos-rebuild switch

You should see a line that says something like this in the nixos-rebuild output:

starting the following units: acnh-island-check-reminder.timer

Let's test the service out using systemctl:

$ sudo systemctl start acnh-island-check-reminder.service

And you should then see a message on Discord. If you don't see a message, check the logs using journalctl:

$ journalctl -u acnh-island-check-reminder.service

If you see an error that looks like this:

curl: (26) Failed to open/read local data from file/application

This usually means that you tried to do a role or user mention at the beginning of the message and curl tried to interpret that as a file input. Add a word like "hey" at the beginning of the line to disable this behavior. See here for more information.


Also happy December! My site has the snow CSS loaded for the month. Enjoy!


This article was posted on M11 30 2020. Facts and circumstances may have changed since publication. Please contact me before jumping to conclusions if something seems wrong or unclear.

Series: howto

Tags: nixos discord systemd

This post was not WebMentioned yet. You could be the first!

The art for Mara was drawn by Selicre.

The art for Cadey was drawn by ArtZora Studios.

Some of the art for Aoi was drawn by @Sandra_Thomas01.