You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 11:36:14