Как стать автором
Обновить

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

Как, опять?..
Да, но нет!

Да и да…
Скорее нет, чем да. Статья качественнее написана и есть своя плюшка в виде aiohttp.
Телеграм очень опосредован в статье, скорее повод привлечь внимание тех, кто говорит, что хуки — это сложно и накладно.
Мой пример на php (чтобы разобраться в апи телеграмм потратил 5 минут):
$api = "https://api.telegram.org/bot111111111:AAHKeYAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
// получаем данные
$update = json_decode(file_get_contents("php://input"), TRUE);
$message = $update["message"];
// все команды
$commands = array(
  "всем привет"    => "Дратути",
  "кто самый"    => "Без сомнения {$message['from']['first_name']} {$message['from']['last_name']}",
);
// не учитываем регистр
$text_lower = mb_convert_case($message["text"], MB_CASE_LOWER);
// искать команду будем по первым 200 символам.
if (strlen($text_lower) > 200) $text_lower = substr($text_lower, 0, 200);
// крутим текст сообщения от конца до 1го символа в поисках существующего ключа в $commands
for ($i=0; $i < strlen($text_lower); $i++) { 
  $text_lower_new = substr($text_lower, 0, strlen($text_lower)-$i);
  if (isset($commands[$text_lower_new])) {
      $text_lower = $text_lower_new;
      break;
  }
}
// сам ответ
if (isset($commands[$text_lower])) $answer = $commands[$text_lower];
// отправляем ответ в чат
if (!empty($answer)) file_get_contents("{$api}/sendmessage?chat_id={$message["chat"]["id"]}&text={$answer}");


— при желании этот код можно сократить до 5 строк, но тогда его будет совсем сложно читать, поэтому не пойму тех кто хвастается кол-вом строк в коде.

image

На основе этого кода собрал бота который сидит у меня в рабочем чате и делает заметки, посмотреть на его работу можно добавив его: @jReminderBot
все ещё пытаюсь понять логику перебора строки посимвольно, да еще и с конца, если
а) одна из команд «здравствуйте» и базируясь на общепринятых правилах можно ожидать ее в начале строки, а не перебирать 200 символов.
б) существует strpos($text, $command)
ну тут просто не очевидно на примере для чего это…
ну вот в @jReminderBot я пишу "/save очень длинный текст" и вместо того что бы поставить условие:

if (strlen($message['text']) >= 5 && substr($message['text'], 0, 5) == '/save') {
// выполняем запись текста после "/save" в бд
}

— я ищу этот ключ в массиве перебирая строку с конца до начала:
/save очень длинный текст
/save очень длинный текс
/save очень длинный тек
/save очень длинный те

/save оч
/save о
/save
/save — бинго! этот ключ есть и дальше идёт перебрасывание на функцию.

Таким способом после самой команды может быть любой длинны текст… Тот же FatherBot в телеграмм запрашивает параметр для команды отдельно — пишешь /setname, после он просит придумать новое имя и отправить следующим сообщением, в моём примере это бы выглядело следующим образом: "/setname Новое имя"

При этом имя функции я так же вписываю в сам массив, примерно так это выглядит:

$cmd = new Commands($message); // тут все функции

$commands = array(
  "всем привет" => "Дратути",
  "/save" => "fun_saveText"
);

// проверки тут разные, в цикле перебор строки и т.д всё копипастить не буду.. в предыдущем комментарии это есть.

if (strlen($commands[$text_lower]) > 3 && substr($commands[$text_lower], 0, 4) == 'fun_') {
  $fun_name = substr($commands[$text_lower], 4);
  if (method_exists($cmd, $fun_name)) {
    $answer = call_user_func(array($cmd, $fun_name));
  }else{
    $answer = "Функция {$fun_name} не найдена =(";
  }
}else{
  $answer = $commands[$text_lower];
}


ну и согласитесь писать ключи в массиве гораздо удобнее и компактнее нежели всегда писать условие под каждую команду… Видимо нужно было сразу написать что не ставил цели писать обычный ехо-бот… Ну а сам массив у меня уже перекочевал в json формат, вынесенный отдельно в файл и там уже более 40 функций по мониторингу основного сайта и ещё пару шуточных функций и ответов…

Я даже думал на хабре пост написать как на php этот бот пишется закрытыми глазами, но такие статьи уже не встречают восторгом тут…
коллега, давайте еще раз,
— в тексте "/save очень длинный текст" команда идет первой,
— strpos() по религиозным причинам отпадает,
но что мешает начать перебор не с конца Войны и Мир, а с начала строки? каким образом на это влияет хранение команд в массиве?
прошу простить, я с утра не совсем уловил суть вашего вопроса…
что же, действительно тут вы правы:

for ($i=1; $i < strlen($text_lower); $i++) { 
  $text_lower_new = substr($text_lower, 0, $i);
  if (isset($commands[$text_lower_new])) {
      $text_lower = $text_lower_new;
      break;
  }
}


— так мы из "/save очень длинный текст" будем двигаться от 1го символа до последнего (предварительно ограничив длину до 200 символов)

/
/s
/sa
/sav
/save — бинго, ключ найден. И вместо того что бы проверять ключ 21 раз, мы проверили его 5 раз… Что в 4 раза быстрее на данном примере.

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

пример конечно с потолка, но если мне нужно будет выполнить команду "статистика вчера" — то перебирая символы с начала строки выполнится команда "статистика", именно поэтому я и решил перебирать символы с конца. Пока у меня в командах нет подобного противоречия, но кто знает… когда их будет за пару сотен, могут появиться.

P.S
if (strpos($text_lower, "/save") == 0) {
// действие
}


всё же условие, занимает значительно больше места нежели ключ в массиве… А вот то что я вместо strpos использую substr этому нет объяснения, видимо сонный был и затупил…

P.P.S вот за что люблю хабр, что тут люди всегда посоветуют то что лучше, сейчас заменю substr на strpos и временно переключу перебор строки с первого символа, а когда появятся противоречия в командах, верну обратно перебор с конца. Grogina, вам спасибо.
Ребята, вы конечно простите, но на дворе 2017 год.
Чем вам регулярные выражения так в душу нагадили, что вы начали перебирать «Войну и мир»?
Я понимаю и знаю, что они медленные, но в данном случае — это просто панацея от хламавелосипедов. Можно будет команды буквально в любую позицию строки писать.
что бы писать команду в любом месте строки можно и strpos или substr_count использовать. И опять же команды все удобно держать в одном месте, отделив его от кода. Поэтому и такое странное решение с ключами массива…
даже если у вас их будет несколько сотен и вы хотите реализовать все в таком миксе текста и команд, ничто не мешает начать, бог с ним, перебор с позиции strlen($command_with_max_length)-1
поэтому не пойму тех кто хвастается кол-вом строк в коде

Мне странно, что вы где-то увидели хвастовство.

"...50 строк кода" в заголовке — это означает, что кода в статье немного и он не сложный. Не ищите подтекста там, где его нет.
Следующая статья будет называться «На 50 строк кодее»?
Ещё не решил, как вариант — «на 50 строк коже» или действительно «кодее»… Как правильно?

Читаю такие статьи и ни в одной не описано, зачем, используя вебхук, еще дополнительно дергать sendMessage? Ведь в webHook явно сказано, что вместо того, чтобы просто отвечать 200 — можно сразу ответить сообщением и оно уйдет в телеграм.


Какие-то накладные расходы? Минусы? Поделитесь, пожалуйста?

Минусы?

It's not possible to know that such a request was successful or get its result.

По моему этого достаточно.
Отличный гайд, у меня все сработало. Только несколько поправочек для тех, кто деплоит на Хероку.

1. Запускать из командной строки проще так. Хероку автоматически проксирует все запросы.
heroku run curl -X POST "https://api.telegram.org/botTOKEN/setWebhook?url=HOST/api/v1"

А ваш пример почему-то удалял вебхук.
2. Также херока сам проставляет порт из переменной окружения:
port=os.environ.get('PORT', 8080)

Подробнее про деплой Питон приложений на Хероку тут
Кому-то может быть полезным. У Хероки есть бесспорные плюсы:
  • Проксирование запросов к апи телеграмма
  • Бесплатно

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

Оооо, ваш комментарий через 3 года, говорит о том, что мысли оформленные в приступе прокрастинации оказались целостными и самодостаточными.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории