Improve bot messages #31
6 changed files with 54 additions and 15 deletions
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.faercol.me/faercol/public-ip-tracker/tracker/config"
|
||||
|
@ -15,6 +16,20 @@ import (
|
|||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func formatInitMsg(currentTime time.Time, publicIP net.IP, hostname string) string {
|
||||
formattedHostname := fmt.Sprintf("`%s`", hostname)
|
||||
formattedIP := strings.ReplaceAll(publicIP.String(), ".", "\\.")
|
||||
return fmt.Sprintf(`\[Host %s\] %s
|
||||
Public IP tracker initialized\. Current IP is %s`, formattedHostname, currentTime.Format(time.RFC1123), formattedIP)
|
||||
}
|
||||
|
||||
func formatUpdate(currentTime time.Time, publicIP net.IP, hostname string) string {
|
||||
formattedHostname := fmt.Sprintf("`%s`", hostname)
|
||||
formattedIP := strings.ReplaceAll(publicIP.String(), ".", "\\.")
|
||||
return fmt.Sprintf(`\[Host %s\] %s
|
||||
Public IP has changed, new IP is %s`, formattedHostname, currentTime.Format(time.RFC1123), formattedIP)
|
||||
}
|
||||
|
||||
type Notifier struct {
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
|
@ -29,6 +44,7 @@ type Notifier struct {
|
|||
changesChan chan net.IP
|
||||
exitChan chan struct{}
|
||||
logger logrus.Logger
|
||||
hostname string
|
||||
}
|
||||
|
||||
func (n *Notifier) SendInitMessage() error {
|
||||
|
@ -43,8 +59,7 @@ func (n *Notifier) SendInitMessage() error {
|
|||
currentTime := n.timeGetter()
|
||||
|
||||
n.logger.Debug("Sending init message to Telegram")
|
||||
initMsg := fmt.Sprintf("Public IP tracker initialized at %v, public IP is %s", currentTime, publicIP)
|
||||
if err := n.tgBot.SendMessage(n.ctx, n.tgChatID, initMsg); err != nil {
|
||||
if err := n.tgBot.SendMessage(n.ctx, n.tgChatID, formatInitMsg(currentTime, publicIP, n.hostname), structs.FormattingMarkdownV2); err != nil {
|
||||
return fmt.Errorf("failed to send initialization message: %w", err)
|
||||
}
|
||||
n.logger.Debug("Message sent")
|
||||
|
@ -52,8 +67,7 @@ func (n *Notifier) SendInitMessage() error {
|
|||
}
|
||||
|
||||
func (n *Notifier) sendUpdatedIPMsg() error {
|
||||
updateMsg := fmt.Sprintf("Public IP has been changed, is now %s", n.currentIP)
|
||||
if err := n.tgBot.SendMessage(n.ctx, n.tgChatID, updateMsg); err != nil {
|
||||
if err := n.tgBot.SendMessage(n.ctx, n.tgChatID, formatUpdate(n.timeGetter(), n.currentIP, n.hostname), structs.FormattingMarkdownV2); err != nil {
|
||||
return fmt.Errorf("failed to send update message: %w", err)
|
||||
}
|
||||
return nil
|
||||
|
@ -61,7 +75,7 @@ func (n *Notifier) sendUpdatedIPMsg() error {
|
|||
|
||||
func (n *Notifier) sendCurrentIP() error {
|
||||
statusMsg := fmt.Sprintf("Current public IP is %s", n.currentIP)
|
||||
if err := n.tgBot.SendMessage(n.ctx, n.tgChatID, statusMsg); err != nil {
|
||||
if err := n.tgBot.SendMessage(n.ctx, n.tgChatID, statusMsg, structs.FormattingMarkdownV2); err != nil {
|
||||
return fmt.Errorf("failed to send message: %w", err)
|
||||
}
|
||||
return nil
|
||||
|
@ -142,5 +156,6 @@ func New(ctx context.Context, config *config.Config) *Notifier {
|
|||
frequency: config.PollingFrequency,
|
||||
tgWatcher: notifier.New(config.Telegram.Token),
|
||||
logger: logger.L,
|
||||
hostname: config.Hostname,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ const expectedChatID = 42
|
|||
// Need to mock the telegram bot, because no mock is provided by my own lib, what a shame.
|
||||
type mockTGBot struct {
|
||||
SendMessageProp error
|
||||
SendMessageFunc func(context.Context, int64, string) error
|
||||
SendMessageFunc func(context.Context, int64, string, structs.FormattingOption) error
|
||||
}
|
||||
|
||||
// Do nothing here, it's not used by this bot
|
||||
|
@ -25,11 +25,11 @@ func (mb *mockTGBot) GetMe(ctx context.Context) (structs.User, error) {
|
|||
return structs.User{}, nil
|
||||
}
|
||||
|
||||
func (mb *mockTGBot) SendMessage(ctx context.Context, chatID int64, content string) error {
|
||||
func (mb *mockTGBot) SendMessage(ctx context.Context, chatID int64, content string, option structs.FormattingOption) error {
|
||||
if mb.SendMessageFunc == nil {
|
||||
return mb.SendMessageProp
|
||||
}
|
||||
return mb.SendMessageFunc(ctx, chatID, content)
|
||||
return mb.SendMessageFunc(ctx, chatID, content, option)
|
||||
}
|
||||
|
||||
// Need to mock the notifier here too, but will do later on, I need to improve my lib in the future
|
||||
|
@ -49,12 +49,17 @@ func TestInit(t *testing.T) {
|
|||
ctx, cancel := context.WithCancel(context.Background())
|
||||
called := false
|
||||
|
||||
expectedMsg := "\\[Host `test`\\] Sat, 28 Jan 2023 14:17:12 UTC\nPublic IP tracker initialized\\. Current IP is 198\\.51\\.100\\.42"
|
||||
|
||||
tgBot := mockTGBot{
|
||||
SendMessageFunc: func(ctx context.Context, chatID int64, content string) error {
|
||||
SendMessageFunc: func(ctx context.Context, chatID int64, content string, option structs.FormattingOption) error {
|
||||
if option != structs.FormattingMarkdownV2 {
|
||||
t.Errorf("Unexpected formatting option %v", option)
|
||||
}
|
||||
if chatID != expectedChatID {
|
||||
t.Errorf("Unexpected chatID %d", chatID)
|
||||
}
|
||||
if content != "Public IP tracker initialized at 2023-01-28 14:17:12 +0000 UTC, public IP is 198.51.100.42" {
|
||||
if content != expectedMsg {
|
||||
t.Errorf("Unexpected message %s", content)
|
||||
}
|
||||
called = true
|
||||
|
@ -75,6 +80,7 @@ func TestInit(t *testing.T) {
|
|||
ipGetter: &ipGetter,
|
||||
frequency: 1 * time.Minute,
|
||||
tgWatcher: &mockTGNotifier{},
|
||||
hostname: "test",
|
||||
}
|
||||
|
||||
if err := bot.SendInitMessage(); err != nil {
|
||||
|
@ -91,12 +97,17 @@ func TestUpdateIP(t *testing.T) {
|
|||
ctx, cancel := context.WithCancel(context.Background())
|
||||
called := false
|
||||
|
||||
expectedMsg := "\\[Host `test`\\] Sat, 28 Jan 2023 14:17:12 UTC\nPublic IP has changed, new IP is 198\\.51\\.100\\.42"
|
||||
|
||||
tgBot := mockTGBot{
|
||||
SendMessageFunc: func(ctx context.Context, chatID int64, content string) error {
|
||||
SendMessageFunc: func(ctx context.Context, chatID int64, content string, option structs.FormattingOption) error {
|
||||
if option != structs.FormattingMarkdownV2 {
|
||||
t.Errorf("Unexpected formatting option %v", option)
|
||||
}
|
||||
if chatID != expectedChatID {
|
||||
t.Errorf("Unexpected chatID %d", chatID)
|
||||
}
|
||||
if content != "Public IP has been changed, is now 198.51.100.42" {
|
||||
if content != expectedMsg {
|
||||
t.Errorf("Unexpected message %s", content)
|
||||
}
|
||||
called = true
|
||||
|
@ -120,6 +131,7 @@ func TestUpdateIP(t *testing.T) {
|
|||
ipGetter: &ipGetter,
|
||||
tgWatcher: &mockTGNotifier{},
|
||||
frequency: 500 * time.Millisecond,
|
||||
hostname: "test",
|
||||
}
|
||||
|
||||
go bot.Run()
|
||||
|
|
|
@ -25,12 +25,14 @@ type jsonLogConfig struct {
|
|||
type Config struct {
|
||||
Telegram *TelegramConfig
|
||||
PollingFrequency time.Duration
|
||||
Hostname string
|
||||
Log *LogConfig
|
||||
}
|
||||
|
||||
type jsonConfig struct {
|
||||
Telegram *TelegramConfig `json:"telegram"`
|
||||
PollingFrequency int64 `json:"polling_frequency"`
|
||||
Hostname string `json:"hostname"`
|
||||
Log *jsonLogConfig `json:"log"`
|
||||
}
|
||||
|
||||
|
@ -55,6 +57,7 @@ func New(filepath string) (*Config, error) {
|
|||
return &Config{
|
||||
Telegram: jsonConf.Telegram,
|
||||
PollingFrequency: time.Duration(jsonConf.PollingFrequency) * time.Second,
|
||||
Hostname: jsonConf.Hostname,
|
||||
Log: &LogConfig{
|
||||
Level: parseLevel(jsonConf.Log.Level),
|
||||
},
|
||||
|
|
|
@ -3,7 +3,7 @@ module git.faercol.me/faercol/public-ip-tracker/tracker
|
|||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/ahugues/go-telegram-api v0.1.0
|
||||
github.com/ahugues/go-telegram-api v0.2.0
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
github.com/ahugues/go-telegram-api v0.1.0 h1:CGJG0WR282O0hAO9JH2RutPj+Vn+Q+zbjdSHjuvN5yY=
|
||||
github.com/ahugues/go-telegram-api v0.1.0/go.mod h1:8I/JWxd9GYM7dHOgGmkRI3Ei1u+nGvzeR2knIMmFw7E=
|
||||
github.com/ahugues/go-telegram-api v0.2.0 h1:wAY4qr0T0I2mgW1HxAZFdzhOdXuZ5WE4e8GNR4t7Yrs=
|
||||
github.com/ahugues/go-telegram-api v0.2.0/go.mod h1:8I/JWxd9GYM7dHOgGmkRI3Ei1u+nGvzeR2knIMmFw7E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
|
|
@ -38,6 +38,15 @@ func main() {
|
|||
logger.Init(conf.Log.Level)
|
||||
logger.L.Infof("Intialized logger with level %v", conf.Log.Level)
|
||||
|
||||
if conf.Hostname == "" {
|
||||
logger.L.Warn("Unspecified hostname, trying to get current hostname, this might not be reliable")
|
||||
conf.Hostname, err = os.Hostname()
|
||||
if err != nil {
|
||||
logger.L.Errorf("Failed to get hostname, using a default value: %s", err.Error())
|
||||
conf.Hostname = "default"
|
||||
}
|
||||
}
|
||||
|
||||
logger.L.Debug("Initializing notification bot")
|
||||
notifBot := bot.New(mainCtx, conf)
|
||||
|
||||
|
|
Loading…
Reference in a new issue