Медицинский маркетинг — что это, как продвигать медицинские услуги клиники и центров
Какой бы ни была хорошей и известной клиника, если ее не продвигать — очереди из пациентов не будет! В статье расскажу: как продвигаться врачам, медицинским клиникам и центрам, чтобы заполнить запись в клинику на неделю вперед. Видео разбор мед сайта в конце.
Лет 10-20 назад, главным инструментом продвижения любого медицинского центра была: наружная реклама и сарафанное радио. СЕГОДНЯ, ЭТОГО НЕ ЭФФЕКТИВНО!
Всем привет. Меня зовут Толстенко Александр. Я специалист по комплексному маркетингу с опытом работы с экспертами, врачами, медицинским клиниками и центрами 💉 Помогаю привлекать увеличить запись в медцентр и продажи за счет рекламы, экспертного контента и грамотной стратегии продвижения marketing-digital.ru
Для успешного продвижения медицинской клиники нужен удобный и красивый сайт + задействовать разные маркетинговые стратегии, причем комплексно (об этом ниже).
Ниже расскажу про маркетинговые стратегии, которые подойдут для продвижения:
Медицинских клиник по коррекции зрения;
Центров стоматологии;
Клиник пластической хирургии;
Медцентров репродуктивной медицины (ЭКО);
Наркологических центров и реабилитационных диспансеров;
Пансионатов для престарелых и оздоровительных домов отдыха;
Многопрофильных диагностических центров (УЗИ, МТР, КТ) и узко специализирующихся учреждений;
Лабораторий, фармкомпаний, ветеринарных клиник;
Личного бренда врача или поликлиники;
Кабинетов косметологии и эстетики тела (массаж, маникюр, педикюр) и других многопрофильных.
Конкуренция в медицине высокая. Поэтому, для привлечения стабильного потока новых пациентов в центр, нужна эффективная маркетинговая стратегия продвижения, в которой сайт играет очень важную роль.
ТОП 5 Проблем роста медицинских центров
1.) ПРОДВИГАЕТСЯ ТОЛЬКО ЧЕРЕЗ САРАФАННОЕ РАДИО
Сарафанное радио считается успешным в условиях низкой конкуренции. В рамках жесткой конкуренции использовать его означает — отсутствие плотной записи к врачам. Вы не сможете конкурировать и развиваться как ваши конкуренты.
2.) ВАШ САЙТ НЕ ГОТОВ К РЕКЛАМЕ
Большинство сайтов НЕ продающие! С точки зрения посетителя, сайт неудобный, плохо отображается на телефоне, на нем сложно записаться на прием, недостаточно информации по услуги, нет важных блоков для принять решение о записи и т.д.
Плохой и неудобный сайт — зря потраченные деньги на рекламу (дорогая стоимость привлечения клиентов). У каждого свой набор ошибок. По статистике консультаций: из 10 сайтов, только 2-3 сделаны хорошо и есть нужные страницы для продвижения в Яндекс/Google.
Пример экспресс аудита сайта пансионата для пожилых
3.) НЕ АНАЛИЗИРУЮТСЯ СТРАТЕГИИ ПРОДВИЖЕНИЯ КОНКУРЕНТОВ
Анализ стратегий продвижения конкурентов помогает понять их сильные и слабые стороны, правильно подобрать рабочие инструменты, настроить эффективную рекламу для нужной аудитории и найти быстрые точки клиентов из результатов Яндекс/Google.
4.) НЕПРАВИЛЬНОЕ РАСПРЕДЕЛЕНИЕ МАРКЕТИНГОВОГО БЮДЖЕТА
Для продвижения врача, федеральной клиники или небольшой частной стоматологии используются разные методы. Хаотическое использования и неверно подобранные инструменты продвижения, не позволят вам создать очередь в клинику. Нужно подходить индивидуально к разным специализациям.
5.) ЗАПИСЬ В КЛИНИКУ ПРОИЗВОДИТСЯ ПО СТАРИНКЕ ВРУЧНУЮ, А НЕ В ЦРМ
Нет системы регистрации и ведения клиента. Поэтому:
- Теряются звонки и их записи к врачам,
- Администраторы звонят через день, два, неделю.
- Данные сложно оцифровать, не понятно на каком этапе возникает проблема, нет возможности повлиять на доход клиники и т.д.
Если еще нет медицинской информационной системы по работе с клиентами, рекомендую задуматься о ее внедрении.
Что важно для продвижения медицинской ниши
1.) Главным инструментом продвижения — ЯВЛЯЕТСЯ САЙТ. Хороший сайт повышает доверие пациентов.
Считайте, что сайт — это стойка администратора клиники, которую видит пациент, когда приходит на запись к врачу. Будет сайт сложным и непонятным, посетитель не найдет нужной информации и уйдет к конкурентам.
К тому же, если сайта не будет, вы не сможете использовать инструменты онлайн-рекламы, поэтому о его создании нужно подумать в первую очередь.
2.) Согласно ФЗ № 323 от 21.11.2011 года «Об основах охраны здоровья граждан в Российской Федерации» граждане имеют право получать информацию о враче и медорганизации в доступной для них форме, в том числе через интернет.
3.) Должна быть лицензия, подтверждающая вашу деятельность. Без нее, не будет возможности запустить платные рекламные каналы.
Как эффективно привлекать клиентов в клинику через сайт
При разработке медицинского сайта рекомендую учесть следующие требования (если сайт есть проверьте наличие):
Сайт должен быть современным, красивым, привлекательным (должен продавать, посмотрите на конкурентов)
Сайт должен хорошо отображаться всех устройствах, не допускается не читаемой информации
Сайт должен быстро загружаться на мобильных телефонах и ПК.
В шапке должны быть: ссылки на услуги, телефон, кнопка записи в клинику и график работы и т.д.
На сайте должна быть простая и удобная форма записи на прием! В идеале два поля: Имя, телефон — больше полей, меньше обращений.
На первом экране услуги, посетитель должен понять, что вы ему предлагаете и сколько это может стоить (УТП с преимуществами).
На сайте должны быть лицензии, награды, документы о включении организации в госреестр и т.д.
Должны быть отзывы о клиники и врачах пациентов
О каждом враче должна быть информация на сайте (карточка врача, похожа на вакансию сайте работы hh.ru)
Надежная и гибкая CMS с возможностью доработки нужного функционала (WordPress, Modx, 1с-битрикс и т.д. Для большинства решений подойдет WordPress).
CMS должна быть гибкой для SEO продвижения (конструкторы типа Tilda — не подойдут)
Запустив сайт клиники, можно будет продвигать ее услуги в интернете задействовав другие маркетинговые инструменты.
Медицинский маркетинг
Разработка маркетинговой стратегии продвижения и удобный сайт играют большую роль в успешном продвижении. Перед началом, рекомендую:
1.) ОБРАТИТЬ ВНИМАНИЕ НА КЛИЕНТСКИЙ СЕРВИС
Ни один из перечисленных инструментов ниже не будет эффективным, если администраторы не будут отвечать на звонки, будут хамить пациентам, будет видна антисанитария… Не к чему, хорошему — это не приведет.
Вы должны быть клиентоориентированными. Тогда сарафанное радио станет самым лучшим и бесплатным инструментом продвижения медцентра.
2.) ДОБАВИТЬ КЛИНИКУ В ГЕОСЕРВИСЫ И КАТАЛОГИ
Потенциальные пациенты, очень часто ищут клинику на разных площадках вблизи от дома. Рекомендую, добавить информацию о компании (пользоваться или нет услугами раскрутки — это уже отдельный вопрос, но присутствовать рекомендую) в:
— Яндекс.Карты;
— Google Maps;
— 2ГИС;
— zoon.ru;
— СберЗдоровье;
— НаПоправку;
— docdoc.ru;
— Яндекс.Здоровье и другие.
3.) ПОРАБОТАТЬ С РЕПУТАЦИЕЙ (ОТЗЫВЫ / SERM)
Работа с отзывами клиентов – важная часть формирования репутации мед центра.
Просите ваших пациентов оставлять отзыв на геосервисах, сайтах отзовиках и вашем сайте за небольшую скидку или бонус — отзывы играют большую роль по выбору поликлиники для потенциальных клиентов.
Самые популярные порталы и сервисы, где можно оставить отзывы*:
— Яндекс.Карты;
— Google Maps;
— 2GIS;
— otzovik.com;
— spr.ru;
— yell.ru;
— docdoc.ru;
— zoon.ru;
— СберЗдоровье и другие агрегаторы.
* - Для работы с обратной связью с пациентами, заведите на порталах профили вашей клиники.
Как продвигать медицинские сайты сегодня
Согласно исследованиям сервиса сквозной аналитики Calltouch, ТОП-3 каналов привлечения пациентов — это геосервисы, Яндекс Директ, SEO-продвижение в Яндекс/Google и другие платные каналы привлечения клиентов.
Для построения эффективной системы привлечения клиентов в медицинских тематиках, можно использовать:
— Рекламу в Яндекс.Бизнес
— Рекламу в Яндекс.Директ (контекстная реклама)
— SEO-ПРОДВИЖЕНИЕ В ЯНДЕКС/GOOGLE
— Реклама в медицинских агрегаторах
— Таргетированную рекламу в соц сетях
— Рассылки e-mail, SMS, WhatsApp, Telegram и т.д.
— ЯНДЕКС.ДЗЕНЕ
— Социальные сети (SMM)
1.) РЕКЛАМА В ЯНДЕКС.БИЗНЕС НА КАРТАХ И ПОИСКЕ
Из платных инструментов, рекомендую начинать именно с него. Отлично работает для локальных бизнесов, имеющих географическую привязку. Трафик идет приоритетно с Яндекс Карт. Многие ищут клиники поближе к дому.
Кому подходит: Начинающим клиникам, врачам и специалистам с отсутствующей клиентской базой, у которых нет даже сайта.
2.) РЕКЛАМА В ЯНДЕКС.ДИРЕКТ (КОНТЕКСТНАЯ РЕКЛАМА)
Продвижения медицинской клиники с помощью контекстной рекламы является самым быстрым способом создать очередь из пациентов. Получить первого клиента можно сразу же после запуска рекламной компании. Минус только — нет денег на балансе, нет новых клиентов.
С платной рекламы в результатах поисковой выдачи на сайт приходят посетители, которые срочно хотят решить свою проблему.
Как можно сэкономить на рекламе
Чтобы получить только горячих клиентов, подбор фраз рекомендуем делать по принципу: Название услуги + географическая привязка, а также ключи:
прием;
консультация;
лечение;
вылечить;
инъекции, вакцины;
уход;
диагностика;
реабилитация
и другие фразы по вашему направлению, которые могут побудить оставить заявку на сайте.
Если позволяет бюджет, можно расширить рекламу на целевую аудиторию по менее горячим фразам. Мы обычно тестируем разные стратегии запуска с разными ключами, минусуем мусорные слова (фото, видео и т.д.), а нерабочие запросы — отключаем, чтобы не тратить рекламный бюджет.
Кому подходит: Яндекс пропускает лишь несколько медицинских тематик для рекламы
пищевые добавки, витамины, пребиотики;
лекарственные препараты;
медицинская диагностика;
стоматологические услуги;
гастроэнтерология;
флебология;
общая терапия;
педиатрия;
ортопедия;
ветеринарные услуги и препараты;
оториноларингология;
офтальмология.
Что потребуется для запуска рекламы в Яндексе.Директе
Отправить модераторам копию лицензии, приложение с адресом и перечнем видов медицинской деятельности. Адрес оказания медицинских услуг должен совпадать с адресом в лицензии и на странице перехода по объявлению.
Если рекламируете клинику, нужно предоставить гарантийное письмо
Другие документы, которые потребует модератор Яндекс.Директа
После одобрения, можно запустить рекламу на поиске и в Рекламной сети Яндекса (РСЯ, картинки которые догоняют вас неделями).
3.) SEO-ПРОДВИЖЕНИЕ САЙТА В ЯНДЕКС/GOOGLE
Продвижение клиники с помощью SEO-оптимизации — это самый эффективный и выгодный канал продвижения для медицинских центров, экспертов, врачей, фармацевтических компаний и не только, если его рассматривать в долгосрочной перспективе.
Простыми словами SEO-продвижение — это инвестиция в будущее, которая в отличие от платной рекламы, позволит из месяца в месяц получать стабильный поток клиентов, даже если работы по раскрутке по какой-то причине будут приостановлены.
Для продвижения в результатах поисковой выдачи, нужно будет:
Создать отдельные страницы под направления услуг — нет страниц, нет новых посетителей (например запрос: «МРТ» и «МРТ спины» — должны подвигаться на разных страницах);
Написать много статей в блог (ниша информационная, можно получать более 1.000.000 посетителей в месяц!);
Сделать оптимизацию написанных текстов;
Внедрить элементы, которые увеличат количество обращений с сайта;
Проработать E-E-A-T факторы доверия (информация о врачах, клиники, лицензии и т.д.)
Написать тексты в блог (ниша информационная, люди ищут, а потом обращаются в клинику)
т.д.
Поисковым роботам нужно время учесть изменения на сайте, обычно рост позиций и посетителей начинается уже через 2-3 месяца.
Блог на сайте медицинского центра
Наверняка, не один раз вы видели сайты конкурентов по разным интересующим вас запросам. Это не спроста:
Помогает увеличить количество пациентов за счет увеличения посещаемости сайта. Люди сначала ищут информацию, потом идут в клинику;
Для поисковых роботов, есть несколько типов запросов: коммерческие, информационные и назовем их прочие. Нельзя продвигаться с одной страницей сразу по всем типам запросов. Нужно создать на сайте разные страницы для продвижения.
Помогает сформировать положительное мнение, показать экспертизу и увеличить узнаваемости клиники;
Помощь пациенту в принятии решения, записаться в клинику именно к вам.
Кому подходит: Всем, если рассматриваете раскрутку в долгосрочной перспективе. Поможет сэкономить инвестиционный бюджет в будущем, инвестировав сейчас.
4.) РЕКЛАМА В МЕДИЦИНСКИХ АГРЕГАТОРАХ
Медицинские агрегаторы — это сайты-сервисы, на которых представлена информация о клиники и врачах определенного профиля.
Цель агрегаторов — облегчить процесс поиска и выбора специалиста, с возможностью сразу записаться на прием к врачу и оплатить услуги онлайн. В России самые известные:
napopravku.ru (НаПоправку)
docdoc.ru (ДокДок)
sberhealth.ru (СберЗдоровье)
prodoctorov.ru (ПроДокторов)
и другие.
Источник: Kontakt InterSearch Russia - Агрегаторы, с которыми клиники работали или работают сейчас
Кому подходит: Медицинским центрам, врачам и частным специалистам, которые только начинают свою работу.
5.) ТАРГЕТИРОВАННАЯ РЕКЛАМА
Продвижения медицинского центра с помощью таргетированной рекламы — хороший инструмент рекламы. С помощью определенных метрик, можно показывать рекламные объявления определенной аудитории по возрасту, полу, интересам и месту проживания / нахождения ваших потенциальных клиентов.
Существуют разные инструменты таргетинга: VK Реклама, Яндекс Директ (Яндекс Аудитории), MyTarget и другие. В зависимости от выбранного инструмента, для более эффективного сбора и обработки аудитории специалисты используют разные инструменты: парсинг, ретаргетинг и look-alike, в Яндекс Директ — Яндекс аудитории, для таргета на поиске и РСЯ.
Кому подходит: Всем, кто готов работать с целевыми клиентами, которые возможно не готовы заказать услуги в моменте. Для эффективности работы рекламы, лучше создавать чат ботов с серией отложенных публикаций после подписки.
6.) РАССЫЛКИ E-MAIL, SMS, WhatsApp, TELEGRAM и т.д.
Рассылка позволяют напомнить о себе, «подтолкнуть» сомневающихся на запись в медклинику, привлечь клиентов для повторной записи к врачу в больницу, напоминать о записях на прием или плановом приеме. Продать услуги действующему клиенту выгоднее, чем привлечь нового.
Рекомендация:
Для рассылки, лучше использовать информацию о скидках, акциях и новых услугах.
Продумайте заранее работу с программой лояльности. Например: накопительная система скидок или бонусов для постоянных клиентов (работайте с LTV - вся прибыль от клиента за период, пока вы с ним работаете).
Желательно, чтобы содержание рассылки было максимально персонализировано, а частота информирования не носила навязчивый характер.
Важно: Чтобы рассылки сработали, их нужно делать регулярно, количество обращений не будет сильно большим, но в голове клиента будет отпечатываться информация о вас (в случае чего, вы будете первыми в его списке).
Так же, мессенджеры WhatsApp, Viber или Telegram помогают коммуницировать не только в формате «человек-человек», но и «человек-бизнес». Не всегда бывает удобно набрать по телефону в моменте, проще написать в чат и получить ответ позже. Разместив кнопки мессенджеров на сайте, вы покажете свою клиентоориентированность, готовность быстро проконсультировать и прийти на помощь. Чтобы сократить время работы консультанта, можно внедрить чат бот, который будет отвечать на самые популярные вопросы и собирать контакты новых клиентов для ответов.
Кому подходит: Всем, у кого есть большая база пациентов. На маленьких объемах плохо работает.
7.) ПРОДВИЖЕНИЕ В ЯНДЕКС.ДЗЕНЕ
Яндекс.Дзен — это сервис персональных рекомендаций. Zen создает ленту контента, которая автоматически подстраивается под интересы пользователя. Выбор контента основан на анализе истории посещенных страниц, пользовательских предпочтений, местоположения, времени суток и других факторов. Обычно, запускают самостоятельно или возвращаются к продвижению канала позже, когда задействованы другие маркетинговые инструменты.
На этой площадке можно бесплатно создать личный канал клиники или бренд врача. На площадке разрешено публиковать: статьи, посты, видео.
Яндекс.Дзен дает хороший органический охват целевых посетителей, не требует больших вложений и легко масштабируется: для продвижения, не нужны уникальные тексты. Если у вас есть блог или паблик в соцсетях — можно брать тексты и фото оттуда.
Кому подходит: Всем, кто хочет развивать личный бренд и увеличить охваты целевых посетителей.
Бюджет продвижения: Не требуется если вести канал самостоятельно. Бюджет на рекламу рассчитывается индивидуально.
8.) ПРОДВИЖЕНИЕ В СОЦИАЛЬНЫХ СЕТЯХ (SMM)
Ведение группы в социальных сетях позволяет вести неформальное общение и производить дополнительное касание с целевой аудиторией, а также информировать подписчиков об акциях, полезных статьях, делиться полезными видео и т.д. Чем больше касаний, тем больше доверия к центру.
Кому подходит: Всем, кто хочет развивать личный бренд и увеличить охваты целевых посетителей в социальных сетях (ВК, Одноклассники и т.д.).
Какую стратегию продвижения выбрать медицинскому центру
В каждой ситуации должен быть индивидуальный подход. Стратегии продвижения врача, частной клиники и федерального медицинского центра будут отличаться кардинально в подходе. Какие методы можно применять и какой примерно бюджет готовить, написал выше.
Примеры распределения бюджетов на рекламу в медицинских центрах, приложил в скринах ниже с опроса в блоге НаПоправку.
📍 Что нужно знать о рекламе и маркетинге медицинских услуг в 2024 году
Частная медицина является успешным бизнеса. Филиалы открываются в разных городах, как грибы. В центрах работают профессиональные специалисты, используется новейшее оборудование, но из-за отсутствия рекламы и продвижения в интернете — поток клиентов будет мал.
Продвижение медицинских центров ничем не отличается от рекламы любого другого бизнеса, но есть ограничения со стороны закона о рекламе медицинских препаратов и услуг в интернете, о которых нужно знать:
Запрещается рекламировать запрещенные препараты, средства прерывания беременности, психотропные вещества и наркотики
Запрещается гарантировать положительный результат лечения
В рекламе запрещается упоминание конкретных заболеваний и симптомов
В любой PR-рекламе должен быть дисклеймер – предупреждение: «Имеются противопоказания. Необходима консультация со специалистом».
Перед началом продвижения медицинских услуг, рекомендую изучить актуальные нормативно-правовые акты.
📕 Документы регулирующие рекламу медицинских услуг
Ст. 24 Федерального закона № 38 «О рекламе» от 13 марта 2006 г. с поправками от 2013 г.
Письмо Федеральной антимонопольной службы (ФАС) от 17 декабря 2013 г. № АД/51199/13 «О внесении изменений в статью 24 Федерального закона «О рекламе».
Письмо ФАС от 21 июня 2017 г. № АД/41673/17 «О применении ст. 14.3 КоАП РФ».
Письмо ФАС от 25 сентября 2017 г. № АК/65861/17 «О рекламе методов профилактики, диагностики, лечения и медицинской реабилитации».
Письмо Федеральной антимонопольной службы от 14 июня 2018 г. № АК/43550/18 «Об использовании образов медицинских работников в рекламе учебных заведений для медицинских работников».
Рекомендации по соблюдению законодательства о рекламе безрецептурных лекарственных средств, утв. 7 ноября 2018 г.
На этом все, спасибо за внимание. Есть чем дополнить или поделиться, пишите в комменты или в личные сообщения.
Почему реклама в бизнесе должна работать всегда
Как избежать проблем с привлечением клиентов в бизнес и почему постоянная работа над маркетингом - это единственная жизнеспособная модель
Почему не окупается реклама?
Где брать клиентов? Сколько бы рекламу не запускал, никогда не работает
А ответ, почему она не работает, в видео
Как не менять меню 75 лет и порвать всех конкурентов: история легендарной американской фастфуд-сети In-N-Out Burger
В статье расскажу о знаменитой на Западном побережье бургерной сети США. Ребята сделали меню из пары позиций, не меняют его уже более полувека и обгоняют всех конкурентов на голову по качеству и вкусу. Затронем историю, открытие, меню, экономику и рекламу.
Про нас кратко
Всем привет! На связи Миша Кузьмин из Сконта. Мы с помощью контроля по видеокамерам увеличиваем продажи и улучшаем клиентский сервис более 200 клиентам.
Серия статей про фастфуд
Это будет очередная статья про интересный фастфуд.
Первая была про самую сложную для получения франшизу Фил Чик эй.
Вторая была про самую быструю франшизу Sonic Drive.
Третья была про убийцу Старбакса из Китая.
Ну а если вам лень читать, но интересно узнать о легендарной американской бургерной: мы специально сделали небольшое 15-минутное видео и выложили его на ютуб — вот ссылка.
In-N-Out
In-N-Out — это история трёх поколений семьи Снайдеров, которые создали сеть, охватившую всю Калифорнию и юго-западное побережье Америки. Благодаря трём блюдам — бургеру, картофелю фри и газировке — In-N-Out стал примером успешного ведения бизнеса.
Неудивительно, что In-N-Out занял первое место по популярности среди ресторанов быстрого питания в Калифорнии. Второе место, к слову, принадлежит Макдональдсу . Но обо всём по порядку.
С чего всё началось?
После возвращения со Второй мировой войны Гарри Снайдер, основатель In-N-Out, устроился в кейтеринговую компанию, где и познакомился с Эстер, будущей супругой и компаньоном.
Молодожёны захотели попробовать себя в ресторанном бизнесе. У них не было опыта в сфере фастфуда, поэтому в 1948 году Снайдеры обратились к Карлу Карчеру, владельцу Carl’s Jr. Именно он дал им важное напутствие: сосредоточиться на качестве продуктов и сохранить индивидуальный подход. Этому совету In-N-Out следует вплоть до сегодняшнего дня.
Гарри и Эстер Снайдеры со своими сыновьями, Ричем и Гаем
В 1948 году Гарри и Эстер Снайдер открыли первый In-N-Out Burger в Болдуин-Парк (ЛА), через дорогу от дома Гарри. Ресторан представлял собой здание размером 10 на 10 футов с системой drive-thru, которая позволяла гостям делать заказы, не выходя из машины. К слову, для 50-х годов это было первое изобретение «сквозного проезда». После Второй мировой войны в США система автомагистралей значительно выросла, что увеличило количество машин и темп жизни в стране.
Интересный факт: первое сквозное окно в Макдональдс появилось только спустя 27 лет, в 1975 году.
In-N-Out Burger стала закусочной «новой Америки», Америки, которая постоянно была в движении
В день открытия пара продала 47 гамбургеров. Именно в первые дни работы Гарри создал «формулу успеха», основанную на трёх столпах — качество, чистота и обслуживание.
В это же время в 45 милях от In-N-Out братья Макдональд тоже открывают ресторан. Но если Снайдеры сконцентрировались на качестве своих гамбургеров и высоком обслуживании клиентов, то Макдональды выбрали другую стратегию — снизить затраты и обеспечить высокий объём производства.
«Вся наша концепция была основана на скорости, низких ценах и объёме», — объяснял Ричард «Дик» Макдональд. Этот новый способ питания быстро стал распространяться по всей Америке.
В отличие от быстрорастущей сети Макдональдс, вторая точка In-N-Out открылась только спустя три года в долине Сан-Габриэль к востоку от ЛА. До 1970-х годов бургерная оставалась небольшой сетью в Южной Калифорнии.
В декабре 1976 года Гарри Снайдер ушёл из жизни, и его сыновья, Рич и Гай, заняли посты президента и вице-президента соответственно. Так бизнес перешёл в руки второго поколения Снайдеров.
За время пребывания в 80-х и 90-х годах Рича Снайдера в должности президента компании, количество ресторанов увеличилось с 18 до 93. Однако 15 декабря 1993 года Рич Снайдер трагически погиб в авиакатастрофе. Его вклад в семейный бизнес был огромен: он превратил местный бургерный ресторан в растущую империю, которая шла нога в ногу с гигантами в индустрии быстрого питания.
В начале января 1994 года 73-летняя Эстер Снайдер вступила в должность президента, а Гай Снайдер занял пост председателя. В 1998 году In-N-Out отметил 50-летний юбилей, достигнув отметки в 134 ресторана.
В 1999 году скончался Гай Снайдер. За шесть лет его управления компанией доходы сети выросли на 83%. In-N-Out географически расширился до Невады и собирался открыться в Аризоне.
Несмотря на трагические события In-N-Out Burger продолжал работать. К 2000 году сеть выросла до 142 ресторанов, в то время как выручка составила около 220 миллионов долларов США.
Сейчас компанией руководит Линдси, внучка Гарри и Эстер Снайдера. Пост президента она заняла в 2010 году, на тот момент ей было 28 лет.
Линдси Снайдер, внучка Гарри и Эстер
По состоянию на 2023 год открыто 392 ресторана In-N-Out в Калифорнии, Неваде, Аризоне, Юте, Техасе, Орегоне и Колорадо, в сети работают 35 000 сотрудников. Скорость расширения сети составляет около пяти новых ресторанов в год.
22 октября сеть отпраздновала 75-летие в In-N-Out Burger Pomona Dragstrip. На мероприятии были драг-рейсинг и живая музыка. Билеты были распроданы за две недели до даты проведения, солдаут 😲
Ингредиенты высшего качества: фокус на свежести
В отличие от Макдональдса и Carl’s Jr., которые пытались создать настоящую фастфуд-сеть, сокращая время на приготовление блюд (заморозка котлет и предварительно нарезанный картофель фри). Снайдер выбрал противоположную тактику: котлеты готовятся только из свежей незамороженной говядины, картошку нарезают для фри прямо перед приготовлением, а коктейли делают из настоящего мороженого.
Меню In-N-Out Burger в 2023
Забавный факт: 31 октября 2004 года блогер Уилл Янг посетил In-N-Out в Лас-Вегасе и заказал «Double-Double» с 98 дополнительными котлетами и сыром. С него взяли 97,66$ за 100 x 100 (100 говяжьих котлет, 100 ломтиков сыра). Ребята всемером одолели этот огромный бургер. Как только эта новость начала распространяться по Интернету, руководство In-N-Out отклоняла заказы на бургеры больше, чем 4 x 4.
Тот самый бургер
Ограниченное меню значительно снижает затраты на продукты. In-N-Out использует модель вертикальной интеграции для производства сырья, самостоятельно закупая и изготавливая большую часть продуктов питания. Компания не использует морозильные камеры, ежедневно доставляя продукты в рестораны из своих распределительных центров.
In-N-Out также экономит деньги, закупая мясо оптом и перемалывая его на месте. Большую часть говядины компания поставляет с крупнейшей фермы крупного рогатого скота в Калифорнии — Harris Ranch Beef Company. Котлеты для гамбургеров изготавливаются из 100% американской говядины, а целые куски мяса очищаются от костей и измельчаются мясниками In-N-Out.
Булочки же в рестораны поступают из Puritan Bakery. Они полностью безмолочные и выпекаются без масла из старомодного медленно поднимающегося опарного теста.
В недавнем интервью Thrillist Горден Рамзи сказал, что определённо предпочитает In-N-Out сети Shake Shack на восточном побережье. «Не в обиду моему другу Дэнни Мейеру из Shake Shack, но я в любом случае выберу бургер из In-N-Out», — сказал он.
Говядина в In-N-Out не содержит добавок, консервантов и наполнителей. Согласно официальному сайту бренда, говядина — это «100% молотый патрон USDA без добавок, наполнителей и консервантов».
Признаемся честно, захотелось ;)
In-N-Out придерживается того же подхода и с картофелем фри. В 50-х годах мешки из цельного свежего картофеля Kennebec, специально выращенного для In-N-Out, поступали в ресторан, где их мыли, очищали, резали, а потом готовили в 100% растительном масле без холестерина. Гарри очень заботился о том, чтобы картофель был свежий. Он проверял его на содержание крахмала, сразу же готовя тестовую партию. Если картофель не устраивал Гарри, то вся поставка отправлялась обратно. Этот подход сохранился и до сегодняшнего дня.
Бывшая сотрудница Кортни Веррилл рассказала Business Insider:
Картофель очищают и нарезают ломтиками прямо на кухне, а мясо никогда не замораживают. Я могу сказать вам по личному опыту, что если салат немного потемнел, его выбрасывают. Если помидор помяты, их тоже выбрасывают. Все ингредиенты доставляются через день, поэтому никогда и ничего не бывает испорченным. Вы определённо сможете оценить их высокое качество.
Кортни Веррилл
Что касается молочных коктейлей: вместо использования дешёвых концентрированных смесей холодного молока с консервантами, In-N-Out готовит свои молочные коктейли только из 100% мороженого.
Признаемся честно, захотелось 2.0
Когда на улице идёт дождь, In-N-Out предлагает детям до 12 лет горячий шоколад. Платить за такой приятный бонус не надо. Вот что значит клиентоориентированный подход.
Секретное меню
Известно в In-N-Out Burger есть «Не такое уж и секретное меню». Вариации стандартного меню превратились в то, что завсегдатаи начали называть «секретным» меню. Клиенты заказывали эти позиции с такой частотой, что у них стали появляется названия. Среди фаворитов: «4x4» (четыре говяжьи котлеты и четыре ломтика сыра); «Animal Style» (бургер с «секретным» соусом); «Protein Style» (бургер или чизбургер, завернутый в салат без булочки) и «Grilled Cheesе» (без говяжьей котлеты).
«секретное» меню стало чем-то вроде рукопожатия, которое распространялось среди тех, кто «в теме»
Бургер «Animal Style» в In-N-Out — один из самых легендарных секретных пунктов меню сети. Говяжья котлета готовится на гриле с горчицей, затем подаётся с солёными огурцами, салатом, луком на гриле и дополнительным «секретным» соусом на поджаренной булочке.
В течение многих десятилетий фанаты задавались вопросом, как бургер получил такое название. Может быть, когда делаешь укус этого невероятного бургера, становишься настоящим хищником?
В своей новой книге, которая выйдет в октябре в честь 75-летия компании, Линси Снайдер рассказала историю создания бургера «Animal Style». Но благодаря Insider, мы уже приоткрыли завесу этой тайны.
Линси Снайдер сказала, что шумных клиентов в начале 1960-х годов называли «животными», именно они и вдохновили сотрудников на создание самой культовой позиции в «секретном» меню сети. Эти «животные» постоянно тусовались на парковке, включали громко музыку, мусорили, сигналили и даже вступали в драки. «Между собой сотрудники добродушно стали называть их «животными»», — написала Снайдер.
Давайте вернёмся в прошлое.
Ночь. 1961 год. Компания молодых людей (animals) тусуется на парковке In-N-Out. Но тут, один из них замечает через прозрачное стекло, что Тео Робертс, менеджер In-N-Out, готовит какой-то бургер.
На вопрос: «Что это такое ты там готовишь?»
«Это жареная говяжья котлета с горчицей», — улыбаясь ответил Тео. «Сейчас ещё добавлю солёные огурцы, лук на гриле и дополнительный секретный соус».
Хулиган (animal) попросил сделать ему такой же.
Парень возвращался каждую ночь и просил сделать ему этот бургер. Но он не знал, как его назвать. Робертс сказал ему: «Просто называй его животным стилем (animal style)».
Animal Style Burger
Благодаря таким ночным хулиганам, которые зависали на парковках, и появился бургер «Animal Style». Название бургера в честь так называемых «клиентов-животных» поначалу кажется не в стиле In-N-Out, который отличается своим клиентоориентированным подходом. Но в конечном итоге эта история о том, что гость получил то, что хотел, а именно, самый вкусный бургер!
Раньше «секретное» меню и вправду было секретным. Его ассортимент не рекламировали, он ограничивался узким кругом тех, кто «в теме». Сейчас же оно размещено на главной странице сайта компании. Вот «Double-Double», например, незаметно перекочевал из «секретного» меню в обычное 😅
Каково это — работать в In-N-Out
С самого начала Гарри Снайдер предлагал своим сотрудникам больше, чем просто работу. Когда In-N-Out только открылся, минимальная заработная плата в Калифорнии составляла 65 центов/час, но Гарри платил 1$/час + один бесплатный гамбургер за смену.
В In-N-Out действует система «медленного роста». Это значит, что каждый сотрудник может построить карьеру, только вот начать придётся с самого низа. В России у Додо пиццы применяется такая же система.
Сотрудников начального уровня учат взаимодействию с клиентами «с улыбкой и искренним дружелюбием». Далее начинается стадия обработки продукции. Сотрудники учатся нарезать помидоры, чистить картофель и крошить салат-латук. Затем идёт стадия взаимодействия с клиентами в зале и через окно заказов.
После освоения этих базовых навыков, сотрудникам доверяют приготовление бургеров.
Когда ты переворачиваешь бургеры в In-N-Out, ты находишься в кресле капитана. Ты управляешь кораблём. Задача не из простых сделать каждый бургер идеальным.
Линдси Снайдер
Двигаясь по карьерной лестнице, сотрудники вырастали до позиции менеджера, средняя продолжительность работы которого в компании составляет 15 лет.
Средняя зарплата менеджера в In-N-Out — более 180 000$/год. Это намного выше отраслевых стандартов, где годовая средняя заработная плата менеджера ресторана составляет 63 000-65 000$/год.
Помимо высокой заработной платы Снайдеры постоянно устраивают многочисленные собрания, пикники, барбекю и рождественские вечеринки для сотрудников и их семей. Мероприятия направлены на сохранение корпоративной культуры.
В 2023 году компания занимает 10 место в списке лучших мест для работы. После неё уже стоят Microsoft и Linkedin.
Качество обслуживания и тайные покупатели
В эти тяжёлые времена, когда люди ежедневно сталкиваются с трудностями, порадовать их может ваша улыбка и дружелюбное обслуживание!
Рич Снайдер
Работники In-N-Out обязаны улыбаться, смотреть клиентам в глаза и поддерживать уровень профессиональной вежливости с каждым гостем. В Сконте тоже вносим этот пункт в чек-листы для улучшения качества сервиса вашего бизнеса. Мы контролируем и другие ключевые показатели: от дружелюбного приветствия до соблюдения требований пищевой безопасности.
Рич Снайдер даже ввёл конкурс «Лучшая улыбка месяца» среди сотрудников
Вернёмся на 70 лет назад и посмотрим, как проходил контроль за работой сотрудников в 50-е годы. Первые рестораны находились недалеко от Болдуин-парка (дома Снайдеров), чтобы Гарри мог ежедневно принимать доставки свежего мяса и продуктов.
Утром, днём или вечером Гарри заходил в рестораны без предупреждения. Паре нравилось знать каждого сотрудника In-N-Out по имени. Посещение ресторанов было обусловлено не только поддержанием дружеских отношений с сотрудниками, но и проверкой достойного обслуживания клиентов.
Для обеспечения высоких стандартов качества фастфуд-сети, Рич уже в 90-ые внедрил армию «тайных покупателей». Ежемесячно они посещали каждый ресторан: оценивали чистоту униформы сотрудников, корректное оформление заказа, качество приготовленных блюд и даже проверку чеков и выданной сдачи.
По сути, «тайные покупатели» Рича на самом деле стали масштабной вариацией частых посещений ресторанов Эстер и Гарри.
Сейчас в In-N-Out есть ежемесячная проверка качества под названием QFC, где представитель службы приходит и оценивает процесс готовки, чистоту и уровень комфорта клиентов, чтобы дать рекомендации по улучшению качества сервиса.
В 1984 года Рич Снайдер открывает университет In-N-Out для обучения своих сотрудников, чтобы добиться в ресторанах высокого качества блюд и сервиса. Напомним, что новых сотрудников сразу не подпускали к работе. Иногда рост с уровня «чистки картофеля» до работы с бургерами, занимал полтора года.
Плюс с 1991 года по инициативе Рича Снайдера начинает свою работу прямая линия обслуживания клиентов по номеру +1-800-786-1000. Позвонить можно с вопросом или за решением проблемы.
Дизайн, ландшафт и пальмы
In-N-Out известен быстрым обслуживанием и дружелюбной атмосферой. Эти принципы нашли отражение в их простом дизайне, логотипах и местоположении. Выбор цветов In-N-Out, минималистичный дизайн и ретро-шрифт — отсылка к многолетней истории компании.
Стрелка в логотипе направляет в In-N-Out Burger
В логотипе присутствуют красный, чистый белый и всеамериканский жёлтый. Эти цвета также используются как в дизайне интерьеров ресторана, так и в принте обёрточной бумаги для гамбургеров. Плюс уже с 1974 года традиционные цвета In-N-Out становятся частью униформы сотрудников — красные фартуки приходят на смену белым.
Кстати, логотип разработали сами основатели, Гарри и Эстер Снайдер. Они хотели придумать что-то такое, что выражало бы скорость и удобство обслуживания в их ресторане. И скажем честно, у них это получилось.
Результат — простой, но яркий дизайн, который стал символом автомобильной культуры Калифорнии и революции в фастфуде. Конечно, логотип претерпевал незначительные изменения за эти годы, но он, по сути, не изменился.
Что говорить об обстановке внутри ресторана, здесь также соблюдена стандартная цветовая палитра In-N-Out. На стенах изображены пальмы и вывески со слоганом компании.
Дизайн интерьера ресторана
Наиболее заметной является жёлтая неоновая вывеска «Качество, которое вы можете попробовать». Новые и реконструированные магазины перешли на неоновую зелёную вывеску, цвет, который нечасто ассоциируется с белой, красной и жёлтой цветовой гаммой фастфуд-сети.
В наших недавно отремонтированных ресторанах цвет неоновой вывески мы изменили на классический зелёный неоновый цвет. Хотя слоган всегда занимал место рядом с табло заказов, я уверен, что новый цвет привлёк внимание, особенно наших давних клиентов.
Вице-президент по операциям Денни Уорник
Вот как выглядит новая вывеска. Мне кажется, или жёлтый цвет был лучше?
Уорник сказал, что в рестораны вносятся незначительные изменения по мере необходимости для поддержания высоких стандартов компании.
«В некоторых наших новых ресторанах клиенты могут заметить новые обои и освещение», — сказал он. «В частности, в ресторанах с новым ремонтом акцент сделан на чёрно-белые фотографии, которые напоминают об истории нашей компании».
Чёрно-белые фотографии в ресторане Санта-Ана
Чуть не забыл рассказать о главном символе In-N-Out — о пальмах. Идея со скрещенными пальмами, посаженными перед многими ресторанами, взята из любимого фильма Гарри Снайдера «Это безумный, безумный, безумный, безумный, безумный мир». В фильме персонажи искали тайник с деньгами, спрятанный под пальмами в форме буквы W. Под буквой Х же спрятано другое сокровище — ресторан Снайдера.
Вот такая отсылочка к фильму «Этот безумный, безумный, безумный, безумный мир»
Останавливаться на сайте не будем. Здесь всё также со вкусом и аутентично😄
Расширение без франшизы
В отличие от руководителя сети Subway, который был одержим открытием новых заведений по франшизе даже в ущерб компании, Снайдеры полностью отвергали эту идею.
Основная концепция фастфуда в 1950-х годах заключалась в следующем: «Начинай, развивай, франчайзи, продавай». Те, кто не получил или не продал франшизу, вскоре поглощались крупными организациями или просто исчезали. In-N-Out легко мог бы стать одной из таких сетей, если бы не непоколебимая философия Гарри и Эстер Снайдер. Они не видели смысла жертвовать качеством ради прибыли.
В течение этого периода индустрия быстрого питания росла в среднем на 15,5% в год. Большая тройка, Макдональдс, Burger King и Kentucky Fried Chicken, превратилась в империи. К примеру, в период с 1965 по 1973 год количество ресторанов Макдональдс только в Соединенных Штатах выросло с 738 до 2500.
Количество ресторанов In-N-Out в США
Поскольку In-N-Out никогда не следовал стратегиям своих конкурентов, на него едва ли повлияли эти колебания рынка, которые сначала подняли фастфуд к вершине успеха, а затем опустили на дно. In-N-Out позиционировал себя как бренд, который мог выдержать многочисленные отраслевые подъёмы и спады, придерживаясь своей выигрышной формулы.
In-N-Out остаётся частным семейным бизнесом, который никогда не привлекал сторонние инвестиционные деньги, не продавал акции и не предлагал свои рестораны по франшизе.
Как фильм Сперлока изменил всю фастфуд-индустрию
В 2004 году вышла скандальная кинокартина-эксперимент «Двойная порция» (или «Supersize me»). В этом фильме Морган Сперлок в течение 30 дней ел только Макдональдс и рассказывал о физических (учащённое сердцебиение, увеличение веса, повышенное кровяное давление) и психологических последствиях такого рациона питания.
За три года до этого книга Шлоссера «Нация фастфуда» уже потрясла страну: «Посидите полчаса с этой книгой, и вы захотите стать вегетерианцем».
Те самые расследования, перевернувшие мир фастфуда
По мере того, как сеть Макдональдс выросла до 30 000 ресторанов по всему миру, их сервис и качество упали. В январе 2003 года фастфуд-гигант опубликовал первый в истории ежеквартальный убыток –334,8 миллиона долларов США. И Макдональдс был не один.
Отрасль, которая испытывала непрерывный рост в течение десятилетий, оказалась в кризисе. Репутация фастфуд-гигантов была серьёзно подорвана. Неприятности со здоровьем, случаи заражения кишечной палочкой, перенасыщение рынка, скандальные расследования, грязные рестораны и низкий уровень обслуживания заставили клиентов массово отказаться от фаст-фуда. В то же время идея перехода на свежие и полезные продукты питания без добавок начала набирать популярность.
Новый сегмент рынка под названием «fast casual», который предлагал полезные сэндвичи и здоровые перекусы, начал переманивать потребителей из ресторанов быстрого питания. В течение следующих нескольких лет крупные сети агрессивно пытались бороться с имиджем «торговцев нездоровой едой» и увеличивать продажи.
Fast casual dining — это концепция ресторанов с быстрым обслуживанием в стиле фаст-фуда, но с более здоровыми вариантами блюд.
В то время как фастфуд-лидеры начали адаптироваться к новым реалиям, пытаться улучшить сервис и качество продуктов, In-N-Out остался прежним и продолжал расти. К слову, в 2003 году, во время падения рынка фастфуда, продажи In-N-Out достигли примерно 302 миллионов долларов США, что на 9,8% больше, чем в 2002 году.
Для американцев In-N-Out стал не типичной фастфуд-сетью, а местом с едой высокого качества.
Маркетинг
Гарри Снайдера мало интересовало продвижение бренда через рекламу. Их философия была простой: продукт, если он хороший, должен продаваться сам, а все остальное — напускное. Однако я нашёл несколько упоминаний о ресторане в газетах того времени.
Упоминание In-N-Out в газете Covina Argus 28 сентября 1951 года
Реклама In-N-Out в Daily News-Post 3 октября 1952 года
Активно заниматься маркетингом начал Рич Снайдер. Расширение сети ресторанов по юго-западу Америки, заставило президента компании заняться привлечением новой аудитории через рекламу.
В 1977 году Рич запустил первую телевизионную рекламу In-N-Out. В кратком анимационном ролике был показан ковбой, который ехал на лошади, поднимаясь к In-N-Out и заказывая «Double-Double». К сожалению, эту рекламу я не нашёл. Зато в открытом доступе есть реклама 1981 года.
Под руководством Рича и сеть запустила радио-джингл с запоминающимся припевом: «In-N-Out, In-N-Out, вот что такое гамбургер», и он быстро стал чем-то вроде гимна Южной Калифорнии. Вскоре появились новые слоганы: «Качество, которое вы можете попробовать» и «Чистота, которую вы можете увидеть».
Одной из наиболее успешных маркетинговых стратегий компании стали наклейки на бампер. В Южной Калифорнии, начиная с 1980-х годов, размещение наклейки In-N-Out на задней части автомобиля означало членство в своеобразном клубе.
В 1984 году Рич использовал широкую популярность наклеек на бампер для запуска масштабного розыгрыша от In-N-Out. В течение нескольких месяцев компания раздавала их всем желающим, а сотрудники записывали номерные знаки автомобилей, будущих участников розыгрыша. Среди призов: поездка на Гавайи, микроволновые печи, видеомагнитофоны и футболки In-N-Out.
Вместо массовой рекламы на билбордах по Лос-Анджелесу, In-N-Out запустил рекламу «из уст в уста». Акция объединила два культурных символа ЛА — гамбургеры и автомобили — и передала основные ценности бренда In-N-Out.
В Калифорнии, просто благодаря наклейкам на бампер, In-N-Out стал таким же известным, как Диснейленд или Макдональдс. По оценкам рекламный бюджет In-N-Out варьировался от одного до 10 миллионов долларов США в год. Эти суммы — ничто по сравнению с бюджетами его конкурентов в области фастфуда, которые регулярно вливали сотни миллионов долларов в рекламу. С постоянным спросом на бургеры у In-N-Out было мало необходимости в сложных маркетинговых кампаниях, которые регулярно использовали её конкуренты.
In-N-Out полагался на свой радио-джингл и нечастую телевизионную рекламу, обычно транслируемую по кабелю. Удивительно, но, наклейки на бамперы, футболки и преданные поклонники, казалось, рекламировали In-N-Out намного эффективнее, чем дорогостоящая реклама на ТВ.
Стоит упомянуть ещё одну необычную рекламную кампанию. Вскоре после того, как Рич объявил о глубокой приверженности христианству, он напечатал библейские стихи на упаковке In-N-Out. Внутри обода на дне стаканчиков с газировкой спрятался стих «Иоанна 3:16» («Ибо Бог так возлюбил мир, что отдал Своего Единородного Сына»). Затем и другие стихи появились без предупреждения на стаканчиках с молочными коктейлями («Притчи 3:5») и на бумажных обертках для гамбургеров и чизбургеров («Откровение 3:20»).
Библейские стихи на упаковке
Необычный маркетинговый шаг был принят как с одобрением, так и с откровенной критикой. Стали ходить слухи о том, что In-N-Out принадлежит христианской секте. Но это не было правдой.
Итак, подытожим: у In-N-Out один из самых дорогостоящих видов маркетинга — рекомендации и лояльность клиентов. Благодаря рекламе «из уст в уста», маркетинговые бюджеты бренда намного ниже, чем у других ресторанов быстрого питания. Это позволяет им вкладывать сэкономленные деньги в поддержание высокого качества и аутентичности бренда.
Почему In-N-Out остаётся легендой
В своих книгах я всегда использую In-N-Out в качестве примера того, как вести любой бизнес. У них есть пять позиций, которые действительно хорошо приготовлены, и этого достаточно!
Джордж Гири, шеф-повар
Книга Джорджа Гири «Сделано в Калифорнии: калифорнийские закусочные, бургерные, рестораны быстрого питания, которые изменили Америку»
Как мы уже поняли, In-N-Out не распыляется, а чётко соблюдает свои принципы и медленно двигается в выбранном направлении. In-N-Out — пример успешной реализации стратегии фокусирования.
Теперь по пунктам рассмотрим соответствие In-N-Out этой стратегии:
In-N-Out ограничена географически — посетить ресторан можно только в нескольких штатах. Сеть получила культовый статус, частично благодаря своему расположению на юго-западе Америки и уникальной маркетинговой стратегии.
К продукции предъявлены высокие стандарты качества. Рестораны расположены рядом с поставщиками, благодаря чему продукты всегда свежие.
Ограниченное меню In-N-Out. Акцент на нескольких позициях в меню, приверженность традиционным рецептам — формула успеха In-N-Out. А «секретное» меню (хотя оно уже давно не секретное) придаёт ощущение какой-то тайны для посетителей.
Компания делает ставку на тех, кто выбирает только фастфуд высокого качества — узкий круг потребителей (хотя с каждым днём он только растёт).
Философия заведения, как и меню остались практически неизменными за долгие годы. Приоритетами Снайдеров были и остаются высокое качество, свежие продукты, дружелюбное обслуживание и чистота в ресторанах.
Ограниченный охват In-N-Out и узкая направленность бизнеса также означает, что сети не приходится постоянно тратить деньги на дополнительное оборудование или придумывание новых блюд. Кроме того, отсутствие акционеров даёт Снайдерам полную свободу в распоряжении финансами. Они явно уходят на поддержание высоких стандартов качества.
In-N-Out остается семейным бизнесом с 75-летней историей. Это создаёт ощущение ностальгии и аутентичности для всех посетителей.
In-N-Out Burger — пример того, что на минимальном ассортименте можно выстроить уникальную и эффективную бизнес-стратегию.
В сочетании эти факторы делают In-N-Out легендой в индустрии фастфуда: компания продолжает привлекать и удивлять клиентов в течение многих десятилетий.
Подписывайтесь на наш телеграм: https://t.me/scontt
Казань глазами курьера: сколько зарабатывают, плюсы и минусы работы. Трогательные истории курьеров
Наши города заполонили курьеры - почти каждый второй пользуется доставками. Яндекс лавка, Самокат, Сбермаркет - основные «игроки», курьеры которых ежедневно доставляют заказы в столице Татарстана. Подработка курьером отличное занятие для студентов, чаще всего они идут в доставщики. Яндекс курьеры, курьер Самоката - сейчас эта профессия звучит гордо) Мы сняли большой фильм про работу курьера в нашем городе - вы услышите три реальные истории от курьеров и узнаете, сколько можно заработать на доставке, какие условия труда, а также с какими трудностями приходится сталкиваться во время работы курьером.
Ответ FishGod в «Клиент, такой клиент»
-Можно мне прокладку?
Сам себе экосистема. Часть 4: как я реализовал клиент Telegram на Android-смартфоне 14-летней давности?
С момента выхода первой части статьи из рубрики «сам себе экосистема» прошёл уже практически год! За это время, мы успели с вами реализовать клиенты 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 медиаэлементов. Так что листинги будут совсем без табов, но алгоритм их работы понять можно :)
[DllImport(Library, EntryPoint = "td_create_client_id", CallingConvention = CallingConvention.Cdecl)]
public static extern int CreateClientID();
[DllImport(Library, EntryPoint = "td_send", CallingConvention = CallingConvention.Cdecl)]
public static extern void Send(int id, string request);
[DllImport(Library, EntryPoint = "td_receive", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr RawReceive(double timeOut);
[DllImport(Library, EntryPoint = "td_execute")]
public static extern StringBuilder Execute(string request);
public static unsafe string Receive(double timeOut)
{
IntPtr str = RawReceive(timeOut);
return str != IntPtr.Zero ? new string((sbyte*)str.ToPointer()) : null;
}
Позволю себе чуточку критики в сторону 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);
string type = json["@type"].ToString();
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, что означает готовность библиотеки к работе:
private void OnAuthState(string raw, JObject obj)
{
JObject authState = (JObject)obj["authorization_state"];
string type = authState["@type"].ToString();
if (type == "authorizationStateWaitTdlibParameters")
{
Console.WriteLine("Preparing TDLib parameters...");
NativeInterface.Send(InstanceID,
Utils.Format("{" +
"\"@type\": \"setTdlibParameters\", " +
"\"database_directory\": \"tdlib\", " +
"\"api_id\": {0}, " +
"\"api_hash\": \"{1}\", " +
"\"use_chat_info_database\": true," +
"\"use_file_database\": true," +
"\"use_message_database\": true," +
"\"system_language_code\": \"en\", " +
"\"device_model\": \"Phone\", " +
"\"application_version\": \"1.0\" " +
"}", APIId, APIHash));
}
if (type == "authorizationStateWaitPhoneNumber")
{
Console.WriteLine("Sending phone number");
NativeInterface.Send(InstanceID, Utils.Format("{\"@type\": \"setAuthenticationPhoneNumber\", \"phone_number\": \"{0}\" }", PhoneNumber));
}
if(type == "authorizationStateWaitCode")
{
NativeInterface.Send(InstanceID, Utils.Format("{\"@type\": \"checkAuthenticationCode\", \"code\": \"{0}\" }", WaitCode));
}
if(type == "authorizationStateReady")
{
Console.WriteLine("Authorized");
waitHandle.Set();
}
}
...
Client.AttachEventHandler("updateAuthorizationState", OnAuthState);
После этого, можно начать работу с данными. Обратите внимание, мой подход потоко-небезопасен, его нельзя дергать из нескольких потоков одновременно! В коде ниже, я вызываю метод для фетча сообщений, а затем в соответствующем коллбэке от TDLib обрабатываю данные (дабы статья не разрасталась на 20+ минут, я чуть урезал все листинги).
public List<Message> QueryMessagesInChat(long chatId, long lastMessage, int count)
{
messages.Clear();
requestMessageCount = count;
string json = Utils.Format("{\"@type\": \"getChatHistory\", \"chat_id\": \"{0}\", \"from_message_id\": {1}, \"limit\": {2} }", chatId, lastMessage, count);
NativeInterface.Send(InstanceID, json);
waitHandle.WaitOne();
return messages;
}
public User QueryUser(long userId)
{
string json = Utils.Format("{\"@type\": \"getUser\", \"user_id\": \"{0}\" }", userId);
NativeInterface.Send(InstanceID, json);
waitHandle.WaitOne();
return user;
}
Переходим к реализации самого сервера, для наших целей хватит обычного HttpListener. Сначала мы зарегистрируем все поддерживаемые методы и занесем их в ассоциативный список ключ-значение. Сами методы реализованы в виде делегатов, которые принимают лишь один аргумент — список параметров из строки запроса, а возвращают строку — все ответы, за исключением особых (связанных с загрузкой вложений) — текстовые.
private HttpListener listener;
private List<HttpMethodHandler> methods;
private ScheduledRestart restartManager;
private void AddMethod(HttpMethodHandler info)
{
if(info != null)
{
methods.Add(info);
Console.WriteLine("Registered method: {0}", info.Method.Name);
}
}
private void PrepareMethods()
{
AddMethod(Chats.QueryChats);
AddMethod(Chats.QueryMessages);
AddMethod(Chats.SendMessage);
AddMethod(Users.QueryUserInfo);
}
private void PrepareState()
{
// We should fetch dialog list due to TDLib nature of preloading-everything
Client.QueryChats(15);
}
public HttpServer()
{
listener = new HttpListener();
listener.Prefixes.Add("http://+:13377/");
Client = new SyncClient("test");
Client.Start();
Client.WaitUntilReady();
//restartManager = new ScheduledRestart(5);
//restartManager.Start();
methods = new List<HttpMethodHandler>();
PrepareMethods();
PrepareState();
}
...
public void Start()
{
listener.Start();
while(listener.IsListening)
{
HandleRequest(listener.GetContext());
}
}
Переходим к обработке запроса. Метод ищет, зарегистрирован ли запрошенный метод и если да, то парсит строку запроса, которая начинается с "?", которую затем передаёт в виде коллекции ключ->значения обработчику метода:
private void HandleRequest(HttpListenerContext ctx)
{
string method = ctx.Request.Url.LocalPath.Substring(1).ToLower();
if (method.Length < 0)
{
SendResponse(HttpGenericResponse.MethodRequired.ToString(), ctx);
return;
}
foreach(HttpMethodHandler handler in methods)
{
if(method == handler.Method.Name.ToLower())
{
string result = "";
if (ctx.Request.Url.Query.Length > 0)
{
string[] args = ctx.Request.Url.Query.Substring(1).Split('&', StringSplitOptions.RemoveEmptyEntries);
Dictionary<string, string> keyValuePairs = new Dictionary<string, string>();
foreach (string arg in args)
{
if (arg.IndexOf('=') >= 0)
keyValuePairs.Add(arg.Substring(0, arg.IndexOf('=')), arg.Substring(arg.IndexOf('=') + 1));
else
keyValuePairs.Add(arg.Substring(0, arg.IndexOf('=')), "");
}
result = handler(keyValuePairs);
if (result == null || result.Length < 1)
{
Console.WriteLine("Suspicious result from {0}", handler.Method.Name);
}
}
SendResponse(result, ctx);
return;
}
}
SendResponse(HttpGenericResponse.UnknownMethod.ToString(), ctx);
}
А сами методы, в свою очередь, дергают соответствующие функции из клиента и формируют на их основе датасет в примитивном формате:
public static string QueryChats(Dictionary<string, string> args)
{
if(args.ContainsKey("count"))
{
int count = int.Parse(args["count"]);
StringBuilder ret = new StringBuilder();
List<Chat> chats = HttpServer.Instance.Client.QueryChats(count);
ret.AppendLine(string.Format("Count={0}", chats.Count));
foreach(Chat chat in chats)
{
ret.AppendLine("Begin");
ret.AppendLine("ID=" + chat.ID);
ret.AppendLine("Date=" + chat.LastMessageDate);
ret.AppendLine("Name=" + chat.Name);
ret.AppendLine("Text=" + Uri.EscapeDataString(chat.LastMessageText));
ret.AppendLine("MsgId=" + chat.LastMessageID);
ret.AppendLine("End");
}
return ret.ToString();
}
return HttpGenericResponse.InternalException.ToString();
}
В результате получаем вот такой простой датасет, который, как я и говорил, легко распарсить и на Siemens C60, и на Atmega328 — да где угодно! В целом, такой сервер можно использовать для реализации бота в телеграме, который будет передавать показания каких-то датчиков, сигнализацию и прочие клевые штуки!
Переходим к реализации клиента, т.е. приложения на Android. Здесь будет не менее интересно!
❯ Пилим для Android
В геймдеве есть своеобразный мем — некоторые инди-разработчики сначала начинают делать меню, вместо основного геймплея, что становится предметом насмешек среди других разработчиков. Но в разработке приложений для смартфонов всё по другому — здесь как-раз таки хорошо заранее продумывать макет будущего приложения!
Поскольку у нас с вами мессенджер, то главный экран должен представлять из себя список чатов (ListView) и верхнюю панельку, где в будущем могут разместиться настройки и свайп-менюшка:
Такой вот простой макет.
Каждый пункт меню — это тоже отдельный layout, в котором мы по шаблону строим внешний вид будущего элемента списка. На немолодых устройствах есть смысл использовать как можно меньше контейнеров в layout'е, поскольку пересчет позиций и размеров элементов — одна из самых «тяжелых» операций в UI-фреймворке вообще. Кроме того, не стоит использовать кучу картинок и drawable — в Android 2.x всё 2D рисуется софтварно, аппаратное ускорение появилось только в 3.0 (частично).
Но дабы в списке диалогов что-то появилось, нужно сначала реализовать фетчинг (получение) этих самых диалогов с сервера! Сам объект, который занимается обработкой запросов называется ClientManager и является синглтоном — он в единственном экземпляре на все время работы программы. Помимо менеджмента «ноды» (т.е. прокси-сервера), токена для авторизации и обработчика ошибок, ClientManager реализует метод для асинхронного запроса информации с сервера и, собственно, формирует строки запросов с помощью соответствующих методов:
public void queryChats(int count, Response resp) {
sendRequest(String.format("%s/QueryChats?count=%d&auth_key=%s", nodeAddress, count, token), resp);
}
Подгрузка чатов и сообщений реализована через Adapter — концепция «виртуальных» списков, которая предполагает что система создаст не 50 элементов интерфейса на каждую кнопку чата, а только 5 и будет их виртуально «мотать по кругу», обновляя только данные в уже существующих элементах. Это позволяет значительно ускорить отрисовку, учитывая то, что Android 2.x Canvas рисуется программно.
private void updateDialogList() {
ClientManager.getCurrent().queryChats(50, new ClientManager.Response() {
@override
public void onReady(String str) {
try {
List<Packets.Chat> chats = Packets.parseChatListFromQueryResponse(str);
DialogAdapter adapter = new DialogAdapter();
adapter.setChats(chats);
((ListView) findViewById(R.id.messages_view)).setAdapter(adapter);
} catch (Exception e) {
Toast.makeText(MainActivity.this, "Упс!", Toast.LENGTH_SHORT);
}
}
});
}
Ну вы уже явно замучились видеть простыни кода, давайте посмотрим что у нас вышло!
Шустренько, да? А ведь это ультрабюджетник Alcatel OT-916D, один из последних массовых дешевых QWERTY-смартфонов за 5 000 рублей из 2012 года. Кстати, смартфон подарил мне читатель chuvakoff с Хабра!
Переходим к окну чата. Основной макет почти такой-же, как и у основного окна: только добавилась панелька для ввода сообщения снизу.
Концептуально, всё тоже самое — запрашиваем данные с сервера, парсим их и загружаем в адаптер, благодаря чему мы сможем листать наш диалог. Однако в сообщения я добавил контекстное меню с стандартными фишками типа копирования, ответа и прочих подобных действий. Поскольку у нас нет ни пушей, ни еще каких-либо средств для поулчения данных о новых сообщениях, я раз в определенный интервал просто получаю сообщения — и если новый датасет отличается от старого — обновляю окошко чата.
view.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
@Override
public void onCreateContextMenu(ContextMenu contextMenu, View view, ContextMenu.ContextMenuInfo contextMenuInfo) {
// Reply to...
contextMenu.add(getString(R.string.reply)).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
setReplyContext((Packets.Message) view.getTag());
return true;
}
});
// Copy
contextMenu.add(getString(R.string.copy)).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
ViewGroup vg = (ViewGroup)view;
android.text.ClipboardManager manager = (android.text.ClipboardManager) view.getContext().getSystemService(CLIPBOARD_SERVICE);
manager.setText(((TextView)vg.findViewById(R.id.message_content)).getText());
return true;
}
});
// Send to...
contextMenu.add(getString(R.string.resend)).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
ViewGroup vg = (ViewGroup)view;
String text = ((TextView)vg.findViewById(R.id.message_content)).getText().toString();
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_TEXT, text);
intent.setType("text/plain");
startActivity(Intent.createChooser(intent, null));
return true;
}
});
}
});
Переходим к реализации поля для ввода сообщения. Здесь всё просто — на серверсайде за это отвечает метод SendMessage. Однако для того, чтобы с нашего клиента можно было ответить на другие сообщения, я ввёл также «контекст ответа», в котором запоминается сообщение, на которое мы хотим ответить. Telegram также поддерживает Markdown, однако его полная поддержка пока не реализована.
EditText editText = ((EditText)findViewById(R.id.message_text));
if(editText.getText().length() > 0) {
long replyTo = replyContext != null ? replyContext.ID : 0;
ClientManager.getCurrent().sendTextMessage(chat.ID, editText.getText().toString(), replyTo, new ClientManager.Response() {
@Override
public void onReady(String str) {
}
});
editText.setText("");
setReplyContext(null);
}
В остальном же, функционал конечно пока совсем базовый, однако клиент работает очень шустро даже бюджетной X10 Mini Pro и позволяет чатится с моими читателями в Telegram. В будущем хотелось бы допилить:
Поддержка картинок: Сейчас уже есть кривоватый механизм кэширования изображений на стороне сервера, который позволяет загружать аватарки чатов. В будущем, я добавлю поддержку «галерей» с картинками!
Поддержка голосовых сообщений: Не все их любят, но они порой удобны и выручают. Реализую как прослушивание, так и запись!
Подробный просмотр профилей и менеджмент чатов: Удаление сообщений, чатов и прочие фишечки из официальных клиентов.
Казалось бы — до официальных клиентов ещё очень далеко. Но сам факт, чтобы всё это работало достаточно шустро на девайсах, которым уже более 10 лет!
❯ Звучит интересно! Как заюзать твой клиент?
Тут всё очень и очень просто! В первую очередь, нам понадобится ПК с белым IP, роутер (если под него есть сборка dotnet), либо VDS. Виртуальные сервера сейчас стоят копейки, у ТаймВеба есть тариф за 188 рублей в месяц, которого с головой хватит для нашего сервера.
Такая вот рекламная интеграция (к слову, прокси для всех приложений уже более года крутятся именно на мощностях TimeWeb Cloud)!
Берём уже собранный TDLib и сервер под Windows, или собираем TDLib под Linux, накатываем .NET Core. Пример для Debian/Ubuntu:
sudo apt-get install dotnet
Затем запускаем сервер:
dotnet tdsrv.dll
Программа сначала запросит номер телефона, а затем код подтверждения 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, чтобы не пропускать новые статьи каждую неделю!