user,group,newsletter: strip query params when parsing links

This commit is contained in:
Tulir Asokan
2026-05-25 15:31:19 +03:00
parent 8d3700152a
commit 7c107215fa
3 changed files with 28 additions and 16 deletions
+8 -6
View File
@@ -455,10 +455,11 @@ func (cli *Client) JoinGroupWithInvite(ctx context.Context, jid, inviter types.J
// GetGroupInfoFromLink resolves the given invite link and asks the WhatsApp servers for info about the group.
// This will not cause the user to join the group.
func (cli *Client) GetGroupInfoFromLink(ctx context.Context, code string) (*types.GroupInfo, error) {
code = strings.TrimPrefix(code, InviteLinkPrefix)
resp, err := cli.sendGroupIQ(ctx, iqGet, types.GroupServerJID, waBinary.Node{
Tag: "invite",
Attrs: waBinary.Attrs{"code": code},
Tag: "invite",
Attrs: waBinary.Attrs{
"code": stripURLPrefix(code, InviteLinkPrefix),
},
})
if errors.Is(err, ErrIQGone) {
return nil, wrapIQError(ErrInviteLinkRevoked, err)
@@ -476,10 +477,11 @@ func (cli *Client) GetGroupInfoFromLink(ctx context.Context, code string) (*type
// JoinGroupWithLink joins the group using the given invite link.
func (cli *Client) JoinGroupWithLink(ctx context.Context, code string) (types.JID, error) {
code = strings.TrimPrefix(code, InviteLinkPrefix)
resp, err := cli.sendGroupIQ(ctx, iqSet, types.GroupServerJID, waBinary.Node{
Tag: "invite",
Attrs: waBinary.Attrs{"code": code},
Tag: "invite",
Attrs: waBinary.Attrs{
"code": stripURLPrefix(code, InviteLinkPrefix),
},
})
if errors.Is(err, ErrIQGone) {
return types.EmptyJID, wrapIQError(ErrInviteLinkRevoked, err)
+1 -2
View File
@@ -11,7 +11,6 @@ import (
"encoding/json"
"fmt"
"log"
"strings"
"time"
"github.com/beeper/argo-go/codec"
@@ -278,7 +277,7 @@ func (cli *Client) GetNewsletterInfo(ctx context.Context, jid types.JID) (*types
// Note that the ViewerMeta field of the returned NewsletterMetadata will be nil.
func (cli *Client) GetNewsletterInfoWithInvite(ctx context.Context, key string) (*types.NewsletterMetadata, error) {
return cli.getNewsletterInfo(ctx, map[string]any{
"key": strings.TrimPrefix(key, NewsletterLinkPrefix),
"key": stripURLPrefix(key, NewsletterLinkPrefix),
"type": types.NewsletterKeyTypeInvite,
}, false)
}
+19 -8
View File
@@ -32,15 +32,29 @@ const (
NewsletterLinkPrefix = "https://whatsapp.com/channel/"
)
func stripQuery(link string) string {
if idx := strings.Index(link, "?"); idx > 0 {
return link[:idx]
}
return link
}
func stripURLPrefix(link string, prefixes ...string) string {
for _, prefix := range prefixes {
unprefixed, ok := strings.CutPrefix(link, prefix)
if ok {
return stripQuery(unprefixed)
}
}
return link
}
// ResolveBusinessMessageLink resolves a business message short link and returns the target JID, business name and
// text to prefill in the input field (if any).
//
// The links look like https://wa.me/message/<code> or https://api.whatsapp.com/message/<code>. You can either provide
// the full link, or just the <code> part.
func (cli *Client) ResolveBusinessMessageLink(ctx context.Context, code string) (*types.BusinessMessageLinkTarget, error) {
code = strings.TrimPrefix(code, BusinessMessageLinkPrefix)
code = strings.TrimPrefix(code, BusinessMessageLinkDirectPrefix)
resp, err := cli.sendIQ(ctx, infoQuery{
Namespace: "w:qr",
Type: iqGet,
@@ -48,7 +62,7 @@ func (cli *Client) ResolveBusinessMessageLink(ctx context.Context, code string)
Content: []waBinary.Node{{
Tag: "qr",
Attrs: waBinary.Attrs{
"code": code,
"code": stripURLPrefix(code, BusinessMessageLinkPrefix, BusinessMessageLinkDirectPrefix),
},
}},
})
@@ -85,16 +99,13 @@ func (cli *Client) ResolveBusinessMessageLink(ctx context.Context, code string)
// The links look like https://wa.me/qr/<code> or https://api.whatsapp.com/qr/<code>. You can either provide
// the full link, or just the <code> part.
func (cli *Client) ResolveContactQRLink(ctx context.Context, code string) (*types.ContactQRLinkTarget, error) {
code = strings.TrimPrefix(code, ContactQRLinkPrefix)
code = strings.TrimPrefix(code, ContactQRLinkDirectPrefix)
resp, err := cli.sendIQ(ctx, infoQuery{
Namespace: "w:qr",
Type: iqGet,
Content: []waBinary.Node{{
Tag: "qr",
Attrs: waBinary.Attrs{
"code": code,
"code": stripURLPrefix(code, ContactQRLinkPrefix, ContactQRLinkDirectPrefix),
},
}},
})