2018-08-23 00:12:26 +02:00
|
|
|
// mautrix-whatsapp - A Matrix-WhatsApp puppeting bridge.
|
|
|
|
// Copyright (C) 2018 Tulir Asokan
|
|
|
|
//
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU Affero General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU Affero General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
2018-08-26 00:55:21 +02:00
|
|
|
package whatsappExt
|
2018-08-23 00:12:26 +02:00
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
2018-08-26 15:11:48 +02:00
|
|
|
"fmt"
|
2018-08-23 00:12:26 +02:00
|
|
|
"io"
|
2018-08-26 15:11:48 +02:00
|
|
|
"io/ioutil"
|
|
|
|
"net/http"
|
2018-08-23 00:12:26 +02:00
|
|
|
"strings"
|
2018-08-26 15:11:48 +02:00
|
|
|
|
|
|
|
"github.com/Rhymen/go-whatsapp"
|
2018-08-23 00:12:26 +02:00
|
|
|
)
|
|
|
|
|
2018-08-23 23:51:40 +02:00
|
|
|
const (
|
|
|
|
OldUserSuffix = "@c.us"
|
|
|
|
NewUserSuffix = "@s.whatsapp.net"
|
|
|
|
)
|
|
|
|
|
2018-08-23 00:12:26 +02:00
|
|
|
type ExtendedConn struct {
|
|
|
|
*whatsapp.Conn
|
2018-08-23 23:51:40 +02:00
|
|
|
|
|
|
|
handlers []whatsapp.Handler
|
2018-08-23 00:12:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func ExtendConn(conn *whatsapp.Conn) *ExtendedConn {
|
2018-08-23 23:51:40 +02:00
|
|
|
ext := &ExtendedConn{
|
2018-08-23 00:12:26 +02:00
|
|
|
Conn: conn,
|
|
|
|
}
|
2018-08-23 23:51:40 +02:00
|
|
|
ext.Conn.AddHandler(ext)
|
|
|
|
return ext
|
2018-08-23 00:12:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
type GroupInfo struct {
|
|
|
|
JID string `json:"jid"`
|
|
|
|
OwnerJID string `json:"owner"`
|
|
|
|
|
|
|
|
Name string `json:"subject"`
|
|
|
|
NameSetTime int64 `json:"subjectTime"`
|
|
|
|
NameSetBy string `json:"subjectOwner"`
|
|
|
|
|
|
|
|
Topic string `json:"desc"`
|
|
|
|
TopicID string `json:"descId"`
|
|
|
|
TopicSetAt int64 `json:"descTime"`
|
|
|
|
TopicSetBy string `json:"descOwner"`
|
|
|
|
|
|
|
|
GroupCreated int64 `json:"creation"`
|
|
|
|
|
2018-12-05 09:20:39 +01:00
|
|
|
Status int16 `json:"status"`
|
|
|
|
|
2018-08-23 00:12:26 +02:00
|
|
|
Participants []struct {
|
|
|
|
JID string `json:"id"`
|
|
|
|
IsAdmin bool `json:"isAdmin"`
|
|
|
|
IsSuperAdmin bool `json:"isSuperAdmin"`
|
|
|
|
} `json:"participants"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ext *ExtendedConn) GetGroupMetaData(jid string) (*GroupInfo, error) {
|
|
|
|
data, err := ext.Conn.GetGroupMetaData(jid)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to get group metadata: %v", err)
|
|
|
|
}
|
|
|
|
content := <-data
|
2018-08-23 23:51:40 +02:00
|
|
|
|
2018-08-23 00:12:26 +02:00
|
|
|
info := &GroupInfo{}
|
|
|
|
err = json.Unmarshal([]byte(content), info)
|
|
|
|
if err != nil {
|
|
|
|
return info, fmt.Errorf("failed to unmarshal group metadata: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
for index, participant := range info.Participants {
|
2018-08-23 23:51:40 +02:00
|
|
|
info.Participants[index].JID = strings.Replace(participant.JID, OldUserSuffix, NewUserSuffix, 1)
|
2018-08-23 00:12:26 +02:00
|
|
|
}
|
2018-08-26 00:55:21 +02:00
|
|
|
info.NameSetBy = strings.Replace(info.NameSetBy, OldUserSuffix, NewUserSuffix, 1)
|
|
|
|
info.TopicSetBy = strings.Replace(info.TopicSetBy, OldUserSuffix, NewUserSuffix, 1)
|
2018-08-23 00:12:26 +02:00
|
|
|
|
|
|
|
return info, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
type ProfilePicInfo struct {
|
|
|
|
URL string `json:"eurl"`
|
|
|
|
Tag string `json:"tag"`
|
2018-12-05 10:30:07 +01:00
|
|
|
|
|
|
|
Status int16 `json:"status"`
|
2018-08-23 00:12:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ppi *ProfilePicInfo) Download() (io.ReadCloser, error) {
|
|
|
|
resp, err := http.Get(ppi.URL)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return resp.Body, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ppi *ProfilePicInfo) DownloadBytes() ([]byte, error) {
|
|
|
|
body, err := ppi.Download()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer body.Close()
|
|
|
|
data, err := ioutil.ReadAll(body)
|
|
|
|
return data, err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ext *ExtendedConn) GetProfilePicThumb(jid string) (*ProfilePicInfo, error) {
|
|
|
|
data, err := ext.Conn.GetProfilePicThumb(jid)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to get avatar: %v", err)
|
|
|
|
}
|
|
|
|
content := <-data
|
|
|
|
info := &ProfilePicInfo{}
|
|
|
|
err = json.Unmarshal([]byte(content), info)
|
|
|
|
if err != nil {
|
|
|
|
return info, fmt.Errorf("failed to unmarshal avatar info: %v", err)
|
|
|
|
}
|
|
|
|
return info, nil
|
|
|
|
}
|