Skip to content
Open
Changes from all commits
Commits
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
158 changes: 87 additions & 71 deletions plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"net/http"
"net/http/httputil"
"os"
"strings"
"time"

"github.com/gotify/plugin-api"
Expand All @@ -17,31 +18,31 @@ import (
// GetGotifyPluginInfo returns gotify plugin info
func GetGotifyPluginInfo() plugin.Info {
return plugin.Info{
Version: "1.0",
Author: "Anh Bui",
Name: "Gotify 2 Telegram",
Description: "Telegram message fowarder for gotify",
ModulePath: "https://github.com/anhbh310/gotify2telegram",
Version: "1.0",
Author: "Anh Bui",
Name: "Gotify 2 Telegram",
Description: "Telegram message forwarder for gotify",
ModulePath: "https://github.com/anhbh310/gotify2telegram",
}
}

// Plugin is the plugin instance
type Plugin struct {
ws *websocket.Conn;
msgHandler plugin.MessageHandler;
debugLogger *log.Logger;
chatid string;
telegram_bot_token string;
gotify_host string;
ws *websocket.Conn
msgHandler plugin.MessageHandler
debugLogger *log.Logger
chatids []string
telegram_bot_token string
gotify_host string
}

type GotifyMessage struct {
Id uint32;
Appid uint32;
Message string;
Title string;
Priority uint32;
Date string;
Id uint32
Appid uint32
Message string
Title string
Priority uint32
Date string
}

type Payload struct {
Expand All @@ -51,63 +52,74 @@ type Payload struct {

func (p *Plugin) send_msg_to_telegram(msg string) {
step_size := 4090
sending_message := ""

for i:=0; i<len(msg); i+=step_size {

var messageParts []string
for i := 0; i < len(msg); i += step_size {
if i+step_size < len(msg) {
sending_message = msg[i : i+step_size]
} else {
sending_message = msg[i:len(msg)]
}

data := Payload{
// Fill struct
ChatID: p.chatid,
Text: sending_message,
}
payloadBytes, err := json.Marshal(data)
if err != nil {
p.debugLogger.Println("Create json false")
return
}
body := bytes.NewBuffer(payloadBytes)
// For future debugging
backup_body := bytes.NewBuffer(body.Bytes())

req, err := http.NewRequest("POST", "https://api.telegram.org/bot"+ p.telegram_bot_token +"/sendMessage", body)
if err != nil {
p.debugLogger.Println("Create request false")
return
messageParts = append(messageParts, msg[i:i+step_size])
} else {
messageParts = append(messageParts, msg[i:len(msg)])
}
req.Header.Set("Content-Type", "application/json")

resp, err := http.DefaultClient.Do(req)
}

if err != nil {
p.debugLogger.Printf("Send request false: %v\n", err)
return
for _, chatID := range p.chatids {
chatID = strings.TrimSpace(chatID)
if chatID == "" {
continue
}
p.debugLogger.Println("HTTP request was sent successfully")

for _, sending_message := range messageParts {
data := Payload{
ChatID: chatID,
Text: sending_message,
}
payloadBytes, err := json.Marshal(data)
if err != nil {
p.debugLogger.Printf("Create json false for chat_id %s: %v\n", chatID, err)
continue
}
body := bytes.NewBuffer(payloadBytes)
backup_body := bytes.NewBuffer(payloadBytes)

if resp.StatusCode == http.StatusOK {
p.debugLogger.Println("The message was forwarded successfully to Telegram")
} else {
// Log infor for debugging
p.debugLogger.Println("============== Request ==============")
pretty_print, err := httputil.DumpRequest(req, true)
req, err := http.NewRequest("POST", "https://api.telegram.org/bot"+p.telegram_bot_token+"/sendMessage", body)
if err != nil {
p.debugLogger.Printf("%v\n", err)
p.debugLogger.Printf("Create request false for chat_id %s: %v\n", chatID, err)
continue
}
p.debugLogger.Printf(string(pretty_print))
p.debugLogger.Printf("%v\n", backup_body)
req.Header.Set("Content-Type", "application/json")

p.debugLogger.Println("============== Response ==============")
bodyBytes, err := io.ReadAll(resp.Body)
p.debugLogger.Printf("%v\n", string(bodyBytes))
resp, err := http.DefaultClient.Do(req)
if err != nil {
p.debugLogger.Printf("Send request false for chat_id %s: %v\n", chatID, err)
continue
}

if resp.StatusCode == http.StatusOK {
p.debugLogger.Printf("The message was forwarded successfully to Telegram for chat_id %s\n", chatID)
} else {
// Log info for debugging
p.debugLogger.Printf("============== Request for chat_id %s ==============\n", chatID)
pretty_print, err := httputil.DumpRequest(req, true)
if err != nil {
p.debugLogger.Printf("%v\n", err)
}
p.debugLogger.Printf(string(pretty_print))
p.debugLogger.Printf("%v\n", backup_body)

p.debugLogger.Println("============== Response ==============")
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
p.debugLogger.Printf("Error reading response body: %v\n", err)
} else {
p.debugLogger.Printf("%v\n", string(bodyBytes))
}
}
resp.Body.Close()

time.Sleep(100 * time.Millisecond)
}

defer resp.Body.Close()
p.debugLogger.Printf("Completed sending messages to chat_id: %s\n", chatID)
}
}

Expand All @@ -119,15 +131,22 @@ func (p *Plugin) connect_websocket() {
break
}
p.debugLogger.Printf("Cannot connect to websocket: %v\n", err)
time.Sleep(5)
time.Sleep(5 * time.Second)
}
p.debugLogger.Println("WebSocket connected successfully, ready for forwarding")
}

func (p *Plugin) get_websocket_msg(url string, token string) {
p.gotify_host = url + "/stream?token=" + token
p.chatid = os.Getenv("TELEGRAM_CHAT_ID")
p.debugLogger.Printf("chatid: %v\n", p.chatid)

chatidsStr := os.Getenv("TELEGRAM_CHAT_ID")
p.chatids = strings.Split(chatidsStr, ",")
p.debugLogger.Printf("Number of chat_ids: %d\n", len(p.chatids))
for i, chatid := range p.chatids {
p.chatids[i] = strings.TrimSpace(chatid)
p.debugLogger.Printf("chat_id %d: %s\n", i+1, p.chatids[i])
}

p.telegram_bot_token = os.Getenv("TELEGRAM_BOT_TOKEN")
p.debugLogger.Printf("Bot token: %v\n", p.telegram_bot_token)

Expand All @@ -136,7 +155,7 @@ func (p *Plugin) get_websocket_msg(url string, token string) {
for {
msg := &GotifyMessage{}
if p.ws == nil {
time.Sleep(3)
time.Sleep(3 * time.Second)
continue
}
err := p.ws.ReadJSON(msg)
Expand Down Expand Up @@ -176,7 +195,4 @@ func NewGotifyPluginInstance(ctx plugin.UserContext) plugin.Plugin {

func main() {
panic("this should be built as go plugin")
// For testing
// p := &Plugin{nil, nil, "", "", ""}
// p.get_websocket_msg(os.Getenv("GOTIFY_HOST"), os.Getenv("GOTIFY_CLIENT_TOKEN"))
}