VE 8.3: unable to send notification to discord webhook

Hey NullBy7e!

I could reproduce the problem by setting up a Discord webhook endpoint myself. It seems like that Discord has a problem with escaping characters and is more stricter on the webhook request body, so to fix this problem you can use the escape helper on the two properties in the request body like so:

JSON:
{"content":null,"embeds":[{"title":"```{{ escape title }}```","description":"```{{ escape message }}```","color":null,"footer":{"text":"Proxmox"}}],"attachments":[]}
 
For further reference, I want to briefly illustrate why escape is needed.

If you use {{ message }} in the body template, it will be expanded to to the full notification message content. For illustrative purposes, let's assume that the notification content is

Code:
Backup finished.

Visit the web interface for more details.

Let's assume that you want to include this message in a JSON payload:

Code:
{
  "body": "{{ message }}"
}

When the body template is rendered, the result would be the following:

Code:
{
  "body": "Backup finished
 
Visit the web interface for more details"
}

As you can see, the result is a malformed JSON payload, because the message contained in {{ message }} contains line breaks and also potentially other characters that need to be escaped.

Now, if we change the body template as follows:
Code:
{
  "body": "{{ escape message }}"
}

then the control characters will be escaped properly, resulting in valid JSON:

Code:
{
  "body": "Backup finished\nVisit the web interface for more details"
}


I hope this helps!
 
Hey, Sorry to dig this back up.
I have copied the JSON above,

Code:
{"content":null,"embeds":[{"title":"```{{ escape title }}```","description":"```{{ escape message }}```","color":null,"footer":{"text":"Proxmox"}}],"attachments":[]}

and while can get the notifications to work using the proxmox test function, when triggering a backup i get a 400 error (in syslog) when it tries to send the notification.

Code:
could not notify via target `Discord`: https://discord.com/api/webhooks/{{ secrets.token }}: status code 400

I have also tried with the basic example for the body as written in the Proxmox docs and that also tests fine, but errors when running a backup.

Can you see what I am doing wrong?

Here is my webhook target,

1732812273544.png


If its applicable, i have Proxmox Backup installed on the same host, and have a notification webhook setup there and it sends notifications about backup sync jobs just fine.
 
Hey, Sorry to dig this back up.
I have copied the JSON above,

Code:
{"content":null,"embeds":[{"title":"```{{ escape title }}```","description":"```{{ escape message }}```","color":null,"footer":{"text":"Proxmox"}}],"attachments":[]}

and while can get the notifications to work using the proxmox test function, when triggering a backup i get a 400 error (in syslog) when it tries to send the notification.

Code:
could not notify via target `Discord`: https://discord.com/api/webhooks/{{ secrets.token }}: status code 400

I have also tried with the basic example for the body as written in the Proxmox docs and that also tests fine, but errors when running a backup.

Can you see what I am doing wrong?

Here is my webhook target,

View attachment 78388


If its applicable, i have Proxmox Backup installed on the same host, and have a notification webhook setup there and it sends notifications about backup sync jobs just fine.

A few things:

- The payload has ` characters which shouldn't be needed.
- Is there a newline or two in your payload? Because the JSON should either be formatted properly or all on one line.
- is secrets.token defined?
 
Last edited:
A few things:

- The payload has ` characters which shouldn't be needed.
- Is there a newline or two in your payload? Because the JSON should either be formatted properly or all on one line.
- is secrets.token defined?
Hey, Very much appreciate you taking the time.

If it isn't straight away apparent, i'm very new to JSON and don't fully understand it.

I have formatted the code as below, however still getting the same behaviour. Tests fine, but errors out in the console when a backup completes.

Code:
{
    "content": null,
    "embeds": [
        {
            "title": "{{ escape title }}",
            "description": "{{ escape message }}",
            "color": null,
            "footer": {
                "text": "Proxmox"
            }
        }
    ],
    "attachments": []
}

And yep, the secrets token is defined, I just sanitised it before posting. Very weird, it triggers a notification when i remove the fingerprint from the PBS backup repo, to show its failed. But always errors on a successful backup. Is there a way to view the output that's failing to send, so I can see if there is formatting errors, that you know of?

Thanks again!
 
Hey, Very much appreciate you taking the time.

If it isn't straight away apparent, i'm very new to JSON and don't fully understand it.

I have formatted the code as below, however still getting the same behaviour. Tests fine, but errors out in the console when a backup completes.

Code:
{
    "content": null,
    "embeds": [
        {
            "title": "{{ escape title }}",
            "description": "{{ escape message }}",
            "color": null,
            "footer": {
                "text": "Proxmox"
            }
        }
    ],
    "attachments": []
}

And yep, the secrets token is defined, I just sanitised it before posting. Very weird, it triggers a notification when i remove the fingerprint from the PBS backup repo, to show its failed. But always errors on a successful backup. Is there a way to view the output that's failing to send, so I can see if there is formatting errors, that you know of?

Thanks again!

Ah right so the test is ifne, then perhaps the message generated by the backup includes a double quote or some other illegal character that makes discord spew it out. In this case it's best to wait for an answer from support staff :)
 
  • Like
Reactions: Jyrowne
Can you see what I am doing wrong?
Unfortunately not. Your input seems right to me at first glance and I could not reproduce the issue you described with any of the given webhook requests body, including the slightly modified request body from your screenshot. I've also tried both https://discord.com/api/webhooks/{{ secrets.token }} and https://discordapp.com/api/webhooks/{{ secrets.token }}, but both worked fine for me on the webhook test as well as sending a notification from the PVE host when making a backup to a PBS instance.

I'm still curious, that the syslog has printed the webhook url with the curly braces included:
could not notify via target `Discord`: https://discord.com/api/webhooks/{{ secrets.token }}: status code 400

While when I trigger an error by intentionally using a wrong token (e.g. removed the last letter), I got:
Code:
could not notify via target `Discord`: https://discord.com/api/webhooks/<masked>: status code 401

I suspect that there's something wrong with the token value, as it should normally be replaced, so that the secret won't be displayed in error messages, but it seems that part doesn't happen during backups for you.

Does the webhook notification work when you (temporarily) replace the {{ secrets.token }} in the url with the token directly? How have you setup the notification matching on the PVE host to trigger the webhook?
 
I have exactly the same problem and am using Jyrowne's body.

Code:
Code:
{
    "content": null,
    "embeds": [
        {
            "title": "{{ escape title }}",
            "description": "{{ escape message }}",
            "color": null,
            "footer": {
                "text": "Proxmox"
            }
        }
    ],
    "attachments": []
}

The Discord hook only seems to work when the backup job backs up 1 container/1 VM. As soon as a second object is included in the selection, I no longer receive any notifications.
 
I have exactly the same problem and am using Jyrowne's body.



The Discord hook only seems to work when the backup job backs up 1 container/1 VM. As soon as a second object is included in the selection, I no longer receive any notifications.

Hmmm, it seems like Discord has a relatively low limit on the amount of text you can send via a webhook.
The official docs state a 2000 character limit which appears to be exceeded once you back up more than two VMs at once.
 
  • Like
Reactions: dakralex
Unfortunately not. Your input seems right to me at first glance and I could not reproduce the issue you described with any of the given webhook requests body, including the slightly modified request body from your screenshot. I've also tried both https://discord.com/api/webhooks/{{ secrets.token }} and https://discordapp.com/api/webhooks/{{ secrets.token }}, but both worked fine for me on the webhook test as well as sending a notification from the PVE host when making a backup to a PBS instance.

I'm still curious, that the syslog has printed the webhook url with the curly braces included:


While when I trigger an error by intentionally using a wrong token (e.g. removed the last letter), I got:
Code:
could not notify via target `Discord`: https://discord.com/api/webhooks/<masked>: status code 401

I suspect that there's something wrong with the token value, as it should normally be replaced, so that the secret won't be displayed in error messages, but it seems that part doesn't happen during backups for you.

Does the webhook notification work when you (temporarily) replace the {{ secrets.token }} in the url with the token directly? How have you setup the notification matching on the PVE host to trigger the webhook?
Hi Dakralex, thanks a lot for going over this,

I just replaced the actual token with {{ secrets.token }} when posting on the forum it was never printed in the syslog. Sorry for not making that apparent!

I have exactly the same problem and am using Jyrowne's body.



The Discord hook only seems to work when the backup job backs up 1 container/1 VM. As soon as a second object is included in the selection, I no longer receive any notifications.

I concur! I changed my backup job to be a single VM and the notification came through without issue, didn't think to try that sooner. So I guess I will either move to a single VM per backup job or try out slack instead as that appears to have a significantly larger character limit.

Thanks a lot for the assistance, It's hugely appreciated :)
 
So I have tried this myself, and im getting error 400 when i try it outside of the test notification. im using target as the full webhook URL for discord, see below. Any help would be appreciated. Dec 02 11:55:44 pve perl[3032866]: could not notify via target `Discord`: https://discord.com/api/webhooks/1310280840298889307/<masked>: status code 400

1733158805368.png
 
Is this log entry being generated after a backup happens? If so, are you backing up more than 1 VM?

For me, I configured the job to include just a single VM and then the notification came though.

Discord only allow about 2000 characters in the message body so it errors out.
 
Is this log entry being generated after a backup happens? If so, are you backing up more than 1 VM?

For me, I configured the job to include just a single VM and then the notification came though.

Discord only allow about 2000 characters in the message body so it errors out.
Ive tried it with multiple or single vms, neither one succeeds. gets the same result every time. Am I missing something in the config? Even tried manually backing up single vm and it fails with same error
 
Last edited:
I'm not an authority on JSON, but I can't see anything wrong. You could try and use the example from the proxmox docs and see if you get the same behaviour. It's the same error I got so I would be inclined to say it's a discord limitation, is there another change you can make that will trigger a different type of notification to confirm?

I use a PBS volume as a backup repo, so I just removed the fingerprint from there and triggered the backup and I did get that message through, it was fewer characters than the backup.
 
Well I tried with the example in the documentation and got the same thing error 400. the test works every time, but the backups fail it. What else would I change to try and fix it? I know nothing of JSON myself. I have my PBS set as a volume in PVE if that helps.
 
Im not in front of my server so I can't get screen shots, but if you go into storage (can't remember if it's in the host settings or the cluster, but i think it's the cluster) find the PBS volume, in the settings you'll see a fingerprint, copy and save that and then save it blank. If you trigger a backup that will then fail, for me that then sent. Don't forget to put the fingerprint back in.

I only noticed this as my cert expired for my pbs server and I had to add in a new fingerprint when I renewed the cert.
 
nope. I tried that and it still didnt send at all. under token at the bottom i put the token for the webhook if that makes any difference.
 
Reenabled fingerprint and it worked fine with just one ct. gonna try a full backup job and see