Allow to customize notification message (#415)

Co-authored-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
CrazyMax
2021-06-25 23:24:02 +02:00
committed by GitHub
parent 066eafc8a9
commit 5d583809a0
43 changed files with 573 additions and 276 deletions

View File

@@ -27,12 +27,14 @@ a Docker registry.
Documentation can be found on https://crazymax.dev/diun/
## How can I help?
## Contributing
All kinds of contributions are welcome :raised_hands:! The most basic way to show your support is to star :star2: the
project, or to raise issues :speech_balloon: You can also support this project by
[**becoming a sponsor on GitHub**](https://github.com/sponsors/crazy-max) :clap: or by making a
[Paypal donation](https://www.paypal.me/crazyws) to ensure this journey continues indefinitely! :rocket:
Want to contribute? Awesome! The most basic way to show your support is to star :star2: the project,
or to raise issues :speech_balloon:. If you want to open a pull request, please read the
[contributing guidelines](.github/CONTRIBUTING.md).
You can also support this project by [**becoming a sponsor on GitHub**](https://github.com/sponsors/crazy-max) or by
making a [Paypal donation](https://www.paypal.me/crazyws) to ensure this journey continues indefinitely!
Thanks again for your support, it is much appreciated! :pray:

View File

@@ -10,48 +10,48 @@
{% set assets = config.site_url ~ 'assets' %}
{% block extrahead %}
<link rel="preconnect" href="https://{{ config.extra.plausible.server }}">
<script defer data-domain="{{ config.extra.plausible.domain }}" src="https://{{ config.extra.plausible.server }}/js/plausible.outbound-links.js" ></script>
<link rel="preconnect" href="https://[[ config.extra.plausible.server ]]">
<script defer data-domain="[[ config.extra.plausible.domain ]]" src="https://[[ config.extra.plausible.server ]]/js/plausible.outbound-links.js" ></script>
<script>window.plausible = window.plausible || function() { (window.plausible.q = window.plausible.q || []).push(arguments) }</script>
<meta name="application-name" content="{{ config.site_name }}">
<meta name="application-name" content="[[ config.site_name ]]">
<meta name="msapplication-TileColor" content="#FFFFFF">
<meta name="msapplication-TileImage" content="{{ assets }}/meta/mstile-144x144.png">
<meta name="msapplication-square70x70logo" content="{{ assets }}/meta/mstile-70x70.png">
<meta name="msapplication-square150x150logo" content="{{ assets }}/meta/mstile-150x150.png">
<meta name="msapplication-wide310x150logo" content="{{ assets }}/meta/mstile-310x150.png">
<meta name="msapplication-square310x310logo" content="{{ assets }}/meta/mstile-310x310.png">
<meta name="msapplication-TileImage" content="[[ assets ]]/meta/mstile-144x144.png">
<meta name="msapplication-square70x70logo" content="[[ assets ]]/meta/mstile-70x70.png">
<meta name="msapplication-square150x150logo" content="[[ assets ]]/meta/mstile-150x150.png">
<meta name="msapplication-wide310x150logo" content="[[ assets ]]/meta/mstile-310x150.png">
<meta name="msapplication-square310x310logo" content="[[ assets ]]/meta/mstile-310x310.png">
<meta property="og:type" content="website">
<meta property="og:title" content="{{ title }}">
<meta property="og:description" content="{{ config.site_description }}">
<meta property="og:url" content="{{ page.canonical_url }}">
<meta property="og:image" content="{{ assets }}/meta/card.png">
<meta property="og:image:alt" content="{{ config.site_name }}">
<meta property="og:title" content="[[ title ]]">
<meta property="og:description" content="[[ config.site_description ]]">
<meta property="og:url" content="[[ page.canonical_url ]]">
<meta property="og:image" content="[[ assets ]]/meta/card.png">
<meta property="og:image:alt" content="[[ config.site_name ]]">
<meta property="og:image:type" content="image/png">
<meta property="og:image:width" content="1280">
<meta property="og:image:height" content="640">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@crazyws">
<meta name="twitter:creator" content="@crazyws">
<meta name="twitter:title" content="{{ title }}">
<meta name="twitter:description" content="{{ config.site_description }}">
<meta name="twitter:image" content="{{ assets }}/meta/card.png">
<meta name="google-site-verification" content="{{ config.extra.seo.google }}">
<meta name="msvalidate.01" content="{{ config.extra.seo.bing }}">
<meta name="twitter:title" content="[[ title ]]">
<meta name="twitter:description" content="[[ config.site_description ]]">
<meta name="twitter:image" content="[[ assets ]]/meta/card.png">
<meta name="google-site-verification" content="[[ config.extra.seo.google ]]">
<meta name="msvalidate.01" content="[[ config.extra.seo.bing ]]">
<link rel="apple-touch-icon-precomposed" sizes="57x57" href="{{ assets }}/meta/apple-touch-icon-57x57.png">
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="{{ assets }}/meta/apple-touch-icon-114x114.png">
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="{{ assets }}/meta/apple-touch-icon-72x72.png">
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="{{ assets }}/meta/apple-touch-icon-144x144.png">
<link rel="apple-touch-icon-precomposed" sizes="60x60" href="{{ assets }}/meta/apple-touch-icon-60x60.png">
<link rel="apple-touch-icon-precomposed" sizes="120x120" href="{{ assets }}/meta/apple-touch-icon-120x120.png">
<link rel="apple-touch-icon-precomposed" sizes="76x76" href="{{ assets }}/meta/apple-touch-icon-76x76.png">
<link rel="apple-touch-icon-precomposed" sizes="152x152" href="{{ assets }}/meta/apple-touch-icon-152x152.png">
<link rel="icon" type="image/png" href="{{ assets }}/meta/favicon-196x196.png" sizes="196x196">
<link rel="icon" type="image/png" href="{{ assets }}/meta/favicon-96x96.png" sizes="96x96">
<link rel="icon" type="image/png" href="{{ assets }}/meta/favicon-32x32.png" sizes="32x32">
<link rel="icon" type="image/png" href="{{ assets }}/meta/favicon-16x16.png" sizes="16x16">
<link rel="icon" type="image/png" href="{{ assets }}/meta/favicon-128.png" sizes="128x128">
<link rel="apple-touch-icon-precomposed" sizes="57x57" href="[[ assets ]]/meta/apple-touch-icon-57x57.png">
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="[[ assets ]]/meta/apple-touch-icon-114x114.png">
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="[[ assets ]]/meta/apple-touch-icon-72x72.png">
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="[[ assets ]]/meta/apple-touch-icon-144x144.png">
<link rel="apple-touch-icon-precomposed" sizes="60x60" href="[[ assets ]]/meta/apple-touch-icon-60x60.png">
<link rel="apple-touch-icon-precomposed" sizes="120x120" href="[[ assets ]]/meta/apple-touch-icon-120x120.png">
<link rel="apple-touch-icon-precomposed" sizes="76x76" href="[[ assets ]]/meta/apple-touch-icon-76x76.png">
<link rel="apple-touch-icon-precomposed" sizes="152x152" href="[[ assets ]]/meta/apple-touch-icon-152x152.png">
<link rel="icon" type="image/png" href="[[ assets ]]/meta/favicon-196x196.png" sizes="196x196">
<link rel="icon" type="image/png" href="[[ assets ]]/meta/favicon-96x96.png" sizes="96x96">
<link rel="icon" type="image/png" href="[[ assets ]]/meta/favicon-32x32.png" sizes="32x32">
<link rel="icon" type="image/png" href="[[ assets ]]/meta/favicon-16x16.png" sizes="16x16">
<link rel="icon" type="image/png" href="[[ assets ]]/meta/favicon-128.png" sizes="128x128">
{% endblock %}
<!-- Announcement bar -->

View File

@@ -3,18 +3,18 @@
Hi there! I'm thrilled that you'd like to contribute to this project. Your help is essential for keeping it great.
Contributions to this project are [released](https://help.github.com/articles/github-terms-of-service/#6-contributions-under-repository-license)
to the public under the [project's open source license]({{ config.repo_url }}/blob/master/LICENSE).
to the public under the [project's open source license]([[ config.repo_url ]]/blob/master/LICENSE).
## Submitting a pull request
1. [Fork]({{ config.repo_url }}fork) and clone the repository
1. [Fork]([[ config.repo_url ]]fork) and clone the repository
2. Configure and install the dependencies: `go mod download`
3. Create a new branch: `git checkout -b my-branch-name`
4. Make your changes
5. Validate: `docker buildx bake validate`
6. Test your code: `docker buildx bake test`
7. Build the project: `docker buildx bake artifact-all image-all`
8. Push to your fork and [submit a pull request]({{ config.repo_url }}compare)
8. Push to your fork and [submit a pull request]([[ config.repo_url ]]compare)
9. Pat your self on the back and wait for your pull request to be reviewed and merged.
Here are a few things you can do that will increase the likelihood of your pull request being accepted:

View File

@@ -1,7 +1,7 @@
**Diun** :bell: is free and open source and always will be.
All kinds of contributions are welcome! The most basic way to show your support is to
[star the project]({{ config.repo_url }}), or to raise issues.
[star the project]([[ config.repo_url ]]), or to raise issues.
You can also support this project by [**becoming a sponsor on GitHub**](https://github.com/sponsors/crazy-max) or
by making a [Paypal donation](https://www.paypal.me/crazyws) to ensure this journey continues indefinitely!

View File

@@ -26,6 +26,43 @@ Or within a container:
docker-compose exec diun diun notif test
```
## Notification template
The title and body of a notification message can be customized for each notifier through `templateTitle` and
`templateBody` fields except for those rendering _JSON_ or _Env_ like [Amqp](notif/amqp.md),
[MQTT](notif/mqtt.md), [Script](notif/script.md) and [Webhook](notif/webhook.md).
Templating is supported with the following fields:
| Key | Description |
|----------------------------------|-------------|
| `.Meta.ID` | App ID: `diun` |
| `.Meta.Name` | App Name: `Diun` |
| `.Meta.Desc` | App description: `Docker image update notifier` |
| `.Meta.URL` | App repo URL: `https://github.com/crazy-max/diun` |
| `.Meta.Logo` | App logo URL: `https://raw.githubusercontent.com/crazy-max/diun/master/.res/diun.png` |
| `.Meta.Author` | App author: `CrazyMax` |
| `.Meta.Version` | App version: `v4.19.0` |
| `.Meta.UserAgent` | App user-agent used to talk with registries: `diun/4.19.0 go/1.16 Linux` |
| `.Meta.Hostname` | Hostname |
| `.Entry.Status` | Entry status. Can be `new`, `update`, `unchange`, `skip` or `error` |
| `.Entry.Provider` | [Provider](config/providers.md) used |
| `.Entry.Image` | Docker image name. e.g. `docker.io/crazymax/diun:latest` |
| `.Entry.Image.Domain` | Docker image domain. e.g. `docker.io` |
| `.Entry.Image.Path` | Docker image path. e.g. `crazymax/diun` |
| `.Entry.Image.Tag` | Docker image tag. e.g. `latest` |
| `.Entry.Image.Digest` | Docker image digest |
| `.Entry.Image.HubLink` | Docker image hub link (if available). e.g. `https://hub.docker.com/r/crazymax/diun` |
| `.Entry.Manifest.Name` | Manifest name. e.g. `docker.io/crazymax/diun` |
| `.Entry.Manifest.Tag` | Manifest tag. e.g. `latest` |
| `.Entry.Manifest.MIMEType` | Manifest MIME type. e.g. `application/vnd.docker.distribution.manifest.list.v2+json` |
| `.Entry.Manifest.Digest` | Manifest digest |
| `.Entry.Manifest.Created` | Manifest created date. e.g. `2021-06-20T12:23:56Z` |
| `.Entry.Manifest.DockerVersion` | Version of Docker that was used to build the image. e.g. `20.10.7` |
| `.Entry.Manifest.Labels` | Image labels |
| `.Entry.Manifest.Layers` | Image layers |
| `.Entry.Manifest.Platform` | Platform that the image is runs on. e.g. `linux/amd64` |
## Authentication against the registry
You can authenticate against the registry through the [`regopts` settings](config/regopts.md) or you can mount

View File

@@ -2,27 +2,27 @@
## Download
Diun binaries are available on [releases]({{ config.repo_url }}releases) page.
Diun binaries are available on [releases]([[ config.repo_url ]]releases) page.
Choose the archive matching the destination platform:
* [diun_{{ git.tag | trim('v') }}_darwin_arm64.tar.gz]({{ config.repo_url }}/releases/download/v{{ git.tag | trim('v') }}/diun_{{ git.tag | trim('v') }}_darwin_arm64.tar.gz)
* [diun_{{ git.tag | trim('v') }}_darwin_x86_64.tar.gz]({{ config.repo_url }}/releases/download/v{{ git.tag | trim('v') }}/diun_{{ git.tag | trim('v') }}_darwin_x86_64.tar.gz)
* [diun_{{ git.tag | trim('v') }}_linux_arm64.tar.gz]({{ config.repo_url }}/releases/download/v{{ git.tag | trim('v') }}/diun_{{ git.tag | trim('v') }}_linux_arm64.tar.gz)
* [diun_{{ git.tag | trim('v') }}_linux_armv5.tar.gz]({{ config.repo_url }}/releases/download/v{{ git.tag | trim('v') }}/diun_{{ git.tag | trim('v') }}_linux_armv5.tar.gz)
* [diun_{{ git.tag | trim('v') }}_linux_armv6.tar.gz]({{ config.repo_url }}/releases/download/v{{ git.tag | trim('v') }}/diun_{{ git.tag | trim('v') }}_linux_armv6.tar.gz)
* [diun_{{ git.tag | trim('v') }}_linux_armv7.tar.gz]({{ config.repo_url }}/releases/download/v{{ git.tag | trim('v') }}/diun_{{ git.tag | trim('v') }}_linux_armv7.tar.gz)
* [diun_{{ git.tag | trim('v') }}_linux_i386.tar.gz]({{ config.repo_url }}/releases/download/v{{ git.tag | trim('v') }}/diun_{{ git.tag | trim('v') }}_linux_i386.tar.gz)
* [diun_{{ git.tag | trim('v') }}_linux_ppc64le.tar.gz]({{ config.repo_url }}/releases/download/v{{ git.tag | trim('v') }}/diun_{{ git.tag | trim('v') }}_linux_ppc64le.tar.gz)
* [diun_{{ git.tag | trim('v') }}_linux_s390x.tar.gz]({{ config.repo_url }}/releases/download/v{{ git.tag | trim('v') }}/diun_{{ git.tag | trim('v') }}_linux_s390x.tar.gz)
* [diun_{{ git.tag | trim('v') }}_linux_x86_64.tar.gz]({{ config.repo_url }}/releases/download/v{{ git.tag | trim('v') }}/diun_{{ git.tag | trim('v') }}_linux_x86_64.tar.gz)
* [diun_{{ git.tag | trim('v') }}_windows_i386.zip]({{ config.repo_url }}/releases/download/v{{ git.tag | trim('v') }}/diun_{{ git.tag | trim('v') }}_windows_i386.zip)
* [diun_{{ git.tag | trim('v') }}_windows_x86_64.zip]({{ config.repo_url }}/releases/download/v{{ git.tag | trim('v') }}/diun_{{ git.tag | trim('v') }}_windows_x86_64.zip)
* [diun_[[ git.tag | trim('v') ]]_darwin_arm64.tar.gz]([[ config.repo_url ]]/releases/download/v[[ git.tag | trim('v') ]]/diun_[[ git.tag | trim('v') ]]_darwin_arm64.tar.gz)
* [diun_[[ git.tag | trim('v') ]]_darwin_x86_64.tar.gz]([[ config.repo_url ]]/releases/download/v[[ git.tag | trim('v') ]]/diun_[[ git.tag | trim('v') ]]_darwin_x86_64.tar.gz)
* [diun_[[ git.tag | trim('v') ]]_linux_arm64.tar.gz]([[ config.repo_url ]]/releases/download/v[[ git.tag | trim('v') ]]/diun_[[ git.tag | trim('v') ]]_linux_arm64.tar.gz)
* [diun_[[ git.tag | trim('v') ]]_linux_armv5.tar.gz]([[ config.repo_url ]]/releases/download/v[[ git.tag | trim('v') ]]/diun_[[ git.tag | trim('v') ]]_linux_armv5.tar.gz)
* [diun_[[ git.tag | trim('v') ]]_linux_armv6.tar.gz]([[ config.repo_url ]]/releases/download/v[[ git.tag | trim('v') ]]/diun_[[ git.tag | trim('v') ]]_linux_armv6.tar.gz)
* [diun_[[ git.tag | trim('v') ]]_linux_armv7.tar.gz]([[ config.repo_url ]]/releases/download/v[[ git.tag | trim('v') ]]/diun_[[ git.tag | trim('v') ]]_linux_armv7.tar.gz)
* [diun_[[ git.tag | trim('v') ]]_linux_i386.tar.gz]([[ config.repo_url ]]/releases/download/v[[ git.tag | trim('v') ]]/diun_[[ git.tag | trim('v') ]]_linux_i386.tar.gz)
* [diun_[[ git.tag | trim('v') ]]_linux_ppc64le.tar.gz]([[ config.repo_url ]]/releases/download/v[[ git.tag | trim('v') ]]/diun_[[ git.tag | trim('v') ]]_linux_ppc64le.tar.gz)
* [diun_[[ git.tag | trim('v') ]]_linux_s390x.tar.gz]([[ config.repo_url ]]/releases/download/v[[ git.tag | trim('v') ]]/diun_[[ git.tag | trim('v') ]]_linux_s390x.tar.gz)
* [diun_[[ git.tag | trim('v') ]]_linux_x86_64.tar.gz]([[ config.repo_url ]]/releases/download/v[[ git.tag | trim('v') ]]/diun_[[ git.tag | trim('v') ]]_linux_x86_64.tar.gz)
* [diun_[[ git.tag | trim('v') ]]_windows_i386.zip]([[ config.repo_url ]]/releases/download/v[[ git.tag | trim('v') ]]/diun_[[ git.tag | trim('v') ]]_windows_i386.zip)
* [diun_[[ git.tag | trim('v') ]]_windows_x86_64.zip]([[ config.repo_url ]]/releases/download/v[[ git.tag | trim('v') ]]/diun_[[ git.tag | trim('v') ]]_windows_x86_64.zip)
And extract diun:
```shell
wget -qO- {{ config.repo_url }}releases/download/v{{ git.tag | trim('v') }}/diun_{{ git.tag | trim('v') }}_linux_x86_64.tar.gz | tar -zxvf - diun
wget -qO- [[ config.repo_url ]]releases/download/v[[ git.tag | trim('v') ]]/diun_[[ git.tag | trim('v') ]]_linux_x86_64.tar.gz | tar -zxvf - diun
```
After getting the binary, it can be tested with [`./diun --help`](../usage/command-line.md#global-options) command

View File

@@ -10,7 +10,7 @@ To create a new service, paste this content in `/etc/systemd/system/diun.service
```
[Unit]
Description=Diun
Documentation={{ config.site_url }}
Documentation=[[ config.site_url ]]
After=syslog.target
After=network.target

View File

@@ -16,18 +16,37 @@ Allow to send notifications to your Discord channel.
- "<@125>"
- "<@&200>"
timeout: 10s
templateTitle: "{{ .Entry.Image }} released"
templateBody: |
Docker tag {{ .Entry.Image }} which you subscribed to through {{ .Entry.Provider }} provider has been released.
```
| Name | Default | Description |
|--------------------|---------------|---------------|
|---------------------|---------------------------------------|---------------|
| `webhookURL`[^1] | | Discord [incoming webhook URL](https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks) |
| `mentions` | | List of users or roles to notify |
| `timeout` | `10s` | Timeout specifies a time limit for the request to be made |
| `templateTitle`[^1] | See [below](#default-templatetitle) | [Notification template](../faq.md#notification-template) for message title |
| `templateBody`[^1] | See [below](#default-templatebody) | [Notification template](../faq.md#notification-template) for message body |
!!! abstract "Environment variables"
* `DIUN_NOTIF_DISCORD_WEBHOOKURL`
* `DIUN_NOTIF_DISCORD_MENTIONS` (comma separated)
* `DIUN_NOTIF_DISCORD_TIMEOUT`
* `DIUN_NOTIF_DISCORD_TEMPLATETITLE`
* `DIUN_NOTIF_DISCORD_TEMPLATEBODY`
### Default `templateTitle`
```
[[ config.extra.template.defaultTitle ]]
```
### Default `templateBody`
```
[[ config.extra.template.defaultBody ]]
```
## Sample

View File

@@ -12,15 +12,20 @@ Notifications can be sent using a [Gotify](https://gotify.net/) instance.
token: Token123456
priority: 1
timeout: 10s
templateTitle: "{{ .Entry.Image }} released"
templateBody: |
Docker tag {{ .Entry.Image }} which you subscribed to through {{ .Entry.Provider }} provider has been released.
```
| Name | Default | Description |
|--------------------|---------------|---------------|
|---------------------|---------------------------------------|---------------|
| `endpoint`[^1] | | Gotify base URL |
| `token` | | Application token |
| `tokenFile` | | Use content of secret file as application token if `token` not defined |
| `priority` | `1` | The priority of the message |
| `timeout` | `10s` | Timeout specifies a time limit for the request to be made |
| `templateTitle`[^1] | See [below](#default-templatetitle) | [Notification template](../faq.md#notification-template) for message title |
| `templateBody`[^1] | See [below](#default-templatebody) | [Notification template](../faq.md#notification-template) for message body |
!!! abstract "Environment variables"
* `DIUN_NOTIF_GOTIFY_ENDPOINT`
@@ -28,6 +33,20 @@ Notifications can be sent using a [Gotify](https://gotify.net/) instance.
* `DIUN_NOTIF_GOTIFY_TOKENFILE`
* `DIUN_NOTIF_GOTIFY_PRIORITY`
* `DIUN_NOTIF_GOTIFY_TIMEOUT`
* `DIUN_NOTIF_GOTIFY_TEMPLATETITLE`
* `DIUN_NOTIF_GOTIFY_TEMPLATEBODY`
### Default `templateTitle`
```
[[ config.extra.template.defaultTitle ]]
```
### Default `templateBody`
```
[[ config.extra.template.defaultBody ]]
```
## Sample

View File

@@ -14,10 +14,13 @@ Notifications can be sent through SMTP.
insecureSkipVerify: false
from: diun@example.com
to: webmaster@example.com
templateTitle: "{{ .Entry.Image }} released"
templateBody: |
Docker tag {{ .Entry.Image }} which you subscribed to through {{ .Entry.Provider }} provider has been released.
```
| Name | Default | Description |
|-----------------------|---------------|---------------|
|-----------------------|--------------------------------------------|---------------|
| `host`[^1] | `localhost` | SMTP server host |
| `port`[^1] | `25` | SMTP server port |
| `ssl` | `false` | SSL defines whether an SSL connection is used. Should be false in most cases since the auth mechanism should use STARTTLS |
@@ -29,6 +32,8 @@ Notifications can be sent through SMTP.
| `passwordFile` | | Use content of secret file as SMTP password if `password` not defined |
| `from`[^1] | | Sender email address |
| `to`[^1] | | Recipient email address |
| `templateTitle`[^1] | See [below](#default-templatetitle) | [Notification template](../faq.md#notification-template) for message title |
| `templateBody`[^1] | See [below](#default-templatebody) | [Notification template](../faq.md#notification-template) for message body |
!!! abstract "Environment variables"
* `DIUN_NOTIF_MAIL_HOST`
@@ -42,6 +47,28 @@ Notifications can be sent through SMTP.
* `DIUN_NOTIF_MAIL_PASSWORDFILE`
* `DIUN_NOTIF_MAIL_FROM`
* `DIUN_NOTIF_MAIL_TO`
* `DIUN_NOTIF_MAIL_TEMPLATETITLE`
* `DIUN_NOTIF_MAIL_TEMPLATEBODY`
### Default `templateTitle`
```
[[ config.extra.template.defaultTitle ]]
```
### Default `templateBody`
```
Docker tag {{ if .Entry.Image.HubLink }}[**{{ .Entry.Image }}**]({{ .Entry.Image.HubLink }}){{ else }}**{{ .Entry.Image }}**{{ end }}
which you subscribed to through {{ .Entry.Provider }} provider has been {{ if (eq .Entry.Status "new") }}newly added{{ else }}updated{{ end }}
on {{ .Meta.Hostname }}.
This image has been {{ if (eq .Entry.Status "new") }}created{{ else }}updated{{ end }} at
<code>{{ .Entry.Manifest.Created.Format "Jan 02, 2006 15:04:05 UTC" }}</code> with digest <code>{{ .Entry.Manifest.Digest }}</code>
for <code>{{ .Entry.Manifest.Platform }}</code> platform.
Need help, or have questions? Go to {{ .Meta.URL }} and leave an issue.
```
## Sample

View File

@@ -13,10 +13,12 @@ Allow to send notifications to your Matrix server.
password: bar
roomID: "!abcdefGHIjklmno:matrix.org"
msgType: notice
templateBody: |
Docker tag {{ .Entry.Image }} which you subscribed to through {{ .Entry.Provider }} provider has been released.
```
| Name | Default | Description |
|-----------------------|------------------------|-------------------|
|-----------------------|--------------------------------------------|-------------------|
| `homeserverURL` | `https://matrix.org` | Matrix server URL |
| `user` | | Username for authentication |
| `userFile` | | Use content of secret file as username authentication if `username` not defined |
@@ -24,6 +26,7 @@ Allow to send notifications to your Matrix server.
| `passwordFile` | | Use content of secret file as password authentication if `password` not defined |
| `roomID` | | Room ID to send messages |
| `msgType` | `notice` | Type of message being sent. Can be `notice` or `text` |
| `templateBody`[^1] | See [below](#default-templatebody) | [Notification template](../faq.md#notification-template) for message body |
!!! abstract "Environment variables"
* `DIUN_NOTIF_MATRIX_HOMESERVERURL`
@@ -33,6 +36,13 @@ Allow to send notifications to your Matrix server.
* `DIUN_NOTIF_MATRIX_PASSWORDFILE`
* `DIUN_NOTIF_MATRIX_ROOMID`
* `DIUN_NOTIF_MATRIX_MSGTYPE`
* `DIUN_NOTIF_MATRIX_TEMPLATEBODY`
### Default `templateBody`
```
[[ config.extra.template.defaultBody ]]
```
## Sample

View File

@@ -10,20 +10,39 @@ You can send notifications using [Pushover](https://pushover.net/).
pushover:
token: uQiRzpo4DXghDmr9QzzfQu27cmVRsG
recipient: gznej3rKEVAvPUxu9vvNnqpmZpokzF
templateTitle: "{{ .Entry.Image }} released"
templateBody: |
Docker tag {{ .Entry.Image }} which you subscribed to through {{ .Entry.Provider }} provider has been released.
```
| Name | Default | Description |
|--------------------|---------------|---------------|
|---------------------|--------------------------------------------|---------------|
| `token` | | Pushover [application/API token](https://pushover.net/api#registration) |
| `tokenFile` | | Use content of secret file as Pushover application/API token if `token` not defined |
| `recipient` | | User key to send notification to |
| `recipientFile` | | Use content of secret file as User key if `recipient` not defined |
| `templateTitle`[^1] | See [below](#default-templatetitle) | [Notification template](../faq.md#notification-template) for message title |
| `templateBody`[^1] | See [below](#default-templatebody) | [Notification template](../faq.md#notification-template) for message body |
!!! abstract "Environment variables"
* `DIUN_NOTIF_PUSHOVER_TOKEN`
* `DIUN_NOTIF_PUSHOVER_TOKENFILE`
* `DIUN_NOTIF_PUSHOVER_RECIPIENT`
* `DIUN_NOTIF_PUSHOVER_RECIPIENTFILE`
* `DIUN_NOTIF_PUSHOVER_TEMPLATETITLE`
* `DIUN_NOTIF_PUSHOVER_TEMPLATEBODY`
### Default `templateTitle`
```
[[ config.extra.template.defaultTitle ]]
```
### Default `templateBody`
```
[[ config.extra.template.defaultBody ]]
```
## Sample

View File

@@ -13,16 +13,21 @@ Allow to send notifications to your Rocket.Chat channel.
userID: abcdEFGH012345678
token: Token123456
timeout: 10s
templateTitle: "{{ .Entry.Image }} released"
templateBody: |
Docker tag {{ .Entry.Image }} which you subscribed to through {{ .Entry.Provider }} provider has been released.
```
| Name | Default | Description |
|--------------------|---------------|---------------|
|---------------------|--------------------------------------------|---------------|
| `endpoint`[^1] | | Rocket.Chat base URL |
| `channel`[^1] | | Channel name with the prefix in front of it |
| `userID`[^1] | | User ID |
| `token` | | Authentication token |
| `tokenFile` | | Use content of secret file as authentication token if `token` not defined |
| `timeout` | `10s` | Timeout specifies a time limit for the request to be made |
| `templateTitle`[^1] | See [below](#default-templatetitle) | [Notification template](../faq.md#notification-template) for message title |
| `templateBody`[^1] | See [below](#default-templatebody) | [Notification template](../faq.md#notification-template) for message body |
!!! warning
You must first create a _Personal Access Token_ through your account settings on your Rocket.Chat instance.
@@ -34,6 +39,20 @@ Allow to send notifications to your Rocket.Chat channel.
* `DIUN_NOTIF_ROCKETCHAT_TOKEN`
* `DIUN_NOTIF_ROCKETCHAT_TOKENFILE`
* `DIUN_NOTIF_ROCKETCHAT_TIMEOUT`
* `DIUN_NOTIF_ROCKETCHAT_TEMPLATETITLE`
* `DIUN_NOTIF_ROCKETCHAT_TEMPLATEBODY`
### Default `templateTitle`
```
[[ config.extra.template.defaultTitle ]]
```
### Default `templateBody`
```
Docker tag {{ .Entry.Image }} which you subscribed to through {{ .Entry.Provider }} provider has been {{ if (eq .Entry.Status "new") }}newly added{{ else }}updated{{ end }} on {{ .Meta.Hostname }}.
```
## Sample

View File

@@ -12,14 +12,24 @@ You can send notifications to your Slack channel using an [incoming webhook URL]
notif:
slack:
webhookURL: https://hooks.slack.com/services/ABCD12EFG/HIJK34LMN/01234567890abcdefghij
templateBody: |
Docker tag {{ .Entry.Image }} which you subscribed to through {{ .Entry.Provider }} provider has been released.
```
| Name | Default | Description |
|--------------------|---------------|---------------|
|--------------------|--------------------------------------------|---------------|
| `webhookURL`[^1] | | Slack [incoming webhook URL](https://api.slack.com/messaging/webhooks) |
| `templateBody`[^1] | See [below](#default-templatebody) | [Notification template](../faq.md#notification-template) for message body |
!!! abstract "Environment variables"
* `DIUN_NOTIF_SLACK_WEBHOOKURL`
* `DIUN_NOTIF_SLACK_TEMPLATEBODY`
### Default `templateBody`
```
<!channel> Docker tag `{{ .Entry.Image }}` {{ if (eq .Entry.Status "new") }}newly added{{ else }}updated{{ end }}.
```
## Sample

View File

@@ -9,14 +9,24 @@ You can send notifications to your Teams team-channel using an [incoming webhook
notif:
teams:
webhookURL: https://outlook.office.com/webhook/ABCD12EFG/HIJK34LMN/01234567890abcdefghij
templateBody: |
Docker tag {{ .Entry.Image }} which you subscribed to through {{ .Entry.Provider }} provider has been released.
```
| Name | Default | Description |
|--------------------|---------------|---------------|
|--------------------|--------------------------------------------|---------------|
| `webhookURL`[^1] | | Teams [incoming webhook URL](https://docs.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/what-are-webhooks-and-connectors) |
| `templateBody`[^1] | See [below](#default-templatebody) | [Notification template](../faq.md#notification-template) for message body |
!!! abstract "Environment variables"
* `DIUN_NOTIF_TEAMS_WEBHOOKURL`
* `DIUN_NOTIF_TEAMS_TEMPLATEBODY`
### Default `templateBody`
```
Docker tag {{ if .Entry.Image.HubLink }}[`{{ .Entry.Image }}`]({{ .Entry.Image.HubLink }}){{ else }}`{{ .Entry.Image }}`{{ end }}{{ if (eq .Entry.Status "new") }}newly added{{ else }}updated{{ end }}.
```
## Sample

View File

@@ -17,24 +17,37 @@ Multiple chat IDs can be provided in order to deliver notifications to multiple
chatIDs:
- 123456789
- 987654321
templateBody: |
Docker tag {{ .Entry.Image }} which you subscribed to through {{ .Entry.Provider }} provider has been released.
```
| Name | Default | Description |
|--------------------|---------------|---------------|
|--------------------|--------------------------------------------|---------------|
| `token` | | Telegram bot token |
| `tokenFile` | | Use content of secret file as Telegram bot token if `token` not defined |
| `chatIDs` | | List of chat IDs to send notifications to |
| `chatIDsFile` | | Use content of secret file as chat IDs if `chatIDs` not defined |
| `templateBody`[^1] | See [below](#default-templatebody) | [Notification template](../faq.md#notification-template) for message body |
!!! abstract "Environment variables"
* `DIUN_NOTIF_TELEGRAM_TOKEN`
* `DIUN_NOTIF_TELEGRAM_TOKENFILE`
* `DIUN_NOTIF_TELEGRAM_CHATIDS` (comma separated)
* `DIUN_NOTIF_TELEGRAM_CHATIDSFILE`
* `DIUN_NOTIF_TELEGRAM_TEMPLATEBODY`
!!! example "chat IDs secret file"
Chat IDs secret file must be a valid JSON array like: `[123456789,987654321]`
### Default `templateBody`
```
Docker tag {{ if .Entry.Image.HubLink }}[{{ .Entry.Image }}]({{ .Entry.Image.HubLink }}){{ else }}{{ .Entry.Image }}{{ end }} which you subscribed to through {{ .Entry.Provider }} provider has been {{ if (eq .Entry.Status "new") }}newly added{{ else }}updated{{ end }} on {{ escapeMarkdown .Meta.Hostname }}.
```
!!! note
`escapeMarkdown` is a special function to deal with a [makrdown strict parsing issue](https://github.com/crazy-max/diun/issues/162#issuecomment-683095898) on Telegram server.
## Sample
![](../assets/notif/telegram.png)

View File

@@ -4,7 +4,7 @@
First, [be a good guy](https://github.com/kossnocorp/etiquette/blob/master/README.md).
Please do a search in [open issues]({{ config.repo_url }}issues?utf8=%E2%9C%93&q=) to see if the issue or feature request has already been filed and read the [FAQ](faq.md) page first.
Please do a search in [open issues]([[ config.repo_url ]]issues?utf8=%E2%9C%93&q=) to see if the issue or feature request has already been filed and read the [FAQ](faq.md) page first.
If you find your issue already exists, make relevant comments and add your [reaction](https://github.com/blog/2119-add-reactions-to-pull-requests-issues-and-comments). Use a reaction in place of a "+1" comment.
@@ -23,7 +23,7 @@ File a single issue per problem and feature request.
The more information you can provide, the more likely someone will be successful reproducing the issue and finding a fix.
You are now ready to [create a new issue]({{ config.repo_url }}issues/new/choose)!
You are now ready to [create a new issue]([[ config.repo_url ]]issues/new/choose)!
## Closure policy

View File

@@ -77,12 +77,16 @@ func TestLoadFile(t *testing.T) {
"<@&200>",
},
Timeout: utl.NewDuration(10 * time.Second),
TemplateTitle: model.NotifDefaultTemplateTitle,
TemplateBody: model.NotifDefaultTemplateBody,
},
Gotify: &model.NotifGotify{
Endpoint: "http://gotify.foo.com",
Token: "Token123456",
Priority: 1,
Timeout: utl.NewDuration(10 * time.Second),
TemplateTitle: model.NotifDefaultTemplateTitle,
TemplateBody: model.NotifDefaultTemplateBody,
},
Mail: &model.NotifMail{
Host: "localhost",
@@ -92,6 +96,14 @@ func TestLoadFile(t *testing.T) {
LocalName: "localhost",
From: "diun@example.com",
To: "webmaster@example.com",
TemplateTitle: model.NotifDefaultTemplateTitle,
TemplateBody: `Docker tag {{ if .Entry.Image.HubLink }}[**{{ .Entry.Image }}**]({{ .Entry.Image.HubLink }}){{ else }}**{{ .Entry.Image }}**{{ end }}
which you subscribed to through {{ .Entry.Provider }} provider has been {{ if (eq .Entry.Status "new") }}newly added{{ else }}updated{{ end }}.
This image has been {{ if (eq .Entry.Status "new") }}created{{ else }}updated{{ end }} at
<code>{{ .Entry.Manifest.Created.Format "Jan 02, 2006 15:04:05 UTC" }}</code> with digest <code>{{ .Entry.Manifest.Digest }}</code>
for <code>{{ .Entry.Manifest.Platform }}</code> platform.
`,
},
Matrix: &model.NotifMatrix{
HomeserverURL: "https://matrix.org",
@@ -99,6 +111,7 @@ func TestLoadFile(t *testing.T) {
Password: "bar",
RoomID: "!abcdefGHIjklmno:matrix.org",
MsgType: model.NotifMatrixMsgTypeNotice,
TemplateBody: model.NotifDefaultTemplateBody,
},
Mqtt: &model.NotifMqtt{
Scheme: "mqtt",
@@ -113,6 +126,8 @@ func TestLoadFile(t *testing.T) {
Pushover: &model.NotifPushover{
Token: "uQiRzpo4DXghDmr9QzzfQu27cmVRsG",
Recipient: "gznej3rKEVAvPUxu9vvNnqpmZpokzF",
TemplateTitle: model.NotifDefaultTemplateTitle,
TemplateBody: model.NotifDefaultTemplateBody,
},
RocketChat: &model.NotifRocketChat{
Endpoint: "http://rocket.foo.com:3000",
@@ -120,6 +135,8 @@ func TestLoadFile(t *testing.T) {
UserID: "abcdEFGH012345678",
Token: "Token123456",
Timeout: utl.NewDuration(10 * time.Second),
TemplateTitle: model.NotifDefaultTemplateTitle,
TemplateBody: model.NotifRocketChatDefaultTemplateBody,
},
Script: &model.NotifScript{
Cmd: "uname",
@@ -129,13 +146,16 @@ func TestLoadFile(t *testing.T) {
},
Slack: &model.NotifSlack{
WebhookURL: "https://hooks.slack.com/services/ABCD12EFG/HIJK34LMN/01234567890abcdefghij",
TemplateBody: model.NotifSlackDefaultTemplateBody,
},
Teams: &model.NotifTeams{
WebhookURL: "https://outlook.office.com/webhook/ABCD12EFG/HIJK34LMN/01234567890abcdefghij",
TemplateBody: model.NotifTeamsDefaultTemplateBody,
},
Telegram: &model.NotifTelegram{
Token: "abcdef123456",
ChatIDs: []int64{8547439, 1234567},
TemplateBody: model.NotifTelegramDefaultTemplateBody,
},
Webhook: &model.NotifWebhook{
Endpoint: "http://webhook.foo.com/sd54qad89azd5a",
@@ -293,6 +313,7 @@ func TestLoadEnv(t *testing.T) {
Telegram: &model.NotifTelegram{
Token: "abcdef123456",
ChatIDs: []int64{8547439, 1234567},
TemplateBody: model.NotifTelegramDefaultTemplateBody,
},
},
Providers: &model.Providers{
@@ -398,6 +419,14 @@ func TestLoadMixed(t *testing.T) {
LocalName: "foo.com",
From: "diun@foo.com",
To: "webmaster@foo.com",
TemplateTitle: model.NotifDefaultTemplateTitle,
TemplateBody: `Docker tag {{ if .Entry.Image.HubLink }}[**{{ .Entry.Image }}**]({{ .Entry.Image.HubLink }}){{ else }}**{{ .Entry.Image }}**{{ end }}
which you subscribed to through {{ .Entry.Provider }} provider has been {{ if (eq .Entry.Status "new") }}newly added{{ else }}updated{{ end }}.
This image has been {{ if (eq .Entry.Status "new") }}created{{ else }}updated{{ end }} at
<code>{{ .Entry.Manifest.Created.Format "Jan 02, 2006 15:04:05 UTC" }}</code> with digest <code>{{ .Entry.Manifest.Digest }}</code>
for <code>{{ .Entry.Manifest.Platform }}</code> platform.
`,
},
},
RegOpts: nil,

View File

@@ -6,6 +6,13 @@ notif:
insecureSkipVerify: false
from: diun@example.com
to: webmaster@example.com
templateBody: |
Docker tag {{ if .Entry.Image.HubLink }}[**{{ .Entry.Image }}**]({{ .Entry.Image.HubLink }}){{ else }}**{{ .Entry.Image }}**{{ end }}
which you subscribed to through {{ .Entry.Provider }} provider has been {{ if (eq .Entry.Status "new") }}newly added{{ else }}updated{{ end }}.
This image has been {{ if (eq .Entry.Status "new") }}created{{ else }}updated{{ end }} at
<code>{{ .Entry.Manifest.Created.Format "Jan 02, 2006 15:04:05 UTC" }}</code> with digest <code>{{ .Entry.Manifest.Digest }}</code>
for <code>{{ .Entry.Manifest.Platform }}</code> platform.
providers:
docker: {}

View File

@@ -38,6 +38,13 @@ notif:
insecureSkipVerify: false
from: diun@example.com
to: webmaster@example.com
templateBody: |
Docker tag {{ if .Entry.Image.HubLink }}[**{{ .Entry.Image }}**]({{ .Entry.Image.HubLink }}){{ else }}**{{ .Entry.Image }}**{{ end }}
which you subscribed to through {{ .Entry.Provider }} provider has been {{ if (eq .Entry.Status "new") }}newly added{{ else }}updated{{ end }}.
This image has been {{ if (eq .Entry.Status "new") }}created{{ else }}updated{{ end }} at
<code>{{ .Entry.Manifest.Created.Format "Jan 02, 2006 15:04:05 UTC" }}</code> with digest <code>{{ .Entry.Manifest.Digest }}</code>
for <code>{{ .Entry.Manifest.Platform }}</code> platform.
matrix:
homeserverURL: https://matrix.org
user: "@foo:matrix.org"

View File

@@ -38,6 +38,13 @@ notif:
insecureSkipVerify: false
from: diun@example.com
to: webmaster@example.com
templateBody: |
Docker tag {{ if .Entry.Image.HubLink }}[**{{ .Entry.Image }}**]({{ .Entry.Image.HubLink }}){{ else }}**{{ .Entry.Image }}**{{ end }}
which you subscribed to through {{ .Entry.Provider }} provider has been {{ if (eq .Entry.Status "new") }}newly added{{ else }}updated{{ end }}.
This image has been {{ if (eq .Entry.Status "new") }}created{{ else }}updated{{ end }} at
<code>{{ .Entry.Manifest.Created.Format "Jan 02, 2006 15:04:05 UTC" }}</code> with digest <code>{{ .Entry.Manifest.Digest }}</code>
for <code>{{ .Entry.Manifest.Platform }}</code> platform.
matrix:
homeserverURL: https://matrix.org
user: "@foo:matrix.org"

View File

@@ -4,6 +4,12 @@ import (
"github.com/crazy-max/diun/v4/pkg/registry"
)
// Defaults used for notification template
const (
NotifDefaultTemplateTitle = `{{ if (eq .Entry.Status "new") }}New image {{ .Entry.Image }} has been added{{ else }}Image update for {{ .Entry.Image }}{{ end }}`
NotifDefaultTemplateBody = `Docker tag {{ if .Entry.Image.HubLink }}[**{{ .Entry.Image }}**]({{ .Entry.Image.HubLink }}){{ else }}**{{ .Entry.Image }}**{{ end }} which you subscribed to through {{ .Entry.Provider }} provider has been {{ if (eq .Entry.Status "new") }}newly added{{ else }}updated{{ end }} on {{ .Meta.Hostname }}.`
)
// NotifEntries represents a list of notification entries
type NotifEntries struct {
Entries []NotifEntry

View File

@@ -11,6 +11,8 @@ type NotifDiscord struct {
WebhookURL string `yaml:"webhookURL,omitempty" json:"webhookURL,omitempty" validate:"required"`
Mentions []string `yaml:"mentions,omitempty" json:"mentions,omitempty"`
Timeout *time.Duration `yaml:"timeout,omitempty" json:"timeout,omitempty" validate:"required"`
TemplateTitle string `yaml:"templateTitle,omitempty" json:"templateTitle,omitempty" validate:"required"`
TemplateBody string `yaml:"templateBody,omitempty" json:"templateBody,omitempty" validate:"required"`
}
// GetDefaults gets the default values
@@ -23,4 +25,6 @@ func (s *NotifDiscord) GetDefaults() *NotifDiscord {
// SetDefaults sets the default values
func (s *NotifDiscord) SetDefaults() {
s.Timeout = utl.NewDuration(10 * time.Second)
s.TemplateTitle = NotifDefaultTemplateTitle
s.TemplateBody = NotifDefaultTemplateBody
}

View File

@@ -13,6 +13,8 @@ type NotifGotify struct {
TokenFile string `yaml:"tokenFile,omitempty" json:"tokenFile,omitempty" validate:"omitempty,file"`
Priority int `yaml:"priority,omitempty" json:"priority,omitempty" validate:"omitempty,min=0"`
Timeout *time.Duration `yaml:"timeout,omitempty" json:"timeout,omitempty" validate:"required"`
TemplateTitle string `yaml:"templateTitle,omitempty" json:"templateTitle,omitempty" validate:"required"`
TemplateBody string `yaml:"templateBody,omitempty" json:"templateBody,omitempty" validate:"required"`
}
// GetDefaults gets the default values
@@ -26,4 +28,6 @@ func (s *NotifGotify) GetDefaults() *NotifGotify {
func (s *NotifGotify) SetDefaults() {
s.Priority = 1
s.Timeout = utl.NewDuration(10 * time.Second)
s.TemplateTitle = NotifDefaultTemplateTitle
s.TemplateBody = NotifDefaultTemplateBody
}

View File

@@ -4,6 +4,17 @@ import (
"github.com/crazy-max/diun/v4/pkg/utl"
)
// NotifMailDefaultTemplateBody ...
const NotifMailDefaultTemplateBody = `Docker tag {{ if .Entry.Image.HubLink }}[**{{ .Entry.Image }}**]({{ .Entry.Image.HubLink }}){{ else }}**{{ .Entry.Image }}**{{ end }}
which you subscribed to through {{ .Entry.Provider }} provider has been {{ if (eq .Entry.Status "new") }}newly added{{ else }}updated{{ end }}
on {{ .Meta.Hostname }}.
This image has been {{ if (eq .Entry.Status "new") }}created{{ else }}updated{{ end }} at
<code>{{ .Entry.Manifest.Created.Format "Jan 02, 2006 15:04:05 UTC" }}</code> with digest <code>{{ .Entry.Manifest.Digest }}</code>
for <code>{{ .Entry.Manifest.Platform }}</code> platform.
Need help, or have questions? Go to {{ .Meta.URL }} and leave an issue.`
// NotifMail holds mail notification configuration details
type NotifMail struct {
Host string `yaml:"host,omitempty" json:"host,omitempty" validate:"required"`
@@ -17,6 +28,8 @@ type NotifMail struct {
PasswordFile string `yaml:"passwordFile,omitempty" json:"passwordFile,omitempty" validate:"omitempty,file"`
From string `yaml:"from,omitempty" json:"from,omitempty" validate:"required,email"`
To string `yaml:"to,omitempty" json:"to,omitempty" validate:"required,email"`
TemplateTitle string `yaml:"templateTitle,omitempty" json:"templateTitle,omitempty" validate:"required"`
TemplateBody string `yaml:"templateBody,omitempty" json:"templateBody,omitempty" validate:"required"`
}
// GetDefaults gets the default values
@@ -33,4 +46,6 @@ func (s *NotifMail) SetDefaults() {
s.SSL = utl.NewFalse()
s.InsecureSkipVerify = utl.NewFalse()
s.LocalName = "localhost"
s.TemplateTitle = NotifDefaultTemplateTitle
s.TemplateBody = NotifMailDefaultTemplateBody
}

View File

@@ -9,6 +9,7 @@ type NotifMatrix struct {
PasswordFile string `yaml:"passwordFile,omitempty" json:"passwordFile,omitempty" validate:"omitempty,file"`
RoomID string `yaml:"roomID,omitempty" json:"roomID,omitempty" validate:"required"`
MsgType NotifMatrixMsgType `yaml:"msgType,omitempty" json:"msgType,omitempty" validate:"required,oneof=notice text"`
TemplateBody string `yaml:"templateBody,omitempty" json:"templateBody,omitempty" validate:"required"`
}
// NotifMatrix message type constants
@@ -31,4 +32,5 @@ func (s *NotifMatrix) GetDefaults() *NotifMatrix {
func (s *NotifMatrix) SetDefaults() {
s.HomeserverURL = "https://matrix.org"
s.MsgType = NotifMatrixMsgTypeNotice
s.TemplateBody = NotifDefaultTemplateBody
}

View File

@@ -7,14 +7,19 @@ type NotifPushover struct {
Recipient string `yaml:"recipient,omitempty" json:"recipient,omitempty" validate:"omitempty"`
RecipientFile string `yaml:"recipientFile,omitempty" json:"recipientFile,omitempty" validate:"omitempty,file"`
Priority int `yaml:"priority,omitempty" json:"priority,omitempty" validate:"omitempty,min=-2,max=2"`
TemplateTitle string `yaml:"templateTitle,omitempty" json:"templateTitle,omitempty" validate:"required"`
TemplateBody string `yaml:"templateBody,omitempty" json:"templateBody,omitempty" validate:"required"`
}
// GetDefaults gets the default values
func (s *NotifPushover) GetDefaults() *NotifPushover {
return nil
n := &NotifPushover{}
n.SetDefaults()
return n
}
// SetDefaults sets the default values
func (s *NotifPushover) SetDefaults() {
// noop
s.TemplateTitle = NotifDefaultTemplateTitle
s.TemplateBody = NotifDefaultTemplateBody
}

View File

@@ -6,6 +6,9 @@ import (
"github.com/crazy-max/diun/v4/pkg/utl"
)
// NotifRocketChatDefaultTemplateBody ...
const NotifRocketChatDefaultTemplateBody = `Docker tag {{ .Entry.Image }} which you subscribed to through {{ .Entry.Provider }} provider has been {{ if (eq .Entry.Status "new") }}newly added{{ else }}updated{{ end }} on {{ .Meta.Hostname }}.`
// NotifRocketChat holds Rocket.Chat notification configuration details
type NotifRocketChat struct {
Endpoint string `yaml:"endpoint,omitempty" json:"endpoint,omitempty" validate:"required"`
@@ -14,6 +17,8 @@ type NotifRocketChat struct {
Token string `yaml:"token,omitempty" json:"token,omitempty" validate:"omitempty"`
TokenFile string `yaml:"tokenFile,omitempty" json:"tokenFile,omitempty" validate:"omitempty,file"`
Timeout *time.Duration `yaml:"timeout,omitempty" json:"timeout,omitempty" validate:"required"`
TemplateTitle string `yaml:"templateTitle,omitempty" json:"templateTitle,omitempty" validate:"required"`
TemplateBody string `yaml:"templateBody,omitempty" json:"templateBody,omitempty" validate:"required"`
}
// GetDefaults gets the default values
@@ -26,4 +31,6 @@ func (s *NotifRocketChat) GetDefaults() *NotifRocketChat {
// SetDefaults sets the default values
func (s *NotifRocketChat) SetDefaults() {
s.Timeout = utl.NewDuration(10 * time.Second)
s.TemplateTitle = NotifDefaultTemplateTitle
s.TemplateBody = NotifRocketChatDefaultTemplateBody
}

View File

@@ -1,16 +1,22 @@
package model
// NotifSlackDefaultTemplateBody ...
const NotifSlackDefaultTemplateBody = "<!channel> Docker tag `{{ .Entry.Image }}` {{ if (eq .Entry.Status \"new\") }}newly added{{ else }}updated{{ end }}."
// NotifSlack holds slack notification configuration details
type NotifSlack struct {
WebhookURL string `yaml:"webhookURL,omitempty" json:"webhookURL,omitempty" validate:"required"`
TemplateBody string `yaml:"templateBody,omitempty" json:"templateBody,omitempty" validate:"required"`
}
// GetDefaults gets the default values
func (s *NotifSlack) GetDefaults() *NotifSlack {
return nil
n := &NotifSlack{}
n.SetDefaults()
return n
}
// SetDefaults sets the default values
func (s *NotifSlack) SetDefaults() {
// noop
s.TemplateBody = NotifSlackDefaultTemplateBody
}

View File

@@ -1,16 +1,22 @@
package model
// NotifTeamsDefaultTemplateBody ...
const NotifTeamsDefaultTemplateBody = "Docker tag {{ if .Entry.Image.HubLink }}[`{{ .Entry.Image }}`]({{ .Entry.Image.HubLink }}){{ else }}`{{ .Entry.Image }}`{{ end }}{{ if (eq .Entry.Status \"new\") }}newly added{{ else }}updated{{ end }}."
// NotifTeams holds Teams notification configuration details
type NotifTeams struct {
WebhookURL string `yaml:"webhookURL,omitempty" json:"webhookURL,omitempty" validate:"required"`
TemplateBody string `yaml:"templateBody,omitempty" json:"templateBody,omitempty" validate:"required"`
}
// GetDefaults gets the default values
func (s *NotifTeams) GetDefaults() *NotifTeams {
return nil
n := &NotifTeams{}
n.SetDefaults()
return n
}
// SetDefaults sets the default values
func (s *NotifTeams) SetDefaults() {
// noop
s.TemplateBody = NotifTeamsDefaultTemplateBody
}

View File

@@ -1,19 +1,25 @@
package model
// NotifTelegramDefaultTemplateBody ...
const NotifTelegramDefaultTemplateBody = `Docker tag {{ if .Entry.Image.HubLink }}[{{ .Entry.Image }}]({{ .Entry.Image.HubLink }}){{ else }}{{ .Entry.Image }}{{ end }} which you subscribed to through {{ .Entry.Provider }} provider has been {{ if (eq .Entry.Status "new") }}newly added{{ else }}updated{{ end }} on {{ escapeMarkdown .Meta.Hostname }}.`
// NotifTelegram holds Telegram notification configuration details
type NotifTelegram struct {
Token string `yaml:"token,omitempty" json:"token,omitempty" validate:"omitempty"`
TokenFile string `yaml:"tokenFile,omitempty" json:"tokenFile,omitempty" validate:"omitempty,file"`
ChatIDs []int64 `yaml:"chatIDs,omitempty" json:"chatIDs,omitempty" validate:"omitempty"`
ChatIDsFile string `yaml:"chatIDsFile,omitempty" json:"chatIDsFile,omitempty" validate:"omitempty,file"`
TemplateBody string `yaml:"templateBody,omitempty" json:"templateBody,omitempty" validate:"required"`
}
// GetDefaults gets the default values
func (s *NotifTelegram) GetDefaults() *NotifTelegram {
return nil
n := &NotifTelegram{}
n.SetDefaults()
return n
}
// SetDefaults sets the default values
func (s *NotifTelegram) SetDefaults() {
// noop
s.TemplateBody = NotifTelegramDefaultTemplateBody
}

View File

@@ -11,6 +11,7 @@ import (
"github.com/crazy-max/diun/v4/internal/model"
"github.com/microcosm-cc/bluemonday"
"github.com/opencontainers/go-digest"
"github.com/pkg/errors"
"github.com/russross/blackfriday/v2"
)
@@ -23,13 +24,11 @@ type Client struct {
type Options struct {
Meta model.Meta
Entry model.NotifEntry
TplFuncs template.FuncMap
TemplateTitle string
TemplateBody string
TemplateFuncs template.FuncMap
}
const defaultTpl = `Docker tag {{ if .Entry.Image.HubLink }}[**{{ .Entry.Image }}**]({{ .Entry.Image.HubLink }}){{ else }}**{{ .Entry.Image }}**{{ end }}
which you subscribed to through {{ .Entry.Provider }} provider has been {{ if (eq .Entry.Status "new") }}newly added{{ else }}updated{{ end }}
on {{ .Meta.Hostname }}.`
// New initializes a new msg client
func New(opts Options) (*Client, error) {
return &Client{
@@ -38,47 +37,49 @@ func New(opts Options) (*Client, error) {
}
// RenderMarkdown returns a notification message as markdown
func (c *Client) RenderMarkdown() (title string, text []byte, err error) {
return c.RenderMarkdownTemplate(strings.ReplaceAll(defaultTpl, "\n", " "))
}
// RenderMarkdownTemplate returns a notification message as markdown with a custom template
func (c *Client) RenderMarkdownTemplate(tpl string) (title string, text []byte, err error) {
title = fmt.Sprintf("Image update for %s", c.opts.Entry.Image.String())
if c.opts.Entry.Status == model.ImageStatusNew {
title = fmt.Sprintf("New image %s has been added", c.opts.Entry.Image.String())
}
var msgBuf bytes.Buffer
msgTpl := template.Must(template.New("notif").Funcs(c.opts.TplFuncs).Parse(tpl))
err = msgTpl.Execute(&msgBuf, struct {
func (c *Client) RenderMarkdown() (title []byte, body []byte, err error) {
var titleBuf bytes.Buffer
titleTpl := template.Must(template.New("title").Funcs(c.opts.TemplateFuncs).Parse(strings.TrimSuffix(strings.TrimSpace(c.opts.TemplateTitle), "\n")))
err = titleTpl.Execute(&titleBuf, struct {
Meta model.Meta
Entry model.NotifEntry
}{
Meta: c.opts.Meta,
Entry: c.opts.Entry,
})
if err != nil {
return title, body, errors.Wrap(err, "Cannot render notif title")
}
title = titleBuf.Bytes()
var bodyBuf bytes.Buffer
bodyTpl := template.Must(template.New("body").Funcs(c.opts.TemplateFuncs).Parse(strings.TrimSuffix(strings.TrimSpace(c.opts.TemplateBody), "\n")))
err = bodyTpl.Execute(&bodyBuf, struct {
Meta model.Meta
Entry model.NotifEntry
}{
Meta: c.opts.Meta,
Entry: c.opts.Entry,
})
if err != nil {
return title, body, errors.Wrap(err, "Cannot render notif body")
}
body = bodyBuf.Bytes()
text = msgBuf.Bytes()
return
}
// RenderHTML returns a notification message as html
func (c *Client) RenderHTML() (title string, text []byte, err error) {
return c.RenderHTMLTemplate(strings.ReplaceAll(defaultTpl, "\n", " "))
}
// RenderHTMLTemplate returns a notification message as html with a custom template
func (c *Client) RenderHTMLTemplate(tpl string) (title string, text []byte, err error) {
title, text, err = c.RenderMarkdownTemplate(tpl)
func (c *Client) RenderHTML() (title []byte, body []byte, err error) {
title, body, err = c.RenderMarkdown()
if err != nil {
return
return title, body, err
}
text = []byte(bluemonday.UGCPolicy().Sanitize(
body = []byte(bluemonday.UGCPolicy().Sanitize(
// Dirty way to remove wrapped <p></p> and newline
// https://github.com/russross/blackfriday/issues/237
strings.TrimRight(strings.TrimLeft(strings.TrimSpace(string(blackfriday.Run(text))), "<p>"), "</p>"),
strings.TrimRight(strings.TrimLeft(strings.TrimSpace(string(blackfriday.Run(body))), "<p>"), "</p>"),
))
return
}

View File

@@ -47,12 +47,14 @@ func (c *Client) Send(entry model.NotifEntry) error {
message, err := msg.New(msg.Options{
Meta: c.meta,
Entry: entry,
TemplateTitle: c.cfg.TemplateTitle,
TemplateBody: c.cfg.TemplateBody,
})
if err != nil {
return err
}
title, text, err := message.RenderMarkdown()
title, body, err := message.RenderMarkdown()
if err != nil {
return err
}
@@ -62,7 +64,7 @@ func (c *Client) Send(entry model.NotifEntry) error {
content.WriteString(fmt.Sprintf("%s ", mention))
}
}
content.WriteString(title)
content.WriteString(string(title))
fields := []EmbedField{
{
@@ -100,7 +102,7 @@ func (c *Client) Send(entry model.NotifEntry) error {
AvatarURL: c.meta.Logo,
Embeds: []Embed{
{
Description: string(text),
Description: string(body),
Footer: EmbedFooter{
Text: fmt.Sprintf("%s © %d %s %s", c.meta.Author, time.Now().Year(), c.meta.Name, c.meta.Version),
IconURL: c.meta.Logo,

View File

@@ -52,24 +52,26 @@ func (c *Client) Send(entry model.NotifEntry) error {
message, err := msg.New(msg.Options{
Meta: c.meta,
Entry: entry,
TemplateTitle: c.cfg.TemplateTitle,
TemplateBody: c.cfg.TemplateBody,
})
if err != nil {
return err
}
title, text, err := message.RenderMarkdown()
title, body, err := message.RenderMarkdown()
if err != nil {
return err
}
body, err := json.Marshal(struct {
jsonBody, err := json.Marshal(struct {
Message string `json:"message"`
Title string `json:"title"`
Priority int `json:"priority"`
Extras map[string]interface{} `json:"extras"`
}{
Message: string(text),
Title: title,
Message: string(body),
Title: string(title),
Priority: c.cfg.Priority,
Extras: map[string]interface{}{
"client::display": map[string]string{
@@ -91,13 +93,13 @@ func (c *Client) Send(entry model.NotifEntry) error {
q.Set("token", token)
u.RawQuery = q.Encode()
req, err := http.NewRequest("POST", u.String(), bytes.NewBuffer(body))
req, err := http.NewRequest("POST", u.String(), bytes.NewBuffer(jsonBody))
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Add("Content-Length", strconv.Itoa(len(string(body))))
req.Header.Add("Content-Length", strconv.Itoa(len(string(jsonBody))))
req.Header.Set("User-Agent", c.meta.UserAgent)
resp, err := hc.Do(req)

View File

@@ -21,16 +21,6 @@ type Client struct {
meta model.Meta
}
const customTpl = `Docker tag {{ if .Entry.Image.HubLink }}[**{{ .Entry.Image }}**]({{ .Entry.Image.HubLink }}){{ else }}**{{ .Entry.Image }}**{{ end }}
which you subscribed to through {{ .Entry.Provider }} provider has been {{ if (eq .Entry.Status "new") }}newly added{{ else }}updated{{ end }}
on {{ .Meta.Hostname }}.
This image has been {{ if (eq .Entry.Status "new") }}created{{ else }}updated{{ end }} at
<code>{{ .Entry.Manifest.Created.Format "Jan 02, 2006 15:04:05 UTC" }}</code> with digest <code>{{ .Entry.Manifest.Digest }}</code>
for <code>{{ .Entry.Manifest.Platform }}</code> platform.
Need help, or have questions? Go to {{ .Meta.URL }} and leave an issue.`
// New creates a new mail notification instance
func New(config *model.NotifMail, meta model.Meta) notifier.Notifier {
return notifier.Notifier{
@@ -65,12 +55,14 @@ func (c *Client) Send(entry model.NotifEntry) error {
message, err := msg.New(msg.Options{
Meta: c.meta,
Entry: entry,
TemplateTitle: c.cfg.TemplateTitle,
TemplateBody: c.cfg.TemplateBody,
})
if err != nil {
return err
}
title, text, err := message.RenderMarkdownTemplate(customTpl)
title, body, err := message.RenderMarkdown()
if err != nil {
return err
}
@@ -78,7 +70,7 @@ func (c *Client) Send(entry model.NotifEntry) error {
email := hermes.Email{
Body: hermes.Body{
Title: fmt.Sprintf("%s 🔔 notification", c.meta.Name),
FreeMarkdown: hermes.Markdown(text),
FreeMarkdown: hermes.Markdown(body),
Signature: "Thanks for your support!",
},
}
@@ -95,12 +87,12 @@ func (c *Client) Send(entry model.NotifEntry) error {
return fmt.Errorf("hermes: %v", err)
}
msg := gomail.NewMessage()
msg.SetHeader("From", fmt.Sprintf("%s <%s>", c.meta.Name, c.cfg.From))
msg.SetHeader("To", c.cfg.To)
msg.SetHeader("Subject", title)
msg.SetBody("text/plain", textpart)
msg.AddAlternative("text/html", htmlpart)
mailMessage := gomail.NewMessage()
mailMessage.SetHeader("From", fmt.Sprintf("%s <%s>", c.meta.Name, c.cfg.From))
mailMessage.SetHeader("To", c.cfg.To)
mailMessage.SetHeader("Subject", string(title))
mailMessage.SetBody("text/plain", textpart)
mailMessage.AddAlternative("text/html", htmlpart)
var tlsConfig *tls.Config
if *c.cfg.InsecureSkipVerify {
@@ -128,5 +120,5 @@ func (c *Client) Send(entry model.NotifEntry) error {
LocalName: c.cfg.LocalName,
}
return dialer.DialAndSend(msg)
return dialer.DialAndSend(mailMessage)
}

View File

@@ -74,6 +74,7 @@ func (c *Client) Send(entry model.NotifEntry) error {
message, err := msg.New(msg.Options{
Meta: c.meta,
Entry: entry,
TemplateBody: c.cfg.TemplateBody,
})
if err != nil {
return err

View File

@@ -8,8 +8,6 @@ import (
"github.com/crazy-max/diun/v4/internal/notif/notifier"
"github.com/crazy-max/diun/v4/pkg/utl"
MQTT "github.com/eclipse/paho.mqtt.golang"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)
// Client represents an active mqtt notification object
@@ -17,7 +15,6 @@ type Client struct {
*notifier.Notifier
cfg *model.NotifMqtt
meta model.Meta
logger zerolog.Logger
mqttClient MQTT.Client
}
@@ -27,7 +24,6 @@ func New(config *model.NotifMqtt, meta model.Meta) notifier.Notifier {
Handler: &Client{
cfg: config,
meta: meta,
logger: log.With().Str("notif", "mqtt").Logger(),
},
}
}

View File

@@ -48,19 +48,21 @@ func (c *Client) Send(entry model.NotifEntry) error {
message, err := msg.New(msg.Options{
Meta: c.meta,
Entry: entry,
TemplateTitle: c.cfg.TemplateTitle,
TemplateBody: c.cfg.TemplateBody,
})
if err != nil {
return err
}
title, text, err := message.RenderHTML()
title, body, err := message.RenderHTML()
if err != nil {
return err
}
_, err = pushover.New(token).SendMessage(&pushover.Message{
Message: string(text),
Title: title,
Title: string(title),
Message: string(body),
Priority: c.cfg.Priority,
URL: c.meta.URL,
URLTitle: c.meta.Name,

View File

@@ -24,8 +24,6 @@ type Client struct {
meta model.Meta
}
const customTpl = `Docker tag {{ .Entry.Image }} which you subscribed to through {{ .Entry.Provider }} provider has been {{ if (eq .Entry.Status "new") }}newly added{{ else }}updated{{ end }} on {{ .Meta.Hostname }}.`
// New creates a new rocketchat notification instance
func New(config *model.NotifRocketChat, meta model.Meta) notifier.Notifier {
return notifier.Notifier{
@@ -56,12 +54,14 @@ func (c *Client) Send(entry model.NotifEntry) error {
message, err := msg.New(msg.Options{
Meta: c.meta,
Entry: entry,
TemplateTitle: c.cfg.TemplateTitle,
TemplateBody: c.cfg.TemplateBody,
})
if err != nil {
return err
}
title, text, err := message.RenderMarkdownTemplate(customTpl)
title, body, err := message.RenderMarkdown()
if err != nil {
return err
}
@@ -106,10 +106,10 @@ func (c *Client) Send(entry model.NotifEntry) error {
Alias: c.meta.Name,
Avatar: c.meta.Logo,
Channel: c.cfg.Channel,
Text: title,
Text: string(title),
Attachments: []Attachment{
{
Text: string(text),
Text: string(body),
Ts: json.Number(strconv.FormatInt(time.Now().Unix(), 10)),
Fields: fields,
},

View File

@@ -19,8 +19,6 @@ type Client struct {
meta model.Meta
}
const customTpl = "<!channel> Docker tag `{{ .Entry.Image }}` {{ if (eq .Entry.Status \"new\") }}newly added{{ else }}updated{{ end }}."
// New creates a new slack notification instance
func New(config *model.NotifSlack, meta model.Meta) notifier.Notifier {
return notifier.Notifier{
@@ -41,12 +39,13 @@ func (c *Client) Send(entry model.NotifEntry) error {
message, err := msg.New(msg.Options{
Meta: c.meta,
Entry: entry,
TemplateBody: c.cfg.TemplateBody,
})
if err != nil {
return err
}
_, text, err := message.RenderMarkdownTemplate(customTpl)
_, body, err := message.RenderMarkdown()
if err != nil {
return err
}
@@ -99,7 +98,7 @@ func (c *Client) Send(entry model.NotifEntry) error {
AuthorSubname: "github.com/crazy-max/diun",
AuthorLink: c.meta.URL,
AuthorIcon: c.meta.Logo,
Text: string(text),
Text: string(body),
Footer: fmt.Sprintf("%s © %d %s %s", c.meta.Author, time.Now().Year(), c.meta.Name, c.meta.Version),
Fields: fields,
Ts: json.Number(strconv.FormatInt(time.Now().Unix(), 10)),

View File

@@ -18,9 +18,6 @@ type Client struct {
meta model.Meta
}
const customTpl = "Docker tag {{ if .Entry.Image.HubLink }}[`{{ .Entry.Image }}`]({{ .Entry.Image.HubLink }}){{ else }}`{{ .Entry.Image }}`{{ end }}" +
"{{ if (eq .Entry.Status \"new\") }}newly added{{ else }}updated{{ end }}."
// New creates a new webhook notification instance
func New(config *model.NotifTeams, meta model.Meta) notifier.Notifier {
return notifier.Notifier{
@@ -58,12 +55,13 @@ func (c *Client) Send(entry model.NotifEntry) error {
message, err := msg.New(msg.Options{
Meta: c.meta,
Entry: entry,
TemplateBody: c.cfg.TemplateBody,
})
if err != nil {
return err
}
_, text, err := message.RenderMarkdownTemplate(customTpl)
_, body, err := message.RenderMarkdown()
if err != nil {
return err
}
@@ -73,7 +71,7 @@ func (c *Client) Send(entry model.NotifEntry) error {
themeColor = "0076D7"
}
body, err := json.Marshal(struct {
jsonBody, err := json.Marshal(struct {
Type string `json:"@type"`
Context string `json:"@context"`
ThemeColor string `json:"themeColor"`
@@ -81,11 +79,11 @@ func (c *Client) Send(entry model.NotifEntry) error {
Sections []Sections `json:"sections"`
}{
Type: "MessageCard",
Context: "http://schema.org/extensions",
Context: "https://schema.org/extensions",
ThemeColor: themeColor,
Summary: string(text),
Summary: string(body),
Sections: []Sections{{
ActivityTitle: string(text),
ActivityTitle: string(body),
ActivitySubtitle: "Provider: " + entry.Provider,
Facts: []Fact{
{"Hostname", c.meta.Hostname},
@@ -99,7 +97,7 @@ func (c *Client) Send(entry model.NotifEntry) error {
return err
}
req, err := http.NewRequest("POST", c.cfg.WebhookURL, bytes.NewBuffer(body))
req, err := http.NewRequest("POST", c.cfg.WebhookURL, bytes.NewBuffer(jsonBody))
if err != nil {
return err
}

View File

@@ -20,10 +20,6 @@ type Client struct {
meta model.Meta
}
const customTpl = `Docker tag {{ if .Entry.Image.HubLink }}[{{ .Entry.Image }}]({{ .Entry.Image.HubLink }}){{ else }}{{ .Entry.Image }}{{ end }}
which you subscribed to through {{ .Entry.Provider }} provider has been {{ if (eq .Entry.Status "new") }}newly added{{ else }}updated{{ end }}
on {{ escapeMarkdown .Meta.Hostname }}.`
// New creates a new Telegram notification instance
func New(config *model.NotifTelegram, meta model.Meta) notifier.Notifier {
return notifier.Notifier{
@@ -65,7 +61,8 @@ func (c *Client) Send(entry model.NotifEntry) error {
message, err := msg.New(msg.Options{
Meta: c.meta,
Entry: entry,
TplFuncs: template.FuncMap{
TemplateBody: c.cfg.TemplateBody,
TemplateFuncs: template.FuncMap{
"escapeMarkdown": func(text string) string {
text = strings.ReplaceAll(text, "_", "\\_")
text = strings.ReplaceAll(text, "*", "\\*")
@@ -79,7 +76,7 @@ func (c *Client) Send(entry model.NotifEntry) error {
return err
}
_, text, err := message.RenderMarkdownTemplate(strings.ReplaceAll(customTpl, "\n", " "))
_, body, err := message.RenderMarkdown()
if err != nil {
return err
}
@@ -89,7 +86,7 @@ func (c *Client) Send(entry model.NotifEntry) error {
BaseChat: tgbotapi.BaseChat{
ChatID: chatID,
},
Text: string(text),
Text: string(body),
ParseMode: "markdown",
DisableWebPagePreview: true,
})

View File

@@ -22,6 +22,13 @@ extra:
plausible:
server: plausible.re4per.com
domain: crazymax.dev/diun
template:
defaultTitle: |
{{ if (eq .Entry.Status "new") }}New image {{ .Entry.Image }} has been added{{ else }}Image update for {{ .Entry.Image }}{{ end }}
defaultBody: |
Docker tag {{ if .Entry.Image.HubLink }}[**{{ .Entry.Image }}**]({{ .Entry.Image.HubLink }}){{ else }}**{{ .Entry.Image }}**{{ end }}
which you subscribed to through {{ .Entry.Provider }} provider has been {{ if (eq .Entry.Status "new") }}newly added{{ else }}updated{{ end }}
on {{ .Meta.Hostname }}.
theme:
name: material
@@ -76,7 +83,11 @@ plugins:
- git-revision-date-localized:
type: iso_datetime
enable_creation_date: true
- macros
- macros:
j2_block_start_string: '[[%'
j2_block_end_string: '%]]'
j2_variable_start_string: '[['
j2_variable_end_string: ']]'
- search:
prebuild_index: python
lang: