Skip to content

Commit 922b318

Browse files
ernadoclaude
andcommitted
feat(location): add Edit/StopMessageLiveLocation
Edit a live location message via messages.editMessage with an inputMediaGeoLive payload (heading, proximity radius, accuracy, markup), and stop one early with stopped=true. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent f293a25 commit 922b318

1 file changed

Lines changed: 101 additions & 0 deletions

File tree

live_location.go

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package botapi
2+
3+
import (
4+
"context"
5+
6+
"github.com/gotd/td/tg"
7+
)
8+
9+
// LiveLocationOption configures a live-location edit.
10+
type LiveLocationOption func(*liveLocationConfig)
11+
12+
type liveLocationConfig struct {
13+
heading int
14+
proximityAlertRadius int
15+
accuracy float64
16+
markup ReplyMarkup
17+
}
18+
19+
// WithHeading sets the direction in which the user is moving, 1-360 degrees.
20+
func WithHeading(degrees int) LiveLocationOption {
21+
return func(c *liveLocationConfig) { c.heading = degrees }
22+
}
23+
24+
// WithProximityAlertRadius sets the maximum distance, in meters, for proximity
25+
// alerts about another chat member.
26+
func WithProximityAlertRadius(meters int) LiveLocationOption {
27+
return func(c *liveLocationConfig) { c.proximityAlertRadius = meters }
28+
}
29+
30+
// WithHorizontalAccuracy sets the radius of uncertainty for the location, in
31+
// meters (0-1500).
32+
func WithHorizontalAccuracy(meters float64) LiveLocationOption {
33+
return func(c *liveLocationConfig) { c.accuracy = meters }
34+
}
35+
36+
// WithLiveLocationMarkup attaches or replaces the inline keyboard on the edited
37+
// message.
38+
func WithLiveLocationMarkup(markup ReplyMarkup) LiveLocationOption {
39+
return func(c *liveLocationConfig) { c.markup = markup }
40+
}
41+
42+
// EditMessageLiveLocation edits a live location message, moving the point to the
43+
// given coordinates.
44+
func (b *Bot) EditMessageLiveLocation(
45+
ctx context.Context, chat ChatID, messageID int, latitude, longitude float64, opts ...LiveLocationOption,
46+
) (*Message, error) {
47+
var cfg liveLocationConfig
48+
for _, o := range opts {
49+
o(&cfg)
50+
}
51+
52+
media := &tg.InputMediaGeoLive{
53+
GeoPoint: &tg.InputGeoPoint{
54+
Lat: latitude,
55+
Long: longitude,
56+
},
57+
}
58+
if cfg.accuracy > 0 {
59+
media.GeoPoint.(*tg.InputGeoPoint).AccuracyRadius = int(cfg.accuracy)
60+
}
61+
if cfg.heading > 0 {
62+
media.Heading = cfg.heading
63+
}
64+
if cfg.proximityAlertRadius > 0 {
65+
media.ProximityNotificationRadius = cfg.proximityAlertRadius
66+
}
67+
return b.editLiveLocation(ctx, chat, messageID, media, cfg.markup)
68+
}
69+
70+
// StopMessageLiveLocation stops updating a live location message before its
71+
// live period expires.
72+
func (b *Bot) StopMessageLiveLocation(ctx context.Context, chat ChatID, messageID int, markup ReplyMarkup) (*Message, error) {
73+
media := &tg.InputMediaGeoLive{
74+
Stopped: true,
75+
GeoPoint: &tg.InputGeoPointEmpty{},
76+
}
77+
return b.editLiveLocation(ctx, chat, messageID, media, markup)
78+
}
79+
80+
// editLiveLocation issues the editMessage with a geo-live media payload.
81+
func (b *Bot) editLiveLocation(
82+
ctx context.Context, chat ChatID, messageID int, media tg.InputMediaClass, markup ReplyMarkup,
83+
) (*Message, error) {
84+
peer, err := b.resolveInputPeer(ctx, chat)
85+
if err != nil {
86+
return nil, err
87+
}
88+
89+
req := &tg.MessagesEditMessageRequest{Peer: peer, ID: messageID}
90+
req.SetMedia(media)
91+
if markup != nil {
92+
mkp, err := replyMarkupToTg(markup)
93+
if err != nil {
94+
return nil, err
95+
}
96+
req.SetReplyMarkup(mkp)
97+
}
98+
99+
resp, err := b.raw.MessagesEditMessage(ctx, req)
100+
return b.sentMessage(ctx, peer, resp, err)
101+
}

0 commit comments

Comments
 (0)