Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apprise Support 📡 #1971

Merged
merged 25 commits into from
Aug 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
4c1496f
🎉 Initial Notion Support
jeankhawand Jul 1, 2023
2d2025b
Merge remote-tracking branch 'origin' into feature/notion-support
jeankhawand Jul 1, 2023
51791ec
➕ default us l11n for notion form field
jeankhawand Jul 1, 2023
3ea17e3
✍️ fix typo
jeankhawand Jul 1, 2023
8be6cc8
✍️ migration typo
jeankhawand Jul 1, 2023
3354351
✍️ typo again!!
jeankhawand Jul 1, 2023
4f2ab56
🔃 replace http with https in placeholder
jeankhawand Jul 2, 2023
7af1759
➕ add missing translations keys for other locales
jeankhawand Jul 4, 2023
ef6e6a7
✍️ combine resource with endpoint url
jeankhawand Jul 4, 2023
41fbf1e
✍️ fix new client params
jeankhawand Jul 4, 2023
4a430c6
add license lines
jeankhawand Jul 6, 2023
8a7a7a3
remove unnecessary trailing newline (whitespace)
jeankhawand Jul 7, 2023
097cb8d
🎉 support apprise to push entries/entry via different messaging services
jeankhawand Jul 8, 2023
1bf0e2c
Merge remote-tracking branch 'origin' into feature/apprise-support
jeankhawand Jul 8, 2023
48fc672
➕ placeholder text for apprise url
jeankhawand Jul 8, 2023
a756ef4
😃fix conflicts
jeankhawand Jul 8, 2023
38cf76a
using markdown format
jeankhawand Jul 9, 2023
1ddff9b
✍️ typo servicesURL
jeankhawand Jul 10, 2023
85d76d8
Merge branch 'main' into feature/apprise-support
jeankhawand Jul 16, 2023
2e1780f
Merge branch 'main' into feature/apprise-support
jeankhawand Jul 29, 2023
4b63575
Revert "✍️ typo servicesURL"
jeankhawand Jul 29, 2023
63f67eb
fix(golang-linter): `gofmt`-ed with `-s`
jeankhawand Jul 29, 2023
c1c5358
enhance(integration-view): add tooltip to guide user setting up right…
jeankhawand Jul 29, 2023
cd29c0e
add(services-urls-field): placeholder
jeankhawand Jul 29, 2023
828c887
fix(entries-push): discovered some messaging services limit payload s…
jeankhawand Jul 31, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
jeankhawand marked this conversation as resolved.
Show resolved Hide resolved
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
Loading