Skip to content

Commit

Permalink
Add Apprise integration
Browse files Browse the repository at this point in the history
  • Loading branch information
jeankhawand authored Aug 1, 2023
1 parent da0198c commit bf4823b
Show file tree
Hide file tree
Showing 28 changed files with 193 additions and 4 deletions.
4 changes: 4 additions & 0 deletions .devcontainer/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,9 @@ services:
POSTGRES_HOST_AUTH_METHOD: trust
ports:
- 5432:5432
apprise:
image: caronc/apprise:latest
restart: unless-stopped
hostname: apprise
volumes:
postgres-data: null
9 changes: 9 additions & 0 deletions database/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -724,4 +724,13 @@ var migrations = []func(tx *sql.Tx) error{
_, err = tx.Exec(sql)
return err
},
func(tx *sql.Tx) (err error) {
sql := `
ALTER TABLE integrations ADD COLUMN apprise_enabled bool default 'f';
ALTER TABLE integrations ADD COLUMN apprise_url text default '';
ALTER TABLE integrations ADD COLUMN apprise_services_url text default '';
`
_, err = tx.Exec(sql)
return err
},
}
54 changes: 54 additions & 0 deletions integration/apprise/apprise.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package apprise

import (
"fmt"
"net"
"strings"
"time"

"miniflux.app/http/client"
"miniflux.app/model"
)

// Client represents a Apprise client.
type Client struct {
servicesURL string
baseURL string
}

// NewClient returns a new Apprise client.
func NewClient(serviceURL, baseURL string) *Client {
return &Client{serviceURL, baseURL}
}

// PushEntry pushes entry to apprise
func (c *Client) PushEntry(entry *model.Entry) error {
if c.baseURL == "" || c.servicesURL == "" {
return fmt.Errorf("apprise: missing credentials")
}
timeout := time.Duration(1 * time.Second)
_, err := net.DialTimeout("tcp", c.baseURL, timeout)
if err != nil {
clt := client.New(c.baseURL + "/notify")
message := "[" + entry.Title + "]" + "(" + entry.URL + ")" + "\n\n"
data := &Data{
Urls: c.servicesURL,
Body: message,
}
response, error := clt.PostJSON(data)
if error != nil {
return fmt.Errorf("apprise: ending message failed: %v", error)
}

if response.HasServerFailure() {
return fmt.Errorf("apprise: request failed, status=%d", response.StatusCode)
}
} else {
return fmt.Errorf("%s %s %s", c.baseURL, "responding on port:", strings.Split(c.baseURL, ":")[1])
}

return nil
}
9 changes: 9 additions & 0 deletions integration/apprise/wrapper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package apprise

type Data struct {
Urls string `json:"urls"`
Body string `json:"body"`
}
13 changes: 13 additions & 0 deletions integration/integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package integration // import "miniflux.app/integration"

import (
"miniflux.app/config"
"miniflux.app/integration/apprise"
"miniflux.app/integration/espial"
"miniflux.app/integration/instapaper"
"miniflux.app/integration/linkding"
Expand Down Expand Up @@ -160,4 +161,16 @@ func PushEntry(entry *model.Entry, integration *model.Integration) {
logger.Error("[Integration] push entry to telegram bot failed: %v", err)
}
}
if integration.AppriseEnabled {
logger.Debug("[Integration] Sending Entry %q for User #%d to apprise", entry.URL, integration.UserID)

client := apprise.NewClient(
integration.AppriseServicesURL,
integration.AppriseURL,
)
err := client.PushEntry(entry)
if err != nil {
logger.Error("[Integration] push entry to apprise failed: %v", err)
}
}
}
3 changes: 3 additions & 0 deletions locale/translations/de_DE.json
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,9 @@
"form.integration.notion_activate": "Save entries to Notion",
"form.integration.notion_page_id": "Notion Page ID",
"form.integration.notion_token": "Notion Secret Token",
"form.integration.apprise_activate": "Push entries to Apprise",
"form.integration.apprise_url": "Apprise API URL",
"form.integration.apprise_services_url": "Apprise services urls seperated by comma",
"form.integration.nunux_keeper_activate": "Artikel in Nunux Keeper speichern",
"form.integration.nunux_keeper_endpoint": "Nunux Keeper API-Endpunkt",
"form.integration.nunux_keeper_api_key": "Nunux Keeper API-Schlüssel",
Expand Down
3 changes: 3 additions & 0 deletions locale/translations/el_EL.json
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,9 @@
"form.integration.notion_activate": "Save entries to Notion",
"form.integration.notion_page_id": "Notion Page ID",
"form.integration.notion_token": "Notion Secret Token",
"form.integration.apprise_activate": "Push entries to Apprise",
"form.integration.apprise_url": "Apprise API URL",
"form.integration.apprise_services_url": "Apprise services urls seperated by comma",
"form.integration.nunux_keeper_activate": "Αποθήκευση άρθρων στο Nunux Keeper",
"form.integration.nunux_keeper_endpoint": "Τελικό σημείο Nunux Keeper API",
"form.integration.nunux_keeper_api_key": "Κλειδί API Nunux Keeper",
Expand Down
3 changes: 3 additions & 0 deletions locale/translations/en_US.json
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,9 @@
"form.integration.notion_activate": "Save entries to Notion",
"form.integration.notion_page_id": "Notion Page ID",
"form.integration.notion_token": "Notion Secret Token",
"form.integration.apprise_activate": "Push entries to Apprise",
"form.integration.apprise_url": "Apprise API URL",
"form.integration.apprise_services_url": "Apprise Services URLs (seperated by comma)",
"form.integration.nunux_keeper_activate": "Save entries to Nunux Keeper",
"form.integration.nunux_keeper_endpoint": "Nunux Keeper API Endpoint",
"form.integration.nunux_keeper_api_key": "Nunux Keeper API key",
Expand Down
3 changes: 3 additions & 0 deletions locale/translations/es_ES.json
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,9 @@
"form.integration.notion_activate": "Save entries to Notion",
"form.integration.notion_page_id": "Notion Page ID",
"form.integration.notion_token": "Notion Secret Token",
"form.integration.apprise_activate": "Push entries to Apprise",
"form.integration.apprise_url": "Apprise API URL",
"form.integration.apprise_services_url": "Apprise services urls seperated by comma",
"form.integration.nunux_keeper_activate": "Enviar artículos a Nunux Keeper",
"form.integration.nunux_keeper_endpoint": "Acceso API de Nunux Keeper",
"form.integration.nunux_keeper_api_key": "Clave de API de Nunux Keeper",
Expand Down
3 changes: 3 additions & 0 deletions locale/translations/fi_FI.json
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,9 @@
"form.integration.notion_activate": "Save entries to Notion",
"form.integration.notion_page_id": "Notion Page ID",
"form.integration.notion_token": "Notion Secret Token",
"form.integration.apprise_activate": "Push entries to Apprise",
"form.integration.apprise_url": "Apprise API URL",
"form.integration.apprise_services_url": "Apprise services urls seperated by comma",
"form.integration.nunux_keeper_activate": "Tallenna artikkelit Nunux Keeperiin",
"form.integration.nunux_keeper_endpoint": "Nunux Keeper API-päätepiste",
"form.integration.nunux_keeper_api_key": "Nunux Keeper API-avain",
Expand Down
3 changes: 3 additions & 0 deletions locale/translations/fr_FR.json
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,9 @@
"form.integration.notion_activate": "Sauvegarder les articles vers Notion",
"form.integration.notion_page_id": "l'identifiant de la page Notion",
"form.integration.notion_token": "Jeton d'accès de l'API de Notion",
"form.integration.apprise_activate": "Push entries to Apprise",
"form.integration.apprise_url": "Apprise API URL",
"form.integration.apprise_services_url": "Apprise services urls seperated by comma",
"form.integration.nunux_keeper_activate": "Sauvegarder les articles vers Nunux Keeper",
"form.integration.nunux_keeper_endpoint": "URL de l'API de Nunux Keeper",
"form.integration.nunux_keeper_api_key": "Clé d'API de Nunux Keeper",
Expand Down
3 changes: 3 additions & 0 deletions locale/translations/hi_IN.json
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,9 @@
"form.integration.notion_activate": "Save entries to Notion",
"form.integration.notion_page_id": "Notion Page ID",
"form.integration.notion_token": "Notion Secret Token",
"form.integration.apprise_activate": "Push entries to Apprise",
"form.integration.apprise_url": "Apprise API URL",
"form.integration.apprise_services_url": "Apprise services urls seperated by comma",
"form.integration.nunux_keeper_activate": "विषय-वस्तु को ननक्स कीपर में सहेजें",
"form.integration.nunux_keeper_endpoint": "ननक्स कीपर एपीआई समापन बिंदु",
"form.integration.nunux_keeper_api_key": "ननक्स कीपर एपीआई कुंजी",
Expand Down
3 changes: 3 additions & 0 deletions locale/translations/id_ID.json
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,9 @@
"form.integration.notion_activate": "Save entries to Notion",
"form.integration.notion_page_id": "Notion Page ID",
"form.integration.notion_token": "Notion Secret Token",
"form.integration.apprise_activate": "Push entries to Apprise",
"form.integration.apprise_url": "Apprise API URL",
"form.integration.apprise_services_url": "Apprise services urls seperated by comma",
"form.integration.nunux_keeper_activate": "Simpan artikel ke Nunux Keeper",
"form.integration.nunux_keeper_endpoint": "Titik URL API Nunux Keeper",
"form.integration.nunux_keeper_api_key": "Kunci API Nunux Keeper",
Expand Down
3 changes: 3 additions & 0 deletions locale/translations/it_IT.json
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,9 @@
"form.integration.notion_activate": "Save entries to Notion",
"form.integration.notion_page_id": "Notion Page ID",
"form.integration.notion_token": "Notion Secret Token",
"form.integration.apprise_activate": "Push entries to Apprise",
"form.integration.apprise_url": "Apprise API URL",
"form.integration.apprise_services_url": "Apprise services urls seperated by comma",
"form.integration.nunux_keeper_activate": "Salva gli articoli su Nunux Keeper",
"form.integration.nunux_keeper_endpoint": "Endpoint dell'API di Nunux Keeper",
"form.integration.nunux_keeper_api_key": "API key dell'account Nunux Keeper",
Expand Down
3 changes: 3 additions & 0 deletions locale/translations/ja_JP.json
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,9 @@
"form.integration.notion_activate": "Save entries to Notion",
"form.integration.notion_page_id": "Notion Page ID",
"form.integration.notion_token": "Notion Secret Token",
"form.integration.apprise_activate": "Push entries to Apprise",
"form.integration.apprise_url": "Apprise API URL",
"form.integration.apprise_services_url": "Apprise services urls seperated by comma",
"form.integration.nunux_keeper_activate": "Nunux Keeper に記事を保存する",
"form.integration.nunux_keeper_endpoint": "Nunux Keeper の API Endpoint",
"form.integration.nunux_keeper_api_key": "Nunux Keeper の API key",
Expand Down
3 changes: 3 additions & 0 deletions locale/translations/nl_NL.json
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,9 @@
"form.integration.notion_activate": "Save entries to Notion",
"form.integration.notion_page_id": "Notion Page ID",
"form.integration.notion_token": "Notion Secret Token",
"form.integration.apprise_activate": "Push entries to Apprise",
"form.integration.apprise_url": "Apprise API URL",
"form.integration.apprise_services_url": "Apprise services urls seperated by comma",
"form.integration.nunux_keeper_activate": "Opslaan naar Nunux Keeper",
"form.integration.nunux_keeper_endpoint": "Nunux Keeper URL",
"form.integration.nunux_keeper_api_key": "Nunux Keeper API-sleutel",
Expand Down
3 changes: 3 additions & 0 deletions locale/translations/pl_PL.json
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,9 @@
"form.integration.notion_activate": "Save entries to Notion",
"form.integration.notion_page_id": "Notion Page ID",
"form.integration.notion_token": "Notion Secret Token",
"form.integration.apprise_activate": "Push entries to Apprise",
"form.integration.apprise_url": "Apprise API URL",
"form.integration.apprise_services_url": "Apprise services urls seperated by comma",
"form.integration.nunux_keeper_activate": "Zapisz artykuly do Nunux Keeper",
"form.integration.nunux_keeper_endpoint": "Nunux Keeper URL",
"form.integration.nunux_keeper_api_key": "Nunux Keeper API key",
Expand Down
3 changes: 3 additions & 0 deletions locale/translations/pt_BR.json
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,9 @@
"form.integration.notion_activate": "Save entries to Notion",
"form.integration.notion_page_id": "Notion Page ID",
"form.integration.notion_token": "Notion Secret Token",
"form.integration.apprise_activate": "Push entries to Apprise",
"form.integration.apprise_url": "Apprise API URL",
"form.integration.apprise_services_url": "Apprise services urls seperated by comma",
"form.integration.nunux_keeper_activate": "Salvar itens no Nunux Keeper",
"form.integration.nunux_keeper_endpoint": "Endpoint de API do Nunux Keeper",
"form.integration.nunux_keeper_api_key": "Chave de API do Nunux Keeper",
Expand Down
3 changes: 3 additions & 0 deletions locale/translations/ru_RU.json
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,9 @@
"form.integration.notion_activate": "Save entries to Notion",
"form.integration.notion_page_id": "Notion Page ID",
"form.integration.notion_token": "Notion Secret Token",
"form.integration.apprise_activate": "Push entries to Apprise",
"form.integration.apprise_url": "Apprise API URL",
"form.integration.apprise_services_url": "Apprise services urls seperated by comma",
"form.integration.nunux_keeper_activate": "Сохранять статьи в Nunux Keeper",
"form.integration.nunux_keeper_endpoint": "Конечная точка Nunux Keeper API",
"form.integration.nunux_keeper_api_key": "API-ключ Nunux Keeper",
Expand Down
3 changes: 3 additions & 0 deletions locale/translations/tr_TR.json
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,9 @@
"form.integration.notion_activate": "Save entries to Notion",
"form.integration.notion_page_id": "Notion Page ID",
"form.integration.notion_token": "Notion Secret Token",
"form.integration.apprise_activate": "Push entries to Apprise",
"form.integration.apprise_url": "Apprise API URL",
"form.integration.apprise_services_url": "Apprise services urls seperated by comma",
"form.integration.nunux_keeper_activate": "Makaleleri Nunux Keeper'a kaydet",
"form.integration.nunux_keeper_endpoint": "Nunux Keeper API Uç Noktası",
"form.integration.nunux_keeper_api_key": "Nunux Keeper API anahtarı",
Expand Down
3 changes: 3 additions & 0 deletions locale/translations/uk_UA.json
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,9 @@
"form.integration.notion_activate": "Save entries to Notion",
"form.integration.notion_page_id": "Notion Page ID",
"form.integration.notion_token": "Notion Secret Token",
"form.integration.apprise_activate": "Push entries to Apprise",
"form.integration.apprise_url": "Apprise API URL",
"form.integration.apprise_services_url": "Apprise services urls seperated by comma",
"form.integration.nunux_keeper_activate": "Зберігати статті до Nunux Keeper",
"form.integration.nunux_keeper_endpoint": "Nunux Keeper API Endpoint",
"form.integration.nunux_keeper_api_key": "Ключ API Nunux Keeper",
Expand Down
3 changes: 3 additions & 0 deletions locale/translations/zh_CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,9 @@
"form.integration.notion_activate": "Save entries to Notion",
"form.integration.notion_page_id": "Notion Page ID",
"form.integration.notion_token": "Notion Secret Token",
"form.integration.apprise_activate": "Push entries to Apprise",
"form.integration.apprise_url": "Apprise API URL",
"form.integration.apprise_services_url": "Apprise services urls seperated by comma",
"form.integration.nunux_keeper_activate": "保存文章到 Nunux Keeper",
"form.integration.nunux_keeper_endpoint": "Nunux Keeper API 端点",
"form.integration.nunux_keeper_api_key": "Nunux Keeper API 密钥",
Expand Down
3 changes: 3 additions & 0 deletions locale/translations/zh_TW.json
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,9 @@
"form.integration.notion_activate": "Save entries to Notion",
"form.integration.notion_page_id": "Notion Page ID",
"form.integration.notion_token": "Notion Secret Token",
"form.integration.apprise_activate": "Push entries to Apprise",
"form.integration.apprise_url": "Apprise API URL",
"form.integration.apprise_services_url": "Apprise services urls seperated by comma",
"form.integration.nunux_keeper_activate": "儲存文章到 Nunux Keeper",
"form.integration.nunux_keeper_endpoint": "Nunux Keeper API 端點",
"form.integration.nunux_keeper_api_key": "Nunux Keeper API 金鑰",
Expand Down
3 changes: 3 additions & 0 deletions model/integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,7 @@ type Integration struct {
MatrixBotPassword string
MatrixBotURL string
MatrixBotChatID string
AppriseEnabled bool
AppriseURL string
AppriseServicesURL string
}
20 changes: 16 additions & 4 deletions storage/integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,10 @@ func (s *Storage) Integration(userID int64) (*model.Integration, error) {
matrix_bot_user,
matrix_bot_password,
matrix_bot_url,
matrix_bot_chat_id
matrix_bot_chat_id,
apprise_enabled,
apprise_url,
apprise_services_url
FROM
integrations
WHERE
Expand Down Expand Up @@ -214,6 +217,9 @@ func (s *Storage) Integration(userID int64) (*model.Integration, error) {
&integration.MatrixBotPassword,
&integration.MatrixBotURL,
&integration.MatrixBotChatID,
&integration.AppriseEnabled,
&integration.AppriseURL,
&integration.AppriseServicesURL,
)
switch {
case err == sql.ErrNoRows:
Expand Down Expand Up @@ -278,9 +284,12 @@ func (s *Storage) UpdateIntegration(integration *model.Integration) error {
notion_token=$45,
notion_page_id=$46,
readwise_enabled=$47,
readwise_api_key=$48
readwise_api_key=$48,
apprise_enabled=$49,
apprise_url=$50,
apprise_services_url=$51
WHERE
user_id=$49
user_id=$52
`
_, err := s.db.Exec(
query,
Expand Down Expand Up @@ -332,6 +341,9 @@ func (s *Storage) UpdateIntegration(integration *model.Integration) error {
integration.NotionPageID,
integration.ReadwiseEnabled,
integration.ReadwiseAPIKey,
integration.AppriseEnabled,
integration.AppriseURL,
integration.AppriseServicesURL,
integration.UserID,
)

Expand All @@ -352,7 +364,7 @@ func (s *Storage) HasSaveEntry(userID int64) (result bool) {
WHERE
user_id=$1
AND
(pinboard_enabled='t' OR instapaper_enabled='t' OR wallabag_enabled='t' OR notion_enabled='t' OR nunux_keeper_enabled='t' OR espial_enabled='t' OR readwise_enabled='t' OR pocket_enabled='t' OR linkding_enabled='t')
(pinboard_enabled='t' OR instapaper_enabled='t' OR wallabag_enabled='t' OR notion_enabled='t' OR nunux_keeper_enabled='t' OR espial_enabled='t' OR readwise_enabled='t' OR pocket_enabled='t' OR linkding_enabled='t' OR apprise_enabled='t')
`
if err := s.db.QueryRow(query, userID).Scan(&result); err != nil {
result = false
Expand Down
19 changes: 19 additions & 0 deletions template/templates/views/integrations.html
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,26 @@ <h3>Linkding</h3>
<button type="submit" class="button button-primary" data-label-loading="{{ t "form.submit.saving" }}">{{ t "action.update" }}</button>
</div>
</div>
<h3>Apprise</h3>
<div class="form-section">
<label>
<input type="checkbox" name="apprise_enabled" value="1" {{ if .form.AppriseEnabled }}checked{{ end }}> {{ t "form.integration.apprise_activate" }}
</label>

<label for="form-apprise-url">{{ t "form.integration.apprise_url" }}</label>
<input type="text" name="apprise_url" id="form-apprise-url" value="{{ .form.AppriseURL }}" placeholder="http://apprise:8080" spellcheck="false">

<label for="form-apprise-services-url">{{ t "form.integration.apprise_services_url" }}
<a href="https://github.com/caronc/apprise/wiki" target="_blank">
{{ icon "external-link" }}
</a>
</label>
<input type="text" name="apprise_services_url" id="form-apprise-services-urls" value="{{ .form.AppriseServicesURL }}" placeholder="tgram://<token>/<chat_id>/,matrix://" spellcheck="false">

<div class="buttons">
<button type="submit" class="button button-primary" data-label-loading="{{ t "form.submit.saving" }}">{{ t "action.update" }}</button>
</div>
</div>
<h3>Telegram Bot</h3>
<div class="form-section">
<label>
Expand Down
Loading

0 comments on commit bf4823b

Please sign in to comment.