private Mono<Void> sendMeetingInvitationMessage(
            @NotNull Long requesterId,
            @NotNull byte[] senderIp,
            @NotNull im.turms.server.common.access.client.dto.model.conference.Meeting meeting,
            @Nullable Long userId,
            @Nullable Long groupId) {
        if (userId != null) {
            if (groupId != null) {
                return EXCEPTION_USER_ID_AND_GROUP_ID_MUST_NOT_BOTH_NON_NULL;
            }
            var meetingInfoForParticipant = getMeetingInfoForParticipant(meeting);
            return messageService.saveAndSendMessage(null,
                    requesterId,
                    null,
                    senderIp,
                    null,
                    true,
                    true,
                    null,
                    List.of(BuiltinSystemMessageType.MEETING_INVITATION_BYTES,
                            meetingInfoForParticipant.toByteArray()),
                    userId,
                    null,
                    null);
        } else if (groupId == null) {
            return EXCEPTION_USER_ID_AND_GROUP_ID_MUST_NOT_BOTH_NULL;
        }
        var meetingInfoForParticipant = getMeetingInfoForParticipant(meeting);
        return messageService.saveAndSendMessage(null,
                requesterId,
                null,
                senderIp,
                null,
                false,
                true,
                null,
                List.of(BuiltinSystemMessageType.MEETING_INVITATION_BYTES,
                        meetingInfoForParticipant.toByteArray()),
                groupId,
                null,
                null);
    }
Use {@link SecureRandom} because users usually input meeting IDs to join meetings, so we
should make sure they are unpredictable.
turms-service/src/main/java/im/turms/service/domain/conference/service/ConferenceService.java