Тут на Пикабу всякие службы поддержки отвечают прям сразу, так что, давайте позовём Пятёрочку? Уже спортивный интерес.
Мне настойчиво лезет реклама доставки пяторошной. Хотя адрес у меня вполне деревенский. Но мало ли, Озон и Вб на дом вполне приезжают, Тинькофф тоже без проблем, а чего ж не быть Пятёрочке?
С год назад поставила приложение. Оно запросило все права, показало мне рекламу, повисло и было снесено. Думаю, прежде чем лезть в авантюру, надо глянуть, а поедет ли оно в принципе в наши степи
Но нет! На сайте нет информации о географии! Совсем нет!
Лады, напишем в поддержку.
Очень принципиальное нововведение. Не будем отвечать потенциальному клиенту, пусть напишет ещё разик.
Пишу
Сутки прочь, ответ примчался
Ответ, кстати, типовой, мой вопрос не читали в принципе
Главного экрана чего? Приложения? Или телевизора... То есть, чтобы понять, возможно ли заказать, нужно поставить приложение, дать ему кучу данных?
Там ещё куча...
Ну не знааааю.... Чтоб заказать корм котам, конечно, можно заморочиться, но я не буду.
В современной деловой среде успех напрямую зависит от умения предприятия предложить клиентам не только качественный товар или услугу, но и высокий уровень обслуживания. Компания по продаже вилочных погрузчиков и складской техники, сделала ставку именно на удобство и информативность своего интернет-магазина. Цель проекта была ясна: создать такую платформу, где каждый клиент чувствовал бы себя уверенно, легко находя необходимую информацию и выбирая лучшие решения для своего бизнеса.
Сегодня расскажем о том, как с помощью глубокого понимания потребностей целевой аудитории и внедрения последних технологий удалось не просто достичь поставленных целей, но и значительно превзойти ожидания своих клиентов. От стратегического планирования до реализации, мы поделимся ключевыми моментами и решениями, которые помогли создать удобный сайт для покупки и обслуживания вилочных погрузчиков.
Прошлый сайт клиента
Особенности проекта и пожелания заказчика:
Ключом к успешному проекту стали детально проработанные пожелания заказчика. Компания заказчика стремилась предоставить своим клиентам уникальный опыт выбора и покупки, сделав процесс максимально простым и понятным. Важными аспектами были высокая скорость загрузки страниц, интуитивно понятный интерфейс и полная адаптация под мобильные устройства. Вдобавок, заказчик подчеркивал необходимость в интеграции современных CRM-систем для эффективного управления взаимоотношениями с клиентами и автоматизации бизнес-процессов.
Этапы разработки:
Разработка включала несколько ключевых этапов:
Исследование и Планирование: Начальный этап был посвящен глубокому анализу целевой аудитории и конкурентов. Особое внимание уделялось изучению потребностей и предпочтений покупателей складской техники, что позволило выделить ключевые функции и элементы дизайна для будущего сайта.
Дизайн: Следующий шаг — разработка уникального дизайна, сочетающего в себе эстетику и функциональность. Благодаря тесному сотрудничеству дизайнеров и заказчика, удалось создать интерфейс, который не только привлекает внимание своей визуальной составляющей, но и обеспечивает легкость навигации.
Разработка и Интеграция: На этом этапе проекта команда разработчиков подобрала оптимальную CMS для интернет-магазина, настроила каталог товаров и реализовала необходимые интеграции с внешними сервисами и CRM-системами. Это обеспечило высокую функциональность сайта и удобство управления для владельцев.
Тестирование: Перед запуском сайт прошел тестирование на различных устройствах и во всех основных браузерах. Этот этап позволил выявить и устранить возможные ошибки и несоответствия, гарантируя работу сайта с момента его запуска.
Запуск и Поддержка: После запуска сайта осуществлялась его оптимизация для поисковых систем и мониторинг работы.
Главная страница нового сайта
Сложности и Решения:
Разработка сайта для продажи и обслуживания вилочных погрузчиков столкнулась с рядом сложностей, которые требовали решений. Во-первых, оптимизация под мобильные устройства была критически важна, учитывая постоянно растущую долю трафика с смартфонов и планшетов. Адаптация дизайна под маленькие экраны, упрощение навигации и сокращение времени загрузки страниц требовали творческого подхода и технологических инноваций. Решение проблемы заключалось в разработке адаптивного дизайна, который обеспечивал удобство просмотра и управления на любом устройстве.
Во-вторых, интеграция с внешними сервисами и CRM-системами представляла собой сложную задачу из-за необходимости синхронизировать большие объемы данных в реальном времени. Разработка API и использование облачных технологий позволили обеспечить стабильную работу интеграций, автоматизировать процессы заказа и управления клиентской базой.
Проблемы, с которыми сталкиваются продавцы и заказчики в интернет-магазинах, зачастую связаны с неудобством поиска товаров, отсутствием достаточной информации о продукции и сложностью оформления заказа. Мы учли эти моменты, предложив продвинутую систему фильтрации и поиска, подробные описания и характеристики товаров, а также упрощенный процесс покупки с возможностью онлайн-консультаций. Эти решения направлены на минимизацию возможных препятствий на пути клиента к покупке, повышая общую удовлетворенность и лояльность.
Сайт на этапе заполнения товаров
Результаты:
После запуска обновленного сайта заметно улучшились ключевые показатели эффективности. Уменьшение показателя отказов и увеличение среднего времени пребывания на сайте указывали на то, что пользователи стали активнее взаимодействовать с контентом, исследовать ассортимент и делать заказы. Сайт еще находится на этапе заполнения актуальной продукции заказчиком.
Кроме того, благодаря внедрению системы управления взаимоотношениями с клиентами, компания смогла значительно улучшить сервисное обслуживание. Автоматизация процессов заказа и обратной связи позволила не только сократить время на обработку запросов, но и повысить качество обслуживания, предоставляя клиентам персонализированные предложения и оперативно решая возникающие вопросы.
В заключение:
Проект является ярким примером того, как инновационный подход к разработке сайта и внимание к деталям могут трансформировать бизнес, укрепить позиции на рынке и вывести взаимодействие с клиентами на новый уровень. Инвестиции в качественное онлайн-присутствие окупаются не только увеличением продаж, но и ростом удовлетворенности и лояльности клиентов. Мы доказали, что даже в такой конкретной и технически сложной нише, как продажа и обслуживание вилочных погрузчиков, возможно создать удобный и функциональный сайт, который будет отвечать всем современным требованиям пользователей.
С момента выхода первой части статьи из рубрики «сам себе экосистема» прошёл уже практически год! За это время, мы успели с вами реализовать клиенты VK и YouTube, которые работают на Android 2.2+, а также на Windows Phone 8, написать небольшую 2D-игру с нуля весом менее 1Мб, которая работает практически везде и довести существующее приложение до ума, дабы оно работало даже на смартфоне с дисплеем 240x320! Но на дворе 2024 год, люди стремительно переходят из соц. сетей в продвинутые мессенджеры и уже сложно себе представить современного человека, который не пользовался бы «телегой» или даже «вайбером» в качестве основного средства общения. Поэтому я решил реализовать клиент Telegram на смартфоне 14-летней давности на базе официальной реализации MTProto от команды Telegram — TDLib. Сегодня мы с вами: узнаем новые причины мотивации вернуть в строй смартфоны прошлых лет, напишем на C# реле-сервер, который обрабатывает пакеты MTProto и кодирует их в простой текстовый формат датасетов, который можно моментально обработать даже при нестабильном GPRS-соединении на 21-летнем Siemens C60, а также узнаем о разработке миниатюрных Android-приложений на базе «голого» API-системы, которые не тянут за собой никаких зависимостей, в том числе и AppCompat/androidx. Интересно? Тогда жду вас под катом!
На дворе уже стукнул 2024 год, современные смартфоны предлагают какие-то немыслимые мощности относительно тех, которые когда-то были в первых Android-девайсах. Сейчас за сотню баксов можно купить смартфон с хорошей 1080p IPS-матрицей, 4Гб ОЗУ и 8-ядерным шустрым чипсетом, который вполне способен плавно тянуть даже стремительно «жиреющие» на ресурсы клиенты социальных сетей, банков и прочие необходимые в повседневной жизни приложения. И казалось бы: всё хорошо, покупай себе редмик раз в год или айфон раз в несколько лет и наслаждайся всеми прелестями работы современных приложений…
Для многих людей смартфон — это лишь инструмент, повседневный компаньон, который помогает облегчить выполнение каких-то задач. Им совершенно не важно, как он выглядит, как ощущается в руках, какой у него дисплей и железо «под капотом», лишь бы работал да и нормально. Но есть и другая категория людей, для которых телефоны, смартфоны и любые портативные гаджеты — это не просто утилитарный девайс, а настоящее инженерное произведение искусства, с которого буквально сдувают пылинки и стараются до последнего пользоваться ими как повседневными устройствами. Хотите пример? Смотрите ниже:
Фактически, среди современных смартфонов по сути и нет представителей такого нынче вымершего форм-фактора, как сайдслайдеры с физической QWERTY-клавиатурой, боковые раскладушки с двумя дисплеями и даже из QWERTY-моноблоков есть только смартфоны от Unihertz. Даже среди моноблоков с тачскринами нет никакого разнообразия, лишь без-рамочные одинаковые девайсы за исключением устройств от Sony.
Galaxy S Plus
Раньше меня часто спрашивали, мол, да как ты вообще можешь пользоваться смартфоном 10-летней давности, на котором давно нет официальных клиентов популярных сервисов и только недавно, с развитием блога, мне перестали задавать этот вопрос, поняв, что это бесполезно — ведь это дело принципа и порыва энтузиазма! Смотрите сами: у нас уже есть простенькие, но вполне рабочие клиенты ВК, YouTube, сейчас я допиливаю клиент «Сбера» на СМСках, реализую карты OpenStreetMap (правда пока без адекватной навигации), а в будущем планирую написать приложение для мониторинга погоды и трекинга посылок. Кроме того, в рамках этой статьи мы реализуем с вами клиент Telegram: так чем же это не функционал современного смартфона?
Но хорошо, с функционалом разобрались, однако для многих читателей слова «старый смартфон» это прямые синонимы «тормозной смартфон», мол «фуу, да как можно пользоваться этим тормозным кирпичом, он же лагает в последней версии моей ВКшечки!». Но давайте поставим вопрос ребром: может, это не столько девайсы немощные, сколько сами приложения, с кодовой базой, которая тянется более 10 лет, откровенно жиреют, обрастают костылями и хаками после далеко не одного поколения программистов, которые над ними работали? :) Один, вот, предпочитал пользоваться чистым AppCompat'ом, другой решил притащить зависимость, которая, например, оптимизирует виртуализацию ListView, третий решил заменить всю сериализацию Json со встроенных классов в Android на что-то стороннее и реализовал это костылями и вот так, по чуть-чуть изначально оптимальный и шустрый код превращается в неповоротливое УГ, которое не рефакторили кучу лет.
На видео Galaxy Pocket Neo — очень дешёвый Android-смартфон из 2011 года с 1-ядерным чипсетом на ~800МГц и 256Мб ОЗУ. При этом всём, Android софтварно рисует все анимации на процессоре, без участия GPU.
А значит у стареньких девайсов всё равно есть шанс быть полезными и стать полноценными повседневными смартфонами даже спустя более чем десять лет после выхода! И в сегодняшнем материале, я вам расскажу об особенностях разработки самопального клиента Telegram с собственным прокси-сервером, которое концептуально допускает реализацию даже на кнопочном Siemens C60 2003 года. Как? Читаем ниже!
❯ Принцип работы
В отличии от ВК (который разрабатывали те же самые люди, что и Telegram), API которого построено на базе REST-запросов и концепции Longpolling'а для моментального получения событий с сервера, Telegram построен на базе собственного протокола под названием MTProto, который может работать поверх любого «транспорта» (протокола нижнего уровня) — TCP, HTTP, WebSocket и т.п. Сам по себе MTProto в современном виде, разработка прожженного математика Николая Дурова и его команды — протокол относительно сложный для реализации «на коленке» и в первую очередь требует довольно серьезного понимания принципов работы современной криптографии, да и документирован он всё ещё не особо хорошо. Кроме того, у MTProto весьма интересный бинарный формат пакетов, эдакий велосипед Protobuf. В долгосрочной перспективе поддерживать свой велосипед MTProto может быть весьма проблематично, учитывая не самую лучшую документацию.
Но городить велосипед и не нужно, поскольку у команды Telegram есть официальная реализация MTProto — библиотека TDLib, которая инкапсулирует в себе не только детали реализации протокола, но и сетевой ввод/вывод и выбор транспорта, хранение базы данных сообщений и авторизации, автоматическую загрузку фото и видео, конвертация объектов из бинарного формата MTProto в JSON и полная многопоточность и частичная потоко-безопасность. С одной стороны это плюс — уже готовое решение для реализации клиента на новой поддерживаемой платформе, где есть OpenSSL (можно статически слинковать), zlib (линкуется статически), сокеты и файловый ввод/вывод, а также довольно неплохой механизм JSON-based API, которое позволяет использовать библиотеку в любом языке, который поддерживает вызов C-функций, а с другой и минус — библиотека довольно много весит, в одиночку прибавляя ~20Мб веса приложения для каждой архитектуры, у неё течёт память и у нее странный механизм получения данных с сервера (например, нельзя ответить на сообщение, зная его ID, если сообщение предварительно не загружено, при том что на сервере весь ответ — это просто ID, на какое сообщение прилетел ответ).
Понятное дело, что на стареньком смартфоне использовать оригинальный TDLib будет проблематичным — даже если собрать либы современным NDK и запилить JNI-интерфейс, библиотека «жрёт» много ОЗУ (20-100Мб «вхолостую», в зависимости от числа диалогов и частоты прилетающих событий, плюс со временем течет до 1-2Гб, если не использовать базу данных сообщений. Скорее всего, это косяк в реализации пулов, объекты из которых выгружаются при сбросе в базу, но не выгружаются при высоком потреблении ОЗУ) и уж тем-более TDLib не запустить на любимых кнопочных Java-сонериках! Поэтому я решил написать прокси-сервер, который отправляет команды, слушает ивенты TDLib и предоставляет REST-like API для клиентских программ, которые просто вызывают какой-либо метод, а в ответ получают простой и короткий строковой датасет только с необходимыми полями, весом до 10Кб (что позволяет его быстро загрузить даже с GPRS-интернетом), который можно быстро распарсить даже на преусловутом Siemens C60!
К сожалению, поскольку TDLib прожорлив, я не смогу захостить на своём сервере инстансы для читателей, которые хотят поюзать приложение, поэтому вам придется ставить и запускать сервер на своём VDS/компьютере с белым IP/роутере, если под него есть .NET Core :)
Клиентом же будет выступать Android-смартфон, где приложение будет фронтэндом данных с сервера. Ничего сложного на первое время нет: первое окно — это список диалогов, второе окно — список сообщений в диалоге + поле для написания сообщения, третье окно — информация о пользователе. Всё это я реализовал за три дня не-напряжной работы «на коленке».
Давайте же перейдем к реализации сервера!
❯ Прокси-сервер
Сервер я решил писать на C#, поскольку у .NET Core сейчас всё очень хорошо с кроссплатформенностью и производительностью. Его можно даже на Raspberry Pi запустить :)
Итак, какая-же архитектура такого сервера может быть? Программа инициализирует TDLib, начинает слушать её события в отдельном потоке, пока в основном потоке крутится HTTP-сервер, который обрабатывает каждый отдельный запрос с клиентского приложения. Почему синхронно? Потому что TDLib фактически не возвращает никаких идентификаторов для возвращаемых датасетов, дабы их можно было отличить друг от друга. Приведу пример: у нас есть метод getChatHistory, который возвращает n-сообщений. При этом TDLib сам определяет, сколько хочет сообщений вернуть (и в первый вызов возвращает одно сообщение вне зависимости от настрое и отправляем пакет message n-раз. При этом в пакете message нет какого-либо ID, который позволял бы ассоциировать текущий объект с какой-либо операцией. Увы!
Начинаем с коммуникации с TDLib. Для работы с библиотекой, мы будем использовать json-интерфейс. Для .NET есть биндинги через C++/CLI, но в таком случае, сервер не будет работать на Linux. Для работы с библиотекой хватит лишь три функции: CreateClientID, которая аллокейтит новый инстанс клиента, Send, которая асинхронно отправляет JSON-объект с командой, которую затем обработает TDLib и Receive, которая ждёт N-секунд и возвращает в виде ASCII-строки (!) JSON-объект с описанием события или данными после одного из запросов. За это у нас отвечает класс TDLibInterface, который объявляет PInvoke-методы для вызова нативных методов из библиотеки. .NET Core сам подгрузит библиотеку tdjson (причём на Linux он добавит ей префикс а-ля libtdjson.so, а на Windows загрузит tdjson.dll) и сам разберется с маршаллингом аргументов функций: например, string автоматически преобразует в const char*. Тем не менее, с const char* возвратами нужно быть аккуратнее — у меня был SIGSEGV, пока я ручками не конвертировал их в обычную строку.
З.Ы: На Пикабу нет отдельного тега для кода, а вставить листинги картинками я не могу из-за ограничения на 25 медиаэлементов. Так что листинги будут совсем без табов, но алгоритм их работы понять можно :)
Позволю себе чуточку критики в сторону TDLib. Во первых, почему нет s-версии функции с возможностью указать длину входной строки, а tdjson полагается исключительно на \0 в конце строки? Во вторых, почему const char*, а не wchar_t*? Сейчас юникод во входной строке приходится escape'ами превращать в \u-последовательности. После этого, нам нужно написать обёртку над TDLib, которая будет вызывать для зарегистрированных событий специальные функции, называемые коллбэками. При этом закомментированный WriteLine снизу — это «дебаг» для того, чтобы узнать названия неизвестных мне ивентов :)
В каждом объекте, полученном с помощью receive, есть поле "@type", которое содержит в себе имя класса возвращаемого объекта. Первый же вопрос от читателей — почему я использую JObject с ручным дерганьем нужных полей и вручную пишу JSON в виде строковых литералов вместо нормальной сериализации/десериализации? Ответ прост: во-первых, для актуализации Data-классов придется писать кодогенератор из TL-схемы, а во-вторых иногда TDLib может возвращать немного разные объекты в JSON, из-за чего приходится мудрить с атрибутами на этих самых Data-классах, иначе десериализатор выбросит исключение. Это решается нормальными юнит-тестами на всех вариантах данных, но зачем себе в колени стрелять, если нужен конкретный фиксированный функционал и лишь малое число от всех полей, возвращаемых TDLib?
string recv = NativeInterface.Receive(10.0d);
if (recv != null) { JObject json = JObject.Parse(recv);
if (!handlers.ContainsKey(type)) { //Console.WriteLine("Unknown event type: {0}", type); continue; }
handlers[type](recv, json); }
Теперь переходим к самому интересному — обработке событий и реализации синхронного клиента, который позволяет без async/await просто запросить список сообщений и сразу же его получить (такой подход может быть полезен и юзерботам, которые не хотят размазывать стейты по всей программе). Почему без асинков? Честно сказать, мне они просто не нравятся: как привык к концепции wait/notify и коллбэков из Java, так их и юзаю всю жизнь :)
Сначала TDLib запрашивает параметры инициализации (стейт authorizationStateWaitTdlibParameters), затем если пользователь не авторизован — запрашивает номер телефона и код подтверждения (плюс дополнительные шаги для авторизации если они есть). В конце, TDLib возвращает стейт Ready, что означает готовность библиотеки к работе:
После этого, можно начать работу с данными. Обратите внимание, мой подход потоко-небезопасен, его нельзя дергать из нескольких потоков одновременно! В коде ниже, я вызываю метод для фетча сообщений, а затем в соответствующем коллбэке от TDLib обрабатываю данные (дабы статья не разрасталась на 20+ минут, я чуть урезал все листинги).
public List<Message> QueryMessagesInChat(long chatId, long lastMessage, int count) { messages.Clear();
public User QueryUser(long userId) { string json = Utils.Format("{\"@type\": \"getUser\", \"user_id\": \"{0}\" }", userId); NativeInterface.Send(InstanceID, json);
waitHandle.WaitOne(); return user; }
Переходим к реализации самого сервера, для наших целей хватит обычного HttpListener. Сначала мы зарегистрируем все поддерживаемые методы и занесем их в ассоциативный список ключ-значение. Сами методы реализованы в виде делегатов, которые принимают лишь один аргумент — список параметров из строки запроса, а возвращают строку — все ответы, за исключением особых (связанных с загрузкой вложений) — текстовые.
Переходим к обработке запроса. Метод ищет, зарегистрирован ли запрошенный метод и если да, то парсит строку запроса, которая начинается с "?", которую затем передаёт в виде коллекции ключ->значения обработчику метода:
А сами методы, в свою очередь, дергают соответствующие функции из клиента и формируют на их основе датасет в примитивном формате:
public staticstring QueryChats(Dictionary<string, string> args) { if(args.ContainsKey("count")) { int count = int.Parse(args["count"]); StringBuilder ret = new StringBuilder();
В результате получаем вот такой простой датасет, который, как я и говорил, легко распарсить и на Siemens C60, и на Atmega328 — да где угодно! В целом, такой сервер можно использовать для реализации бота в телеграме, который будет передавать показания каких-то датчиков, сигнализацию и прочие клевые штуки!
Переходим к реализации клиента, т.е. приложения на Android. Здесь будет не менее интересно!
❯ Пилим для Android
В геймдеве есть своеобразный мем — некоторые инди-разработчики сначала начинают делать меню, вместо основного геймплея, что становится предметом насмешек среди других разработчиков. Но в разработке приложений для смартфонов всё по другому — здесь как-раз таки хорошо заранее продумывать макет будущего приложения!
Поскольку у нас с вами мессенджер, то главный экран должен представлять из себя список чатов (ListView) и верхнюю панельку, где в будущем могут разместиться настройки и свайп-менюшка:
Такой вот простой макет.
Каждый пункт меню — это тоже отдельный layout, в котором мы по шаблону строим внешний вид будущего элемента списка. На немолодых устройствах есть смысл использовать как можно меньше контейнеров в layout'е, поскольку пересчет позиций и размеров элементов — одна из самых «тяжелых» операций в UI-фреймворке вообще. Кроме того, не стоит использовать кучу картинок и drawable — в Android 2.x всё 2D рисуется софтварно, аппаратное ускорение появилось только в 3.0 (частично).
Но дабы в списке диалогов что-то появилось, нужно сначала реализовать фетчинг (получение) этих самых диалогов с сервера! Сам объект, который занимается обработкой запросов называется ClientManager и является синглтоном — он в единственном экземпляре на все время работы программы. Помимо менеджмента «ноды» (т.е. прокси-сервера), токена для авторизации и обработчика ошибок, ClientManager реализует метод для асинхронного запроса информации с сервера и, собственно, формирует строки запросов с помощью соответствующих методов:
Подгрузка чатов и сообщений реализована через Adapter — концепция «виртуальных» списков, которая предполагает что система создаст не 50 элементов интерфейса на каждую кнопку чата, а только 5 и будет их виртуально «мотать по кругу», обновляя только данные в уже существующих элементах. Это позволяет значительно ускорить отрисовку, учитывая то, что Android 2.x Canvas рисуется программно.
Ну вы уже явно замучились видеть простыни кода, давайте посмотрим что у нас вышло!
Шустренько, да? А ведь это ультрабюджетник Alcatel OT-916D, один из последних массовых дешевых QWERTY-смартфонов за 5 000 рублей из 2012 года. Кстати, смартфон подарил мне читатель chuvakoff с Хабра!
Переходим к окну чата. Основной макет почти такой-же, как и у основного окна: только добавилась панелька для ввода сообщения снизу.
Концептуально, всё тоже самое — запрашиваем данные с сервера, парсим их и загружаем в адаптер, благодаря чему мы сможем листать наш диалог. Однако в сообщения я добавил контекстное меню с стандартными фишками типа копирования, ответа и прочих подобных действий. Поскольку у нас нет ни пушей, ни еще каких-либо средств для поулчения данных о новых сообщениях, я раз в определенный интервал просто получаю сообщения — и если новый датасет отличается от старого — обновляю окошко чата.
Переходим к реализации поля для ввода сообщения. Здесь всё просто — на серверсайде за это отвечает метод SendMessage. Однако для того, чтобы с нашего клиента можно было ответить на другие сообщения, я ввёл также «контекст ответа», в котором запоминается сообщение, на которое мы хотим ответить. Telegram также поддерживает Markdown, однако его полная поддержка пока не реализована.
В остальном же, функционал конечно пока совсем базовый, однако клиент работает очень шустро даже бюджетной X10 Mini Pro и позволяет чатится с моими читателями в Telegram. В будущем хотелось бы допилить:
Поддержка картинок: Сейчас уже есть кривоватый механизм кэширования изображений на стороне сервера, который позволяет загружать аватарки чатов. В будущем, я добавлю поддержку «галерей» с картинками!
Поддержка голосовых сообщений: Не все их любят, но они порой удобны и выручают. Реализую как прослушивание, так и запись!
Подробный просмотр профилей и менеджмент чатов: Удаление сообщений, чатов и прочие фишечки из официальных клиентов.
Казалось бы — до официальных клиентов ещё очень далеко. Но сам факт, чтобы всё это работало достаточно шустро на девайсах, которым уже более 10 лет!
❯ Звучит интересно! Как заюзать твой клиент?
Тут всё очень и очень просто! В первую очередь, нам понадобится ПК с белым IP, роутер (если под него есть сборка dotnet), либо VDS. Виртуальные сервера сейчас стоят копейки, у ТаймВеба есть тариф за 188 рублей в месяц, которого с головой хватит для нашего сервера.
Такая вот рекламная интеграция (к слову, прокси для всех приложений уже более года крутятся именно на мощностях TimeWeb Cloud)!
Программа сначала запросит номер телефона, а затем код подтверждения Telegram. После этого будет создана папка tdlib/, где будут хранится данные вашей сессии, а также файл authkey.txt, где хранится случайный ключ для сессии (md5 phone_number + response code + псевдослучайное число). Не оставляйте его в /var/www/!
Если всё нормально, программа начнёт слушать порт 13377 на всех сетевых интерфейсах, в т.ч и в локальной сети. После этого, ставим уже предварительно собранный, либо собираем сами в Android Studio APK и в окне авторизации пишем адрес ноды и ключ авторизации. Если всё настроено верно — программа запомнит сервер и будет работать без проблем! Вот так всё легко :) Как видите — всё очень и очень просто!
Кроме того, буквально за пару дней до публикации статьи я сел вечерком из интереса что-нить под Java-телефоны попилить… и, как и обещал, реализовал Proof of Concept возможности работы Telegram даже на сонериках, которым скоро 20 лет стукнет! А ведь если ещё чуть заморочится, можно запустить приложение даже на преусловутых монохромных сименсах!
❯ Заключение
Вот такой у нас получился проект с реализацией лёгкого, примитивного, но тем не менее рабочего клиента Telegram, который на клиентской части вообще не использует никаких зависимостей. Вес собранного APK в release-версии — всего 54 килобайта! Понятное дело что с ростом функционала, вес программы будет увеличиваться, но я обещаю — больше 1Мб он не вырастет :)
Ну а вам, моим читателям, надеюсь было интересно прочитать такой «двойной материал» не только о разработке сетевой части без использования Apache/nginx/IIS, но и UI-фронтэнда для Android-смартфонов, которым уже более 10 лет! Исходный код проекта можно найти на моём GitHub: как приложения, так и сервера, а также убедиться в отсутствии каких либо закладок и, если совсем не доверяете, собрать бинарники сами! Для сборки понадобится VS2017 или свежее, а также Android Studio 2.3.2 (если собираете для Android 2.1 и ниже).
Друзья! Сейчас на Хабре опросы сломаны, поэтому если у вас есть желание, вы можете проголосовать в комментариях: какой стиль статей вам больше нравится — где больше конкретики и кода с пояснением как конкретно работает та или иная часть программы, или наоборот стиль ближе к научпопу, где фрагментов кода нет, или их значительно меньше? Пишите своё мнение о проекте в комментариях!
Кроме того, у меня есть канал в Telegram, куда я публикую бэкстейдж статей, ссылки на новый материал, свои наработки, а также посты о ремонте девайсов и различные мысли.
Статья подготовлена при поддержке TimeWeb Cloud. Подписывайтесь на меня и @Timeweb.Cloud, чтобы не пропускать новые статьи каждую неделю!
Сейчас каждый чувствует, как интернет меняет всё вокруг, и даже школы с кружками не остаются в стороне. Они начинают использовать крутые инструменты вроде контент-воронок — это как путь, который мы проходим от первого клика по рекламе до записи ребенка на курсы. В этой статье я расскажу вам, как это работает на примере детских образовательных центров.
Оформление группы для нашего клиента
Как работает контент-воронка:
Представьте, что вы хотите записать ребенка на танцы или робототехнику. Вы заходите в соцсеть, и тут на вас выскакивает расписание занятий или приглашение на бесплатный урок. Вы кликаете, изучаете, что предлагают, смотрите фотки и видео — и вот вы уже на сайте центра, выбираете удобное время и записываетесь. Всё это и есть контент-воронка — путь от знакомства с центром до записи на занятие.
Вы когда-нибудь замечали, что после посещения сайта с игрушками вам начинают показывать рекламу кубиков и пазлов в соцсетях? Так вот, это и есть начало контент-воронки. Для родителей, которые ищут занятия для своих детей, это может начаться с интересной статьи о том, как развивающие занятия влияют на успеваемость, или с поста о том, как важно учить детей программированию с раннего возраста. Дальше — больше: вы кликаете на ссылку, попадаете на страницу с расписанием, видео с занятий, отзывами других родителей и фотографиями улыбающихся детей. Прежде чем вы это осознаете, вы уже заполняете заявку на пробное занятие. И всё это — магия контент-маркетинга, которая работает на подсознательном уровне.
Что показали цифры:
Рассмотрим, как это работает на реальных примерах. В одном городе число подписчиков страницы центра увеличилось на 15%, в другом — на 14%. Это значит, что родители активно интересуются предложениями центров. А еще мы выяснили, что когда родители видят конкретные предложения, например, о шахматах, они чаще записывают детей на эти курсы.
Мы анализируем каждый шаг пользователя в нашей воронке, чтобы узнать, что работает лучше всего. В одном городе мы увидели, что после публикации расписания занятий количество посещений страницы увеличилось в два раза. Это как раз один из тех моментов, когда статистика говорит нам: "Эй, это действительно работает!". А в другом городе после серии постов в соцсетях о новых группах на рисование и театра количество заявок на участие увеличилось на 30%. Цифры не врут: когда родители видят конкретные, интересные им курсы, они с большей вероятностью запишут своего ребенка.
Как мы это делаем:
Мы не просто слепо следуем трендам — мы их создаем, анализируя интересы нашей аудитории и предлагая им именно то, что им нужно. Мы учимся на отзывах: если видим, что посты о керамических мастер-классах собирают много лайков и комментариев, мы организуем ещё один и снова делаем акцент в нашем следующем контенте. И так далее — каждый отзыв, каждый лайк и каждый просмотр страницы помогают нам стать лучше и узнать, что действительно важно для наших клиентов.
Мы постоянно смотрим, как люди реагируют на наш контент, что им нравится, а что нет. Если замечаем, что что-то работает хорошо, например, упоминания о мастер-классах, мы делаем на это акцент. Так мы постоянно улучшаем то, как рассказываем о центрах и их предложениях.
Практические советы:
Чтобы всё это заработало, важно делать контент интересным и живым. Показывайте настоящие фото и видео, чтобы родители могли представить, как их дети будут заниматься. И не забывайте следить за тем, на что родители реагируют лучше всего — это поможет вам стать лучше.
Индивидуализация контент-стратегии: разработка уникального контент-плана, который будет учитывать специфику и предпочтения целевой аудитории в каждом городе.
Усиление визуального воздействия: интенсивное использование "живых" фотографий и видео с занятий, чтобы усилить эмоциональную связь потенциальных клиентов с образовательным центром.
Оптимизация расходов на рекламу: перераспределение бюджета в пользу наиболее результативных каналов и форматов рекламы, исходя из аналитики предыдущих кампаний.
Анализ отклика аудитории: регулярный мониторинг реакции на различные рекламные и контентные акции для своевременной адаптации стратегии.
В заключение:
Контент-воронка — это как GPS для маркетинга в образовании. Она помогает не заблудиться среди множества предложений и привести клиента туда, куда нужно. В эпоху интернета такой подход помогает образовательным центрам быть на связи с родителями и делать их предложения еще более привлекательными.
В итоге, всё сводится к одному: мы не просто раскручиваем образовательные курсы, мы создаем связь между центрами и семьями. Наша работа с контент-воронками показывает, что если правильно подобрать ключи к сердцам родителей и детей, можно не только заинтересовать их, но и вдохновить на новые знания и открытия. Этот подход помогает образовательным центрам стать не просто местом учебы, а настоящим сообществом, где каждый найдет что-то полезное и интересное для себя и своего ребенка. И в этом вся красота и сила современного маркетинга.
К нам в агентство обратился предприниматель, который продаёт беспроводные наушники и смарт-часы на Озон. Обрисовал проблему: карточки товаров работают очень слабо, мало продаж, хотя карточки хорошо оформлены. Он попросил запустить таргетированную рекламу через ВК на карточки товаров.
В новом рекламном кабинете Вк как раз есть соответствующий рекламный объект «Каталог товаров» → «Магазин на маркетплейсе». Через эти настройки можно рекламировать товары на Озон, Вайлдберрис, Алиэкспресс и Яндекс.маркет. В старом рекламном кабинете ВК таких настроек нет. У нашего агентства большой опыт таргетированной рекламы, однако в этой ситуации возникли неожиданные сложности.
Объявления, созданные для рекламы магазина на маркетплейсе, долго висели на проверке, а затем их отклонили. Все!
Пришлось долго спорить с модераторами в переписке. Они утверждали, что реклама наушников не соответствует правилам Вконтакте, поскольку мы не имеем права рекламировать реплики и копии товаров. Непонятно, почему модераторы решили, что смарт-часы и белые беспроводные наушники — это реплика или копия (видимо, намекали на яблоко с откушенным боком). В карточках товаров чётко указаны наименования товаров и производитель, которые не имеют ничего общего с яблоком. Как будто никто больше не может производить аналогичные товары. После двух суток переписки объявления всё-таки одобрили.
Объявления, которые не работали
Однако на этом мучения не закончились. Объявления запустились и поначалу даже шли показы. Вскоре выяснилось, что дневные лимиты не откручиваются!
Срок рекламы был ограничен 10 днями — до Нового года, так как товары позиционировались в качестве новогодних подарков. За это время нужно было использовать назначенный бюджет и получить максимум кликов. На каждое объявление был установлен дневной лимит 1000 руб. Но он не откручивался, тратилось максимум 600 руб. Решили сделать большее число объявлений с лимитом 500-600 рублей. Но даже этот лимит не откручивался.
Максимум тратилось 150 руб. Начинались показы, клики, а потом всё стопорилось. То есть объявления просто не показывали аудитории! Снова пришлось переписываться с поддержкой ВК-рекламы. Поддержка ответила, что объявления проигрывают в аукционе и нужно менять целевую аудиторию и поднимать лимиты. Всё было сделано, но это не помогло.
ЦА 600 тысяч человек рекламный кабинет упорно помечал жёлтой галочкой и утверждал, что ЦА слишком большая, надо сужать. Хотя в случае с рекламой от другого клиента, где тоже ЦА 500-700 тысяч, была зелёная галочка — значит, алгоритмы не считали такую ЦА слишком широкой. Новый рекламный кабинет, конечно, ещё сырой. Функция рекламы магазина на маркетплейсе работает со сбоями.
В конце концов было решено сменить рекламный объект и указать в рекламной кампании категорию «Сайт» вместо «Каталог товаров→ Магазин на маркетплейсе».
В этой категории для настройки рекламы по целевым действиям нужно создать рекламный пиксель, а на Озоне его разместить не получится. Подробности о настройке пикселя есть в руководстве ВК рекламы
Но есть лазейка: пиксель можно просто создать и настроить, но нигде не размещать. Так и сделали.
Это сработало! Пошла открутка объявления, пошли клики.
Объявление с механикой "Реклама сайта"
Таким образом, с рекламным объектом «Сайт», мы получили переходы на магазин продавца на Озон, а с рекламным объектом «Каталог товаров» → «Магазин на маркетплейсе» практически ничего не получили.
Softr- это платформа, с помощью которой можно создавать сайты, веб-приложения, клиентские порталы, платные онлайн курсы, сообщества с платным доступом, каталоги ивентов, маркетплейсы, доски объявлений и многое другое на основе Airtable за 10 минут. Без необходимости участия разработчиков! Это может быть полезно для тех, кто не имеет опыта в программировании, но хочет создать свой сайт или приложение.
Не зацикливайтесь на одной операционной системе. Ваше приложение будет доступно на iOS, Android, macOS, Windows и Chrome OS. Оно будет адаптироваться и отлично выглядеть на каждом экране без дополнительного дизайна или ресурсов.
Например, вы можете использовать Softr, чтобы создать сайт для своего бизнеса, онлайн-магазин, блог или портфолио. Сервис предоставляет готовые шаблоны, которые можно настроить под свои нужды. Вы можете выбрать дизайн, добавить свои изображения и текст, и ваш сайт будет готов.
Softr не использует нейросети или искусственный интеллект. Вместо этого, сервис использует базу данных Airtable, чтобы хранить информацию о вашем сайте или приложении. Вы можете использовать Airtable, чтобы хранить информацию о своих клиентах, продуктах, услугах и т.д.
Подписывайтесь на ИИшница🍳 - тут все самое интересное из мира новых технологий и нейросетей 🤖
Такую задачу поставил Little.Bit пикабушникам. И на его призыв откликнулись PILOTMISHA, MorGott и Lei Radna. Поэтому теперь вы знаете, как сделать игру, скрафтить косплей, написать историю и посадить самолет. А если еще не знаете, то смотрите и учитесь.