github.com/status-im/status-go@v1.1.0/services/chat/api_group_chats.go (about)

     1  package chat
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/status-im/status-go/eth-node/crypto"
     7  	"github.com/status-im/status-go/eth-node/types"
     8  	"github.com/status-im/status-go/protocol"
     9  	"github.com/status-im/status-go/protocol/common"
    10  	"github.com/status-im/status-go/protocol/requests"
    11  )
    12  
    13  type GroupChatResponse struct {
    14  	Chat     *protocol.Chat    `json:"chat"`
    15  	Messages []*common.Message `json:"messages"`
    16  }
    17  
    18  type GroupChatResponseWithInvitations struct {
    19  	Chat        *protocol.Chat                  `json:"chat"`
    20  	Messages    []*common.Message               `json:"messages"`
    21  	Invitations []*protocol.GroupChatInvitation `json:"invitations"`
    22  }
    23  
    24  type CreateOneToOneChatResponse struct {
    25  	Chat    *protocol.Chat    `json:"chat,omitempty"`
    26  	Contact *protocol.Contact `json:"contact,omitempty"`
    27  }
    28  
    29  type StartGroupChatResponse struct {
    30  	Chat     *protocol.Chat      `json:"chat,omitempty"`
    31  	Contacts []*protocol.Contact `json:"contacts"`
    32  	Messages []*common.Message   `json:"messages,omitempty"`
    33  }
    34  
    35  func (api *API) CreateOneToOneChat(ctx context.Context, communityID types.HexBytes, ID types.HexBytes, ensName string) (*CreateOneToOneChatResponse, error) {
    36  	if len(communityID) != 0 {
    37  		return nil, ErrCommunitiesNotSupported
    38  	}
    39  
    40  	response, err := api.s.messenger.CreateOneToOneChat(&requests.CreateOneToOneChat{ID: ID, ENSName: ensName})
    41  	if err != nil {
    42  		return nil, err
    43  	}
    44  
    45  	chat := response.Chats()[0]
    46  
    47  	var contact *protocol.Contact
    48  	if ensName != "" {
    49  		contact = response.Contacts[0]
    50  	}
    51  
    52  	return &CreateOneToOneChatResponse{
    53  		Chat:    chat,
    54  		Contact: contact,
    55  	}, nil
    56  }
    57  
    58  func (api *API) CreateGroupChat(ctx context.Context, communityID types.HexBytes, name string, members []string) (*GroupChatResponse, error) {
    59  	if len(communityID) != 0 {
    60  		return nil, ErrCommunitiesNotSupported
    61  	}
    62  
    63  	return api.execAndGetGroupChatResponse(func() (*protocol.MessengerResponse, error) {
    64  		return api.s.messenger.CreateGroupChatWithMembers(ctx, name, members)
    65  	})
    66  }
    67  
    68  func (api *API) CreateGroupChatFromInvitation(communityID types.HexBytes, name string, chatID string, adminPK string) (*GroupChatResponse, error) {
    69  	if len(communityID) != 0 {
    70  		return nil, ErrCommunitiesNotSupported
    71  	}
    72  
    73  	return api.execAndGetGroupChatResponse(func() (*protocol.MessengerResponse, error) {
    74  		return api.s.messenger.CreateGroupChatFromInvitation(name, chatID, adminPK)
    75  	})
    76  }
    77  
    78  func (api *API) LeaveChat(ctx context.Context, communityID types.HexBytes, chatID string, remove bool) (*GroupChatResponse, error) {
    79  	if len(communityID) != 0 {
    80  		return nil, ErrCommunitiesNotSupported
    81  	}
    82  
    83  	return api.execAndGetGroupChatResponse(func() (*protocol.MessengerResponse, error) {
    84  		return api.s.messenger.LeaveGroupChat(ctx, chatID, remove)
    85  	})
    86  }
    87  
    88  func (api *API) AddMembers(ctx context.Context, communityID types.HexBytes, chatID string, members []string) (*GroupChatResponseWithInvitations, error) {
    89  	if len(communityID) != 0 {
    90  		return nil, ErrCommunitiesNotSupported
    91  	}
    92  
    93  	return api.execAndGetGroupChatResponseWithInvitations(func() (*protocol.MessengerResponse, error) {
    94  		return api.s.messenger.AddMembersToGroupChat(ctx, chatID, members)
    95  	})
    96  }
    97  
    98  func (api *API) RemoveMember(ctx context.Context, communityID types.HexBytes, chatID string, member string) (*GroupChatResponse, error) {
    99  	if len(communityID) != 0 {
   100  		return nil, ErrCommunitiesNotSupported
   101  	}
   102  
   103  	return api.execAndGetGroupChatResponse(func() (*protocol.MessengerResponse, error) {
   104  		return api.s.messenger.RemoveMembersFromGroupChat(ctx, chatID, []string{member})
   105  	})
   106  }
   107  
   108  func (api *API) MakeAdmin(ctx context.Context, communityID types.HexBytes, chatID string, member string) (*GroupChatResponse, error) {
   109  	if len(communityID) != 0 {
   110  		return nil, ErrCommunitiesNotSupported
   111  	}
   112  
   113  	return api.execAndGetGroupChatResponse(func() (*protocol.MessengerResponse, error) {
   114  		return api.s.messenger.AddAdminsToGroupChat(ctx, chatID, []string{member})
   115  	})
   116  }
   117  
   118  func (api *API) RenameChat(ctx context.Context, communityID types.HexBytes, chatID string, name string) (*GroupChatResponse, error) {
   119  	if len(communityID) != 0 {
   120  		return nil, ErrCommunitiesNotSupported
   121  	}
   122  
   123  	return api.execAndGetGroupChatResponse(func() (*protocol.MessengerResponse, error) {
   124  		return api.s.messenger.ChangeGroupChatName(ctx, chatID, name)
   125  	})
   126  }
   127  
   128  func (api *API) SendGroupChatInvitationRequest(ctx context.Context, communityID types.HexBytes, chatID string, adminPK string, message string) (*GroupChatResponseWithInvitations, error) {
   129  	if len(communityID) != 0 {
   130  		return nil, ErrCommunitiesNotSupported
   131  	}
   132  
   133  	return api.execAndGetGroupChatResponseWithInvitations(func() (*protocol.MessengerResponse, error) {
   134  		return api.s.messenger.SendGroupChatInvitationRequest(ctx, chatID, adminPK, message)
   135  	})
   136  }
   137  
   138  func (api *API) GetGroupChatInvitations() ([]*protocol.GroupChatInvitation, error) {
   139  	return api.s.messenger.GetGroupChatInvitations()
   140  }
   141  
   142  func (api *API) SendGroupChatInvitationRejection(ctx context.Context, invitationRequestID string) ([]*protocol.GroupChatInvitation, error) {
   143  	response, err := api.s.messenger.SendGroupChatInvitationRejection(ctx, invitationRequestID)
   144  	if err != nil {
   145  		return nil, err
   146  	}
   147  	return response.Invitations, nil
   148  }
   149  
   150  func (api *API) StartGroupChat(ctx context.Context, communityID types.HexBytes, name string, members []string) (*StartGroupChatResponse, error) {
   151  	if len(communityID) != 0 {
   152  		return nil, ErrCommunitiesNotSupported
   153  	}
   154  
   155  	var response *protocol.MessengerResponse
   156  	var err error
   157  	if len(members) == 1 {
   158  		memberPk, err := common.HexToPubkey(members[0])
   159  		if err != nil {
   160  			return nil, err
   161  		}
   162  		response, err = api.s.messenger.CreateOneToOneChat(&requests.CreateOneToOneChat{
   163  			ID: types.HexBytes(crypto.FromECDSAPub(memberPk)),
   164  		})
   165  		if err != nil {
   166  			return nil, err
   167  		}
   168  	} else {
   169  		response, err = api.s.messenger.CreateGroupChatWithMembers(ctx, name, members)
   170  		if err != nil {
   171  			return nil, err
   172  		}
   173  	}
   174  
   175  	chat := response.Chats()[0]
   176  
   177  	return &StartGroupChatResponse{
   178  		Chat:     chat,
   179  		Contacts: response.Contacts,
   180  		Messages: response.Messages(),
   181  	}, nil
   182  }
   183  
   184  func (api *API) toGroupChatResponse(pubKey string, response *protocol.MessengerResponse) (*GroupChatResponse, error) {
   185  	chat := response.Chats()[0]
   186  
   187  	return &GroupChatResponse{
   188  		Chat:     chat,
   189  		Messages: response.Messages(),
   190  	}, nil
   191  }
   192  
   193  func (api *API) toGroupChatResponseWithInvitations(pubKey string, response *protocol.MessengerResponse) (*GroupChatResponseWithInvitations, error) {
   194  	g, err := api.toGroupChatResponse(pubKey, response)
   195  	if err != nil {
   196  		return nil, err
   197  	}
   198  
   199  	return &GroupChatResponseWithInvitations{
   200  		Chat:        g.Chat,
   201  		Messages:    g.Messages,
   202  		Invitations: response.Invitations,
   203  	}, nil
   204  }
   205  
   206  func (api *API) execAndGetGroupChatResponse(fn func() (*protocol.MessengerResponse, error)) (*GroupChatResponse, error) {
   207  	pubKey := types.EncodeHex(crypto.FromECDSAPub(api.s.messenger.IdentityPublicKey()))
   208  	response, err := fn()
   209  	if err != nil {
   210  		return nil, err
   211  	}
   212  	return api.toGroupChatResponse(pubKey, response)
   213  }
   214  
   215  func (api *API) execAndGetGroupChatResponseWithInvitations(fn func() (*protocol.MessengerResponse, error)) (*GroupChatResponseWithInvitations, error) {
   216  	pubKey := types.EncodeHex(crypto.FromECDSAPub(api.s.messenger.IdentityPublicKey()))
   217  
   218  	response, err := fn()
   219  	if err != nil {
   220  		return nil, err
   221  	}
   222  
   223  	return api.toGroupChatResponseWithInvitations(pubKey, response)
   224  }