diff --git a/pkg/connector/capabilities.go b/pkg/connector/capabilities.go index 1026a12..1afb951 100644 --- a/pkg/connector/capabilities.go +++ b/pkg/connector/capabilities.go @@ -32,7 +32,7 @@ func (*LinkedInConnector) GetCapabilities() *bridgev2.NetworkGeneralCapabilities } func (*LinkedInConnector) GetBridgeInfoVersion() (info, capabilities int) { - return 1, 7 + return 1, 8 } const MaxTextLength = 8000 @@ -46,7 +46,7 @@ func supportedIfFFmpeg() event.CapabilitySupportLevel { } func capID() string { - base := "fi.mau.linkedin.capabilities.2025_10_08" + base := "fi.mau.linkedin.capabilities.2025_12_10" if ffmpeg.Supported() { return base + "+ffmpeg" } @@ -123,6 +123,10 @@ var fileCaps = event.FileFeatureMap{ }, } +var stateCaps = event.StateFeatureMap{ + event.StateRoomName.Type: {Level: event.CapLevelFullySupported}, +} + func (*LinkedInClient) GetCapabilities(ctx context.Context, portal *bridgev2.Portal) *event.RoomFeatures { return &event.RoomFeatures{ ID: capID(), @@ -140,5 +144,6 @@ func (*LinkedInClient) GetCapabilities(ctx context.Context, portal *bridgev2.Por ReadReceipts: true, TypingNotifications: true, DeleteChat: true, + State: stateCaps, } } diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index 6678adc..82056bb 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -78,6 +78,11 @@ func (l *LinkedInClient) conversationToChatInfo(conv linkedingo.Conversation) (c IsFull: true, TotalMemberCount: len(conv.ConversationParticipants), MemberMap: map[networkid.UserID]bridgev2.ChatMember{}, + PowerLevels: &bridgev2.PowerLevelOverrides{ + Events: map[event.Type]int{ + event.StateRoomName: 0, + }, + }, } for _, participant := range conv.ConversationParticipants { userInChat = userInChat || networkid.UserID(participant.EntityURN.ID()) == l.userID diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index ed2337c..50ae8f3 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -43,6 +43,7 @@ var ( _ bridgev2.ReactionHandlingNetworkAPI = (*LinkedInClient)(nil) _ bridgev2.RedactionHandlingNetworkAPI = (*LinkedInClient)(nil) _ bridgev2.ReadReceiptHandlingNetworkAPI = (*LinkedInClient)(nil) + _ bridgev2.RoomNameHandlingNetworkAPI = (*LinkedInClient)(nil) _ bridgev2.TypingHandlingNetworkAPI = (*LinkedInClient)(nil) _ bridgev2.DeleteChatHandlingNetworkAPI = (*LinkedInClient)(nil) ) @@ -282,3 +283,11 @@ func (l *LinkedInClient) HandleMatrixTyping(ctx context.Context, msg *bridgev2.M func (l *LinkedInClient) HandleMatrixDeleteChat(ctx context.Context, chat *bridgev2.MatrixDeleteChat) error { return l.client.DeleteConversation(ctx, linkedingo.NewURN(chat.Portal.ID)) } + +func (l *LinkedInClient) HandleMatrixRoomName(ctx context.Context, msg *bridgev2.MatrixRoomName) (bool, error) { + err := l.client.RenameConversation(ctx, linkedingo.NewURN(msg.Portal.ID), msg.Content.Name) + if err != nil { + return false, err + } + return true, nil +} diff --git a/pkg/linkedingo/conversations.go b/pkg/linkedingo/conversations.go index 7a0076e..7cf8603 100644 --- a/pkg/linkedingo/conversations.go +++ b/pkg/linkedingo/conversations.go @@ -210,3 +210,18 @@ func (c *Client) DeleteConversation(ctx context.Context, conversationURN URN) er type DecoratedConversationDelete struct { Result Conversation `json:"result,omitempty"` } + +type RenameConversationBody struct { + Title string `json:"title"` +} + +func (c *Client) RenameConversation(ctx context.Context, conversationURN URN, title string) error { + url := fmt.Sprintf("%s/%s", linkedInMessagingDashMessengerConversationsURL, url.QueryEscape(conversationURN.String())) + body := GraphQLPatchBody{Patch: Patch{Set: RenameConversationBody{Title: title}}} + req := c.newAuthedRequest(http.MethodPost, url). + WithCSRF(). + WithXLIHeaders(). + WithJSONPayload(body) + _, err := req.Do(ctx, nil) + return err +}