forked from jshiffer/matterbridge
Update Rhymen/go-whatsapp vendor and whatsapp version (#1078)
This commit is contained in:
parent
11fc4c286f
commit
8950575bfb
@ -67,7 +67,7 @@ func (b *Bwhatsapp) Connect() error {
|
||||
// https://github.com/Rhymen/go-whatsapp#creating-a-connection
|
||||
b.Log.Debugln("Connecting to WhatsApp..")
|
||||
conn, err := whatsapp.NewConn(20 * time.Second)
|
||||
conn.SetClientVersion(0, 4, 1307)
|
||||
conn.SetClientVersion(0, 4, 2080)
|
||||
if err != nil {
|
||||
return errors.New("failed to connect to WhatsApp: " + err.Error())
|
||||
}
|
||||
|
2
go.mod
2
go.mod
@ -5,7 +5,7 @@ require (
|
||||
github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f
|
||||
github.com/Jeffail/gabs v1.1.1 // indirect
|
||||
github.com/Philipp15b/go-steam v1.0.1-0.20190816133340-b04c5a83c1c0
|
||||
github.com/Rhymen/go-whatsapp v0.1.0
|
||||
github.com/Rhymen/go-whatsapp v0.1.1-0.20200408093540-2f227c53b44f
|
||||
github.com/d5/tengo/v2 v2.1.2
|
||||
github.com/dfordsoft/golib v0.0.0-20180902042739-76ee6ab99bec
|
||||
github.com/fsnotify/fsnotify v1.4.7
|
||||
|
4
go.sum
4
go.sum
@ -12,8 +12,8 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAE
|
||||
github.com/Philipp15b/go-steam v1.0.1-0.20190816133340-b04c5a83c1c0 h1:TO7d4rocnNFng6ZQrPe7U6WqHtK5eHEMrgrnnM/72IQ=
|
||||
github.com/Philipp15b/go-steam v1.0.1-0.20190816133340-b04c5a83c1c0/go.mod h1:HuVM+sZFzumUdKPWiz+IlCMb4RdsKdT3T+nQBKL+sYg=
|
||||
github.com/Rhymen/go-whatsapp v0.0.0/go.mod h1:rdQr95g2C1xcOfM7QGOhza58HeI3I+tZ/bbluv7VazA=
|
||||
github.com/Rhymen/go-whatsapp v0.1.0 h1:XTXhFIQ/fx9jKObUnUX2Q+nh58EyeHNhX7DniE8xeuA=
|
||||
github.com/Rhymen/go-whatsapp v0.1.0/go.mod h1:xJSy+okeRjKkQEH/lEYrnekXB3PG33fqL0I6ncAkV50=
|
||||
github.com/Rhymen/go-whatsapp v0.1.1-0.20200408093540-2f227c53b44f h1:uclEol7RbpElhXXmwu38PDeGcgMXNU2vh5DWwzlg7xI=
|
||||
github.com/Rhymen/go-whatsapp v0.1.1-0.20200408093540-2f227c53b44f/go.mod h1:o7jjkvKnigfu432dMbQ/w4PH0Yp5u4Y6ysCNjUlcYCk=
|
||||
github.com/Rhymen/go-whatsapp/examples/echo v0.0.0-20190325075644-cc2581bbf24d/go.mod h1:zgCiQtBtZ4P4gFWvwl9aashsdwOcbb/EHOGRmSzM8ME=
|
||||
github.com/Rhymen/go-whatsapp/examples/restoreSession v0.0.0-20190325075644-cc2581bbf24d/go.mod h1:5sCUSpG616ZoSJhlt9iBNI/KXBqrVLcNUJqg7J9+8pU=
|
||||
github.com/Rhymen/go-whatsapp/examples/sendImage v0.0.0-20190325075644-cc2581bbf24d/go.mod h1:RdiyhanVEGXTam+mZ3k6Y3VDCCvXYCwReOoxGozqhHw=
|
||||
|
1387
vendor/github.com/Rhymen/go-whatsapp/binary/proto/def.pb.go
generated
vendored
1387
vendor/github.com/Rhymen/go-whatsapp/binary/proto/def.pb.go
generated
vendored
File diff suppressed because it is too large
Load Diff
76
vendor/github.com/Rhymen/go-whatsapp/binary/proto/def.proto
generated
vendored
76
vendor/github.com/Rhymen/go-whatsapp/binary/proto/def.proto
generated
vendored
@ -56,6 +56,8 @@ message Location {
|
||||
}
|
||||
|
||||
message Point {
|
||||
optional int32 xDeprecated = 1;
|
||||
optional int32 yDeprecated = 2;
|
||||
optional double x = 3;
|
||||
optional double y = 4;
|
||||
}
|
||||
@ -93,6 +95,7 @@ message ContextInfo {
|
||||
optional AdReplyInfo quotedAd = 23;
|
||||
optional MessageKey placeholderKey = 24;
|
||||
optional uint32 expiration = 25;
|
||||
optional int64 ephemeralSettingTimestamp = 26;
|
||||
}
|
||||
|
||||
message SenderKeyDistributionMessage {
|
||||
@ -136,6 +139,11 @@ message LocationMessage {
|
||||
optional string name = 3;
|
||||
optional string address = 4;
|
||||
optional string url = 5;
|
||||
optional bool isLive = 6;
|
||||
optional uint32 accuracyInMeters = 7;
|
||||
optional float speedInMps = 8;
|
||||
optional uint32 degreesClockwiseFromMagneticNorth = 9;
|
||||
optional string comment = 11;
|
||||
optional bytes jpegThumbnail = 16;
|
||||
optional ContextInfo contextInfo = 17;
|
||||
}
|
||||
@ -238,9 +246,29 @@ message ProtocolMessage {
|
||||
enum PROTOCOL_MESSAGE_TYPE {
|
||||
REVOKE = 0;
|
||||
EPHEMERAL_SETTING = 3;
|
||||
EPHEMERAL_SYNC_RESPONSE = 4;
|
||||
HISTORY_SYNC_NOTIFICATION = 5;
|
||||
}
|
||||
optional PROTOCOL_MESSAGE_TYPE type = 2;
|
||||
optional uint32 ephemeralExpiration = 4;
|
||||
optional int64 ephemeralSettingTimestamp = 5;
|
||||
optional HistorySyncNotification historySyncNotification = 6;
|
||||
}
|
||||
|
||||
message HistorySyncNotification {
|
||||
optional bytes fileSha256 = 1;
|
||||
optional uint64 fileLength = 2;
|
||||
optional bytes mediaKey = 3;
|
||||
optional bytes fileEncSha256 = 4;
|
||||
optional string directPath = 5;
|
||||
enum HISTORY_SYNC_NOTIFICATION_HISTORYSYNCTYPE {
|
||||
INITIAL_BOOTSTRAP = 0;
|
||||
INITIAL_STATUS_V3 = 1;
|
||||
FULL = 2;
|
||||
RECENT = 3;
|
||||
}
|
||||
optional HISTORY_SYNC_NOTIFICATION_HISTORYSYNCTYPE syncType = 6;
|
||||
optional uint32 chunkOrder = 7;
|
||||
}
|
||||
|
||||
message ContactsArrayMessage {
|
||||
@ -355,6 +383,8 @@ message StickerMessage {
|
||||
optional int64 mediaKeyTimestamp = 10;
|
||||
optional uint32 firstFrameLength = 11;
|
||||
optional bytes firstFrameSidecar = 12;
|
||||
optional bool isAnimated = 13;
|
||||
optional bytes pngThumbnail = 16;
|
||||
optional ContextInfo contextInfo = 17;
|
||||
}
|
||||
|
||||
@ -401,6 +431,12 @@ message TemplateButtonReplyMessage {
|
||||
optional uint32 selectedIndex = 4;
|
||||
}
|
||||
|
||||
message CatalogSnapshot {
|
||||
optional ImageMessage catalogImage = 1;
|
||||
optional string title = 2;
|
||||
optional string description = 3;
|
||||
}
|
||||
|
||||
message ProductSnapshot {
|
||||
optional ImageMessage productImage = 1;
|
||||
optional string productId = 2;
|
||||
@ -417,6 +453,7 @@ message ProductSnapshot {
|
||||
message ProductMessage {
|
||||
optional ProductSnapshot product = 1;
|
||||
optional string businessOwnerJid = 2;
|
||||
optional CatalogSnapshot catalog = 4;
|
||||
optional ContextInfo contextInfo = 17;
|
||||
}
|
||||
|
||||
@ -513,6 +550,8 @@ message WebFeatures {
|
||||
optional WEB_FEATURES_FLAG templateMessage = 30;
|
||||
optional WEB_FEATURES_FLAG templateMessageInteractivity = 31;
|
||||
optional WEB_FEATURES_FLAG ephemeralMessages = 32;
|
||||
optional WEB_FEATURES_FLAG e2ENotificationSync = 33;
|
||||
optional WEB_FEATURES_FLAG recentStickersV2 = 34;
|
||||
}
|
||||
|
||||
message TabletNotificationsInfo {
|
||||
@ -537,6 +576,11 @@ message WebNotificationsInfo {
|
||||
}
|
||||
|
||||
message PaymentInfo {
|
||||
enum PAYMENT_INFO_CURRENCY {
|
||||
UNKNOWN_CURRENCY = 0;
|
||||
INR = 1;
|
||||
}
|
||||
optional PAYMENT_INFO_CURRENCY currencyDeprecated = 1;
|
||||
optional uint64 amount1000 = 2;
|
||||
optional string receiverJid = 3;
|
||||
enum PAYMENT_INFO_STATUS {
|
||||
@ -559,6 +603,37 @@ message PaymentInfo {
|
||||
optional uint64 expiryTimestamp = 7;
|
||||
optional bool futureproofed = 8;
|
||||
optional string currency = 9;
|
||||
enum PAYMENT_INFO_TXNSTATUS {
|
||||
UNKNOWN = 0;
|
||||
PENDING_SETUP = 1;
|
||||
PENDING_RECEIVER_SETUP = 2;
|
||||
INIT = 3;
|
||||
SUCCESS = 4;
|
||||
COMPLETED = 5;
|
||||
FAILED = 6;
|
||||
FAILED_RISK = 7;
|
||||
FAILED_PROCESSING = 8;
|
||||
FAILED_RECEIVER_PROCESSING = 9;
|
||||
FAILED_DA = 10;
|
||||
FAILED_DA_FINAL = 11;
|
||||
REFUNDED_TXN = 12;
|
||||
REFUND_FAILED = 13;
|
||||
REFUND_FAILED_PROCESSING = 14;
|
||||
REFUND_FAILED_DA = 15;
|
||||
EXPIRED_TXN = 16;
|
||||
AUTH_CANCELED = 17;
|
||||
AUTH_CANCEL_FAILED_PROCESSING = 18;
|
||||
AUTH_CANCEL_FAILED = 19;
|
||||
COLLECT_INIT = 20;
|
||||
COLLECT_SUCCESS = 21;
|
||||
COLLECT_FAILED = 22;
|
||||
COLLECT_FAILED_RISK = 23;
|
||||
COLLECT_REJECTED = 24;
|
||||
COLLECT_EXPIRED = 25;
|
||||
COLLECT_CANCELED = 26;
|
||||
COLLECT_CANCELLING = 27;
|
||||
}
|
||||
optional PAYMENT_INFO_TXNSTATUS txnStatus = 10;
|
||||
}
|
||||
|
||||
message WebMessageInfo {
|
||||
@ -669,3 +744,4 @@ message WebMessageInfo {
|
||||
optional uint64 ephemeralStartTimestamp = 32;
|
||||
optional uint32 ephemeralDuration = 33;
|
||||
}
|
||||
|
||||
|
2
vendor/github.com/Rhymen/go-whatsapp/go.mod
generated
vendored
2
vendor/github.com/Rhymen/go-whatsapp/go.mod
generated
vendored
@ -6,7 +6,7 @@ require (
|
||||
github.com/Rhymen/go-whatsapp/examples/sendImage v0.0.0-20190325075644-cc2581bbf24d // indirect
|
||||
github.com/Rhymen/go-whatsapp/examples/sendTextMessages v0.0.0-20190325075644-cc2581bbf24d // indirect
|
||||
github.com/golang/protobuf v1.3.0
|
||||
github.com/gorilla/websocket v1.4.0
|
||||
github.com/gorilla/websocket v1.4.1
|
||||
github.com/pkg/errors v0.8.1
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2
|
||||
)
|
||||
|
3
vendor/github.com/Rhymen/go-whatsapp/go.sum
generated
vendored
3
vendor/github.com/Rhymen/go-whatsapp/go.sum
generated
vendored
@ -12,8 +12,9 @@ github.com/Rhymen/go-whatsapp/examples/sendTextMessages v0.0.0-20190325075644-cc
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk=
|
||||
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
|
||||
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
|
||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw=
|
||||
|
116
vendor/github.com/Rhymen/go-whatsapp/media.go
generated
vendored
116
vendor/github.com/Rhymen/go-whatsapp/media.go
generated
vendored
@ -10,10 +10,8 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/Rhymen/go-whatsapp/crypto/cbc"
|
||||
@ -95,7 +93,50 @@ func downloadMedia(url string) (file []byte, mac []byte, err error) {
|
||||
return data[:n-10], data[n-10 : n], nil
|
||||
}
|
||||
|
||||
func (wac *Conn) Upload(reader io.Reader, appInfo MediaType) (url string, mediaKey []byte, fileEncSha256 []byte, fileSha256 []byte, fileLength uint64, err error) {
|
||||
type MediaConn struct {
|
||||
Status int `json:"status"`
|
||||
MediaConn struct {
|
||||
Auth string `json:"auth"`
|
||||
TTL int `json:"ttl"`
|
||||
Hosts []struct {
|
||||
Hostname string `json:"hostname"`
|
||||
IPs []string `json:"ips"`
|
||||
} `json:"hosts"`
|
||||
} `json:"media_conn"`
|
||||
}
|
||||
|
||||
func (wac *Conn) queryMediaConn() (hostname, auth string, ttl int, err error) {
|
||||
queryReq := []interface{}{"query", "mediaConn"}
|
||||
ch, err := wac.writeJson(queryReq)
|
||||
if err != nil {
|
||||
return "", "", 0, err
|
||||
}
|
||||
|
||||
var resp MediaConn
|
||||
select {
|
||||
case r := <-ch:
|
||||
if err = json.Unmarshal([]byte(r), &resp); err != nil {
|
||||
return "", "", 0, fmt.Errorf("error decoding query media conn response: %v", err)
|
||||
}
|
||||
case <-time.After(wac.msgTimeout):
|
||||
return "", "", 0, fmt.Errorf("query media conn timed out")
|
||||
}
|
||||
|
||||
if resp.Status != 200 {
|
||||
return "", "", 0, fmt.Errorf("query media conn responded with %d", resp.Status)
|
||||
}
|
||||
|
||||
return resp.MediaConn.Hosts[0].Hostname, resp.MediaConn.Auth, resp.MediaConn.TTL, nil
|
||||
}
|
||||
|
||||
var mediaTypeMap = map[MediaType]string{
|
||||
MediaImage: "/mms/image",
|
||||
MediaVideo: "/mms/video",
|
||||
MediaDocument: "/mms/document",
|
||||
MediaAudio: "/mms/audio",
|
||||
}
|
||||
|
||||
func (wac *Conn) Upload(reader io.Reader, appInfo MediaType) (downloadURL string, mediaKey []byte, fileEncSha256 []byte, fileSha256 []byte, fileLength uint64, err error) {
|
||||
data, err := ioutil.ReadAll(reader)
|
||||
if err != nil {
|
||||
return "", nil, nil, nil, 0, err
|
||||
@ -128,67 +169,30 @@ func (wac *Conn) Upload(reader io.Reader, appInfo MediaType) (url string, mediaK
|
||||
sha.Write(append(enc, mac...))
|
||||
fileEncSha256 = sha.Sum(nil)
|
||||
|
||||
var filetype string
|
||||
switch appInfo {
|
||||
case MediaImage:
|
||||
filetype = "image"
|
||||
case MediaAudio:
|
||||
filetype = "audio"
|
||||
case MediaDocument:
|
||||
filetype = "document"
|
||||
case MediaVideo:
|
||||
filetype = "video"
|
||||
hostname, auth, _, err := wac.queryMediaConn()
|
||||
token := base64.URLEncoding.EncodeToString(fileEncSha256)
|
||||
q := url.Values{
|
||||
"auth": []string{auth},
|
||||
"token": []string{token},
|
||||
}
|
||||
path := mediaTypeMap[appInfo]
|
||||
uploadURL := url.URL{
|
||||
Scheme: "https",
|
||||
Host: hostname,
|
||||
Path: fmt.Sprintf("%s/%s", path, token),
|
||||
RawQuery: q.Encode(),
|
||||
}
|
||||
|
||||
uploadReq := []interface{}{"action", "encr_upload", filetype, base64.StdEncoding.EncodeToString(fileEncSha256)}
|
||||
ch, err := wac.writeJson(uploadReq)
|
||||
body := bytes.NewReader(append(enc, mac...))
|
||||
|
||||
req, err := http.NewRequest("POST", uploadURL.String(), body)
|
||||
if err != nil {
|
||||
return "", nil, nil, nil, 0, err
|
||||
}
|
||||
|
||||
var resp map[string]interface{}
|
||||
select {
|
||||
case r := <-ch:
|
||||
if err = json.Unmarshal([]byte(r), &resp); err != nil {
|
||||
return "", nil, nil, nil, 0, fmt.Errorf("error decoding upload response: %v", err)
|
||||
}
|
||||
case <-time.After(wac.msgTimeout):
|
||||
return "", nil, nil, nil, 0, fmt.Errorf("restore session init timed out")
|
||||
}
|
||||
|
||||
if int(resp["status"].(float64)) != 200 {
|
||||
return "", nil, nil, nil, 0, fmt.Errorf("upload responsed with %d", resp["status"])
|
||||
}
|
||||
|
||||
var b bytes.Buffer
|
||||
w := multipart.NewWriter(&b)
|
||||
hashWriter, err := w.CreateFormField("hash")
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||
}
|
||||
io.Copy(hashWriter, strings.NewReader(base64.StdEncoding.EncodeToString(fileEncSha256)))
|
||||
|
||||
fileWriter, err := w.CreateFormFile("file", "blob")
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||
}
|
||||
io.Copy(fileWriter, bytes.NewReader(append(enc, mac...)))
|
||||
err = w.Close()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", resp["url"].(string), &b)
|
||||
if err != nil {
|
||||
return "", nil, nil, nil, 0, err
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", w.FormDataContentType())
|
||||
req.Header.Set("Origin", "https://web.whatsapp.com")
|
||||
req.Header.Set("Referer", "https://web.whatsapp.com/")
|
||||
|
||||
req.URL.Query().Set("f", "j")
|
||||
|
||||
client := &http.Client{}
|
||||
// Submit the request
|
||||
res, err := client.Do(req)
|
||||
|
6
vendor/github.com/Rhymen/go-whatsapp/read.go
generated
vendored
6
vendor/github.com/Rhymen/go-whatsapp/read.go
generated
vendored
@ -15,7 +15,10 @@ import (
|
||||
)
|
||||
|
||||
func (wac *Conn) readPump() {
|
||||
defer wac.wg.Done()
|
||||
defer func() {
|
||||
wac.wg.Done()
|
||||
_, _ = wac.Disconnect()
|
||||
}()
|
||||
|
||||
var readErr error
|
||||
var msgType int
|
||||
@ -31,7 +34,6 @@ func (wac *Conn) readPump() {
|
||||
case <-readerFound:
|
||||
if readErr != nil {
|
||||
wac.handle(&ErrConnectionFailed{Err: readErr})
|
||||
_, _ = wac.Disconnect()
|
||||
return
|
||||
}
|
||||
msg, err := ioutil.ReadAll(reader)
|
||||
|
8
vendor/github.com/Rhymen/go-whatsapp/session.go
generated
vendored
8
vendor/github.com/Rhymen/go-whatsapp/session.go
generated
vendored
@ -18,7 +18,7 @@ import (
|
||||
)
|
||||
|
||||
//represents the WhatsAppWeb client version
|
||||
var waVersion = []int{0, 3, 3324}
|
||||
var waVersion = []int{0, 4, 2080}
|
||||
|
||||
/*
|
||||
Session contains session individual information. To be able to resume the connection without scanning the qr code
|
||||
@ -110,7 +110,7 @@ func CheckCurrentServerVersion() ([]int, error) {
|
||||
login := []interface{}{"admin", "init", waVersion, []string{wac.longClientName, wac.shortClientName}, b64ClientId, true}
|
||||
loginChan, err := wac.writeJson(login)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error writing login", err)
|
||||
return nil, fmt.Errorf("error writing login: %s", err.Error())
|
||||
}
|
||||
|
||||
// Retrieve an answer from the websocket
|
||||
@ -123,7 +123,7 @@ func CheckCurrentServerVersion() ([]int, error) {
|
||||
|
||||
var resp map[string]interface{}
|
||||
if err = json.Unmarshal([]byte(r), &resp); err != nil {
|
||||
return nil, fmt.Errorf("error decoding login", err)
|
||||
return nil, fmt.Errorf("error decoding login: %s", err.Error())
|
||||
}
|
||||
|
||||
// Take the curr property as X.Y.Z and split it into as int slice
|
||||
@ -151,7 +151,7 @@ func (wac *Conn) SetClientName(long, short string) error {
|
||||
|
||||
/*
|
||||
SetClientVersion sets WhatsApp client version
|
||||
Default value is 0.3.3324
|
||||
Default value is 0.4.2080
|
||||
*/
|
||||
func (wac *Conn) SetClientVersion(major int, minor int, patch int) {
|
||||
waVersion = []int{major, minor, patch}
|
||||
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@ -15,7 +15,7 @@ github.com/Philipp15b/go-steam/protocol/steamlang
|
||||
github.com/Philipp15b/go-steam/rwu
|
||||
github.com/Philipp15b/go-steam/socialcache
|
||||
github.com/Philipp15b/go-steam/steamid
|
||||
# github.com/Rhymen/go-whatsapp v0.1.0
|
||||
# github.com/Rhymen/go-whatsapp v0.1.1-0.20200408093540-2f227c53b44f
|
||||
github.com/Rhymen/go-whatsapp
|
||||
github.com/Rhymen/go-whatsapp/binary
|
||||
github.com/Rhymen/go-whatsapp/binary/proto
|
||||
|
Loading…
Reference in New Issue
Block a user