mirror of
https://github.com/mautrix/whatsapp.git
synced 2025-03-14 14:15:38 +00:00
v2: fix things
This commit is contained in:
parent
91fbf6f609
commit
3c53ea5ed1
7 changed files with 136 additions and 92 deletions
|
@ -8,7 +8,7 @@ INSERT INTO user_login (bridge_id, user_mxid, id, remote_name, space_room, metad
|
|||
SELECT
|
||||
'', -- bridge_id
|
||||
mxid, -- user_mxid
|
||||
username || '@s.whatsapp.net', -- id
|
||||
username, -- id
|
||||
'+' || username, -- remote_name
|
||||
space_room,
|
||||
-- only: postgres
|
||||
|
|
|
@ -2,16 +2,13 @@ package connector
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
"go.mau.fi/whatsmeow"
|
||||
"go.mau.fi/whatsmeow/store"
|
||||
"go.mau.fi/whatsmeow/types"
|
||||
"maunium.net/go/mautrix"
|
||||
waLog "go.mau.fi/whatsmeow/util/log"
|
||||
"maunium.net/go/mautrix/bridge/status"
|
||||
"maunium.net/go/mautrix/bridgev2"
|
||||
"maunium.net/go/mautrix/bridgev2/networkid"
|
||||
|
@ -19,57 +16,35 @@ import (
|
|||
"maunium.net/go/mautrix-whatsapp/pkg/waid"
|
||||
)
|
||||
|
||||
const (
|
||||
WANotLoggedIn status.BridgeStateErrorCode = "wa-not-logged-in"
|
||||
)
|
||||
func (wa *WhatsAppConnector) LoadUserLogin(_ context.Context, login *bridgev2.UserLogin) error {
|
||||
loginMetadata := login.Metadata.(*UserLoginMetadata)
|
||||
|
||||
type respGetProxy struct {
|
||||
ProxyURL string `json:"proxy_url"`
|
||||
}
|
||||
jid := waid.ParseUserLoginID(login.ID, loginMetadata.WADeviceID)
|
||||
|
||||
func (wa *WhatsAppConnector) getProxy(reason string) (string, error) {
|
||||
if wa.Config.GetProxyURL == "" {
|
||||
return wa.Config.Proxy, nil
|
||||
}
|
||||
parsed, err := url.Parse(wa.Config.GetProxyURL)
|
||||
device, err := wa.DeviceStore.GetDevice(jid)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to parse address: %w", err)
|
||||
return err
|
||||
}
|
||||
q := parsed.Query()
|
||||
q.Set("reason", reason)
|
||||
parsed.RawQuery = q.Encode()
|
||||
req, err := http.NewRequest(http.MethodGet, parsed.String(), nil)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to prepare request: %w", err)
|
||||
}
|
||||
req.Header.Set("User-Agent", mautrix.DefaultUserAgent)
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to send request: %w", err)
|
||||
} else if resp.StatusCode >= 300 || resp.StatusCode < 200 {
|
||||
return "", fmt.Errorf("unexpected status code %d", resp.StatusCode)
|
||||
}
|
||||
var respData respGetProxy
|
||||
err = json.NewDecoder(resp.Body).Decode(&respData)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to decode response: %w", err)
|
||||
}
|
||||
return respData.ProxyURL, nil
|
||||
}
|
||||
|
||||
func (wa *WhatsAppConnector) updateProxy(client *whatsmeow.Client, isLogin bool) error {
|
||||
if wa.Config.ProxyOnlyLogin && !isLogin {
|
||||
return nil
|
||||
w := &WhatsAppClient{
|
||||
Main: wa,
|
||||
UserLogin: login,
|
||||
Device: device,
|
||||
JID: jid,
|
||||
}
|
||||
reason := "connect"
|
||||
if isLogin {
|
||||
reason = "login"
|
||||
}
|
||||
if proxy, err := wa.getProxy(reason); err != nil {
|
||||
return fmt.Errorf("failed to get proxy address: %w", err)
|
||||
} else if err = client.SetProxyAddress(proxy); err != nil {
|
||||
return fmt.Errorf("failed to set proxy address: %w", err)
|
||||
|
||||
if device != nil {
|
||||
log := w.UserLogin.Log.With().Str("component", "whatsmeow").Logger()
|
||||
w.Client = whatsmeow.NewClient(w.Device, waLog.Zerolog(log))
|
||||
w.Client.AddEventHandler(w.handleWAEvent)
|
||||
w.Client.AutomaticMessageRerequestFromPhone = true
|
||||
w.Client.SetForceActiveDeliveryReceipts(wa.Config.ForceActiveDeliveryReceipts)
|
||||
} else {
|
||||
w.UserLogin.Log.Debug().Stringer("jid", jid).Msg("No device found for user in whatsmeow store")
|
||||
}
|
||||
|
||||
login.Client = w
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -81,16 +56,7 @@ type WhatsAppClient struct {
|
|||
JID types.JID
|
||||
}
|
||||
|
||||
var (
|
||||
_ bridgev2.NetworkAPI = (*WhatsAppClient)(nil)
|
||||
//_ bridgev2.TypingHandlingNetworkAPI = (*WhatsAppClient)(nil)
|
||||
//_ bridgev2.IdentifierResolvingNetworkAPI = (*WhatsAppClient)(nil)
|
||||
//_ bridgev2.GroupCreatingNetworkAPI = (*WhatsAppClient)(nil)
|
||||
//_ bridgev2.ContactListingNetworkAPI = (*WhatsAppClient)(nil)
|
||||
//_ bridgev2.RoomNameHandlingNetworkAPI = (*WhatsAppClient)(nil)
|
||||
//_ bridgev2.RoomAvatarHandlingNetworkAPI = (*WhatsAppClient)(nil)
|
||||
//_ bridgev2.RoomTopicHandlingNetworkAPI = (*WhatsAppClient)(nil)
|
||||
)
|
||||
var _ bridgev2.NetworkAPI = (*WhatsAppClient)(nil)
|
||||
|
||||
var pushCfg = &bridgev2.PushConfig{
|
||||
Web: &bridgev2.WebPushConfig{},
|
||||
|
@ -134,7 +100,9 @@ func (wa *WhatsAppClient) Connect(ctx context.Context) error {
|
|||
}
|
||||
|
||||
func (wa *WhatsAppClient) Disconnect() {
|
||||
wa.Client.Disconnect()
|
||||
if wa.Client != nil {
|
||||
wa.Client.Disconnect()
|
||||
}
|
||||
}
|
||||
|
||||
func (wa *WhatsAppClient) LogoutRemote(ctx context.Context) {
|
||||
|
|
|
@ -107,6 +107,8 @@ func upgradeConfig(helper up.Helper) {
|
|||
type DisplaynameParams struct {
|
||||
types.ContactInfo
|
||||
Phone string
|
||||
// Deprecated form of Phone
|
||||
JID string
|
||||
}
|
||||
|
||||
func (c *Config) FormatDisplayname(jid types.JID, contact types.ContactInfo) string {
|
||||
|
@ -114,6 +116,7 @@ func (c *Config) FormatDisplayname(jid types.JID, contact types.ContactInfo) str
|
|||
err := c.displaynameTemplate.Execute(&nameBuf, &DisplaynameParams{
|
||||
ContactInfo: contact,
|
||||
Phone: "+" + jid.User,
|
||||
JID: "+" + jid.User,
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
|
|
@ -14,7 +14,6 @@ import (
|
|||
|
||||
"maunium.net/go/mautrix-whatsapp/pkg/connector/wadb"
|
||||
"maunium.net/go/mautrix-whatsapp/pkg/msgconv"
|
||||
"maunium.net/go/mautrix-whatsapp/pkg/waid"
|
||||
)
|
||||
|
||||
type WhatsAppConnector struct {
|
||||
|
@ -91,34 +90,3 @@ func (wa *WhatsAppConnector) Start(ctx context.Context) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (wa *WhatsAppConnector) LoadUserLogin(_ context.Context, login *bridgev2.UserLogin) error {
|
||||
loginMetadata := login.Metadata.(*UserLoginMetadata)
|
||||
|
||||
jid := waid.ParseUserLoginID(login.ID, loginMetadata.WADeviceID)
|
||||
|
||||
device, err := wa.DeviceStore.GetDevice(jid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
w := &WhatsAppClient{
|
||||
Main: wa,
|
||||
UserLogin: login,
|
||||
Device: device,
|
||||
JID: jid,
|
||||
}
|
||||
|
||||
log := w.UserLogin.Log.With().Str("component", "whatsmeow").Logger()
|
||||
|
||||
if device != nil {
|
||||
w.Client = whatsmeow.NewClient(w.Device, waLog.Zerolog(log))
|
||||
w.Client.AddEventHandler(w.handleWAEvent)
|
||||
w.Client.AutomaticMessageRerequestFromPhone = true
|
||||
w.Client.SetForceActiveDeliveryReceipts(wa.Config.ForceActiveDeliveryReceipts)
|
||||
}
|
||||
|
||||
login.Client = w
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"fmt"
|
||||
"time"
|
||||
|
||||
"go.mau.fi/whatsmeow/appstate"
|
||||
"go.mau.fi/whatsmeow/types"
|
||||
"go.mau.fi/whatsmeow/types/events"
|
||||
"maunium.net/go/mautrix/bridge/status"
|
||||
|
@ -15,6 +16,7 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
WANotLoggedIn status.BridgeStateErrorCode = "wa-not-logged-in"
|
||||
WALoggedOut status.BridgeStateErrorCode = "wa-logged-out"
|
||||
WAMainDeviceGone status.BridgeStateErrorCode = "wa-main-device-gone"
|
||||
WAUnknownLogout status.BridgeStateErrorCode = "wa-unknown-logout"
|
||||
|
@ -111,6 +113,42 @@ func (wa *WhatsAppClient) handleWAEvent(rawEvt any) {
|
|||
case *events.Connected:
|
||||
log.Debug().Msg("Connected to WhatsApp socket")
|
||||
wa.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateConnected})
|
||||
if len(wa.Client.Store.PushName) > 0 {
|
||||
go func() {
|
||||
err := wa.Client.SendPresence(types.PresenceUnavailable)
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Msg("Failed to send initial presence after connecting")
|
||||
}
|
||||
}()
|
||||
}
|
||||
case *events.AppStateSyncComplete:
|
||||
if len(wa.Client.Store.PushName) > 0 && evt.Name == appstate.WAPatchCriticalBlock {
|
||||
err := wa.Client.SendPresence(types.PresenceUnavailable)
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Msg("Failed to send presence after app state sync")
|
||||
}
|
||||
} else if evt.Name == appstate.WAPatchCriticalUnblockLow {
|
||||
go func() {
|
||||
// TODO resync contacts
|
||||
//err := user.ResyncContacts(false)
|
||||
//if err != nil {
|
||||
// user.zlog.Err(err).Msg("Failed to resync contacts after app state sync")
|
||||
//}
|
||||
}()
|
||||
}
|
||||
case *events.PushNameSetting:
|
||||
// Send presence available when connecting and when the pushname is changed.
|
||||
// This makes sure that outgoing messages always have the right pushname.
|
||||
err := wa.Client.SendPresence(types.PresenceUnavailable)
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Msg("Failed to send presence after push name update")
|
||||
}
|
||||
_, _, err = wa.Client.Store.Contacts.PutPushName(wa.JID.ToNonAD(), evt.Action.GetName())
|
||||
if err != nil {
|
||||
log.Err(err).Msg("Failed to update push name in store")
|
||||
}
|
||||
// TODO update own ghost info
|
||||
//go user.syncPuppet(user.JID.ToNonAD(), "push name setting")
|
||||
case *events.Disconnected:
|
||||
// Don't send the normal transient disconnect state if we're already in a different transient disconnect state.
|
||||
// TODO remove this if/when the phone offline state is moved to a sub-state of CONNECTED
|
||||
|
|
|
@ -20,6 +20,10 @@ func (wa *WhatsAppClient) makeWAPortalKey(chatJID types.JID) (key networkid.Port
|
|||
}
|
||||
|
||||
func (wa *WhatsAppClient) makeEventSender(id types.JID) bridgev2.EventSender {
|
||||
if id.Server == types.NewsletterServer {
|
||||
// Send as bot
|
||||
return bridgev2.EventSender{}
|
||||
}
|
||||
return bridgev2.EventSender{
|
||||
IsFromMe: waid.MakeUserLoginID(id) == wa.UserLogin.ID,
|
||||
Sender: waid.MakeUserID(id),
|
||||
|
|
63
pkg/connector/proxy.go
Normal file
63
pkg/connector/proxy.go
Normal file
|
@ -0,0 +1,63 @@
|
|||
package connector
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"go.mau.fi/whatsmeow"
|
||||
"maunium.net/go/mautrix"
|
||||
)
|
||||
|
||||
// TODO move proxy stuff to mautrix-go
|
||||
|
||||
type respGetProxy struct {
|
||||
ProxyURL string `json:"proxy_url"`
|
||||
}
|
||||
|
||||
func (wa *WhatsAppConnector) getProxy(reason string) (string, error) {
|
||||
if wa.Config.GetProxyURL == "" {
|
||||
return wa.Config.Proxy, nil
|
||||
}
|
||||
parsed, err := url.Parse(wa.Config.GetProxyURL)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to parse address: %w", err)
|
||||
}
|
||||
q := parsed.Query()
|
||||
q.Set("reason", reason)
|
||||
parsed.RawQuery = q.Encode()
|
||||
req, err := http.NewRequest(http.MethodGet, parsed.String(), nil)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to prepare request: %w", err)
|
||||
}
|
||||
req.Header.Set("User-Agent", mautrix.DefaultUserAgent)
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to send request: %w", err)
|
||||
} else if resp.StatusCode >= 300 || resp.StatusCode < 200 {
|
||||
return "", fmt.Errorf("unexpected status code %d", resp.StatusCode)
|
||||
}
|
||||
var respData respGetProxy
|
||||
err = json.NewDecoder(resp.Body).Decode(&respData)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to decode response: %w", err)
|
||||
}
|
||||
return respData.ProxyURL, nil
|
||||
}
|
||||
|
||||
func (wa *WhatsAppConnector) updateProxy(client *whatsmeow.Client, isLogin bool) error {
|
||||
if wa.Config.ProxyOnlyLogin && !isLogin {
|
||||
return nil
|
||||
}
|
||||
reason := "connect"
|
||||
if isLogin {
|
||||
reason = "login"
|
||||
}
|
||||
if proxy, err := wa.getProxy(reason); err != nil {
|
||||
return fmt.Errorf("failed to get proxy address: %w", err)
|
||||
} else if err = client.SetProxyAddress(proxy); err != nil {
|
||||
return fmt.Errorf("failed to set proxy address: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
Loading…
Add table
Reference in a new issue