Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ require (
github.com/mattn/go-sqlite3 v1.14.52
github.com/rs/zerolog v1.35.1
github.com/u2takey/ffmpeg-go v0.5.0
go.mau.fi/util v0.10.2-0.20260918225449-a4c0d5b86aa8
golang.org/x/crypto v0.57.0
go.mau.fi/util v0.11.0
golang.org/x/crypto v0.58.0
golang.org/x/image v0.23.0
golang.org/x/net v0.59.0
maunium.net/go/mautrix v0.31.1-0.20261012132636-34107524d2ab
golang.org/x/net v0.61.0
maunium.net/go/mautrix v0.32.0
)

require (
Expand All @@ -27,20 +27,20 @@ require (
github.com/lib/pq v1.12.3 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/petermattis/goid v0.0.0-20260820044319-269ab09b5261 // indirect
github.com/petermattis/goid v0.0.0-20260918085751-abfca077860b // indirect
github.com/rs/xid v1.6.0 // indirect
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect
github.com/tidwall/gjson v1.19.0 // indirect
github.com/tidwall/gjson v1.20.0 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
github.com/tidwall/sjson v1.2.5 // indirect
github.com/u2takey/go-utils v0.3.1 // indirect
github.com/yuin/goldmark v1.8.6 // indirect
go.mau.fi/zeroconfig v0.2.0 // indirect
golang.org/x/exp v0.0.0-20260908205506-85c1c2202aba // indirect
golang.org/x/sync v0.23.0 // indirect
golang.org/x/sys v0.48.0 // indirect
golang.org/x/text v0.42.0 // indirect
golang.org/x/exp v0.0.0-20261014143641-f0251eb4aa3e // indirect
golang.org/x/sync v0.24.0 // indirect
golang.org/x/sys v0.49.0 // indirect
golang.org/x/text v0.43.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
maunium.net/go/mauflag v1.0.0 // indirect
Expand Down
40 changes: 20 additions & 20 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/panjf2000/ants/v2 v2.4.2/go.mod h1:f6F0NZVFsGCp5A7QW/Zj/m92atWwOkY0OIhFxRNFr4A=
github.com/petermattis/goid v0.0.0-20260820044319-269ab09b5261 h1:lcWAnrqr2nNfDiArwFNHCE4787Mw2tCdVSOXCru0/0E=
github.com/petermattis/goid v0.0.0-20260820044319-269ab09b5261/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=
github.com/petermattis/goid v0.0.0-20260918085751-abfca077860b h1:OzNsuVdSWGwXvWKTtChx9ve89k4cFJ6NxYM4Aw4/f+E=
github.com/petermattis/goid v0.0.0-20260918085751-abfca077860b/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
Expand All @@ -63,8 +63,8 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
github.com/stretchr/testify v1.12.0 h1:K6Mr6jO9JICuend/5xzTM03ydSV3vdNRYAdPSukj8uI=
github.com/stretchr/testify v1.12.0/go.mod h1:bOYBZb5qJ00vPzWfIqBUZPaxK8jWiXc6d3ErP4Ca9Gw=
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/gjson v1.19.0 h1:xwxm7n691Uf3u5OFjzngavjGTh55KX5q/9w9xHW88JU=
github.com/tidwall/gjson v1.19.0/go.mod h1:V37/opeE/JbLUOfH0QTXiNez2l0RUjYUhpT4szFQAfc=
github.com/tidwall/gjson v1.20.0 h1:+agJ3rEzKcCXKDKo0ml26UROcpcAlnZyjq+TjbY5Fto=
github.com/tidwall/gjson v1.20.0/go.mod h1:V37/opeE/JbLUOfH0QTXiNez2l0RUjYUhpT4szFQAfc=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
Expand All @@ -78,38 +78,38 @@ github.com/u2takey/go-utils v0.3.1 h1:TaQTgmEZZeDHQFYfd+AdUT1cT4QJgJn/XVPELhHw4y
github.com/u2takey/go-utils v0.3.1/go.mod h1:6e+v5vEZ/6gu12w/DC2ixZdZtCrNokVxD0JUklcqdCs=
github.com/yuin/goldmark v1.8.6 h1:d0VcaP1sx9GkFVkoW+KtggpGi2KZ965i14b0+bDQST4=
github.com/yuin/goldmark v1.8.6/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
go.mau.fi/util v0.10.2-0.20260918225449-a4c0d5b86aa8 h1:PxaO4u8ti7Eef1WKPAINXrcUkqKshE+n239UtbbJOn4=
go.mau.fi/util v0.10.2-0.20260918225449-a4c0d5b86aa8/go.mod h1:40TDo7/ekSeOjgr8KAmX31Yf4zrOF94j83WQB+u5ZPc=
go.mau.fi/util v0.11.0 h1:JNEpkVRxfTdJUC0DIGKiRlLKzl4G/qLX/eVzoP7QuwY=
go.mau.fi/util v0.11.0/go.mod h1:04AEFVsc4zNdIkDC1gkdqbg/nZFolHY50pyXh2DSy7s=
go.mau.fi/zeroconfig v0.2.0 h1:e/OGEERqVRRKlgaro7E6bh8xXiKFSXB3eNNIud7FUjU=
go.mau.fi/zeroconfig v0.2.0/go.mod h1:J0Vn0prHNOm493oZoQ84kq83ZaNCYZnq+noI1b1eN8w=
gocv.io/x/gocv v0.25.0/go.mod h1:Rar2PS6DV+T4FL+PM535EImD/h13hGVaHhnCu1xarBs=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M=
golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA=
golang.org/x/exp v0.0.0-20260908205506-85c1c2202aba h1:Ck8QetSgk912qxWLMCKxd0in+aiyBQyDSMae6e/xmpU=
golang.org/x/exp v0.0.0-20260908205506-85c1c2202aba/go.mod h1:50RgIsmK7OwqzTTeqcSXQW8SswW0o8fRcDxmqGluJ8E=
golang.org/x/crypto v0.58.0 h1:COkYLr4k7nDI4r6QtMML2AfzeIswWHAJthLS6K/M/54=
golang.org/x/crypto v0.58.0/go.mod h1:Xh+kl5A+M0gMiWDytH2Hhr5Z7WbNCpv/eB/EFgfSk+w=
golang.org/x/exp v0.0.0-20261014143641-f0251eb4aa3e h1:HgI6W1OolKK6tcV74is+rl9SMT0njsHlp0TbQiGXI/A=
golang.org/x/exp v0.0.0-20261014143641-f0251eb4aa3e/go.mod h1:DBoxwWhjaW8DJJw/YeM4zpeOKMC1FMXSblsYy+1mFSw=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.23.0 h1:HseQ7c2OpPKTPVzNjG5fwJsOTCiiwS4QdsYi5XU6H68=
golang.org/x/image v0.23.0/go.mod h1:wJJBTdLfCCf3tiHa1fNxpZmUI4mmoZvwMCPP0ddoNKY=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.59.0 h1:5zfYln+w5XCxwrnMMJPufRgNoXEaGxl0wo5GqPXyues=
golang.org/x/net v0.59.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg=
golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk=
golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0=
golang.org/x/net v0.61.0 h1:RR+6j/BTBCrggOLugxa+66R8FvoN6MHlzDlZIbN9YFw=
golang.org/x/net v0.61.0/go.mod h1:WgDCOTH8iwtB66T4/GfI94AHo/hhdb7Hah9NDseQfiI=
golang.org/x/sync v0.24.0 h1:iqiDrGoDgyuvAKrhLQthUEzU/R378N78gXbBjxed7oA=
golang.org/x/sync v0.24.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo=
golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og=
golang.org/x/sys v0.49.0 h1:XbzkgYJHdqh/8m2Uu0W/dQv8nktxx4BFHp1M0gROTXA=
golang.org/x/sys v0.49.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI=
golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E=
golang.org/x/text v0.43.0 h1:1QivrlhwAsnMOcqgOdl9my7s9OyZl8O5/UGUTJVXoWc=
golang.org/x/text v0.43.0/go.mod h1:hbSIYA/amXcRXTFSZqh8tWHEoqRvvbKPJ2uz/KU+a+s=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
Expand All @@ -126,6 +126,6 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M=
maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA=
maunium.net/go/mautrix v0.31.1-0.20261012132636-34107524d2ab h1:rCv0s8QwcLeb9Vl68UGIr28jkJkmXE6XLp1Mje0iOYU=
maunium.net/go/mautrix v0.31.1-0.20261012132636-34107524d2ab/go.mod h1:t97J+6KmbmeoepWOunBgpu1xIvuBpI36ebBqIbYT8Jk=
maunium.net/go/mautrix v0.32.0 h1:xuAZzzyWce0pFkBhV/MCLFiJdVs2rFkY3Eep7hNng4I=
maunium.net/go/mautrix v0.32.0/go.mod h1:tZSwPzw+/0pa0dxGufkh0uJqM84BNxB6e2I0+S0UyjU=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
26 changes: 25 additions & 1 deletion pkg/connector/directmedia.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@ package connector
import (
"bytes"
"context"
"errors"
"fmt"
"io"
"net/http"

"maunium.net/go/mautrix"
"maunium.net/go/mautrix/bridgev2"
"maunium.net/go/mautrix/bridgev2/networkid"
"maunium.net/go/mautrix/mediaproxy"

"github.com/beeper/line/pkg/connector/handlers"
"github.com/beeper/line/pkg/line"
)

const (
Expand Down Expand Up @@ -91,7 +94,7 @@ func (lc *LineConnector) Download(ctx context.Context, mediaID networkid.MediaID
}
data, err := client.newMessageHandler().DownloadDirectMedia(ctx, string(parsed.MessageID), metadata.DirectMedia)
if err != nil {
return nil, err
return nil, wrapDirectMediaError(err)
}
if len(data) > handlers.BeeperMaxFileSize {
return nil, fmt.Errorf("%w: LINE %s is %.2f MiB", bridgev2.ErrMediaTooLarge, metadata.DirectMedia.Kind, float64(len(data))/(1024*1024))
Expand All @@ -104,3 +107,24 @@ func (lc *LineConnector) Download(ctx context.Context, mediaID networkid.MediaID
Reader: io.NopCloser(bytes.NewReader(data)), ContentType: contentType, ContentLength: int64(len(data)),
}, nil
}

// wrapDirectMediaError gives the media proxy a status for a failed LINE media
// download, keeping the original error in the chain.
func wrapDirectMediaError(err error) error {
var mapped mautrix.RespError
switch statusCode := line.HTTPStatusCode(err); {
case errors.Is(err, line.ErrOBSObjectNotFound), statusCode == http.StatusNotFound, statusCode == http.StatusGone:
mapped = mautrix.MNotFound.WithMessage("This media is no longer available on LINE")
case errors.Is(err, line.ErrOBSEncodingIncomplete):
mapped = mautrix.MUnknown.WithMessage("LINE is still processing this media").WithStatus(http.StatusGatewayTimeout).WithCanRetry(true)
case statusCode == http.StatusUnauthorized, statusCode == http.StatusForbidden:
mapped = mautrix.MForbidden.WithMessage("LINE refused access to this media")
case statusCode == http.StatusTooManyRequests:
mapped = mautrix.MLimitExceeded.WithMessage("LINE is rate limiting media downloads").WithCanRetry(true)
case statusCode != 0, errors.Is(err, line.ErrOBSObjectValidation):
mapped = mautrix.MUnknown.WithMessage("LINE couldn't return this media").WithStatus(http.StatusBadGateway).WithCanRetry(true)
default:
return err
}
return fmt.Errorf("%w: %w", mapped, err)
}
5 changes: 3 additions & 2 deletions pkg/connector/senderrors.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@ func wrapSendError(err error) error {
WithIsCertain(false).
WithSendNotice(true).
WithMessage("timed out waiting for LINE")
case statusCode == http.StatusTooManyRequests:
case statusCode == http.StatusTooManyRequests, line.IsTalkExceptionRateLimited(err):
return bridgev2.WrapErrorInStatus(err).
WithIsCertain(true).
WithSendNotice(true).
WithErrorReason(event.MessageStatusNetworkError).
WithMessage("LINE is rate limiting requests, try again later")
case statusCode >= 500:
case statusCode >= 500, line.IsTalkExceptionServerError(err):
return bridgev2.WrapErrorInStatus(err).
WithIsCertain(false).
WithSendNotice(true).
Expand All @@ -68,6 +68,7 @@ func wrapSendError(err error) error {
WithIsCertain(true).
WithSendNotice(true).
WithErrorReason(event.MessageStatusNetworkError).
WithStatus(event.MessageStatusFail).
WithMessage("LINE rejected the request")
default:
return bridgev2.WrapErrorInStatus(err).
Expand Down
48 changes: 41 additions & 7 deletions pkg/line/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,14 @@ type talkExceptionData struct {
Reason string `json:"reason"`
}

const (
talkExceptionDBFailed = 2
talkExceptionExcessiveAccess = 4
talkExceptionSystemError = 15
talkExceptionInternalError = 20
talkExceptionMaintenanceError = 33
)

func loginPollingFailure(httpStatus int, body []byte) error {
var response struct {
Code *int `json:"code"`
Expand Down Expand Up @@ -352,25 +360,51 @@ func safeLoginPollingReason(reason string) string {
// IsE2EEGroupMemberMismatch identifies a rejected registration that needs a
// fresh server member/key snapshot, not a plaintext fallback.
func IsE2EEGroupMemberMismatch(err error) bool {
if err == nil {
talk, ok := parseTalkException(err)
return ok && talk.Code == 99 && strings.EqualFold(strings.TrimSpace(talk.Reason), "member count mismatch")
}

// IsTalkExceptionRateLimited returns true when LINE rejected a Talk API call
// for excessive access.
func IsTalkExceptionRateLimited(err error) bool {
talk, ok := parseTalkException(err)
return ok && talk.Code == talkExceptionExcessiveAccess
}

// IsTalkExceptionServerError returns true when a TalkException reports that
// LINE failed to handle a Talk API call, rather than rejecting it.
func IsTalkExceptionServerError(err error) bool {
talk, ok := parseTalkException(err)
if !ok {
return false
}
switch talk.Code {
case talkExceptionDBFailed, talkExceptionSystemError, talkExceptionInternalError, talkExceptionMaintenanceError:
return true
}
return false
}

func parseTalkException(err error) (talkExceptionData, bool) {
Comment thread
indent[bot] marked this conversation as resolved.
Resolved
if err == nil {
return talkExceptionData{}, false
}
msg := err.Error()
start := strings.IndexByte(msg, '{')
if start < 0 {
return false
return talkExceptionData{}, false
}
var response struct {
Code int `json:"code"`
Message string `json:"message"`
Data talkExceptionData `json:"data"`
}
if json.NewDecoder(strings.NewReader(msg[start:])).Decode(&response) != nil {
return false
if json.NewDecoder(strings.NewReader(msg[start:])).Decode(&response) != nil ||
response.Code != 10051 || !strings.EqualFold(response.Message, "RESPONSE_ERROR") ||
!strings.EqualFold(response.Data.Name, "TalkException") {
return talkExceptionData{}, false
}
return response.Code == 10051 && strings.EqualFold(response.Message, "RESPONSE_ERROR") &&
strings.EqualFold(response.Data.Name, "TalkException") && response.Data.Code == 99 &&
strings.EqualFold(strings.TrimSpace(response.Data.Reason), "member count mismatch")
return response.Data, true
}

// IsGroupKeyNotRegisteredError returns true when SendMessage returns code 99
Expand Down
6 changes: 3 additions & 3 deletions pkg/line/methods.go
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ func (c *Client) UpdateSettingsAttributes2Context(ctx context.Context, reqSeq in
if wrapper.Code != 0 {
// Preserve the response data because TalkException details contain the
// error code used by connector-level auth recovery.
return fmt.Errorf("updateSettingsAttributes2 failed: code %d message %s data %s", wrapper.Code, wrapper.Message, string(wrapper.Data))
return fmt.Errorf("updateSettingsAttributes2 failed: %s", resp)
}
return nil
}
Expand All @@ -451,7 +451,7 @@ func (c *Client) React(reqSeq int64, messageID string, reactionType ReactionType
return err
}
if wrapper.Code != 0 {
return fmt.Errorf("react failed: code %d message %s data %s", wrapper.Code, wrapper.Message, string(wrapper.Data))
return fmt.Errorf("react failed: %s", resp)
}
return nil
}
Expand All @@ -474,7 +474,7 @@ func (c *Client) CancelReaction(reqSeq int64, messageID string) error {
return err
}
if wrapper.Code != 0 {
return fmt.Errorf("cancelReaction failed: code %d message %s data %s", wrapper.Code, wrapper.Message, string(wrapper.Data))
return fmt.Errorf("cancelReaction failed: %s", resp)
}
return nil
}
Expand Down
Loading