{"id":13581569,"url":"https://github.com/eternal-flame-AD/gotify-broadcast","last_synced_at":"2025-04-06T10:32:35.841Z","repository":{"id":57622288,"uuid":"169187015","full_name":"eternal-flame-AD/gotify-broadcast","owner":"eternal-flame-AD","description":"A plugin which brings broadcasts to gotify.","archived":false,"fork":false,"pushed_at":"2024-11-15T21:22:10.000Z","size":282,"stargazers_count":59,"open_issues_count":3,"forks_count":7,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-31T10:48:52.190Z","etag":null,"topics":["gotify","gotify-plugin","self-hosted"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eternal-flame-AD.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-02-05T03:48:45.000Z","updated_at":"2025-03-23T13:19:30.000Z","dependencies_parsed_at":"2024-01-16T20:58:23.993Z","dependency_job_id":"24ee17cd-01e4-444f-8f1a-d0ae85679f0a","html_url":"https://github.com/eternal-flame-AD/gotify-broadcast","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eternal-flame-AD%2Fgotify-broadcast","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eternal-flame-AD%2Fgotify-broadcast/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eternal-flame-AD%2Fgotify-broadcast/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eternal-flame-AD%2Fgotify-broadcast/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eternal-flame-AD","download_url":"https://codeload.github.com/eternal-flame-AD/gotify-broadcast/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247470366,"owners_count":20944146,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gotify","gotify-plugin","self-hosted"],"created_at":"2024-08-01T15:02:05.887Z","updated_at":"2025-04-06T10:32:35.114Z","avatar_url":"https://github.com/eternal-flame-AD.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"\n# gotify-broadcast\n\nA plugin which brings broadcasts to gotify.\n\n## Screenshot\n\n\u003cimg alt=\"screenshot\" src=\"docs/broadcast.png\"\u003e\n\n## Installation\n\nIf you found your gotify version is included in the build, you can download the shared object and put that into your plugin dir.\n\nIf you did not find you gotify version, follow these steps to build one for your own:\n\n1. Download a zip file of the source code of current release at the releases page and extract it.\n1. `export GO111MODULE=on` if you are in GOPATH\n1. `make download-tools`\n1. `make GOTIFY_VERSION=v1.2.1 build` to build the plugin for your gotify version (`GOTIFY_VERSION` could be a tag, a branch or a commit).\n\n## Configuration\n\nThe configuration contains three keys: `channels`, `sender_filter`, and `receiver_filter`.\n\n### Channels\n\nThe `channels` key in the configuration describes which channels you are using. Each channen has two parameters: `name` and `public`.\n\nThe `name` parameter is used to identify the channel. It must be unique and is required while sending broadcasts.\n\nThe `public` parameter specifies whether this channel will be visible to other users in the `Displayer` panel in their WebUI. If this is set to `false`, they will not be able to see this channel on the WebUI, but they can still recieve messages from this broadcast. Thus, it is recommended to set a receiver filter which defaults to `Reject` on private channels.\n\n```yaml\nchannels:\n- name: example_public_channel\n  public: true\n- name: example_private_channel\n  public: false\n```\n\n### Filters\n\nIn order to control from which and to which a broadcast is sent, a filter system is integrated into this plugin.\n\n#### The Matching Routine\n\nMessages are filtered with a iptables-like filter system. The filter is a chain of [Rules](https://godoc.org/github.com/eternal-flame-AD/gotify-broadcast/rules/#Rule), which contains a [match](https://godoc.org/github.com/eternal-flame-AD/gotify-broadcast/rules/#MatchSet) describing how this rule matches messages, and a [action](https://godoc.org/github.com/eternal-flame-AD/gotify-broadcast/rules/#Action) describing the action to take when this rule matches successfully.\n\n```yaml\nreceiver_filter:\n  - match:\n    - mode: \u003cmode\u003e\n      \u003cparam\u003e: \u003cparam\u003e\n    - mode: \u003cmode\u003e\n      \u003cparam\u003e: \u003cparam\u003e\n    action: \u003caction\u003e\n  - match:\n    - mode: \u003cmode\u003e\n      \u003cparam\u003e: \u003cparam\u003e\n    - mode: \u003cmode\u003e\n      \u003cparam\u003e: \u003cparam\u003e\n    action: \u003caction\u003e\n  - match:\n    - mode: \u003cmode\u003e\n      \u003cparam\u003e: \u003cparam\u003e\n    - mode: \u003cmode\u003e\n      \u003cparam\u003e: \u003cparam\u003e\n    action: \u003caction\u003e\nsender_filter:\n  - match:\n    - mode: \u003cmode\u003e\n      \u003cparam\u003e: \u003cparam\u003e\n    - mode: \u003cmode\u003e\n      \u003cparam\u003e: \u003cparam\u003e\n    action: \u003caction\u003e\n  - match:\n    - mode: \u003cmode\u003e\n      \u003cparam\u003e: \u003cparam\u003e\n    - mode: \u003cmode\u003e\n      \u003cparam\u003e: \u003cparam\u003e\n    action: \u003caction\u003e\n  - match:\n    - mode: \u003cmode\u003e\n      \u003cparam\u003e: \u003cparam\u003e\n    - mode: \u003cmode\u003e\n      \u003cparam\u003e: \u003cparam\u003e\n    action: \u003caction\u003e\n```\n\nAll modes and its parameter requirements is documented [here](https://godoc.org/github.com/eternal-flame-AD/gotify-broadcast/rules/#Mode)\n\n#### On the sender side\nWhen a broadcast is created, the `receiver_filter` will be applied to each recipient. Similar to the `OUTPUT` chain in iptables, when the filter evaluates to `Accept`, the message is sent to that recipient (but whether the message is actually received also depends on the configuration of the `sender_filter` filter on the recipient side)\n```\n                 +--------------------------------------------------------+\n                 |                  Outgoing Message                      |\n                 |                                                        |\n                 +---------------------------+----------------------------+\n                                             |\n                                             |\n+--------------------------------------------+\n|\n|\n|\n|           +----------------+       +-----------------+       +-----------------+\n|           |                |       |                 |       |                 |\n|           |  +----------+  |       |  +-----------+  |       |  +-----------+  |           +-----------------+\n|           |  |          |  |   N   |  |           |  |   N   |  |           |  |    N      |                 |\n+--------------\u003e   Match  +-------------\u003e   Match   +-------------\u003e   Match   +--------------\u003e Default: Accept |\n            |  |          |  |       |  |           |  |       |  |           |  |           |                 |\n            |  +----+-----+  |       |  +-----+-----+  |       |  +-----+-----+  |           +-----------------+\n            |       |        |       |        |        |       |        |        |\n            |       |Y       |       |        |        |       |        |        |\n            |       |        |       |        |        |       |        |        |\n            |  +----v-----+  |       |        |        |       |        |        |\n            |  |          |  |       |        |        |       |        |        |\n            |  |   Match  |  |       |        |        |       |        |        |\n            |  |          |  |       |        |        |       |        |        |\n            |  +----+-----+  |       |        |        |       |        |        |\n            |       |        |       |        |Y       |       |        |Y       |\n            |       |        |       |        |        |       |        |        |\n            |       |        |       |        |        |       |        |        |\n            |       |        |       |        |        |       |        |        |\n            |       |Y       |       |        |        |       |        |        |\n            |       |        |       |        |        |       |        |        |\n            |       |        |       |        |        |       |        |        |\n            |       |        |       |        |        |       |        |        |\n            |       |        |       |        |        |       |        |        |\n            |  +----v-----+  |       |  +-----v-----+  |       |  +-----v-----+  |\n            |  |  Accept  |  |       |  |   Reject  |  |       |  |   Reject  |  |\n            |  |          |  |       |  |           |  |       |  |           |  |\n            |  +----------+  |       |  +-----------+  |       |  +-----------+  |\n            |                |       |                 |       |                 |\n            +----------------+       +-----------------+       +-----------------+\n             receiver_filter[0]       receiver_filter[1]        receiver_filter[2]\n```\n\n##### Examples\n\nOnly sends broadcast from a channel to admin:\n```yaml\nchannels:\n- name: secret\n  public: false\nreceiver_filter:\n- match:\n  - mode: channel_name\n    channel_name: secret\n  - mode: is_admin\n    is_admin: false\n  action: reject\n```\n\nDon't send broadcast with priority less than a specified value to some user:\n```yaml\nreceiver_filter:\n- match:\n  - mode: user_name\n    user_name: someone_who_does_not_want_to_be_bothered\n  - mode: priority_lt\n    priority: 5\n  action: reject\n```\n\nDon't send broadcast except to `tom` and `jerry`:\n```yaml\nreceiver_filter:\n- match:\n  - mode: user_name\n    user_name: tom\n  action: accept\n- match:\n  - mode: user_name\n    user_name: jerry\n  action: accept\n- match:\n  - mode: any\n  action: reject\n```\n\nMute broadcasts sent by myself:\n```yaml\nreceiver_filter:\n- match:\n  - mode: user_name\n    user_name: \u003cmy_user_name\u003e\n  action: reject\n```\n\n#### On the receiver side\n\nWhen a broadcast is received, the `sender_filter` will be applied, similar to the `INPUT` chain in iptables. When this also evaluates to `Accept`, the message is eventually delivered.\n```\n                 +--------------------------------------------------------+\n                 |                  Incoming Message                      |\n                 |                                                        |\n                 +---------------------------+----------------------------+\n                                             |\n                                             |\n+--------------------------------------------+\n|\n|\n|\n|           +----------------+       +-----------------+       +-----------------+\n|           |                |       |                 |       |                 |\n|           |  +----------+  |       |  +-----------+  |       |  +-----------+  |           +-----------------+\n|           |  |          |  |   N   |  |           |  |   N   |  |           |  |    N      |                 |\n+--------------\u003e   Match  +-------------\u003e   Match   +-------------\u003e   Match   +--------------\u003e Default: Accept |\n            |  |          |  |       |  |           |  |       |  |           |  |           |                 |\n            |  +----+-----+  |       |  +-----+-----+  |       |  +-----+-----+  |           +-----------------+\n            |       |        |       |        |        |       |        |        |\n            |       |Y       |       |        |        |       |        |        |\n            |       |        |       |        |        |       |        |        |\n            |  +----v-----+  |       |        |        |       |        |        |\n            |  |          |  |       |        |        |       |        |        |\n            |  |   Match  |  |       |        |        |       |        |        |\n            |  |          |  |       |        |        |       |        |        |\n            |  +----+-----+  |       |        |        |       |        |        |\n            |       |        |       |        |Y       |       |        |Y       |\n            |       |        |       |        |        |       |        |        |\n            |       |        |       |        |        |       |        |        |\n            |       |        |       |        |        |       |        |        |\n            |       |Y       |       |        |        |       |        |        |\n            |       |        |       |        |        |       |        |        |\n            |       |        |       |        |        |       |        |        |\n            |       |        |       |        |        |       |        |        |\n            |       |        |       |        |        |       |        |        |\n            |  +----v-----+  |       |  +-----v-----+  |       |  +-----v-----+  |\n            |  |  Accept  |  |       |  |   Reject  |  |       |  |   Reject  |  |\n            |  |          |  |       |  |           |  |       |  |           |  |\n            |  +----------+  |       |  +-----------+  |       |  +-----------+  |\n            |                |       |                 |       |                 |\n            +----------------+       +-----------------+       +-----------------+\n             sender_filter[0]         sender_filter[1]           sender_filter[2]\n```\n\n##### Examples\n\nReject messages which matches a regexp from `my_server`:\n```yaml\nsender_filter:\n- match:\n  - mode: user_name\n    user_name: my_server\n  - mode: message_text\n    regex: true\n    message_text: ^\\[(INFO|DEBUG)\\]\n  action: reject\n```\n\nReject messages from non-admins but `my_friend`:\n```yaml\nsender_filter:\n- match:\n  - mode: user_name\n    user_name: my_friend\n  action: accept\n- match:\n  - mode: is_admin\n    is_admin: false\n  action: reject\n```\n\nReject all received broadcasts:\n```yaml\nsender_filter:\n- match:\n  - mode: any\n  action: reject\n```\n\n## Sending messages\n\n1. Go to the WebUI, configure channels and filters.\n\n2. On the `Displayer` panel, you could see the message hook URL.\n\n3. POST your message to that hook URL just like how to push regular messages with an extra query parameter `channel=\u003cchannel_name\u003e`","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feternal-flame-AD%2Fgotify-broadcast","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feternal-flame-AD%2Fgotify-broadcast","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feternal-flame-AD%2Fgotify-broadcast/lists"}