Browse Source

Add initial version

master
Jan-Lukas Else 1 year ago
commit
c8681ba96c
  1. 1
      .gitignore
  2. 13
      Dockerfile
  3. 35
      Feed.go
  4. 73
      JsonFeedToTelegram.go
  5. 31
      Telegram.go
  6. 3
      go.mod

1
.gitignore

@ -0,0 +1 @@
.idea/

13
Dockerfile

@ -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"]

35
Feed.go

@ -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
}

73
JsonFeedToTelegram.go

@ -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()
}

31
Telegram.go

@ -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
}

3
go.mod

@ -0,0 +1,3 @@
module git.jlel.se/jlelse/JsonFeedToTelegram
go 1.14
Loading…
Cancel
Save