mqtt-tools / mqttwarn

A highly configurable MQTT message router, where the routing targets are notification plugins, primarily written in Python.
https://mqttwarn.readthedocs.io/
Eclipse Public License 2.0
958 stars 184 forks source link

Send Apprise/Discord notifications to another user #555

Closed psyciknz closed 2 years ago

psyciknz commented 3 years ago

I Understand using appraise I can get discord notifications, but details are fairly light.

I’m after being able to send a discord message to a certain user. It won’t change. We won’t be connected to a discord server, but are friends.

Can someone give me some pointers.

amotl commented 3 years ago

Dear @psyciknz,

I understand using Appraise I can get Discord notifications.

Indeed, that might work.

But details are fairly light.

Maybe we can make it work together.

I’m after being able to send a discord message to a certain user. It won’t change. We won’t be connected to a discord server, but are friends. Can someone give me some pointers?

I understand. I would recommend first making this work with the Apprise command line program, as outlined at [1]. After this is successful, we can look into how to make it work with mqttwarn.

With kind regards, Andreas.

[1] https://github.com/caronc/apprise/wiki/Notify_discord#example

amotl commented 3 years ago

look into how to make apprise-discord notifications work with mqttwarn.

While I haven't tested it, the corresponding configuration snippet might look like this:

[defaults]
launch    = apprise-discord

[config:apprise-discord]
# discord://{WebhookID}/{WebhookToken}/
module   = 'apprise'
baseuri  = 'discord://4174216298/JHMHI8qBe7bk2ZwO5U711o3dV_js'
; Surrogate for satisfying machinery. 
targets  = {
    'n/a' : [''],
    }

For configuring baseuri correctly, please consult [2] and [3].

With kind regards, Andreas.

[2] https://github.com/caronc/apprise/wiki/Notify_discord#syntax [3] https://github.com/caronc/apprise/wiki/Notify_discord#parameter-breakdown

amotl commented 3 years ago

I’m looking at being able to send a discord message to a certain user.

Wait. Currently, from reading the documentation at [4], I can't see how you would send a message to another Discord user. Maybe the Apprise Discord notifier plugin just aims to send messages to oneselves? Am I missing something?

/cc @caronc

[4] https://github.com/caronc/apprise/wiki/Notify_discord

amotl commented 3 years ago

Hi again.

How you would send a message to another Discord user.

As we can see, direct message (DM) support is outlined at [1]. This type of conversation is not implemented by the Apprise/Discord notification plugin. If this is a strict requirement, that plugin will not help here.

On the other hand, the Apprise/Discord notification plugin implements calling out to the execute webhook API endpoint of Discourse [2]. Such webhooks apparently can post messages to a specified channel, as outlined in the documentation:

Webhooks are a low-effort way to post messages to channels in Discord. They do not require a bot user or authentication to use.

Let me know if that would fit your needs.

If so, in order to make it work, you will probably have to create a webhook [3] at the Discord API first. After you created a webhook,

I would recommend first trying to execute this webhook with the Apprise command line program, as outlined at [4].

After this is successful, the configuration snippet at https://github.com/jpmens/mqttwarn/issues/555#issuecomment-945959534 might help to hook the corresponding functionality into mqttwarn.

With kind regards, Andreas.

[1] https://discord.com/developers/docs/resources/user#create-dm [2] https://discord.com/developers/docs/resources/webhook#execute-webhook [3] https://discord.com/developers/docs/resources/webhook#create-webhook [4] https://github.com/caronc/apprise/wiki/Notify_discord#example

psyciknz commented 3 years ago

Thanks for the jump start.... So I started playing with apprise - which I note is in my docker container already (I expected that was my first problem, but it wasn't).

The 2nd thing I found it to make a webhook, you need a server. Done. So this command, sent a message to the general channel of my server:

apprise -vv -t "test message title" -b "test message body" discord://{WebhookID}/{WebhookToken}/

Interesting, I note in the apprise (mqttwarn) documentation, no mention of how to get the title (-t) ad message (-b) values. That might be a documentation change needed once we figure this out.

So running the above command sends a message to the server. DMs look difficult by design in discord...to stop spamming. But what I figured out, is that with a connected use on your server you can @ them. It's not a straight forward as just @username but pretty close.

apprise -vv -t "<@{user-id> test message title" -b "test message body" discord://{WebhookID}/{WebhookToken}/

where user-id you can get by right-clicking a user and copy id. Hmm, so re: my first point of "I need a server and they must be a member"....I wonder. I have a server, but @sumnerboy12 is not a member, but I'll see if I can @ him from my server.

amotl commented 3 years ago

Dear @psyciknz,

good to hear you figured it out.

I need a server and they must be a member"....I wonder. I have a server, but @sumnerboy12 is not a member, but I'll see if I can @ him from my server.

I believe the "right way" in this context would be to have different members in the same channel, as this channel is addressed from the webhook, right? Is it possible to invite users from different servers into the same channels? [1]

With kind regards, Andreas.

[1] Sorry, I have to admit I don't anything about any eventual kind of Discord federation or running Discord on own servers at all. Isn't it just a (commercial) platform? [2] [2] If this is the case, can users even be on "different servers"? Please educate me.

psyciknz commented 3 years ago

Dear @psyciknz,

good to hear you figured it out.

I need a server and they must be a member"....I wonder. I have a server, but @sumnerboy12 is not a member, but I'll see if I can @ him from my server.

I believe the "right way" in this context would be to have different members in the same channel, as this channel is addressed from the webhook, right?

Yeah that's how I expect it to work. Ben shouldn't get my message or notification as he's not a member of my server. But I'm wanting to message my son to get off the minecraft...discord is the only app I've allowed him, with no servers....but he can join the family one I've just made.

With kind regards, Andreas.

psyciknz commented 3 years ago

So what is not clear from the mqttwarn/apprise doco, is that I seem to need multiple configurations for apprise/discord to reach a channel (unlike say slack where there is one webhook and the targets allow me to specify the various server channels, eg, I have a camera one, mqttwarn, openhab all set up as slack targets).

[config:slack]
token = '{slack token}'
#icons https://unicodey.com/emoji-data/table.htm
targets = {
                  #  #channel/@user   username, icon
   'Paradox'        : [ '#paradox',       'Alerter',       ':house:' ],
   'Plex'           : [ '#plex',          'mqttwarn',      ':vhs:' ],
   'general'        : [ '#notifications', 'mqttwarn',      ':syringe:' ],
   'GPS'            : [ '#gps',           'GPSGate',       ':automobile:' ],
   'InternetUsage'  : [ '#internetusage', 'mqttwarn',      ':chart_with_upwards_trend:' ],
   'CameraEvents'   : [ '#camera',        'CameraEvents',  ':video_camera:' ],
   'OpenHAB'        : [ '#openhab',       'OpenHAB',       ':house_with_garden:' ],
   'Unifi'          : [ '#unifi',         'mqttwarn',      ':syringe:' ]
   }

The apprise mqttwarn plugin, has the baseurl, which specifies discord+ the webhook id and token....where a web hook is for just one channel. Would that be your understanding? Ultimately not as flexible as the slack integration (I am contemplating moving all of my slack channels to discord)

amotl commented 3 years ago

I seem to need multiple configurations for apprise/discord to reach a channel (unlike say slack [as outlined in the example above])?

Currently, this is true.

a) On the Discord side, the documentation [1] seems to be clear: One Webhook can only serve one channel, so you would need a few Webhooks to be configured. Here, we can do nothing about it, right?

b) However, I get your point: It would be sweet to be able to configure multiple Discord Webhook targets within a single configuration item of mqttwarn, like it is possible with the Slack service plugin.

[1] https://discord.com/developers/docs/resources/webhook#create-webhook

psyciknz commented 3 years ago

Yeah I do wonder if we (and I mean I) should bite the bullet and see if I can write a discord service like the slack one.

So i do have it going, and as long as you know the user id on a user you can @ them which gets a notification.

So I think I can add my son to my server and set up something that says: if on laptop for > 60 mins send a mqtt to discord/getoffminecraft - which will send him a discord message to get off minecraft, @'d to his user id.....

Or I can just continue to yell up the stairs.......but where is the fun in that.

amotl commented 3 years ago

Hi again,

If I can write a Discord service like the slack one.

I whipped something up with #558, adding another apprise_multi service plugin, which offers a more generic way of dispatching notifications to Apprise. It is part of the new release mqttwarn 0.28.0 already. Let me know if that works for you.

With kind regards, Andreas.

psyciknz commented 3 years ago

OK so if I have this right:

targets = {
   'discord-channel1'     : [ { 'baseuri':  'discord://4174216298/JHMHI8qBe7bk2ZwO5U711o3dV_js' } ],
   'discord-channel2'     : [ { 'baseuri':  'discord://4174216298/JHMHI8qBe7bk2ZwO5U711o3dV_js' } ],
],
   }

etc is how we could use it?

And a follow on, what triggers a new docker build? I see it's still 0.26.1 https://hub.docker.com/r/jpmens/mqttwarn/tags

amotl commented 3 years ago

Docker release images

I see it's still 0.26.1.

Docker images will get automatically publishes to GHCR, the GitHub Container registry. See also #544, and the Docker documentation. Running this should work:

docker pull ghcr.io/jpmens/mqttwarn-full:0.28.0

Configuration snippets

Service setup

OK so if I have this right:

A slight correction, one ], is too much:

[defaults]
launch    = apprise-multi

[config:apprise-multi]
; Dispatch message to multiple Apprise plugins.
module   = 'apprise_multi'
targets = {
   'discord-channel1'     : [ { 'baseuri':  'discord://4174216298/JHMHI8qBe7bk2ZwO5U711o3dV_js' } ],
   'discord-channel2'     : [ { 'baseuri':  'discord://4174216298/JHMHI8qBe7bk2ZwO5U711o3dV_js' } ],
   }

Routing

How could we use it?

Just exactly how all other mqttwarn plugins are getting their messages from, by adding a configuration section which routes topics to plugin targets. Like, matching your example:

[testdrive-one-channel]
topic    = testdrive/one/#
targets  = apprise-multi:discord-channel1

[testdrive-two-channels]
topic    = testdrive/two/#
targets  = apprise-multi:discord-channel1, apprise-multi:discord-channel2

Dry-run

When using this configuration, you would publish MQTT messages like those:

echo '{"device": "foobar", "name": "temperature", "number": 42.42}' | mosquitto_pub -t 'testdrive/one/foo' -l
echo '{"device": "foobar", "name": "temperature", "number": 42.42}' | mosquitto_pub -t 'testdrive/two/foo' -l
caronc commented 3 years ago

Sorry to be so late for this party guys! :astonished:

I'm not sure if I should add private messages to Discord; even their API kind of insists you don't do it (As you can reach your limit faster to the number of requests) since there is overhead in creating a pipe between the user, getting the unique ID and then posting it there.

Otherwise it sounds like you've got a great alternative solution going too! :heart:

amotl commented 3 years ago

Dear Chris and @psyciknz,

thanks for your response.

I'm not sure if I should add private messages to Discord; even their API kind of insists you don't do it.

Yes, I also believe we should not do it, unless being pressured hard.

Otherwise it sounds like you've got a great alternative solution going too!

I also believe notifying a channel, where the users in question are members of, should be sensible as well. Did you have the chance to test the new feature already, @psyciknz?

With kind regards, Andreas.

psyciknz commented 3 years ago

Hi @amotl Sorry, I just had a play then, seems to work well. Had a few issues with updating mqttwarn in general. Will make a new issue for that, but the apprise-multi worked well.

I need to work out the formatting. image

Config

; -----------------------------------------
;             Discord via Apprise
; -----------------------------------------
[test/general]
targets = log:info, apprise-multi:discord_1
[test/test]
targets = log:info, apprise-multi:test

for the following pulish:

mosquitto_pub -t test/test -m "hello"
psyciknz commented 3 years ago

Oh and while I think about it, here's how you @ a user:

mosquitto_pub -t <discord apprise topic> -m "hello <@user_id> again"

So to get the user id, right click on the user and click copy id, it should be a numerical id. It's not their text user name.

The exception to this rule is that sending a messages to @everyone does not require the id.

mosquitto_pub -t <discord apprise topic> -m "hello @everyone again"

should work. No <> needed

amotl commented 3 years ago

Dear @psyciknz,

The apprise-multi worked well.

Sweet, thanks for letting us know.

Oh and while I think about it, here's how...

It would be nice to add some corresponding words to the documentation. Maybe you want to submit a patch?

With kind regards, Andreas.

P.S.: Would <@everyone> work as well? If so, I would not see a need to add the remark that it also works without.

amotl commented 2 years ago

Dear @psyciknz,

I've just submitted #578, which improves the documentation with your feedback. I believe it is safe to close the issue now. Feel free to reopen if you think something has not been addressed well.

With kind regards, Andreas.