From 995e6ceb24f39a2dff6ae1591f0ee27c23871054 Mon Sep 17 00:00:00 2001 From: wdvxdr Date: Sat, 20 Feb 2021 21:48:39 +0800 Subject: [PATCH 1/2] feat group notice pic up --- client/client.go | 63 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 5 deletions(-) diff --git a/client/client.go b/client/client.go index ceeb5fe2..92440b30 100644 --- a/client/client.go +++ b/client/client.go @@ -4,10 +4,15 @@ import ( "bytes" "crypto/md5" "fmt" + "html" "io" + "io/ioutil" "math" "math/rand" + "mime/multipart" "net" + "net/http" + "net/textproto" "net/url" "runtime/debug" "sort" @@ -17,16 +22,14 @@ import ( "sync/atomic" "time" - "github.com/Mrs4s/MiraiGo/binary/jce" - jsoniter "github.com/json-iterator/go" - - "github.com/pkg/errors" - "github.com/Mrs4s/MiraiGo/binary" + "github.com/Mrs4s/MiraiGo/binary/jce" "github.com/Mrs4s/MiraiGo/client/pb/msg" "github.com/Mrs4s/MiraiGo/message" "github.com/Mrs4s/MiraiGo/protocol/packets" "github.com/Mrs4s/MiraiGo/utils" + jsoniter "github.com/json-iterator/go" + "github.com/pkg/errors" ) var json = jsoniter.ConfigFastest @@ -381,6 +384,56 @@ func (c *QQClient) GetGroupHonorInfo(groupCode int64, honorType HonorType) (*Gro return &ret, nil } +func (c *QQClient) uploadGroupNoticePic(img []byte) (string, error) { + buf := new(bytes.Buffer) + var w = multipart.NewWriter(buf) + err := w.WriteField("bkn", strconv.Itoa(c.getCSRFToken())) + if err != nil { + return "", errors.Wrap(err, "write multipart failed") + } + err = w.WriteField("source", "troopNotice") + if err != nil { + return "", errors.Wrap(err, "write multipart failed") + } + err = w.WriteField("m", "0") + if err != nil { + return "", errors.Wrap(err, "write multipart failed") + } + h := make(textproto.MIMEHeader) + h.Set("Content-Disposition", `form-data; name="pic_up"; filename="temp_uploadFile.png"`) + h.Set("Content-Type", "image/png") + fw, err := w.CreatePart(h) + if err != nil { + return "", errors.Wrap(err, "create multipart field failed") + } + _, err = fw.Write(img) + if err != nil { + return "", errors.Wrap(err, "write multipart failed") + } + err = w.Close() + if err != nil { + return "", errors.Wrap(err, "close multipart failed") + } + req, err := http.NewRequest("POST", "https://web.qun.qq.com/cgi-bin/announce/upload_img", buf) + if err != nil { + return "", errors.Wrap(err, "new request error") + } + req.Header.Set("Content-Type", w.FormDataContentType()) + req.Header.Set("Cookie", c.getCookies()) + resp, err := http.DefaultClient.Do(req) + if err != nil { + return "", errors.Wrap(err, "post error") + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "", errors.Wrap(err, "read body error") + } + str := html.UnescapeString(string(body)) + //fmt.Println(str) + return str, nil +} + func (c *QQClient) AddGroupNoticeSimple(groupCode int64, text string) error { body := fmt.Sprintf(`qid=%v&bkn=%v&text=%v&pinned=0&type=1&settings={"is_show_edit_card":0,"tip_window_type":1,"confirm_required":1}`, groupCode, c.getCSRFToken(), url.QueryEscape(text)) _, err := utils.HttpPostBytesWithCookie("https://web.qun.qq.com/cgi-bin/announce/add_qun_notice?bkn="+fmt.Sprint(c.getCSRFToken()), []byte(body), c.getCookiesWithDomain("qun.qq.com")) From cb034c17b51710c328f32665c92b6d84f345a72b Mon Sep 17 00:00:00 2001 From: wdvxdr Date: Sun, 21 Feb 2021 15:24:51 +0800 Subject: [PATCH 2/2] feat send notice with pic --- client/client.go | 65 ------------------------ client/group_notice.go | 113 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+), 65 deletions(-) create mode 100644 client/group_notice.go diff --git a/client/client.go b/client/client.go index 92440b30..be1a14f3 100644 --- a/client/client.go +++ b/client/client.go @@ -4,16 +4,10 @@ import ( "bytes" "crypto/md5" "fmt" - "html" "io" - "io/ioutil" "math" "math/rand" - "mime/multipart" "net" - "net/http" - "net/textproto" - "net/url" "runtime/debug" "sort" "strconv" @@ -384,65 +378,6 @@ func (c *QQClient) GetGroupHonorInfo(groupCode int64, honorType HonorType) (*Gro return &ret, nil } -func (c *QQClient) uploadGroupNoticePic(img []byte) (string, error) { - buf := new(bytes.Buffer) - var w = multipart.NewWriter(buf) - err := w.WriteField("bkn", strconv.Itoa(c.getCSRFToken())) - if err != nil { - return "", errors.Wrap(err, "write multipart failed") - } - err = w.WriteField("source", "troopNotice") - if err != nil { - return "", errors.Wrap(err, "write multipart failed") - } - err = w.WriteField("m", "0") - if err != nil { - return "", errors.Wrap(err, "write multipart failed") - } - h := make(textproto.MIMEHeader) - h.Set("Content-Disposition", `form-data; name="pic_up"; filename="temp_uploadFile.png"`) - h.Set("Content-Type", "image/png") - fw, err := w.CreatePart(h) - if err != nil { - return "", errors.Wrap(err, "create multipart field failed") - } - _, err = fw.Write(img) - if err != nil { - return "", errors.Wrap(err, "write multipart failed") - } - err = w.Close() - if err != nil { - return "", errors.Wrap(err, "close multipart failed") - } - req, err := http.NewRequest("POST", "https://web.qun.qq.com/cgi-bin/announce/upload_img", buf) - if err != nil { - return "", errors.Wrap(err, "new request error") - } - req.Header.Set("Content-Type", w.FormDataContentType()) - req.Header.Set("Cookie", c.getCookies()) - resp, err := http.DefaultClient.Do(req) - if err != nil { - return "", errors.Wrap(err, "post error") - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return "", errors.Wrap(err, "read body error") - } - str := html.UnescapeString(string(body)) - //fmt.Println(str) - return str, nil -} - -func (c *QQClient) AddGroupNoticeSimple(groupCode int64, text string) error { - body := fmt.Sprintf(`qid=%v&bkn=%v&text=%v&pinned=0&type=1&settings={"is_show_edit_card":0,"tip_window_type":1,"confirm_required":1}`, groupCode, c.getCSRFToken(), url.QueryEscape(text)) - _, err := utils.HttpPostBytesWithCookie("https://web.qun.qq.com/cgi-bin/announce/add_qun_notice?bkn="+fmt.Sprint(c.getCSRFToken()), []byte(body), c.getCookiesWithDomain("qun.qq.com")) - if err != nil { - return errors.Wrap(err, "request error") - } - return nil -} - func (c *QQClient) GetWordSegmentation(text string) ([]string, error) { rsp, err := c.sendAndWait(c.buildWordSegmentationPacket([]byte(text))) if err != nil { diff --git a/client/group_notice.go b/client/group_notice.go new file mode 100644 index 00000000..0c43afca --- /dev/null +++ b/client/group_notice.go @@ -0,0 +1,113 @@ +package client + +import ( + "bytes" + "fmt" + "html" + "io/ioutil" + "mime/multipart" + "net/http" + "net/textproto" + "net/url" + "strconv" + + "github.com/Mrs4s/MiraiGo/utils" + "github.com/pkg/errors" +) + +type noticePicUpResponse struct { + ErrorCode int `json:"ec"` + ErrorMessage string `json:"em"` + ID string `json:"id"` +} + +type noticeImage struct { + Height string `json:"h"` + Width string `json:"w"` + ID string `json:"id"` +} + +func (c *QQClient) uploadGroupNoticePic(img []byte) (*noticeImage, error) { + buf := new(bytes.Buffer) + var w = multipart.NewWriter(buf) + err := w.WriteField("bkn", strconv.Itoa(c.getCSRFToken())) + if err != nil { + return nil, errors.Wrap(err, "write multipart failed") + } + err = w.WriteField("source", "troopNotice") + if err != nil { + return nil, errors.Wrap(err, "write multipart failed") + } + err = w.WriteField("m", "0") + if err != nil { + return nil, errors.Wrap(err, "write multipart failed") + } + h := make(textproto.MIMEHeader) + h.Set("Content-Disposition", `form-data; name="pic_up"; filename="temp_uploadFile.png"`) + h.Set("Content-Type", "image/png") + fw, err := w.CreatePart(h) + if err != nil { + return nil, errors.Wrap(err, "create multipart field failed") + } + _, err = fw.Write(img) + if err != nil { + return nil, errors.Wrap(err, "write multipart failed") + } + err = w.Close() + if err != nil { + return nil, errors.Wrap(err, "close multipart failed") + } + req, err := http.NewRequest("POST", "https://web.qun.qq.com/cgi-bin/announce/upload_img", buf) + if err != nil { + return nil, errors.Wrap(err, "new request error") + } + req.Header.Set("Content-Type", w.FormDataContentType()) + req.Header.Set("Cookie", c.getCookies()) + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, errors.Wrap(err, "post error") + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, errors.Wrap(err, "read body error") + } + res := noticePicUpResponse{} + err = json.Unmarshal(body, &res) + if err != nil { + return nil, errors.Wrap(err, "failed to unmarshal json") + } + if res.ErrorCode != 0 { + return nil, errors.New(res.ErrorMessage) + } + ret := ¬iceImage{} + err = json.UnmarshalFromString(html.UnescapeString(res.ID), &ret) + if err != nil { + return nil, errors.Wrap(err, "failed to unmarshal json") + } + return ret, nil +} + +// AddGroupNoticeSimple 发群公告 +func (c *QQClient) AddGroupNoticeSimple(groupCode int64, text string) error { + body := fmt.Sprintf(`qid=%v&bkn=%v&text=%v&pinned=0&type=1&settings={"is_show_edit_card":0,"tip_window_type":1,"confirm_required":1}`, groupCode, c.getCSRFToken(), url.QueryEscape(text)) + _, err := utils.HttpPostBytesWithCookie("https://web.qun.qq.com/cgi-bin/announce/add_qun_notice?bkn="+fmt.Sprint(c.getCSRFToken()), []byte(body), c.getCookiesWithDomain("qun.qq.com")) + if err != nil { + return errors.Wrap(err, "request error") + } + return nil +} + +// AddGroupNoticeWithPic 发群公告带图片 +func (c *QQClient) AddGroupNoticeWithPic(groupCode int64, text string, pic []byte) error { + img, err := c.uploadGroupNoticePic(pic) + if err != nil { + return err + } + body := fmt.Sprintf(`qid=%v&bkn=%v&text=%v&pinned=0&type=1&settings={"is_show_edit_card":0,"tip_window_type":1,"confirm_required":1}&pic=%v&imgWidth=%v&imgHeight=%v`, groupCode, c.getCSRFToken(), url.QueryEscape(text), img.ID, img.Width, img.Height) + _, err = utils.HttpPostBytesWithCookie("https://web.qun.qq.com/cgi-bin/announce/add_qun_notice?bkn="+fmt.Sprint(c.getCSRFToken()), []byte(body), c.getCookiesWithDomain("qun.qq.com")) + if err != nil { + return errors.Wrap(err, "request error") + } + return nil +}