add nixos/discord webhook post (#272)
* add nixos/discord webhook post Signed-off-by: Christine Dodrill <me@christine.website> * oops Signed-off-by: Christine Dodrill <me@christine.website>
This commit is contained in:
parent
a2b1a4afbf
commit
7c7981bf70
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,146 @@
|
||||||
|
---
|
||||||
|
title: Discord Webhooks via NixOS and Systemd Timers
|
||||||
|
date: 2020-11-30
|
||||||
|
series: howto
|
||||||
|
tags:
|
||||||
|
- nixos
|
||||||
|
- discord
|
||||||
|
- systemd
|
||||||
|
---
|
||||||
|
|
||||||
|
# Discord Webhooks via NixOS and Systemd Timers
|
||||||
|
|
||||||
|
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](/blog/howto-automate-discord-webhook-cron-2018-03-29), however this
|
||||||
|
time we will be using [NixOS](https://nixos.org/) and [systemd
|
||||||
|
timers](https://wiki.archlinux.org/index.php/Systemd/Timers). Here's what you
|
||||||
|
will need to follow along:
|
||||||
|
|
||||||
|
- A machine running NixOS
|
||||||
|
- A [Discord](https://discord.com/) account
|
||||||
|
- A
|
||||||
|
[webhook](https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks)
|
||||||
|
configured for a channel
|
||||||
|
- A message you want to send to Discord
|
||||||
|
|
||||||
|
[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.](conversation://Mara/hacker)
|
||||||
|
|
||||||
|
## 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`:
|
||||||
|
|
||||||
|
```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"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
[This service is a <a href="https://stackoverflow.com/a/39050387">oneshot</a>
|
||||||
|
unit, meaning systemd will launch this once and not expect it to always stay
|
||||||
|
running.](conversation://Mara/hacker)
|
||||||
|
|
||||||
|
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`:
|
||||||
|
|
||||||
|
```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
|
||||||
|
```
|
||||||
|
|
||||||
|
[You can ignore the day of the week if it's not
|
||||||
|
relevant!](conversation://Mara/hacker)
|
||||||
|
|
||||||
|
So our final timer definition would look like this:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
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`:
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ 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`:
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ 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`:
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ 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](https://stackoverflow.com/questions/6408904/send-request-to-curl-with-post-data-sourced-from-a-file)
|
||||||
|
for more information.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Also happy December! My site has the [snow
|
||||||
|
CSS](https://christine.website/blog/let-it-snow-2018-12-17) loaded for the
|
||||||
|
month. Enjoy!
|
|
@ -17,10 +17,10 @@
|
||||||
"homepage": "",
|
"homepage": "",
|
||||||
"owner": "nmattia",
|
"owner": "nmattia",
|
||||||
"repo": "naersk",
|
"repo": "naersk",
|
||||||
"rev": "ce273fa593dcc94a629d0d869f07d96d2b337e37",
|
"rev": "8d562105f960c487cfc013c0e666c1951b03d392",
|
||||||
"sha256": "1hx47l7gfim0cs9fn8r91wwl0641wi2fdq67ygb4ydx7msb8sm6h",
|
"sha256": "16a1k5wamp67sqc341rlbmppm2xldfl207k9yhksgcvd4rw3iy20",
|
||||||
"type": "tarball",
|
"type": "tarball",
|
||||||
"url": "https://github.com/nmattia/naersk/archive/ce273fa593dcc94a629d0d869f07d96d2b337e37.tar.gz",
|
"url": "https://github.com/nmattia/naersk/archive/8d562105f960c487cfc013c0e666c1951b03d392.tar.gz",
|
||||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
||||||
},
|
},
|
||||||
"niv": {
|
"niv": {
|
||||||
|
|
Loading…
Reference in New Issue