Add initial version
This commit is contained in:
commit
c8681ba96c
|
@ -0,0 +1 @@
|
|||
.idea/
|
|
@ -0,0 +1,13 @@
|
|||
FROM golang:1.14-alpine as build
|
||||
ADD . /app
|
||||
WORKDIR /app
|
||||
RUN go build
|
||||
|
||||
FROM alpine:3.11
|
||||
RUN apk add --no-cache tzdata ca-certificates
|
||||
COPY --from=build /app/JsonFeedToTelegram /bin/
|
||||
WORKDIR /app
|
||||
VOLUME /app/storage
|
||||
EXPOSE 8080
|
||||
ENV LAST_ARTICLE_FILE /app/storage/lastarticle
|
||||
CMD ["JsonFeedToTelegram"]
|
|
@ -0,0 +1,35 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type Article struct {
|
||||
Title string `json:"title"`
|
||||
Url string `json:"url"`
|
||||
}
|
||||
|
||||
func LatestArticle(url string) (*Article, error) {
|
||||
jsonFeed := &struct {
|
||||
Items []Article `json:"items"`
|
||||
}{}
|
||||
req, err := http.NewRequest(http.MethodGet, url, nil)
|
||||
if err != nil {
|
||||
return nil, errors.New("failed to create req to get json feed")
|
||||
}
|
||||
req.Header.Add("User-Agent", "JsonFeedToTelegram")
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, errors.New("failed to get json feed")
|
||||
}
|
||||
err = json.NewDecoder(resp.Body).Decode(&jsonFeed)
|
||||
if err != nil {
|
||||
return nil, errors.New("failed to parse json feed")
|
||||
}
|
||||
if len(jsonFeed.Items) < 1 {
|
||||
return nil, errors.New("no articles in feed")
|
||||
}
|
||||
return &jsonFeed.Items[0], nil
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
lastArticleFile, lastArticleFileSet := os.LookupEnv("LAST_ARTICLE_FILE")
|
||||
feed, feedSet := os.LookupEnv("FEED")
|
||||
botToken, botTokenSet := os.LookupEnv("BOT_TOKEN")
|
||||
channel, channelSet := os.LookupEnv("CHANNEL")
|
||||
if lastArticleFileSet && feedSet && botTokenSet && channelSet {
|
||||
telegram := Telegram{botToken: botToken, channel: channel}
|
||||
http.HandleFunc("/hook", func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "Wrong HTTP method", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
fmt.Println("Fetch feed: ", time.Now().Format(time.RFC3339))
|
||||
article, err := LatestArticle(feed)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if lastArticle := lastArticleUrl(lastArticleFile); lastArticle != article.Url {
|
||||
err = telegram.Post(createMessage(article))
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
err = updateLastArticleUrl(lastArticleFile, article.Url)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
http.Error(w, errors.New("no new article").Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
})
|
||||
log.Fatal(http.ListenAndServe(":8080", nil))
|
||||
} else {
|
||||
log.Fatal("Not configured")
|
||||
}
|
||||
}
|
||||
|
||||
func lastArticleUrl(filename string) string {
|
||||
fileContent, _ := ioutil.ReadFile(filename)
|
||||
return string(fileContent)
|
||||
}
|
||||
|
||||
func updateLastArticleUrl(filename, url string) error {
|
||||
return ioutil.WriteFile(filename, []byte(url), 0644)
|
||||
}
|
||||
|
||||
func createMessage(article *Article) string {
|
||||
var message bytes.Buffer
|
||||
message.WriteString("🔔 Something new was published")
|
||||
message.WriteString("\n\n")
|
||||
if article.Title != "" {
|
||||
message.WriteString(article.Title)
|
||||
message.WriteString("\n\n")
|
||||
}
|
||||
message.WriteString(article.Url)
|
||||
return message.String()
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
type Telegram struct {
|
||||
channel string
|
||||
botToken string
|
||||
}
|
||||
|
||||
var telegramBaseUrl = "https://api.telegram.org/bot"
|
||||
|
||||
func (t *Telegram) Post(message string) error {
|
||||
params := url.Values{}
|
||||
params.Add("chat_id", t.channel)
|
||||
params.Add("text", message)
|
||||
tgUrl, err := url.Parse(telegramBaseUrl + t.botToken + "/sendMessage")
|
||||
if err != nil {
|
||||
return errors.New("failed to create Telegram request")
|
||||
}
|
||||
tgUrl.RawQuery = params.Encode()
|
||||
req, _ := http.NewRequest(http.MethodPost, tgUrl.String(), nil)
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil || resp.StatusCode != 200 {
|
||||
return errors.New("failed to send Telegram message")
|
||||
}
|
||||
return nil
|
||||
}
|
Reference in New Issue