Как сделать API на любое Android приложение. На примере WhatsApp

    Приветствую! Нарисовалась у меня задача: нужно интегрировать в CRM систему мессенджеры, а то трудно анализировать работу менеджеров, когда они общаются с клиентами используя один общий «рабочий» телефон. И первым делом нужно было подключить WhatsApp, как один из самых популярных мессенджеров у нашей целевой аудитории.

    Анализ ситуации...


    Казалось, требуется всего лишь отправлять и принимать сообщения. А столько подводных камней…

    1. Официальный API


    Официального API в релизе тогда ещё не было. Но Facebook успел прислать ссылку на форму, для подключения официального API, находящегося в тестировании.

    2. Сторонний сервис. Подключение через WhatsApp WEB


    Рассматривал вариант «серого» способа, использование неофициального сервиса, который отправляет сообщения через WEB интерфейс, подключается сканированием QR кода.

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

    Ну и ещё требуется держать телефон включенным (хотя некоторые сервисы за доп плату решали эту проблему :)

    3. Ручной режим


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

    Решение


    Отправка сообщения


    image Есть такая программка для автоматизации действий под Android, называется Tasker, одна из первых подобных программ. Но я в ней не разобрался с первого раза… Поискал аналоги, наткнулся на программу Automagic. В ней события, действия и ветвления рисуются как блок схема.

    Оффтоп
    Передаю привет конструктору HiAsm, благодаря которому когда то научился понимать концепцию программирования.

    И вот в ней я то и придумал решение, root права нам не нужны. Получилось методом научного тыка нарисовать скрипт отправки сообщения, далее буду называть поток, так именуется каждый отдельный нарисованный алгоритм в данной программе. А теперь разберём его работу:

    Скриншот потока отправки сообщения в WhatsApp
    image

    1. Каждые 5 секунд периодичным таймером генерируется событие и передаётся следующему блоку.
    2. Блок HTTP Request спрашивает у сервера, есть ли в очереди следующее сообщение, которое нужно отправить? Бэкенд написан на PHP.
    3. Парсим ответ сервера JSON.
    4. Если от сервера в ответе пришла метка, что нужно отправить сообщение, идём дальше.
    5. Проверяем, включен ли экран устройства, если нет, отправляем уведомление, с целью разбудить телефон. Если же экран включен, и не выполняется другой поток, проверяющий статус, доставлено ли сообщение, то:
    6. Генерируем ссылку и открываем её, что бы инициировать диалог с полученным от сервера номером телефона в WhatsApp'е
    7. Самое интересное. Блок Control UI. В нём в виде кода реализована логика проверки успешности открытия чата (проверка регистрации в мессенджере), вставка текста в окно ввода и клацанье по кнопке Отправить.

      Код писал с мобильного, как заработал, больше не трогал
      sleep(2000);  // 2 секунды на запуск вацапа
       
      sle = 200;
      ch_c = 0;
      ch = false;
      is_sended = false;
       
      sleep(sle);
      ch = existsElementById("com.whatsapp:id/entry"); // Проверяем, появилась ли на экране кнопка отправить
      sleep(sle);
      if (ch == false) {
        ch = existsElementById("com.whatsapp:id/entry"); // Снова проверяем
        ch_c = ch_c + 1;
        sleep(1500);
      }
      
      if (ch == false) {
        ch = existsElementById("com.whatsapp:id/entry"); 
        ch_c = ch_c + 1;
        sleep(5500);
      }
      
      ch = existsElementById("com.whatsapp:id/entry");
      sleep(sle);
      setText2ById("com.whatsapp:id/entry",text); // Вставляем сообщение
      sleep(sle);
      
      clickById("com.whatsapp:id/send");  // Жмём кнопку отправить
      sleep(sle);
      back();
      sleep(sle);
      back();
      status = 2;
      
      if(ch == true) {  // Если всё хорошо, запоминаем, для отправки на сервер
        is_sended = true;
        status = 1;
      }
      

    8. Отправляем результаты отправки сообщения на сервер.
    9. Возвращаемся на домашний экран.

    Приём сообщений


    Принимать сообщения на много проще. Ставим событие на уведомление от мессенджера. Как только приходит уведомление, помечаем его прочитанным, и отправляем его на сервер как есть. Тот уже спарсит адресата и текст.

    Скриншот алгоритма приёма сообщений


    Плюсы, минусы, доработка и планы


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

    На отправку одного сообщения новому контакту уходит ~5 сек. Для проверки доставки и прочтения сообщения, разработал отдельный поток, но он в черновом варианте и иногда не срабатывает. Поэтому о нём позже.

    В данный момент не реализована функция приёма медиа сообщений (фото, аудио, вложения), но это можно выгружать из WhatsApp, используя кнопку поделиться сообщением в будущем.

    Чуть позже хочу сверху виртуальной машины, где запущен мессенджер, написать SIP транк, через который можно будет звонить через WhatsApp как через SIP ^.^ что может сэкономить расходы на связь.

    Ещё хочу делать скриншоты аватарок и отправлять их на сервер, для прикрепления миниатюры к контакту в CRM системе.

    Ну и вообще самое интересное: Данный способ обёртывания в API подойдёт почти для любого приложения под Android :)

    Всё изначально разрабатывал и запускал на Android 9, xiaomi mi 9 se, root прав нет.

    Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

    Если используете отправку из WhatsApp, то какой API?

    • 38,5%Официальный API15
    • 28,2%Через WhatsApp WEB (QR код)11
    • 20,5%Отправляю вручную8
    • 12,8%Придумал своё5

    Похожие публикации

    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 21

      0
        0

        Опять же сторонний сервис, требует денежку за каждое сообщение, персональные данные уходят посреднику.

          0
          а вы пользуетесь whatsapp через twilio?
          +1

          Пользуюсь этой библиотекой
          https://github.com/Rhymen/go-whatsapp
          Можно сказать, что пользуюсь api через web-клиент

            +1
            Пробовал похожую реализацию через Selenium или Headless Chrome. Но наблюдал частые отвалы веб клиента или большие задержки (были проблемы на стороне вацапа тогда) и решил забросить эту идею… Ваш вариант на языке GO, я пробовал варианты с питоном и nodejs. Вполне рабочий вариант. Но есть риск, что вацап неожиданно что то поменяет в вёрстке…
              +2
              Данная библиотека не работает на подобии selenium, а воспроизводит протокол WhatsappWeb. Это ощутимое преимущество, но и потенциально повышенный шанс получить блокировку. Хотя, пока, лично у меня, не было такого случая.
                +1
                Ух ты! Круто! О таком подходе я не задумывался. Благодарю.
                  0
                  Хотя, пока, лично у меня, не было такого случая.
                  А какая была максимальная частота отправки сообщений? Я давно хочу к метрикам/мониторингу прикрутить вацап, там около 4..5 контактов и порядка 1..2 сообщений в 10..60 минут каждому абоненту, такой кейс не будет сочтен спамом?
                    +1

                    Не смогу подсказать. Мне кажется, невысокий трафик. Чтобы не сочли спамом, контакты должны быть добавлены друг у друга.

                      +1
                      Вотсап проверяет, что вы у получателя в контактах (по номеру телефона), если нет — то ждите блокировок. На 4-5 номеров можете без паузы слать, проблем быть не должно.
                0

                Если я правильно понял то можно парсить json данные приложении на андроид?

                  0
                  Программа automagic имеет в себе встроенный JSON парсер. Но в моём примере я использовал его только для общения с бэкендом. Принимаю сообщения я из уведомлений, там приходит сообщение в формате "+7 XXX XXX XX XX текст сообщения". Можно сделать и открытие чата, и читать сообщения из окна. Такой способ использует алгоритм определения доставки/прочтения сообщения. Но о нём в статье пока не писал.
                  0
                    +1
                    Опять же, это просто один из способов отправки через очередной сторонний сервис. У них много вариантов взаимодействия.
                    +1

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

                      0
                      Интересное решение!
                      Не понял только как на виртуальный сервер установить Андроид. Вы имели ввиду эмулятор?
                        0
                        androidx86 вполне сносно работает под kvm, libhoudini неплохо запускает arm-приложения.
                        +1

                        Идея хорошая.


                        Чтобы не обращаться к сайту wa.me можно сразу использовать такой вариант whatsapp://send/?phone={phone}


                        Код отправки сообщения немного доработал
                        attempts = 0;
                        maxAttemps = 5;
                        isEntryFieldExsist = false;
                        while(!isEntryFieldExsist && attempts <= maxAttemps) {
                        isEntryFieldExsist = existsElementById("com.whatsapp:id/entry");
                        attempts = attempts + 1;
                        sleep(1000);
                        }


                        isTextSended = false;
                        if (isEntryFieldExsist) {
                        setText2ById("com.whatsapp:id/entry", text);
                        isTextSended = clickById("com.whatsapp:id/send");
                        }


                        back();
                        back();

                          0
                          Благодарю за отзыв. Да, ваш код эффективнее!
                          0
                          подскажите, пуши от сбербанк онлайн тоже можно спарсить?
                            0
                            Конечно можно. Через триггер на получение уведомления от приложения сбербанка.

                          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                          Самое читаемое