Skip to content

Commit 2cd6183

Browse files
nexy7574tulir
andauthored
client: add support for arbitrary fields in /profile (#337)
Co-authored-by: Tulir Asokan <[email protected]>
1 parent ba210a1 commit 2cd6183

File tree

2 files changed

+55
-2
lines changed

2 files changed

+55
-2
lines changed

client.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,6 +1043,22 @@ func (cli *Client) SetDisplayName(ctx context.Context, displayName string) (err
10431043
return
10441044
}
10451045

1046+
// UnstableSetProfileField sets an arbitrary MSC4133 profile field. See https://github.com/matrix-org/matrix-spec-proposals/pull/4133
1047+
func (cli *Client) UnstableSetProfileField(ctx context.Context, key string, value any) (err error) {
1048+
urlPath := cli.BuildClientURL("unstable", "uk.tcpip.msc4133", "profile", cli.UserID, key)
1049+
_, err = cli.MakeRequest(ctx, http.MethodPut, urlPath, map[string]any{
1050+
key: value,
1051+
}, nil)
1052+
return
1053+
}
1054+
1055+
// UnstableDeleteProfileField deletes an arbitrary MSC4133 profile field. See https://github.com/matrix-org/matrix-spec-proposals/pull/4133
1056+
func (cli *Client) UnstableDeleteProfileField(ctx context.Context, key string) (err error) {
1057+
urlPath := cli.BuildClientURL("unstable", "uk.tcpip.msc4133", "profile", cli.UserID, key)
1058+
_, err = cli.MakeRequest(ctx, http.MethodDelete, urlPath, nil, nil)
1059+
return
1060+
}
1061+
10461062
// GetAvatarURL gets the avatar URL of the user with the specified MXID. See https://spec.matrix.org/v1.2/client-server-api/#get_matrixclientv3profileuseridavatar_url
10471063
func (cli *Client) GetAvatarURL(ctx context.Context, mxid id.UserID) (url id.ContentURI, err error) {
10481064
urlPath := cli.BuildClientURL("v3", "profile", mxid, "avatar_url")

responses.go

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bytes"
55
"encoding/json"
66
"fmt"
7+
"maps"
78
"reflect"
89
"strconv"
910
"strings"
@@ -155,8 +156,44 @@ type RespUserDisplayName struct {
155156
}
156157

157158
type RespUserProfile struct {
158-
DisplayName string `json:"displayname"`
159-
AvatarURL id.ContentURI `json:"avatar_url"`
159+
DisplayName string `json:"displayname,omitempty"`
160+
AvatarURL id.ContentURI `json:"avatar_url,omitempty"`
161+
Extra map[string]any `json:"-"`
162+
}
163+
164+
type marshalableUserProfile RespUserProfile
165+
166+
func (r *RespUserProfile) UnmarshalJSON(data []byte) error {
167+
err := json.Unmarshal(data, &r.Extra)
168+
if err != nil {
169+
return err
170+
}
171+
r.DisplayName, _ = r.Extra["displayname"].(string)
172+
avatarURL, _ := r.Extra["avatar_url"].(string)
173+
if avatarURL != "" {
174+
r.AvatarURL, _ = id.ParseContentURI(avatarURL)
175+
}
176+
delete(r.Extra, "displayname")
177+
delete(r.Extra, "avatar_url")
178+
return nil
179+
}
180+
181+
func (r *RespUserProfile) MarshalJSON() ([]byte, error) {
182+
if len(r.Extra) == 0 {
183+
return json.Marshal((*marshalableUserProfile)(r))
184+
}
185+
marshalMap := maps.Clone(r.Extra)
186+
if r.DisplayName != "" {
187+
marshalMap["displayname"] = r.DisplayName
188+
} else {
189+
delete(marshalMap, "displayname")
190+
}
191+
if !r.AvatarURL.IsEmpty() {
192+
marshalMap["avatar_url"] = r.AvatarURL.String()
193+
} else {
194+
delete(marshalMap, "avatar_url")
195+
}
196+
return json.Marshal(r.Extra)
160197
}
161198

162199
type RespMutualRooms struct {

0 commit comments

Comments
 (0)