如何通过whatsmeow Golang包获取发送者的实时位置坐标?
使用whatsmeow包获取实时位置坐标
我正在使用Golang的whatsmeow包,运行示例程序无问题,但想了解是否可从消息中获取发送者的实时位置坐标?
发送者已向接收者发送实时位置,接收端通过whatsmeow包可看到MediaType为livelocation,以下是我的日志:
05:57:27.711 [Client/Recv DEBUG] <message from="6281312000300@s.whatsapp.net" id="974EEAED36D9D7B9354CF31D78BBE2A8" notify="Rolly Maulana Awangga" t="1663801047" type="media"><enc duration="3599" mediatype="livelocation" type="pkmsg" v="2"><!-- 3415 bytes --></enc></message> 05:57:27.712 [Client DEBUG] Decrypting 1 messages from 6281312000300@s.whatsapp.net 05:57:27.712 [Client/Send DEBUG] <ack class="message" id="974EEAED36D9D7B9354CF31D78BBE2A8" to="6281312000300@s.whatsapp.net"/> GetConversation : Sender : 6281312000300@s.whatsapp.net Sender Number : 6281312000300 IsGroup : false MessageSource : {6281312000300@s.whatsapp.net 6281312000300@s.whatsapp.net false false } ID : 974EEAED36D9D7B9354CF31D78BBE2A8 PushName : Rolly Maulana Awangga BroadcastListOwner : Category : Chat : 6281312000300@s.whatsapp.net DeviceSentMeta : <nil> IsFromMe : false MediaType : livelocation Multicast : false Info.Chat.Server : s.whatsapp.net 05:57:27.773 [Client/Send DEBUG] <receipt id="974EEAED36D9D7B9354CF31D78BBE2A8" to="6281312000300@s.whatsapp.net" type="inactive"/>
我的代码如下:
package main import ( "context" "fmt" "os" "os/signal" "syscall" _ "github.com/mattn/go-sqlite3" "go.mau.fi/whatsmeow" "go.mau.fi/whatsmeow/store/sqlstore" "go.mau.fi/whatsmeow/types/events" waLog "go.mau.fi/whatsmeow/util/log" ) var client *whatsmeow.Client func eventHandler(evt interface{}) { switch v := evt.(type) { case *events.Message: if !v.Info.IsFromMe { fmt.Println("GetConversation : ", v.Message.GetConversation()) fmt.Println("Sender : ", v.Info.Sender) fmt.Println("Sender Number : ", v.Info.Sender.User) fmt.Println("IsGroup : ", v.Info.IsGroup) fmt.Println("MessageSource : ", v.Info.MessageSource) fmt.Println("ID : ", v.Info.ID) fmt.Println("PushName : ", v.Info.PushName) fmt.Println("BroadcastListOwner : ", v.Info.BroadcastListOwner) fmt.Println("Category : ", v.Info.Category) fmt.Println("Chat : ", v.Info.Chat) fmt.Println("DeviceSentMeta : ", v.Info.DeviceSentMeta) fmt.Println("IsFromMe : ", v.Info.IsFromMe) fmt.Println("MediaType : ", v.Info.MediaType) fmt.Println("Multicast : ", v.Info.Multicast) fmt.Println("Info.Chat.Server : ", v.Info.Chat.Server) if v.Info.Chat.Server == "g.us" { groupInfo, err := client.GetGroupInfo(v.Info.Chat) fmt.Println("error GetGroupInfo : ", err) fmt.Println("Nama Group : ", groupInfo.GroupName.Name) } } } } func main() { dbLog := waLog.Stdout("Database", "DEBUG", true) // Make sure you add appropriate DB connector imports, e.g. github.com/mattn/go-sqlite3 for SQLite container, err := sqlstore.New("sqlite3", "file:gowa.db?_foreign_keys=on", dbLog) if err != nil { panic(err) } // If you want multiple sessions, remember their JIDs and use .GetDevice(jid) or .GetAllDevices() instead. deviceStore, err := container.GetFirstDevice() if err != nil { panic(err) } clientLog := waLog.Stdout("Client", "DEBUG", true) client = whatsmeow.NewClient(deviceStore, clientLog) client.AddEventHandler(eventHandler) if client.Store.ID == nil { // No ID stored, new login qrChan, _ := client.GetQRChannel(context.Background()) err = client.Connect() if err != nil { panic(err) } for evt := range qrChan { if evt.Event == "code" { // Render the QR code here // e.g. qrterminal.GenerateHalfBlock(evt.Code, qrterminal.L, os.Stdout) // or just manually `echo 2@... | qrencode -t ansiutf8` in a terminal fmt.Println("QR code:", evt.Code) } else { fmt.Println("Login event:", evt.Event) } } } else { // Already logged in, just connect err = client.Connect() if err != nil { panic(err) } } // Listen to Ctrl+C (you can also do something else that prevents the program from exiting) c := make(chan os.Signal) signal.Notify(c, os.Interrupt, syscall.SIGTERM) <-c client.Disconnect() }
解决方案
可以获取实时位置的坐标,只需在事件处理函数中对livelocation类型的消息做额外处理,从消息对象中提取LiveLocationMessage结构体即可拿到坐标信息。
修改后的eventHandler函数如下:
func eventHandler(evt interface{}) { switch v := evt.(type) { case *events.Message: if !v.Info.IsFromMe { fmt.Println("GetConversation : ", v.Message.GetConversation()) fmt.Println("Sender : ", v.Info.Sender) fmt.Println("Sender Number : ", v.Info.Sender.User) fmt.Println("IsGroup : ", v.Info.IsGroup) fmt.Println("MessageSource : ", v.Info.MessageSource) fmt.Println("ID : ", v.Info.ID) fmt.Println("PushName : ", v.Info.PushName) fmt.Println("BroadcastListOwner : ", v.Info.BroadcastListOwner) fmt.Println("Category : ", v.Info.Category) fmt.Println("Chat : ", v.Info.Chat) fmt.Println("DeviceSentMeta : ", v.Info.DeviceSentMeta) fmt.Println("IsFromMe : ", v.Info.IsFromMe) fmt.Println("MediaType : ", v.Info.MediaType) fmt.Println("Multicast : ", v.Info.Multicast) fmt.Println("Info.Chat.Server : ", v.Info.Chat.Server) // 新增:处理实时位置消息 if v.Info.MediaType == "livelocation" { liveLoc := v.Message.GetLiveLocation() if liveLoc != nil { fmt.Printf("实时位置 - 纬度:%f,经度:%f,精度:%f\n", liveLoc.Latitude, liveLoc.Longitude, liveLoc.Accuracy) fmt.Printf("更新时间:%d,过期时间:%d\n", liveLoc.Timestamp, liveLoc.Expiration) } } if v.Info.Chat.Server == "g.us" { groupInfo, err := client.GetGroupInfo(v.Info.Chat) fmt.Println("error GetGroupInfo : ", err) fmt.Println("Nama Group : ", groupInfo.GroupName.Name) } } } }
说明
- 当发送者更新实时位置时,whatsmeow会持续收到包含最新坐标的消息,每次触发事件处理函数都能获取到当前最新的位置数据。
LiveLocationMessage结构体还包含精度、更新时间、过期时间等额外信息,可根据需求提取使用。
内容的提问来源于stack exchange,提问作者Rolly Maulana Awangga
相关产品推荐
相关产品推荐

