From 2abc08d582ff55afb54668fde14b9edc5df083e4 Mon Sep 17 00:00:00 2001 From: Melora Hugues Date: Sun, 29 Jan 2023 18:50:43 +0100 Subject: [PATCH] Allow asking for the current public IP Ref #5 This commit adds the /getIP telegram command that allows asking for the current public IP that the bot has stored. As it is just a working version and the telegram API is not yet complete, this command is not yet really tested. I need to provide a more stable version of my Telegram API beforehand because as of now it's just a mess really, but this will do for now. --- tracker/bot/bot.go | 32 ++++++++++++++++++++++++++++++++ tracker/bot/bot_test.go | 15 +++++++++++++++ tracker/go.mod | 5 ++++- tracker/go.sum | 5 +++-- 4 files changed, 54 insertions(+), 3 deletions(-) diff --git a/tracker/bot/bot.go b/tracker/bot/bot.go index 52aba5b..d7a58ba 100644 --- a/tracker/bot/bot.go +++ b/tracker/bot/bot.go @@ -9,6 +9,8 @@ import ( "git.faercol.me/faercol/public-ip-tracker/tracker/config" "git.faercol.me/faercol/public-ip-tracker/tracker/ip" "github.com/ahugues/go-telegram-api/bot" + "github.com/ahugues/go-telegram-api/notifier" + "github.com/ahugues/go-telegram-api/structs" ) type Notifier struct { @@ -16,6 +18,7 @@ type Notifier struct { cancel context.CancelFunc tgBot bot.Bot tgChatID int64 + tgWatcher notifier.EventNotifier ipGetter ip.IPGetter timeGetter func() time.Time currentIP net.IP @@ -49,7 +52,35 @@ func (n *Notifier) sendUpdatedIPMsg() error { return nil } +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 { + return fmt.Errorf("failed to send message: %w", err) + } + return nil +} + +func (n *Notifier) watchTG() { + id, updateChan := n.tgWatcher.Subscribe([]structs.UpdateType{structs.UpdateMessage}) + go n.tgWatcher.Run(n.ctx) + + for { + select { + case update := <-updateChan: + if update.Message.Text == "/getIP" { + if err := n.sendCurrentIP(); err != nil { + n.errChan <- fmt.Errorf("failed to reply current public IP: %w", err) + } + } + case <-n.ctx.Done(): + n.tgWatcher.Unsubscribe(id) + return + } + } +} + func (n *Notifier) Run() { + go n.watchTG() for { select { case <-time.After(n.frequency): @@ -93,5 +124,6 @@ func New(ctx context.Context, config *config.Config) *Notifier { errChan: make(chan error, 10), exitChan: make(chan struct{}, 1), frequency: config.PollingFrequency, + tgWatcher: notifier.New(config.Telegram.Token), } } diff --git a/tracker/bot/bot_test.go b/tracker/bot/bot_test.go index d20ecbf..a21b1e7 100644 --- a/tracker/bot/bot_test.go +++ b/tracker/bot/bot_test.go @@ -9,6 +9,7 @@ import ( iptest "git.faercol.me/faercol/public-ip-tracker/tracker/ip/test" "github.com/ahugues/go-telegram-api/structs" + "github.com/google/uuid" ) const expectedChatID = 42 @@ -31,6 +32,17 @@ func (mb *mockTGBot) SendMessage(ctx context.Context, chatID int64, content stri return mb.SendMessageFunc(ctx, chatID, content) } +// Need to mock the notifier here too, but will do later on, I need to improve my lib in the future +type mockTGNotifier struct { +} + +func (mn *mockTGNotifier) Run(ctx context.Context) {} +func (mn *mockTGNotifier) Subscribe(eventTypes []structs.UpdateType) (uuid.UUID, <-chan structs.Update) { + return uuid.New(), make(chan structs.Update) +} +func (mn *mockTGNotifier) Unsubscribe(id uuid.UUID) {} +func (mn *mockTGNotifier) ErrChan() <-chan error { return nil } + func TestInit(t *testing.T) { t.Parallel() @@ -62,6 +74,7 @@ func TestInit(t *testing.T) { timeGetter: func() time.Time { return time.Date(2023, 1, 28, 14, 17, 12, 0, time.UTC) }, ipGetter: &ipGetter, frequency: 1 * time.Minute, + tgWatcher: &mockTGNotifier{}, } if err := bot.SendInitMessage(); err != nil { @@ -105,6 +118,7 @@ func TestUpdateIP(t *testing.T) { exitChan: make(chan struct{}, 1), errChan: make(chan error, 5), ipGetter: &ipGetter, + tgWatcher: &mockTGNotifier{}, frequency: 500 * time.Millisecond, } @@ -161,6 +175,7 @@ func TestUpdateIPNoChange(t *testing.T) { exitChan: make(chan struct{}, 1), errChan: make(chan error, 5), ipGetter: &ipGetter, + tgWatcher: &mockTGNotifier{}, frequency: 100 * time.Millisecond, } diff --git a/tracker/go.mod b/tracker/go.mod index ccc8544..c1461ac 100644 --- a/tracker/go.mod +++ b/tracker/go.mod @@ -2,4 +2,7 @@ module git.faercol.me/faercol/public-ip-tracker/tracker go 1.16 -require github.com/ahugues/go-telegram-api v0.0.0-20230128131122-4d5782beddd0 +require ( + github.com/ahugues/go-telegram-api v0.0.0-20230129174520-b466e4321512 + github.com/google/uuid v1.3.0 +) diff --git a/tracker/go.sum b/tracker/go.sum index 73c51b5..180a0aa 100644 --- a/tracker/go.sum +++ b/tracker/go.sum @@ -1,5 +1,6 @@ -github.com/ahugues/go-telegram-api v0.0.0-20230128131122-4d5782beddd0 h1:1R472WmBuKK9Bvt4+rlqj01z1MwlVic3Xzgjvql3PXA= -github.com/ahugues/go-telegram-api v0.0.0-20230128131122-4d5782beddd0/go.mod h1:8I/JWxd9GYM7dHOgGmkRI3Ei1u+nGvzeR2knIMmFw7E= +github.com/ahugues/go-telegram-api v0.0.0-20230129174520-b466e4321512 h1:wYRUqplA7L8W9t6/k2ZYWxVVx4zYoW/1tpdogoJ/RFY= +github.com/ahugues/go-telegram-api v0.0.0-20230129174520-b466e4321512/go.mod h1:8I/JWxd9GYM7dHOgGmkRI3Ei1u+nGvzeR2knIMmFw7E= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=