Давным-давно, примерно с год назад, когда Московское метро ломалось в рандомных местах и удивительно часто, у нас ( dcoder_mm & Irenica ) возникла мысль: сделать какой нибудь сервис, для оповещения о поломках.


Вам эта идея может показаться странной, dcoder_mm тоже так казалось, до тех пор, пока сам в одну из таких поломок не попал. Стоять на переполненной платформе 10 минут в ожидании поезда, как оказалось неприятно, да так, что впредь решил так не попадаться.

После этого происшествия решили полистать twitter: пишут ли что-нибудь о происшествиях в метро. Как выяснилось, пишут. Причем первые твиты об этом были минут за 10 до того как зашел в метро.

Тут потихоньку и начала зарождаться идея: собираем информацию из twitter, ищем упоминания поломок метро и оповещаем пользователя, если что-то нашлось.

Правда потом эта идея была заброшена на долгое время, но осенью 2014 мы снова о ней вспомнили — метро опять стало регулярно ломаться.

В качестве способа оповещения решено было использовать смс. Можно было, конечно, использовать что-то другое, хоть твиттер-бота для аггрегации сообщений о метро завести, но у смс есть одно преимущество — они доходят даже когда нет нормального подключения к интернету. А в метро его часто не бывает, но при этом GSM ловится нормально. (Когда мы начали делать сервис, Wifi во всем метро еще не было).

Дело оставалось за малым — собственно, сделать парсилку твитов и отправку смс.

Для проверки боем был написан простенький однострочный скрипт, получающий через поиск (curl search.twitter.com) последние твиты с хештегом #метро, выделяющий из них нужные по ключевым словам, и отправляющий нам смс.

curl -ssl "https://twitter.com/search?f=realtime&q=%23%D0%BC%D0%B5%D1%82%D1%80%D0%BE&src=typd"  |  grep -E -o "js-tweet-text tweet-text.*<\/p>" | sed -e 's;[><\"=-]; ;g;s;js tweet text tweet text lang ru data aria label part 0;;g;s;/a;;g;s;\/\(a\|p\); ;g;s;\(.span\|.strong\|class\|twitter\|timeline\|link\|js display url\|invisible|\tco ellipsis\|href\|nofollow\|dir\|ltr\|data\|expanded\|url\|invisible\|tco\|ellipsis\|google&\;utm_medium\|banner&\;utm_campaign\|business_news\|target\|_blank\|title\|atreply\|pretty\| \;\|rel\|s\|?utm_source\|draggable\|false\|alt\|aria\|label\|u\|hidden\|pre\|embedded|\true\|b\|a\|qery\|orce\|hahtag_click\|hahtag\|j\|nav\|emedded\|tre\|&qot\;\|emedded\|tre\|rc\|hh\|qery\|orce\|hhtg_click\|hhtg\|img\);;g;s; ; ;g;s;
\; ;;g;s;&qot\;;;g;s;emedded;;g;s;tre;;g;s; \/ ;;g;s;hhtg_click hhtg;;g;s;hh;;g;s;qery oe;;g;s;\/tg\/[a-zA-Z]*;;g;s;tweet;;g;s;text;;g;s;lng;;g;s;nd;;g;s;prt;;g;s;http://intgrm.com\s\/[a-zA-Z]*\/;;g;s;[A-Z%a-z]*;;g;s;[\/_\/:\/?\.@&;…]*;;g;s;^[0-9]*;;g;s;[0-9]\{3,\};;g;s;^\s*;;g;s;  *; ;g;s;^[0-9] ;;g;s;# ;#;g;s;[0-9 #]*$;;g'  | grep -E -i  "жертв|авари|ЧП|неполадки|не будет работать|закр|перебои|застрял|интервал|катастрофа|перекрыт|остановлен|простоял|битком|затык|интервал|не ходят|ремонт|приостановлено|сбой|неисправ|сломался поезд|бомб|взрыв|теракт|затруднен|приостанов|траур|давк|дым|взорв|стрел|наводнен|вода|потоп|затопил|на рельсы|не ходят|не идут|напряжение" | grep -E -i "Марьин|Достоевск|Трубн|Сретенск|Чкаловск|Римск|Крестьянск|Дубровк|Кожуховск|Печатник|Волжск|Люблин|Братиславск|Марьин|Борисов|Шипиловск|ЗябликовВаршавск|Каховск|Лесопарков|Старокачаловск|Скобелевск|Ушаков|Горчаков|БунинскРокоссовс|Черкизовс|Преображенск|Сокольн|Красносельск|Красн|Чисты|Лубянк|Охотн|Библиотек|Кропоткинск|Фрунзенск|Спортивн|Воробьёв|Университет|Вернадск|ЮгоЗападн|Западн|Юго Западн|Тропарев|Алма|Красногвардейск|Домодедовск|Орехов|Царицын|Кантемировск|Каширск|Коломенск|Автозаводск|Новокузнецк|Театральн|Тверск|Маяковск|Динам|Аэропорт|Сокол|Войковск|Водн|Речн|Пятницк|Митин|Волоколамск|Мякинин|Строгин|Крылатск|Молодежн|Кунцевск|Славянск|Побед|Смоленск|Арбат|Революц|Бауманск|Электрозаводск|Семеновск|Партизанск|Измайловск|Первомайск|Щелковск|Александровск|Смоленск|Выставочн|Международн|Студенческ|Кутузовск|Фил|Багратионовск|Филевск|Пионерск|Белорусск|Новослободск|проспект Мир|Комсомольск|Курск|Таганск|Павелецк|Добрынинск|Октябрьск|культур|Киевск|КраснопресненскМедведков|Бабушкинск|Свиблов|Ботаническ|ВДНХ|Алексеевск|Рижск|Сухаревск|Тургеневск|Третьяковск|Шаболовск|Ленинск|Академическ|Профсоюзн|Черемушк|Калужск|Беляев|Коньков| Стан |Ясенев|Новоясеневск|Жулебин|Лермонтовск|Выхин|Рязанск|Кузьминк|Текстильщик|Волгоградск|Пролетарск|Китай-город|Кузнецк|Пушкинск|Баррикадн|1905|Бегов|Полежаевск|Октябрьск[а-я ]поле|Щ[ую]кинск|Спартак|Тушинск|Сходненск|Планерн|Новокосин|Новогиреев|Перов|Энтузиаст|Авиамоторн|Ильич|Марксистск|Третьяковск|Делов|Алтуфьев|Бибирев|Отрадн|Владыкин|Петровск|Разумовск|Тимирязевск|Дмитровск|Савеловск|Менделеевск|Цветн|Чеховск|Боровицк|Полянк|Серпуховск|Тульск|Нагатинск|Нагорн|Нахимовск|Севастопольск|Чертановск|Южна|Пражск|Янгел|Аннин|Донск|арбатско-покровск| апл | син[яиюе]|таганско-краснопресненск| ткл |фиолетов[аоу][йюя]|замоскворецк| зл |зел[её]н[аоу][йюя]|серпуховско-тимизязевск| стл | сер[уоа][яйю]|сокольническ| сл | красн[аоу][яйу]|фил[её]вск| фл |голуб[аоу][йюя]|кольц|калужско-рижск| крл | рыж[еау][йюя]|калининск| кл |ж[её]лт[аоу][йюя]|оранжев[оау][йюя]|люблинск|салатов| лк |каховск|бутовск" | grep -i -v  -E "лет назад|год назад|года назад|вспомнил|одесс|украин|спб|питер|петербург|санкт-петербург|повер|резиден|память|годжи|ягод|такси|окна|займ|деньг|iphone|худе|акци|скидк|порн|porn|pron|прон|диет|follow|retweet|скачать|бесплатн|курит смес|спайс|минск|истор|жизнь прекрасна|крещатник|квартир|выжил|прокуратур|киев |киеве|уголовное|Лесн|Геро Днепр|Сырецк|Черниговск|Минск|Дорогожичи|Дарниц|Оболон|Лукьяновск|Левобережн|Петровк|Золот ворот|Гидропарк|Тарас Шевченк|Дворец Спорт|Днепр|Контрактов площад|Кловск|Арсенальн|Почтов площад|Печерск|Крещатик|Майдан Независимост|Дружб Народ|площад Льв Толстог|Выдубич|Олимпийск|Славутич|Вокзальн|Дворец Украин|Осокорк|Политехническ институт|Лыбедск|Позняк|Шулявск|Димеевск|Харьковск|Берестейск|Голосеевск|Вырлиц|Нивк|Васильковск|Бориспольск|Святошин|Красн хутор|Житомирск|Ипподром|Академгородок|Теремк|париж|больниц|бостон|голос|кровь" | sort | uniq


И как ни странно, оно вполне нормально заработало. Иногда, конечно, попадались ложные срабатывания, но главное — оповещения приходили при всех мало-мальски важных поломках. И приходили быстро — значительно раньше, чем эта информация появлялась в СМИ или где нибудь еще.

Теперь, настала очередь фильтровать ложные срабатывания. Самый наглый и очевидный спам, например, реклама с хештегом #метро, не проходил, потому что не содержал ключевых слов (вроде «авария» или «поломка»). Но это не спасало, к примеру, от сообщений о поломках метро в других городах (не всегда в твите о поломке метро в Питере напишут слово «питер»). Поэтому пришлось ввести список «стоп-слов» при наличии которых сообщение не отправлялось. В него были включены некоторые названия станций других городов, ключевые слова, которые часто встречались в рекламе и т.д.

Проблему с тем, что на одно событие может приходится пара десятков твитов, и столько-же смс, решили в лоб: просто блокируем все сообщения про эту ветку метро на определенное время.

Впрочем, были и другие причины ложных срабатываний: сообщения о поломках другого транспорта (но при этом с тегом «метро»), сообщения, о старых поломках метро (пара аккаунтов пишет твиты о трагедии в метро летом 2014, так как будто это случилось только что).

Когда оно наконец-то стало более-менее стабильно работать, мы сделали веб интерфейс с возможностью регистрации по номеру телефона. Потихоньку начали подтягиваться еще люди, и естественно, в полном соответствии с законом подлости, случилось еще несколько ложных срабатываний. Чтобы больше такого не повторялось, сделали премодерацию: То есть сначала сообщения приходят нам, и если мы за пару минут не запретим их отправку, рассылаются всем остальным пользователям.

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

В общем, кому это интересно: msk-metro.ru Вот мы. Можно считать, что проект еще на стадии от бета тестирования, поэтому если вам случайно придет левая смс — не расстраивайтесь. Мы это исправим, и в следующий раз такая-же смс точно не придет.

А живет это все на Raspberry Pi на debian.

Комментарии (52)


  1. Lol4t0
    06.05.2015 23:46
    +6

    Вы надеюсь перешли на официальное twitter API, или все еще колхозите?

    Там, кстати, можно больше условий на хеш-таги накладывать.

    А для избежания ложных срабатываний не пробовали сделать простой пороговый фильтр?


    1. dcoder_mm
      06.05.2015 23:51

      А что подразумевается в данном случае под пороговым фильтром? Подсчет «ключевых» слов?


      1. Lol4t0
        07.05.2015 00:02
        +2

        Вообще можно много чего предложить для улучшения детектирования и отсеивания ложных тревог.

        Самое простейшее — не реагировать на первое сообщение, а накапливать сообщения в течение некоторого окна времени. как только сообщений в окне становится достаточно много, генерируется событие.

        Следующее улучшение — определять для каждого сообщения некоторую степень достоверности, и учитывать ее при подсчете очков.

        Решением таких задач занимаются CEP в широком смысле


        1. Irenica Автор
          07.05.2015 00:14
          +2

          Прежде чем обрабатывать поломку, накапливаем некоторое количество сообщений.

          На данный момент было интересно запустить проект как можно быстрее, не заморачиваясь с чем-то сложным. Интересно нужно ли это народу и в зависимости от этого будет ясно куда дальше двигаться.


  1. click0
    07.05.2015 00:56
    -1

    Код мало читаем.
    Для обработки текста лучше подходит awk, а не grep.


    1. dcoder_mm
      07.05.2015 01:01
      +3

      Ну, так это же регулярки, они всегда нечитаемы) Тем более, это только часть кода.


      1. click0
        07.05.2015 01:08
        -1

        Даже используя регулярные выражения, переносы строк, табуляции и символ "\" сделают код более читабельным.
        Вы же не собрались экономить пару байт кода скрипта в ущерб читабельности и дальнейшего рефакторинга?


        1. Irenica Автор
          07.05.2015 01:15
          +4

          Или знаешь регулярные выражения или не понимаешь


          1. Yaruson
            07.05.2015 10:09
            +7

            Флейм
            xxx> Я умею читать чужие мысли!
            yyy> А я умею читать чужие регулярные выражения
            xxx> Ок, ты победил
            Цитата #431836 — Цитатник Рунета


          1. click0
            07.05.2015 13:12

            И какая взаимосвязь?
            Я вот знаю regexp и все равно, вынужден буду форматировать код для лучшей читабельности.


        1. mtp
          07.05.2015 13:01
          +1

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


    1. Irenica Автор
      07.05.2015 01:14
      +3

      grep полезен если нужно быстро и просто найти строки, по заданному шаблону. Еще он может возвращать некоторую иную информацию, такую как списки имен файлов, выводить n-совпадений и много чего еще интересного и нужного.
      А awk это С-подобный язык, им удобно будет читать, к примеру CSV файлы. Но он не такой простой, чтобы использовать для простых задач. Он умеет всё, что и grep, но это не всегда надо.


      1. click0
        07.05.2015 13:21
        -1

        grep полезен если нужно быстро и просто найти строки

        При больших текстах и файлах это не очень быстро.

        Еще он может возвращать некоторую иную информацию

        Вы и так результат присваиваете переменной и дальше обрабатываете.

        … к примеру CSV файлы. Но он не такой простой

        Вы парсите сложный html текст, форматированный CSV текст значительно проще.


        1. Irenica Автор
          07.05.2015 13:25

          Где вы увидели тут большие тексты? html-страничка весит ну максимум 20кб


          1. click0
            07.05.2015 13:44
            -1

            html-страничка весит ну максимум 20кб

            Вы хотели сказать 20KB? :)

            Плотно размещенный печатный текст формата А4 занимает примерно 2KB в электронном виде.
            Я раз за прогресс в росте производительности микропроцессоров, не не привык зря расходовать процессорные такты.


  1. glazik
    07.05.2015 01:55
    +1

    Здорово!
    А как смски отправляете?


    1. dcoder_mm
      07.05.2015 02:03

      Спасибо :)
      Отправляем через websms.ru. Просто потому что это первое (или одно из первых) что нашлось в гугле. У них есть разнообразное api для отправки, в том числе и простыми get-запросами.
      Думаем о том, чтобы приспособить старенькую нокию для отправки смс (взяв какой-нибудь жирный SMS-пакет) — это должно быть дешевле


      1. Wendor
        07.05.2015 10:07
        +1

        Можно 3g модемом это еще делать. Вполне удобно.
        А если прикрутить какой-нить smsd с плагином mysql, то для отправки будет достаточно вставить запись в БД.


      1. DarkByte
        08.05.2015 11:01

        Есть ведь сервисы, которые позволяют отправлять самому себе различные уведомления совершенно бесплатно. Насколько я помню, sms.ru имеет такую возможность. В случае подписки пользователей на уведомления предлагаем им регнуться на сайте и сообщить свой api-key. В случае малонагруженного сервиса вполне себе рабочее бесплатное решение.


        1. Irenica Автор
          08.05.2015 12:52

          Слишком сложная рега получается


          1. DarkByte
            08.05.2015 12:57

            При желании можно упростить: предупреждаем пользователя что его данные передаются третьей стороне и выводим ему капчу с сайта, остальные поля при регистрации в том сервисе заполняем самостоятельно. Чтобы быть честными с пользователем, сообщаем ему реквизиты от сайта, где его зарегистрировали, а себе в базу записываем его api-key. Это конечно уже не однострочник получится, зато бесплатно.


            1. Irenica Автор
              09.05.2015 02:12

              Пока что прикрутили nokia по uart смски слать о поломках. 1 телефона мало конечно, вскоре еще добавим


  1. RoboSloNE
    07.05.2015 03:38
    -13

    ИМХО как-то слабовато. Вы читаете твиттер, выгрепываете нужное и рассылаете смс через сторонний сервис — кажется, что в такой формулировке задачу способен решить простенький скрипт, написанный первокурсником в качестве лабораторной работы. И ссылки на какой-нибудь гитхаб не хватает.
    И кстати, как вы монетизируетесь?


    1. Newbilius
      07.05.2015 12:23
      +2

      Хорошее и полезное приложение не обязано быть люто сложным внутри. Да и то, что идея и реализация простые не означает, что в решении не будет мелких, но важных нюансов…

      А вот к вопросу о планах монетизации я присоединюсь, СМС-ки то не бесплатные. Посмотрел тарифы, я так понимаю на 500+ людей разослать СМС будет стоить в районе 200 рублей, и чем больше — тем дороже. Можно кстати отказаться от СМС (или сделать его запасным вариантом) и зафигачить собственное мобильное приложение, которое будет принимать push-уведомления :-)


      1. LeshiyUrban
        07.05.2015 14:24

        pushbullet API было бы очень круто


        1. dcoder_mm
          09.05.2015 02:10
          +1

          Поковырялись и прикрутили pushbullet-канал www.pushbullet.com/channel?tag=msk-metro-ru


  1. mrol
    07.05.2015 10:21

    Очень элегантное решение получилось.
    А есть/будет возможность подписаться на определенные ветки метро?


    1. Irenica Автор
      07.05.2015 10:26

      Мы как-то обсуждали такую возможность и не посчитали её нужной. Допустим работа/учеба — дом одни и те же ветки, но периодически человек может ездить по всем остальным веткам — дела, культурные мероприятия, etc
      Как опционально можно и сделать


      1. mrol
        07.05.2015 10:29
        +1

        Не планируете аналогичную штуку для трамваев и троллейбусов? Они встают намного чаще, чем метро :)


        1. Irenica Автор
          07.05.2015 10:35
          +2

          Если люди об этом пишут, то конечно добавим.


          1. xSomeonEx
            07.05.2015 13:22
            +1

            В дополнение было бы классно указывать, по каким дням можно слать смс(в выходные, например, меня нет в Москве — значит мне не интересно получать смс)


    1. Irenica Автор
      15.05.2015 01:36

      Добавили личный кабинет, в котором можно выбрать ветки и время оповещения.


  1. bougakov
    07.05.2015 11:40
    +1

    Вы бы туда ещё подмешивали ленту с dt.mos.ru/infocenterall/opernews


    1. Irenica Автор
      07.05.2015 11:46

      Если добавим, то как отдельную рассылку. Спасибо за идею )


  1. symbix
    07.05.2015 11:56
    +2

    Молодцы, клево. А сделайте еще rss? Я вот, скажем, далеко не каждый день пользуюсь метро, и смски — это излишне; а вот проверить фид было бы самое то.

    В идеале, конечно, вот так — www.tfl.gov.uk/tube-dlr-overground/status


    1. Irenica Автор
      07.05.2015 11:57

      Сделаем ))


      1. iandarken
        07.05.2015 13:17

        + к RSS или возможности каким-нибуть GET получить ткущую ситуацию. Зашел в метро — стоит толпа и поезд не идет — и думай, это временная бага на 5 минут или там на рельсы Михалков упал и праздник, метро ходить не будет еще час, иди на автобус. А так ткнул кнопочку, получил инфу и решил.


  1. Steve_R
    07.05.2015 13:00

    Очень хорошая идея!
    Присоединяюсь к просьбе о RSS.


  1. alterpub
    07.05.2015 14:55
    +1

    Еще можно канал на pushbullet создать, вместо смсок(или в дополнение к ним)



  1. bobrovnikov
    07.05.2015 18:06

    Надеюсь, не сочтёте за откровенную рекламу.
    Я совсем недавно тоже сделал сервис с СМС оповещениями, только по раскрытию информации публичных компаний.
    Скажем, Газпром публикует квартальный отчёт, так вот его подписчикам в течение минуты придёт эта новость вместе с ссылкой на сообщение компании. Рассчитано на весьма узкую в России аудитории участников торгов на фондовой бирже.


  1. Gumanoid
    07.05.2015 19:41

    1. Irenica Автор
      07.05.2015 19:43

      Публикуют руками, далеко не сразу и далеко не обо всем и твиттер аккаунт не у всех есть


  1. chernish2
    09.05.2015 14:54

    Отличная вещь! Я Москвич, но, уверен, жителям, как минимум, Питера, такой сервис был бы тоже полезен. А ещё наверное и Минска, и Киева.


  1. microtrigger
    20.05.2015 14:35
    +2

    В пору прикручивать к Яндекс.Метро =)


  1. Steve_R
    25.05.2015 15:53

    Спасибо за RSS ленту! Очень оперативно.


    1. Irenica Автор
      25.05.2015 16:16

      Пока что в ленту идут все события на дорогах + метро. Возможно потом мы разделим ленты.


  1. Steve_R
    25.05.2015 16:24

    Если сообщений много, то есть смысл разделить ленты.


    1. Irenica Автор
      25.05.2015 16:27

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


      1. Steve_R
        25.05.2015 16:29

        Я это и имел ввиду. Понимаю, что сначала нужно накопить статистику.


        1. Irenica Автор
          25.05.2015 16:32

          Если будут предложения-идеи по разделениям лент обязательно напишите


  1. Steve_R
    25.05.2015 16:28

    повтор. извините.