Перейти к содержанию

Интеграция в мобильные приложения Android

Шаг 1. Установка библиотеки Webim Mobile SDK

  1. Откройте файл build.gradle приложения (модуля). Укажите адрес репозитория и добавьте следующий код:

    repositories {
        maven { url 'https://jitpack.io' }
    }
    
    dependencies {
        ...
        implementation 'ru.webim.sdk:webimclientsdkandroid:3.+'
    }
    

    Для того, чтобы изменения применились, необходимо синхронизировать проект. Например, в Android Studio можно нажать Sync Now или выбрать в меню File → Sync Progect with Gradle Files. Дождитесь окончания синхронизации.

    Если синхронизация завершилась успешно, при компиляции библиотека будет добавлена в проект автоматически. При ошибке компиляции, убедитесь что вы правильно указали репозиторий и зависимость и синхронизируйте проект снова.

    webimclientsdkandroid on JitPack

  2. Редактируйте файл AndroidManifest.xml. Необходимо добавить в Ваш манифест следующие элементы: в корень manifest необходимо добавить разрешение:

    <uses -permission android:name="android.permission.INTERNET">
    

    для хранения истории чата на устройстве следует добавить следующие зависимости:

    <uses -permission android:name="android.permission.READ_EXTERNAL_STORAGE">
    <uses -permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">
    

    при необходимости предотвращения перехода устройства в спящий режим для того, чтобы всегда получать сообщения из чата, добавляется следующая строка:

    <uses -permission android:name="android.permission.WAKE_LOCK">
    

Шаг 2. Работа с Webim Mobile SDK

Работа с сессией

После внедрения зависимости в приложение необходимо создать сессию. Сессия в Webim Mobile SDK является отдельной сущностью от VisitSession, которая реализуется на Webim Server.

Сессией называют сеанс, в течение которого приложение взаимодействует с сервисом. В текущей версии SDK он получает любую информацию от Webim Server только в рамках сессии. До её создания SDK не получит с сервера никакой информации. Началом сессии считается выполнение метода resume(), а завершением — выполнение метода destroy(), либо аварийная остановка приложения.

Но для того, чтобы начать выполнять действия с сессией, необходимо сначала создать объект сессии.

  1. Создание сессии. Объект сессии создаётся методом newSessionBuilder класса Webim, который возвращает объект класса-строителя SessionBuilder (оба класса и их методы описаны в файле Webim.java). После задания всех необходимых параметров на созданном объекте SessionBuilder вызывается метод build(), который возвращает объект WebimSession. Пример использования (для Android):

    WebimSession webimSession = Webim.newSessionBuilder()
        .setAccountName(ACCOUNT_NAME)
        .setLocation(LOCATION_NAME)
        .build()
    

    Поле ACCOUNT_NAME должно соответствовать имени аккаунта, если чат размещён в облачной конфигурации (на серверах Webim — см. Сетевые конфигурации сервиса Webim). Если же чат размещён на серверах заказчика, то вместо него должен быть указан полный URL (пример: https://chat.company.ru).

    Поле LOCATION_NAME содержит наименование размещения. Если в нём указать несуществующее значение, то обращение будет в размещении default.

    Вызов метода build() завершает установку начальных параметров и создаёт сессию в приостановленном виде.

    Описание всех параметров, которые можно задать при создании сессии, а также ошибок, которые могут возникать в процессе, можно найти в справочнике. Обязательными из них являются только два – имя аккаунта и размещение.

    Если заданы только имя аккаунта и размещение, сессия будет создана в неавторизованной зоне, тем не менее, это будет персональный чат.

  2. Методы сессии. Ниже описаны базовые методы, которые необходимо вызывать при работе с объектом сессии.

    Метод Описание Следующий метод
    resume После создания объекта сессии необходимо вызвать метод resume(), который запустит сессию. В результате ответа сервера стартует сетевая активность сессии в результате чего могут быть вызванные методы MessageListener, ChatStateListener, CurrentOperatorChangeListener и LocationSettingsChangeListener. Этот метод также используется для возобновления сессии после вызова метода pause(). pause()
    destroy()
    destroyWithClearVisitorData()
    pause() Метод, который используется для приостановки сетевой активности сессии (например, когда пользователь не находится в активном окне приложения). Если сессия уже находится в приостановленном состоянии, метод не произведёт никаких действий. resume()
    destroy()
    destroyWithClearVisitorData()
    destroy() Метод, который используется для деактивации сессии и экземпляра класса. После вызова данного метода никакие методы, относящиеся к сессии, использованы быть не могут.
    destroyWithClearVisitorData() Метод, который используется для деактивации сессии и экземпляра класса с удалением информации о пользователе. После вызова данного метода никакие методы, относящиеся к сессии, использованы быть не могут.

    Примеры использования:

    public class MainActivity extends AppCompatActivity {
      private WebimSession session;
      private static final String ACCOUNT_NAME = "account";
      private static final String LOCATION_NAME = "mobile";
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          webimSession = Webim.newSessionBuilder()
              .setAccountName(ACCOUNT_NAME)
              .setLocation(LOCATION_NAME)
              .build()
      }
      protected void onStart() {
          super.onStart();
          session.resume();
      }
      protected void onResume() {
          super.onResume();
          session.resume();
      }
      protected void onPause() {
          super.onPause();
          session.pause();
      }
      protected void onDestroy() {
          session.destroy();
          super.onDestroy();
      }
    }
    

Установка интерфейсов и протоколов

Для функционирования приложения на базе SDK обязательна установка всех перечисленных ниже интерфейсов и протоколов. Для использования методов интерфейса необходимо, чтобы сессия не находилась в приостановленном или деактивированном виде.

  1. MessageStream необходим для непосредственного взаимодействия с сервисом Webim (например, для отправки или получения сообщений). Устанавливается путём вызова метода getStream() экземпляра WebimSession. Примеры использования:

    • Отправить сообщение

      session.getStream().sendMessage(message);
      
    • Удалить сообщение

      session.getStream().deleteMessage(message, callback);
      
    • Отследить изменения оператора текущего чата

      session.getStream().setCurrentOperatorChangeListener(
              new MessageStream.CurrentOperatorChangeListener() {
              @Override
              public void onOperatorChanged(@Nullable Operator oldOperator,
                                      @Nullable Operator newOperator) {
      //your code
             }
         });
      
    • Отследить изменения статуса сессии

      session.getStream().setVisitSessionStateListener(
              new MessageStream.VisitSessionStateListener() {
              @Override
              public void onStateChange(@NonNull MessageStream.VisitSessionState previousState,
                                      @NonNull MessageStream.VisitSessionState newState) {
      //your code
              }
          });
      
    • Отследить изменения состояния текущего чата

      session.getStream().setChatStateListener(
              new MessageStream.ChatStateListener() {
              @Override
              public void onStateChange(@NonNull MessageStream.ChatState oldState,
                                      @NonNull MessageStream.ChatState newState) {
      //your code
              }
          });
      

    Список всех методов, а так же более подробную информацию о них можно найти в описании метода MessageStream.

  2. MessageListener необходим для получения изменений в потоке сообщений. Его методы вызываются автоматически при осуществлении действий с сообщениями в чате: при добавлении сообщения, удаления сообщения, удаления всех сообщений и изменении сообщения, соответственно. В пользовательском приложении необходим класс, который реализует методы данного интерфейса: messageAdded(Message, Message), messageRemoved(Message), allMessagesRemoved(), messageChanged(Message, Message).

    Пример использования:

    public class MainActivity extends AppCompatActivity {
        private WebimSession session;
        private ListController listController;
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            webimSession = Webim.newSessionBuilder()
                .setAccountName(ACCOUNT_NAME)
                .setLocation(LOCATION_NAME)
                .build()
            initChatView(rootView);
        }
        private void initChatView(View rootView) {
            RecyclerView recyclerView = rootView.findViewById(R.id.chat_recycler_view);
            listController = ListController.install(this, recyclerView);
        }
        private static class ListController implements MessageListener {
            private static final int MESSAGES_PER_REQUEST = 25;
            private final RecyclerView recyclerView;
            private final MessagesAdapter adapter;
            static ListController install(WebimChatFragment webimChatFragment,
                                          RecyclerView recyclerView) {
                return new ListController(webimChatFragment, recyclerView);
            }
            private ListController(final WebimChatFragment webimChatFragment,
                                   final RecyclerView recyclerView) {
                this.recyclerView = recyclerView;
                this.adapter = new MessagesAdapter(webimChatFragment);
                this.recyclerView.setAdapter(this.adapter);
            }
            @Override
            public void messageAdded(@Nullable Message before, @NonNull Message message) {
                int index = (before == null) ? 0 : adapter.indexOf(before);
                if (index < = 0) {
                    adapter.add(message);
                    adapter.notifyItemInserted(0);
                } else {
                    adapter.add(index, message);
                    adapter.notifyItemInserted(adapter.getItemCount() - index - 1);
                }
            }
    
            @Override
            public void messageRemoved(@NonNull Message message) {
                int index = adapter.indexOf(message);
                if (index != -1) {
                    adapter.remove(index);
                    adapter.notifyItemRemoved(adapter.getItemCount() - index);
                }
            }
    
            @Override
            public void messageChanged(@NonNull Message from, @NonNull Message to) {
                int index = adapter.lastIndexOf(from);
                if (index != -1) {
                    adapter.set(index, to);
                    adapter.notifyItemChanged(adapter.getItemCount() - index - 1, 42);
                }
            }
    
            @Override
            public void allMessagesRemoved() {
                int size = adapter.getItemCount();
                adapter.clear();
                adapter.notifyItemRangeRemoved(0, size);
            }
        }
    }
    

    Список всех методов, а также полную информацию о них можно найти в описании MessageListener.

  3. MessageTracker необходим для получения истории сообщений, которая хранится на локальном устройстве. На сервере же история сообщений хранится без ограничений по времени. Объект класса MessageTracker можно получить через метод newMessageTracker(MessageListener) объекта MessageStream:

    MessageTracker tracker = session.getStream.newMessageTracker(this);
    

    Метод newMessageTracker(MessageListener) объекта MessageStream создает объект класса MessageTracker, с помощью которого можно управлять потоком сообщений в контексте приложения клиента. Для получения последних сообщений из истории можно использовать метод getLastMessages(int limit, GetMessagesCallback callback), но не больше указанного лимита.

    Пример использования метода:

    int MESSAGES_PER_REQUEST = 25;
    tracker.getLastMessages(MESSAGES_PER_REQUEST, new MessageTracker.GetMessagesCallback() {
                    @Override
                    public void receive(@NonNull final List< ? extends Message> received) {
                        //your code
                    }
                });
    

    Для дальнейшей итерации по истории сообщений вызывается метод getNextMessages(int limit, GetMessagesCallback) — он запрашивает определенное количество сообщений из истории.

    Пример использования метода:

    int MESSAGES_PER_REQUEST = 25;
    tracker.getNextMessages(MESSAGES_PER_REQUEST, new MessageTracker.GetMessagesCallback() {
                    @Override
                    public void receive(@NonNull final List< ? extends Message> received) {
                        //your code
                    }
                });
    

    Message необходим для хранения информации о сообщениях. С помощью методов экземпляров класса Message можно получить все необходимые данные о конкретном сообщении: уникальный номер сообщение (метод getId()), текст сообщения (метод getText()), информацию о вложенном файле (метод getAttachment()) и т.д. Методы интерфейса MessageListener оперируют объектами класса Message. Все связанные с этим классом инструменты (методы для работы с вложениями, типы сообщений и пр.) описаны здесь.

    Подробное описание этих и других методов можно найти в справочниках методов для iOS и для Android.

Шаг 3. Прочие Настройки

Кроме установки перечисленных ранее интерфейсов для корректной работы приложения на базе Webim Mobile SDK необходимо произвести ряд настроек в коде приложения.

  1. Необходимо правильно настроить процедуру подсчёта visitor fields и hash. Приватный ключ аккаунта не должен храниться на устройстве или где бы то ни было, кроме сервера заказчика. В противном случае появляется серьёзная угроза безопасности и риск утечки переписок клиента третьим лицам.

    Пример передачи json-encoded объекта посетителя SDK:

    .setVisitorFieldsJson("{
        "id":"1234567890987654321",
        "display_name":"Никита",
        "hash":"ffadeb6aa3c788200824e311b9aa44cb"
    }")
    

    Подробно об идентификации авторизованных клиентов можно почитать в этой статье.

  2. Для приложения на базе SDK может быть использован обфускатор. В этом случае необходимо задавать исключения в правилах обфускатора, чтобы определённые классы не обфусцировались — это необходимо для корректной работы приложения на базе Webim Mobile SDK. В частности, при использовании обфускатора Proguard следует задать в его правилах следующее:

    -keep public class ru.webim.android.sdk.* { *; }
    

    Это будет означать, что указанный пакет/класс не будет "шифроваться" обфускатором.

  3. Обеспечить необходимые сетевые доступы.

    Для мобильного устройства, на котором установлено мобильное приложение, интегрированное с Webim Mobile SDK, должны быть открыты исходящие порты для следующих URL-адресов:

    • https://*.webim.ru/l/v/m/action 443 (POST) - используется для передачи действий от клиентов.

    • https://*.webim.ru/l/v/m/delta 443 (GET) - используется для получения инкрементальных обновлений.

    • https://*.webim.ru/l/v/m/download 443 (GET) (не используется в SDK, но нужно для скачивания файлов в мобильном приложении)

    • https://*.webim.ru/l/v/m/upload 443 (POST) - используется для отправки файлов с клиента на сервер.

    • https://*.webim.ru/l/v/m/history 443 (GET) - используется для получения истории чата из базы данных.

    Для отправки push-уведомлений должны быть открыты следующие порты:

    Если чат размещён на серверах заказчика, то домен должен быть изменен на их собственный.

  4. Для того, чтобы после завершения чата пользователь мог поставить оценку работы оператора, необходимо описать соответствующий механизм в приложении. SDK не реализует механизм оценки, а получает её от приложения клиента.

  5. Включены и настроены push-уведомления (опционально). Подробнее параметры push-уведомлений и примеры можно посмотреть в статье Push-уведомления.

  6. Для начала чата может вызываться метод startChat(). Если метод не будет вызван, чат будет начат после первого сообщения посетителя.