Allow asking for the current public IP
All checks were successful
continuous-integration/drone/push Build is passing

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.
This commit is contained in:
Melora Hugues 2023-01-29 18:50:43 +01:00
parent 4b6e0b116c
commit 2abc08d582
4 changed files with 54 additions and 3 deletions

View file

@ -9,6 +9,8 @@ import (
"git.faercol.me/faercol/public-ip-tracker/tracker/config" "git.faercol.me/faercol/public-ip-tracker/tracker/config"
"git.faercol.me/faercol/public-ip-tracker/tracker/ip" "git.faercol.me/faercol/public-ip-tracker/tracker/ip"
"github.com/ahugues/go-telegram-api/bot" "github.com/ahugues/go-telegram-api/bot"
"github.com/ahugues/go-telegram-api/notifier"
"github.com/ahugues/go-telegram-api/structs"
) )
type Notifier struct { type Notifier struct {
@ -16,6 +18,7 @@ type Notifier struct {
cancel context.CancelFunc cancel context.CancelFunc
tgBot bot.Bot tgBot bot.Bot
tgChatID int64 tgChatID int64
tgWatcher notifier.EventNotifier
ipGetter ip.IPGetter ipGetter ip.IPGetter
timeGetter func() time.Time timeGetter func() time.Time
currentIP net.IP currentIP net.IP
@ -49,7 +52,35 @@ func (n *Notifier) sendUpdatedIPMsg() error {
return nil 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() { func (n *Notifier) Run() {
go n.watchTG()
for { for {
select { select {
case <-time.After(n.frequency): case <-time.After(n.frequency):
@ -93,5 +124,6 @@ func New(ctx context.Context, config *config.Config) *Notifier {
errChan: make(chan error, 10), errChan: make(chan error, 10),
exitChan: make(chan struct{}, 1), exitChan: make(chan struct{}, 1),
frequency: config.PollingFrequency, frequency: config.PollingFrequency,
tgWatcher: notifier.New(config.Telegram.Token),
} }
} }

View file

@ -9,6 +9,7 @@ import (
iptest "git.faercol.me/faercol/public-ip-tracker/tracker/ip/test" iptest "git.faercol.me/faercol/public-ip-tracker/tracker/ip/test"
"github.com/ahugues/go-telegram-api/structs" "github.com/ahugues/go-telegram-api/structs"
"github.com/google/uuid"
) )
const expectedChatID = 42 const expectedChatID = 42
@ -31,6 +32,17 @@ func (mb *mockTGBot) SendMessage(ctx context.Context, chatID int64, content stri
return mb.SendMessageFunc(ctx, chatID, content) 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) { func TestInit(t *testing.T) {
t.Parallel() 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) }, timeGetter: func() time.Time { return time.Date(2023, 1, 28, 14, 17, 12, 0, time.UTC) },
ipGetter: &ipGetter, ipGetter: &ipGetter,
frequency: 1 * time.Minute, frequency: 1 * time.Minute,
tgWatcher: &mockTGNotifier{},
} }
if err := bot.SendInitMessage(); err != nil { if err := bot.SendInitMessage(); err != nil {
@ -105,6 +118,7 @@ func TestUpdateIP(t *testing.T) {
exitChan: make(chan struct{}, 1), exitChan: make(chan struct{}, 1),
errChan: make(chan error, 5), errChan: make(chan error, 5),
ipGetter: &ipGetter, ipGetter: &ipGetter,
tgWatcher: &mockTGNotifier{},
frequency: 500 * time.Millisecond, frequency: 500 * time.Millisecond,
} }
@ -161,6 +175,7 @@ func TestUpdateIPNoChange(t *testing.T) {
exitChan: make(chan struct{}, 1), exitChan: make(chan struct{}, 1),
errChan: make(chan error, 5), errChan: make(chan error, 5),
ipGetter: &ipGetter, ipGetter: &ipGetter,
tgWatcher: &mockTGNotifier{},
frequency: 100 * time.Millisecond, frequency: 100 * time.Millisecond,
} }

View file

@ -2,4 +2,7 @@ module git.faercol.me/faercol/public-ip-tracker/tracker
go 1.16 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
)

View file

@ -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-20230129174520-b466e4321512 h1:wYRUqplA7L8W9t6/k2ZYWxVVx4zYoW/1tpdogoJ/RFY=
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/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/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= 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= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=