From ad9027731536ad3e9410ebe9713af5729ccd36cf Mon Sep 17 00:00:00 2001 From: Jared Swets Date: Tue, 3 Nov 2020 09:28:50 -0500 Subject: [PATCH] Adding GotifyBee (#351) --- assets/bees/gotifybee.png | Bin 0 -> 31094 bytes bees/gotifybee/README.md | 62 ++++++++++++++ bees/gotifybee/gotifybee.go | 90 +++++++++++++++++++++ bees/gotifybee/gotifybeefactory.go | 126 +++++++++++++++++++++++++++++ hives.go | 1 + 5 files changed, 279 insertions(+) create mode 100644 assets/bees/gotifybee.png create mode 100644 bees/gotifybee/README.md create mode 100644 bees/gotifybee/gotifybee.go create mode 100644 bees/gotifybee/gotifybeefactory.go diff --git a/assets/bees/gotifybee.png b/assets/bees/gotifybee.png new file mode 100644 index 0000000000000000000000000000000000000000..cacd256de61d84de73608d4f13ab65fef0ffc055 GIT binary patch literal 31094 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 literal 0 HcmV?d00001 diff --git a/bees/gotifybee/README.md b/bees/gotifybee/README.md new file mode 100644 index 00000000..663f818e --- /dev/null +++ b/bees/gotifybee/README.md @@ -0,0 +1,62 @@ +# GotifyBee + +This bee can push notification to the specified gotify application as an action to some event. + +You can get your **TOKEN** for your specified gotify application by going to the **APPS** section of the gotify server instance +and unhiding the token for your desired application. + +## APP + +* [Android APP](https://play.google.com/store/apps/details?id=com.github.gotify&hl=en_US&gl=US) +* [Chrome extension](https://chrome.google.com/webstore/detail/gotify-push/cbegkpikakpajcaoblfkeindhhikpfmd?hl=en) + +## Configuration + +The **message** field is required. If the message's title is empty, it would be replaced by Gotify. + +The priority of the message is option. + +### Options +```json +"Bees": [ + { + "Name": "gotify example", + "Class": "gotify", + "Description": "This is example of gotify", + "Options": [ + { + "Name": "token", + "Value": "TOKEN" + } + ] + }, +] +``` + +### Actions + +```json +"Actions": [ + { + "Bee": "gotify example", + "Name": "send", + "Options": [ + { + "Name": "title", + "Type": "string", + "Value": "" + }, + { + "Name": "message", + "Type": "string", + "Value": "" + }, + { + "Name": "priority", + "Type": "string", + "Value": "" + } + ] + }, +] +``` \ No newline at end of file diff --git a/bees/gotifybee/gotifybee.go b/bees/gotifybee/gotifybee.go new file mode 100644 index 00000000..2ad31c3e --- /dev/null +++ b/bees/gotifybee/gotifybee.go @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2020 deranjer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * Authors: + * deranjer + */ + +// Package gotifybee is able to send notifications on Gotify. +package gotifybee + +import ( + "net/http" + "net/url" + "regexp" + + "github.com/muesli/beehive/bees" +) + +// GotifyBee is a Bee that is able to send notifications on Gotify. +type GotifyBee struct { + bees.Bee + token string + serverURL string +} + +// Action triggers the action passed to it. +func (mod *GotifyBee) Action(action bees.Action) []bees.Placeholder { + outs := []bees.Placeholder{} + + switch action.Name { + case "send": + var title, message, priority string + action.Options.Bind("title", &title) + action.Options.Bind("message", &message) + action.Options.Bind("priority", &priority) + + if priority == "" { + priority = "0" + } + if title == "" { + title = "Gotify" + } + + // the message must be plain text, so + // remove the HTML tags, such as and so on + re, _ := regexp.Compile("\\<[\\S\\s]+?\\>") + message = re.ReplaceAllString(message, "\n") + + data := url.Values{ + "title": {title}, + "message": {message}, + "priority": {priority}, + } + // Build the URL for sending the message + rawURL := mod.serverURL + "message?token=" + mod.token + resp, err := http.PostForm(rawURL, data) + if err != nil { + panic(err) + } + defer resp.Body.Close() + if resp.StatusCode == 200 { + mod.Logln("Gotify send message success.") + } + + default: + panic("Unknown action triggered in " + mod.Name() + ": " + action.Name) + } + + return outs +} + +// ReloadOptions parses the config options and initializes the Bee. +func (mod *GotifyBee) ReloadOptions(options bees.BeeOptions) { + mod.SetOptions(options) + options.Bind("token", &mod.token) + options.Bind("serverURL", &mod.serverURL) +} diff --git a/bees/gotifybee/gotifybeefactory.go b/bees/gotifybee/gotifybeefactory.go new file mode 100644 index 00000000..9b7729bc --- /dev/null +++ b/bees/gotifybee/gotifybeefactory.go @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2020 deranjer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * Authors: + * deranjer + */ + +// Package gotifybee is able to send notifications on Gotify. +package gotifybee + +import ( + "github.com/muesli/beehive/bees" +) + +// GotifyBeeFactory is a factory for GotifyBees. +type GotifyBeeFactory struct { + bees.BeeFactory +} + +// New returns a new Bee instance configured with the supplied options. +func (factory *GotifyBeeFactory) New(name, description string, options bees.BeeOptions) bees.BeeInterface { + bee := GotifyBee{ + Bee: bees.NewBee(name, factory.ID(), description, options), + } + bee.ReloadOptions(options) + + return &bee +} + +// ID returns the ID of this Bee. +func (factory *GotifyBeeFactory) ID() string { + return "gotifybee" +} + +// Name returns the name of this Bee. +func (factory *GotifyBeeFactory) Name() string { + return "Gotify" +} + +// Description returns the description of this Bee. +func (factory *GotifyBeeFactory) Description() string { + return "Lets you push notifications on Gotify" +} + +// Image returns the filename of an image for this Bee. +func (factory *GotifyBeeFactory) Image() string { + return factory.ID() + ".png" +} + +// LogoColor returns the preferred logo background color (used by the admin interface). +func (factory *GotifyBeeFactory) LogoColor() string { + return "#448CCB" +} + +// Options returns the options available to configure this Bee. +func (factory *GotifyBeeFactory) Options() []bees.BeeOptionDescriptor { + opts := []bees.BeeOptionDescriptor{ + { + Name: "token", + Description: "The gotify token for the Application to send messages", + Type: "string", + Mandatory: true, + }, + { + Name: "serverURL", + Description: "The URL to the gotify server, eg: http://gotify.com/ (trailing slash required!)", + Type: "string", + Mandatory: true, + }, + } + return opts +} + +// Events describes the available events provided by this Bee. +func (factory *GotifyBeeFactory) Events() []bees.EventDescriptor { + events := []bees.EventDescriptor{} + return events +} + +// Actions describes the available actions provided by this Bee. +func (factory *GotifyBeeFactory) Actions() []bees.ActionDescriptor { + actions := []bees.ActionDescriptor{ + { + Namespace: factory.Name(), + Name: "send", + Description: "Sends a message", + Options: []bees.PlaceholderDescriptor{ + { + Name: "title", + Description: "Title of the message", + Type: "string", + }, + { + Name: "message", + Description: "Content of the message", + Type: "string", + Mandatory: true, + }, + { + Name: "priority", + Description: "Priority of the message, see https://github.com/gotify/android#message-priorities", + Type: "string", + }, + }, + }, + } + return actions +} + +func init() { + f := GotifyBeeFactory{} + bees.RegisterFactory(&f) +} diff --git a/hives.go b/hives.go index 4982830e..1a1f1d28 100644 --- a/hives.go +++ b/hives.go @@ -37,6 +37,7 @@ import ( _ "github.com/muesli/beehive/bees/fsnotifybee" _ "github.com/muesli/beehive/bees/githubbee" _ "github.com/muesli/beehive/bees/gitterbee" + _ "github.com/muesli/beehive/bees/gotifybee" _ "github.com/muesli/beehive/bees/horizonboxbee" _ "github.com/muesli/beehive/bees/htmlextractbee" _ "github.com/muesli/beehive/bees/httpbee"