Skip to content

Commit c921d00

Browse files
committed
render incoming image
1 parent 210b448 commit c921d00

File tree

4 files changed

+123
-4
lines changed

4 files changed

+123
-4
lines changed

pkg/connector/client.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ func (c *GChatClient) onConnect(ctx context.Context) {
143143
},
144144
ChatInfo: &bridgev2.ChatInfo{
145145
Name: name,
146-
Members: c.gcMembersToMxMembers(gcMembers),
146+
Members: c.gcMembersToMatrix(gcMembers),
147147
},
148148
})
149149

@@ -200,9 +200,19 @@ func (c *GChatClient) convertToMatrix(ctx context.Context, portal *bridgev2.Port
200200
parts = append(parts, textPart)
201201
}
202202

203+
for _, annotation := range msg.Annotations {
204+
attachmentPart, err := c.gcAnnotationToMatrix(ctx, portal, intent, annotation)
205+
if err != nil {
206+
fmt.Println(err)
207+
continue
208+
}
209+
parts = append(parts, attachmentPart)
210+
}
211+
203212
cm := &bridgev2.ConvertedMessage{
204213
Parts: parts,
205214
}
215+
cm.MergeCaption()
206216

207217
return cm
208218
}

pkg/connector/mapping.go

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
package connector
22

33
import (
4+
"context"
5+
"io"
6+
"mime"
7+
"net/url"
8+
"strings"
9+
410
"maunium.net/go/mautrix/bridgev2"
511
"maunium.net/go/mautrix/bridgev2/networkid"
12+
bridgeEvt "maunium.net/go/mautrix/event"
613

714
"go.mau.fi/mautrix-googlechat/pkg/gchatmeow/proto"
815
)
916

10-
func (c *GChatClient) gcMembersToMxMembers(gcMembers []*proto.UserId) *bridgev2.ChatMemberList {
17+
func (c *GChatClient) gcMembersToMatrix(gcMembers []*proto.UserId) *bridgev2.ChatMemberList {
1118
memberMap := map[networkid.UserID]bridgev2.ChatMember{}
1219
for _, gcMember := range gcMembers {
1320
userId := networkid.UserID(*gcMember.Id)
@@ -23,3 +30,83 @@ func (c *GChatClient) gcMembersToMxMembers(gcMembers []*proto.UserId) *bridgev2.
2330
MemberMap: memberMap,
2431
}
2532
}
33+
34+
func (c *GChatClient) gcAnnotationToMatrix(ctx context.Context, portal *bridgev2.Portal, intent bridgev2.MatrixAPI, annotation *proto.Annotation) (*bridgev2.ConvertedMessagePart, error) {
35+
var attUrl *url.URL
36+
var mimeType string
37+
var fileName string
38+
uploadMeta := annotation.GetUploadMetadata()
39+
urlMeta := annotation.GetUrlMetadata()
40+
if uploadMeta != nil {
41+
mimeType = *uploadMeta.ContentType
42+
fileName = *uploadMeta.ContentName
43+
params := url.Values{
44+
"url_type": []string{"DOWNLOAD_URL"},
45+
"attachment_token": []string{uploadMeta.GetAttachmentToken()},
46+
}
47+
if strings.HasPrefix(*uploadMeta.ContentType, "image/") {
48+
params.Set("url_type", "FIFE_URL")
49+
params.Set("sz", "w10000-h10000")
50+
params.Set("content_type", *uploadMeta.ContentType)
51+
}
52+
parsedUrl, err := url.Parse("https://chat.google.com/api/get_attachment_url")
53+
if err != nil {
54+
return nil, err
55+
}
56+
attUrl = parsedUrl
57+
attUrl.RawQuery = params.Encode()
58+
59+
} else if urlMeta != nil {
60+
if urlMeta.MimeType != nil {
61+
mimeType = *urlMeta.MimeType
62+
}
63+
parsedUrl, err := url.Parse(*urlMeta.Url.Url)
64+
if err != nil {
65+
return nil, err
66+
}
67+
attUrl = parsedUrl
68+
} else {
69+
return nil, nil
70+
}
71+
resp, err := c.client.DownloadAttachment(ctx, attUrl)
72+
if err != nil {
73+
return nil, err
74+
}
75+
76+
if fileName == "" {
77+
_, params, _ := mime.ParseMediaType(resp.Header.Get("Content-Disposition"))
78+
fileName = params["filename"]
79+
}
80+
if mimeType == "" {
81+
mimeType = resp.Header.Get("Content-Type")
82+
}
83+
if fileName == "" && mimeType != "" {
84+
fileName = strings.Replace(mimeType, "/", ".", 1)
85+
}
86+
87+
content := bridgeEvt.MessageEventContent{
88+
Body: fileName,
89+
Info: &bridgeEvt.FileInfo{
90+
MimeType: mimeType,
91+
},
92+
MsgType: bridgeEvt.MsgImage,
93+
}
94+
content.URL, content.File, err = intent.UploadMediaStream(ctx, portal.MXID, resp.ContentLength, true, func(file io.Writer) (*bridgev2.FileStreamResult, error) {
95+
_, err := io.Copy(file, resp.Body)
96+
if err != nil {
97+
return nil, err
98+
}
99+
return &bridgev2.FileStreamResult{
100+
MimeType: content.Info.MimeType,
101+
FileName: fileName,
102+
}, nil
103+
})
104+
if err != nil {
105+
return nil, err
106+
}
107+
return &bridgev2.ConvertedMessagePart{
108+
ID: "",
109+
Type: bridgeEvt.EventMessage,
110+
Content: &content,
111+
}, nil
112+
}

pkg/gchatmeow/channel.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ func (c *Channel) longPollRequest(ctx context.Context) error {
425425

426426
func (c *Channel) onPushData(dataBytes []byte) error {
427427
// Log received chunk
428-
log.Printf("Received chunk:\n%s", string(dataBytes))
428+
// log.Printf("Received chunk:\n%s", string(dataBytes))
429429

430430
// Process chunks
431431
chunks := c.chunkParser.GetChunks(dataBytes)

pkg/gchatmeow/client.go

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import (
99
"net/url"
1010
"os"
1111
"regexp"
12+
"slices"
13+
"strings"
1214
"sync"
1315
"time"
1416

@@ -200,7 +202,7 @@ func (c *Client) onReceiveArray(arg interface{}) {
200202

201203
// Process each event body
202204
for _, evt := range c.splitEventBodies(resp.GetEvent()) {
203-
log.Printf("Dispatching stream event: %v", evt)
205+
log.Printf("Dispatching stream event: %v", evt.String())
204206
c.OnStreamEvent.Fire(evt)
205207
}
206208

@@ -252,3 +254,23 @@ func (c *Client) GetSelf(ctx context.Context) (*proto.User, error) {
252254
func (c *Client) Sync(ctx context.Context) (*proto.PaginatedWorldResponse, error) {
253255
return c.paginatedWorld(ctx)
254256
}
257+
258+
func (c *Client) DownloadAttachment(ctx context.Context, attUrl *url.URL) (*http.Response, error) {
259+
urlStr := attUrl.String()
260+
if strings.HasSuffix(attUrl.Host, ".google.com") {
261+
resp, err := c.session.FetchRaw(ctx, http.MethodGet, urlStr, nil, nil, false, nil)
262+
if err != nil {
263+
return nil, err
264+
}
265+
if slices.Contains([]int{301, 302, 307, 308}, resp.StatusCode) {
266+
redirected, err := url.Parse(resp.Header.Get("Location"))
267+
if err != nil {
268+
return nil, err
269+
}
270+
return c.DownloadAttachment(ctx, redirected)
271+
}
272+
}
273+
274+
// External attachment
275+
return http.Get(urlStr)
276+
}

0 commit comments

Comments
 (0)