Add Espial integration

This commit is contained in:
Berk Özkütük 2022-04-21 05:44:47 +03:00 committed by GitHub
parent fb585d0086
commit ab3fdf509f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 222 additions and 5 deletions

View File

@ -572,4 +572,14 @@ 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 espial_enabled bool default 'f';
ALTER TABLE integrations ADD COLUMN espial_url text default '';
ALTER TABLE integrations ADD COLUMN espial_api_key text default '';
ALTER TABLE integrations ADD COLUMN espial_tags text default 'miniflux';
`
_, err = tx.Exec(sql)
return err
},
}

View File

@ -0,0 +1,69 @@
package espial // import "miniflux.app/integration/espial"
import (
"fmt"
"net/url"
"path"
"miniflux.app/http/client"
)
// Document structure of an Espial document
type Document struct {
Title string `json:"title,omitempty"`
Url string `json:"url,omitempty"`
ToRead bool `json:"toread,omitempty"`
Tags string `json:"tags,omitempty"`
}
// Client represents an Espial client.
type Client struct {
baseURL string
apiKey string
}
// NewClient returns a new Espial client.
func NewClient(baseURL, apiKey string) *Client {
return &Client{baseURL: baseURL, apiKey: apiKey}
}
// AddEntry sends an entry to Espial.
func (c *Client) AddEntry(link, title, content, tags string) error {
if c.baseURL == "" || c.apiKey == "" {
return fmt.Errorf("espial: missing credentials")
}
doc := &Document{
Title: title,
Url: link,
ToRead: true,
Tags: tags,
}
apiURL, err := getAPIEndpoint(c.baseURL, "/api/add")
if err != nil {
return err
}
clt := client.New(apiURL)
clt.WithAuthorization("ApiKey " + c.apiKey)
response, err := clt.PostJSON(doc)
if err != nil {
return fmt.Errorf("espial: unable to send entry: %v", err)
}
if response.HasServerFailure() {
return fmt.Errorf("espial: unable to send entry, status=%d", response.StatusCode)
}
return nil
}
func getAPIEndpoint(baseURL, pathURL string) (string, error) {
u, err := url.Parse(baseURL)
if err != nil {
return "", fmt.Errorf("espial: invalid API endpoint: %v", err)
}
u.Path = path.Join(u.Path, pathURL)
return u.String(), nil
}

View File

@ -6,6 +6,7 @@ package integration // import "miniflux.app/integration"
import (
"miniflux.app/config"
"miniflux.app/integration/espial"
"miniflux.app/integration/instapaper"
"miniflux.app/integration/nunuxkeeper"
"miniflux.app/integration/pinboard"
@ -72,6 +73,19 @@ func SendEntry(entry *model.Entry, integration *model.Integration) {
}
}
if integration.EspialEnabled {
logger.Debug("[Integration] Sending Entry #%d %q for User #%d to Espial", entry.ID, entry.URL, integration.UserID)
client := espial.NewClient(
integration.EspialURL,
integration.EspialAPIKey,
)
if err := client.AddEntry(entry.URL, entry.Title, entry.Content, integration.EspialTags); err != nil {
logger.Error("[Integration] UserID #%d: %v", integration.UserID, err)
}
}
if integration.PocketEnabled {
logger.Debug("[Integration] Sending Entry #%d %q for User #%d to Pocket", entry.ID, entry.URL, integration.UserID)

View File

@ -335,6 +335,10 @@
"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",
"form.integration.espial_activate": "Artikel in Espial speichern",
"form.integration.espial_endpoint": "Espial API-Endpunkt",
"form.integration.espial_api_key": "Espial API-Schlüssel",
"form.integration.espial_tags": "Espial tags",
"form.integration.telegram_bot_activate": "Pushen Sie neue Artikel in den Telegram-Chat",
"form.integration.telegram_bot_token": "Bot token",
"form.integration.telegram_chat_id": "Chat ID",

View File

@ -335,6 +335,10 @@
"form.integration.nunux_keeper_activate": "Αποθήκευση άρθρων στο Nunux Keeper",
"form.integration.nunux_keeper_endpoint": "Τελικό σημείο Nunux Keeper API",
"form.integration.nunux_keeper_api_key": "Κλειδί API Nunux Keeper",
"form.integration.espial_activate": "Αποθήκευση άρθρων στο Espial",
"form.integration.espial_endpoint": "Τελικό σημείο Espial API",
"form.integration.espial_api_key": "Κλειδί API Espial",
"form.integration.espial_tags": "Ετικέτες Espial",
"form.integration.telegram_bot_activate": "Προωθήστε νέα άρθρα στη συνομιλία Telegram",
"form.integration.telegram_bot_token": "Διακριτικό bot",
"form.integration.telegram_chat_id": "Αναγνωριστικό συνομιλίας",

View File

@ -335,6 +335,10 @@
"form.integration.nunux_keeper_activate": "Save articles to Nunux Keeper",
"form.integration.nunux_keeper_endpoint": "Nunux Keeper API Endpoint",
"form.integration.nunux_keeper_api_key": "Nunux Keeper API key",
"form.integration.espial_activate": "Save articles to Espial",
"form.integration.espial_endpoint": "Espial API Endpoint",
"form.integration.espial_api_key": "Espial API key",
"form.integration.espial_tags": "Espial Tags",
"form.integration.telegram_bot_activate": "Push new articles to Telegram chat",
"form.integration.telegram_bot_token": "Bot token",
"form.integration.telegram_chat_id": "Chat ID",

View File

@ -335,6 +335,10 @@
"form.integration.nunux_keeper_activate": "Guardar artículos a Nunux Keeper",
"form.integration.nunux_keeper_endpoint": "Extremo de API de Nunux Keeper",
"form.integration.nunux_keeper_api_key": "Clave de API de Nunux Keeper",
"form.integration.espial_activate": "Guardar artículos a Espial",
"form.integration.espial_endpoint": "Extremo de API de Espial",
"form.integration.espial_api_key": "Clave de API de Espial",
"form.integration.espial_tags": "Etiquetas de Espial",
"form.integration.telegram_bot_activate": "Envíe nuevos artículos al chat de Telegram",
"form.integration.telegram_bot_token": "Token de bot",
"form.integration.telegram_chat_id": "ID de chat",

View File

@ -335,6 +335,10 @@
"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",
"form.integration.espial_activate": "Tallenna artikkelit Espialiin",
"form.integration.espial_endpoint": "Espial API-päätepiste",
"form.integration.espial_api_key": "Espial API-avain",
"form.integration.espial_tags": "Espial-tagit",
"form.integration.telegram_bot_activate": "Lähetä uusia artikkeleita Telegram-chatiin",
"form.integration.telegram_bot_token": "Bot-tunnus",
"form.integration.telegram_chat_id": "Chat ID",

View File

@ -335,6 +335,10 @@
"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",
"form.integration.espial_activate": "Sauvegarder les articles vers Espial",
"form.integration.espial_endpoint": "URL de l'API de Espial",
"form.integration.espial_api_key": "Clé d'API de Espial",
"form.integration.espial_tags": "Libellés de Espial",
"form.integration.telegram_bot_activate": "Envoyer les nouveaux articles vers Telegram",
"form.integration.telegram_bot_token": "Jeton de sécurité de l'API du Bot Telegram",
"form.integration.telegram_chat_id": "Identifiant de discussion",

View File

@ -335,6 +335,10 @@
"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",
"form.integration.espial_activate": "Salva gli articoli su Espial",
"form.integration.espial_endpoint": "Endpoint dell'API di Espial",
"form.integration.espial_api_key": "API key dell'account Espial",
"form.integration.espial_tags": "Tag di Espial",
"form.integration.telegram_bot_activate": "Invia nuovi articoli alla chat di Telegram",
"form.integration.telegram_bot_token": "Token bot",
"form.integration.telegram_chat_id": "ID chat",

View File

@ -335,6 +335,10 @@
"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",
"form.integration.espial_activate": "Espial に記事を保存する",
"form.integration.espial_endpoint": "Espial の API Endpoint",
"form.integration.espial_api_key": "Espial の API key",
"form.integration.espial_tags": "Espial の Tag",
"form.integration.telegram_bot_activate": "新しい記事をTelegramチャットにプッシュする",
"form.integration.telegram_bot_token": "ボットトークン",
"form.integration.telegram_chat_id": "チャットID",

View File

@ -335,6 +335,10 @@
"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",
"form.integration.espial_activate": "Opslaan naar Espial",
"form.integration.espial_endpoint": "Espial URL",
"form.integration.espial_api_key": "Espial API-sleutel",
"form.integration.espial_tags": "Espial tags",
"form.integration.telegram_bot_activate": "Push nieuwe artikelen naar Telegram-chat",
"form.integration.telegram_bot_token": "Bot token",
"form.integration.telegram_chat_id": "Chat ID",

View File

@ -337,6 +337,10 @@
"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",
"form.integration.espial_activate": "Zapisz artykuly do Espial",
"form.integration.espial_endpoint": "Espial URL",
"form.integration.espial_api_key": "Espial API key",
"form.integration.espial_tags": "Espial Tags",
"form.integration.telegram_bot_activate": "Przesyłaj nowe artykuły do czatu Telegram",
"form.integration.telegram_bot_token": "Token bota",
"form.integration.telegram_chat_id": "Identyfikator czatu",

View File

@ -335,6 +335,10 @@
"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",
"form.integration.espial_activate": "Salvar itens no Espial",
"form.integration.espial_endpoint": "Endpoint de API do Espial",
"form.integration.espial_api_key": "Chave de API do Espial",
"form.integration.espial_tags": "Etiquetas (tags) do Espial",
"form.integration.telegram_bot_activate": "Envie novos artigos para o chat do Telegram",
"form.integration.telegram_bot_token": "Token de bot",
"form.integration.telegram_chat_id": "ID de bate-papo",

View File

@ -337,6 +337,10 @@
"form.integration.nunux_keeper_activate": "Сохранять статьи в Nunux Keeper",
"form.integration.nunux_keeper_endpoint": "Конечная точка Nunux Keeper API",
"form.integration.nunux_keeper_api_key": "Nunux Keeper API Key",
"form.integration.espial_activate": "Сохранять статьи в Espial",
"form.integration.espial_endpoint": "Конечная точка Espial API",
"form.integration.espial_api_key": "Espial API key",
"form.integration.espial_tags": "Теги Espial",
"form.integration.telegram_bot_activate": "Публикуйте новые статьи в Telegram-чате",
"form.integration.telegram_bot_token": "Токен бота",
"form.integration.telegram_chat_id": "ID чата",

View File

@ -335,6 +335,10 @@
"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ı",
"form.integration.espial_activate": "Makaleleri Espial'e kaydet",
"form.integration.espial_endpoint": "Espial API Uç Noktası",
"form.integration.espial_api_key": "Espial API Anahtarı",
"form.integration.espial_tags": "Espial Etiketleri",
"form.integration.telegram_bot_activate": "Yeni makaleleri Telegram sohbetine gönderin",
"form.integration.telegram_bot_token": "Bot jetonu",
"form.integration.telegram_chat_id": "Sohbet kimliği",

View File

@ -333,6 +333,10 @@
"form.integration.nunux_keeper_activate": "保存文章到 Nunux Keeper",
"form.integration.nunux_keeper_endpoint": "Nunux Keeper API 端点",
"form.integration.nunux_keeper_api_key": "Nunux Keeper API 密钥",
"form.integration.espial_activate": "保存文章到 Espial",
"form.integration.espial_endpoint": "Espial API 端点",
"form.integration.espial_api_key": "Espial API 密钥",
"form.integration.espial_tags": "Espial 标签",
"form.integration.telegram_bot_activate": "将新文章推送到 Telegram",
"form.integration.telegram_bot_token": "机器人令牌",
"form.integration.telegram_chat_id": "聊天ID",

View File

@ -335,6 +335,10 @@
"form.integration.nunux_keeper_activate": "儲存文章到 Nunux Keeper",
"form.integration.nunux_keeper_endpoint": "Nunux Keeper API 端點",
"form.integration.nunux_keeper_api_key": "Nunux Keeper API 金鑰",
"form.integration.espial_activate": "儲存文章到 Espial",
"form.integration.espial_endpoint": "Espial API 端點",
"form.integration.espial_api_key": "Espial API 金鑰",
"form.integration.espial_tags": "Espial 標籤",
"form.integration.telegram_bot_activate": "將新文章推送到 Telegram",
"form.integration.telegram_bot_token": "Bot token",
"form.integration.telegram_chat_id": "Chat ID",

View File

@ -29,6 +29,10 @@ type Integration struct {
NunuxKeeperEnabled bool
NunuxKeeperURL string
NunuxKeeperAPIKey string
EspialEnabled bool
EspialURL string
EspialAPIKey string
EspialTags string
PocketEnabled bool
PocketAccessToken string
PocketConsumerKey string

View File

@ -133,6 +133,10 @@ func (s *Storage) Integration(userID int64) (*model.Integration, error) {
nunux_keeper_enabled,
nunux_keeper_url,
nunux_keeper_api_key,
espial_enabled,
espial_url,
espial_api_key,
espial_tags,
pocket_enabled,
pocket_access_token,
pocket_consumer_key,
@ -169,6 +173,10 @@ func (s *Storage) Integration(userID int64) (*model.Integration, error) {
&integration.NunuxKeeperEnabled,
&integration.NunuxKeeperURL,
&integration.NunuxKeeperAPIKey,
&integration.EspialEnabled,
&integration.EspialURL,
&integration.EspialAPIKey,
&integration.EspialTags,
&integration.PocketEnabled,
&integration.PocketAccessToken,
&integration.PocketConsumerKey,
@ -225,9 +233,13 @@ func (s *Storage) UpdateIntegration(integration *model.Integration) error {
googlereader_password=$25,
telegram_bot_enabled=$26,
telegram_bot_token=$27,
telegram_bot_chat_id=$28
telegram_bot_chat_id=$28,
espial_enabled=$29,
espial_url=$30,
espial_api_key=$31,
espial_tags=$32,
WHERE
user_id=$29
user_id=$33
`
_, err = s.db.Exec(
query,
@ -259,6 +271,10 @@ func (s *Storage) UpdateIntegration(integration *model.Integration) error {
integration.TelegramBotEnabled,
integration.TelegramBotToken,
integration.TelegramBotChatID,
integration.EspialEnabled,
integration.EspialURL,
integration.EspialAPIKey,
integration.EspialTags,
integration.UserID,
)
} else {
@ -293,9 +309,13 @@ func (s *Storage) UpdateIntegration(integration *model.Integration) error {
googlereader_password=$25,
telegram_bot_enabled=$26,
telegram_bot_token=$27,
telegram_bot_chat_id=$28
telegram_bot_chat_id=$28,
espial_enabled=$29,
espial_url=$30,
espial_api_key=$31,
espial_tags=$32
WHERE
user_id=$29
user_id=$33
`
_, err = s.db.Exec(
query,
@ -327,6 +347,10 @@ func (s *Storage) UpdateIntegration(integration *model.Integration) error {
integration.TelegramBotEnabled,
integration.TelegramBotToken,
integration.TelegramBotChatID,
integration.EspialEnabled,
integration.EspialURL,
integration.EspialAPIKey,
integration.EspialTags,
integration.UserID,
)
}
@ -348,7 +372,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 nunux_keeper_enabled='t' OR pocket_enabled='t')
(pinboard_enabled='t' OR instapaper_enabled='t' OR wallabag_enabled='t' OR nunux_keeper_enabled='t' OR espial_enabled='t' OR pocket_enabled='t')
`
if err := s.db.QueryRow(query, userID).Scan(&result); err != nil {
result = false

View File

@ -156,6 +156,26 @@
</div>
</div>
<h3>Espial</h3>
<div class="form-section">
<label>
<input type="checkbox" name="espial_enabled" value="1" {{ if .form.EspialEnabled }}checked{{ end }}> {{ t "form.integration.espial_activate" }}
</label>
<label for="form-espial-url">{{ t "form.integration.espial_endpoint" }}</label>
<input type="url" name="espial_url" id="form-espial-url" value="{{ .form.EspialURL }}" placeholder="https://esp.ae8.org" spellcheck="false">
<label for="form-espial-api-key">{{ t "form.integration.espial_api_key" }}</label>
<input type="text" name="espial_api_key" id="form-espial-api-key" value="{{ .form.EspialAPIKey }}" spellcheck="false">
<label for="form-espial-tags">{{ t "form.integration.espial_tags" }}</label>
<input type="text" name="espial_tags" id="form-espial-tags" value="{{ .form.EspialTags }}" 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>

View File

@ -34,6 +34,10 @@ type IntegrationForm struct {
NunuxKeeperEnabled bool
NunuxKeeperURL string
NunuxKeeperAPIKey string
EspialEnabled bool
EspialURL string
EspialAPIKey string
EspialTags string
PocketEnabled bool
PocketAccessToken string
PocketConsumerKey string
@ -64,6 +68,10 @@ func (i IntegrationForm) Merge(integration *model.Integration) {
integration.NunuxKeeperEnabled = i.NunuxKeeperEnabled
integration.NunuxKeeperURL = i.NunuxKeeperURL
integration.NunuxKeeperAPIKey = i.NunuxKeeperAPIKey
integration.EspialEnabled = i.EspialEnabled
integration.EspialURL = i.EspialURL
integration.EspialAPIKey = i.EspialAPIKey
integration.EspialTags = i.EspialTags
integration.PocketEnabled = i.PocketEnabled
integration.PocketAccessToken = i.PocketAccessToken
integration.PocketConsumerKey = i.PocketConsumerKey
@ -97,6 +105,10 @@ func NewIntegrationForm(r *http.Request) *IntegrationForm {
NunuxKeeperEnabled: r.FormValue("nunux_keeper_enabled") == "1",
NunuxKeeperURL: r.FormValue("nunux_keeper_url"),
NunuxKeeperAPIKey: r.FormValue("nunux_keeper_api_key"),
EspialEnabled: r.FormValue("espial_enabled") == "1",
EspialURL: r.FormValue("espial_url"),
EspialAPIKey: r.FormValue("espial_api_key"),
EspialTags: r.FormValue("espial_tags"),
PocketEnabled: r.FormValue("pocket_enabled") == "1",
PocketAccessToken: r.FormValue("pocket_access_token"),
PocketConsumerKey: r.FormValue("pocket_consumer_key"),

View File

@ -49,6 +49,10 @@ func (h *handler) showIntegrationPage(w http.ResponseWriter, r *http.Request) {
NunuxKeeperEnabled: integration.NunuxKeeperEnabled,
NunuxKeeperURL: integration.NunuxKeeperURL,
NunuxKeeperAPIKey: integration.NunuxKeeperAPIKey,
EspialEnabled: integration.EspialEnabled,
EspialURL: integration.EspialURL,
EspialAPIKey: integration.EspialAPIKey,
EspialTags: integration.EspialTags,
PocketEnabled: integration.PocketEnabled,
PocketAccessToken: integration.PocketAccessToken,
PocketConsumerKey: integration.PocketConsumerKey,