Comments 46
Не совсем понимаю, почему такое ограничение на вызов лишь одного sendMessage. Разве нельзя вызвать sendPhoto, к примеру?
все эти реализации при получении запроса инициируют post до сервера api telegram, что в условиях крупного Российского хостера невыполнимо
Во-первых, провайдеры хостинга, датацентры и так далее не являются операторами связи. Они ничего не блокируют из списка РКН в своих сетях. В основном. Во всяком случае, если они что-то блокируют, это исключительно их инициатива, по закону они не обязаны. У меня есть прокси Telegram, поднятые на российских VPS, до сих пор работают.
Во-вторых, если webhook с серверов Telegram приходит, то очевидно, что и API так же доступно. Я еще не видел блокировок только в одну сторону.
Но за описанную возможность сразу отправить ответ, не дергая API телеги отдельным запросом спасибо, не знал.
Пока нет ) Предполагаю что даже до стоимости проезда в метро не дойдёт.
Challenge accepted :D (нет)
Но думаю, могут найтись, "доброжелатели"..
При том, что можно написать просто бота, который будет дергать Вашего нное количество раз.
За статью спасибо.
Можно же добпвить простую проверку, чтоюы не отвечать юзеру более N раз в час. Тонда злоумышленнику нужно регистрировать много аккаунтов в телеграме уже.
Проверка будет занимать меньше времени чем работа самого скрипта.
Т.е. Вы считаете, что регистрация айди пользователя и времени/частоты его запросов, а также последующая проверка, будут работать быстрее чем ответ "Привет Хабр"?
Точно. Тогда нужен некий порог, после которого лямбда сворачивается и поднимается уже виртуалка для оптимизпции расходов.
и вишенкой на торте — SLA 99,9
Не такая уж это и вишенка.
Допустим простой 8ч 45м 57с в год.
Полный рабочий день включая обеденный перерыв, другими словами.
Вы можете гарантировать больше?
Вы можете гарантировать больше?
Несведующему человеку указанная 99,9% может показаться высокой, но это не так.
К примеру, при определенном масштабе деятельности, когда можно выделить круглосуточных админов с их дублированием (разумеется не под один этот сервер). И даже дешевле, без облака, но ручками — да. При нормальной организации репликации — сменить хостера при сбое дело нескольких минут.
Далее, для достижения уровня доступности 99,95% вам понадобится просто построить кластер active-passive.
Если вы хотите перешагнуть за 99,982% (уровень доступности в дата-центрах Tier III), вам нужно строить систему, распределенную по нескольким ЦОД.
Еще раз:
Цифры SLA намного более высокой доступности, чем 99,9% — вполне реальны в нашем мире.
При нормальной организации репликации
:-D
сменить хостера при сбое дело нескольких минут
:-DD
просто построить кластер active-passive
:-DDD
Это запредельный уровень допущений. То есть наверняка есть люди, которые могут это сделать и есть конторы, которые могут дать на организацию всего этого время. Но это мизерная часть от всех людей и всех контор.
О чем мы спорим? Яндекс заявляет 99.9. ну, ок. Хорошо.
В принципе, с этим можно жить.
А дальше — как я пишу ниже — дьявол в деталях. Я просто внимталеьно смотрел договора (речь не про Яндекс как таковой — возможно, что там все ок ) И все там не так просто как "мы гарантируем". Ну, положим не выполнил поставщик / провайдер / облако свои гарантии — ну, заплатит он вам штраф. Или даст бесплатный бонус. И ЧТО? Репутацию и клиентов это вам не вернёт.
На самом деле даже 99.9 никто не гарантирует. Если подумать.
Читайте договор мелким шрифтом. И скорее всего там будет, что доступность платформы (т.е. веб-панкели и АПИ), а сами сервисы… Ну, не летит трафик в вашу лямбду. И что? Это у вас провайдер фиговый — к нему и идите )
Если понадобится база — я скорее буду смотреть на cloud managed решения, тот же MySQL в Яндексе будет стоить 508₽ в месяц, и обслуживать несколько проектов. С бэкапами, администрированием и тем-же SLA. В Амазоне, кстати, примерно столько же RDS стоит.
Но да, безусловно облако не панацея и есть множество случаев когда или надо переделывать под него архитектуру чтобы не разориться, или сразу завести всё на бюджетной vds за 1,5$ в месяц.
Минус в том что решение в облаках раз в пару лет обычно нужно чуть чуть переделывать. Потому что облачное окружение меняется. Могут исключить встроенную библиотеку например.
А еще можете посмотреть на azure functions. Там есть большое кол-во триггеров и бесплатные первые 4 млн вызовов в месяц)
Вы получаете безопасное изолированное окружение с последней версией компилятора / интерпретатора.
Вместо того, чтобы следить за обновлением пакетов на настоящей ОС в Виртуальной машине, заниматься настройкой политик безопасности и файрволла — вы загружаете программу на сервер, и она работает.
Звучит очень двояко. А если я не хочу использовать последнюю версию? А если я вообще питонщик и у меня завязка на конкретные версии модулей?
И фраза, что загружаешь и оно работает слишком… Пафосная. Скажем так. Есть два подхода к написанию лямбд. Первый — поднять локальное окружение или эмулятор лямбды. Среды. Амазон, кстати, такой предоставляет. И в нем полностью написать и прогнать свой код. Ну, либо можете наживую отлаживать в облаке (не очень хорошо). Ну, либо — писать будто никакой лямбды нет, потом просто обернуть свой код и запушить в облако. Но могут быть сюрпризы.
Ещё лямбда (=серверлесс) имеет кучу минусов. Это и мониторинг. И отладка. И в целом перенос сложности с одного уровня проекта на другой. Отдельный вопрос — как будут сосуществовать разные версии кода в одном облаке. Бр. В общем — когда нужно написать что-то маленькое, что-то быстрое — serverless прекрасен, но как только нужно написать полноценный сервис, то стоит подумать и об экономике (в промышленных масштабах лямбда дорога), об ограничениях (лимиты памяти, времени выполнения) и удобстве поддержки
Очевидное ограничение самого serverless подхода, не зависимо от платформы — пользоваться приходится ровно тем, что дают. Написать код на неподдерживаемых языках программирования или использовать нестандартные параметры компилятора/интерпретатора вы не сможете. Также возможны дополнительные ограничения призванные защитить всех участников процесса разработки.
Да, всё так. Возможно перебрал пафоса с «последней версией», выбирается конкретный мажорный релиз, с nodejs10 на nodejs12 вас автоматически без предупреждений не переведут.
import json
import base64
import urllib.request
def handler(event, context):
img = urllib.request.urlopen("https://habr.com/images/habr.png").read()
parsed_string = json.loads(event["body"])
chat_id = parsed_string['message']['chat']['id']
answerM = {
"method": "sendMessage",
"chat_id": chat_id,
"text": "привет"
}
answerP = {
"method": "sendPhoto",
"chat_id": chat_id
#"photo": base64.b64encode(img).decode()
}
return {
'statusCode': 200,
'headers': {"Content-Type": "multipart/form-data"},
'body': json.dumps(answerP),
'isBased64Encoded': 'true',
'files': {'photo': base64.b64encode(img).decode()}
}
Я не вижу в документации возможности отдельно прикладывать файлы в поле files, думаю что надо самостоятельно объявить delimiter в заголовке и подготовить данные с ним в body
import json
import base64
import urllib.request
def handler(event, context):
img = urllib.request.urlopen("https://habr.com/images/habr.png").read()
parsed_string = json.loads(event["body"])
chat_id = parsed_string['message']['chat']['id']
boundary = 'Asrf456BGe4h'
parts = []
parts.append('--' + boundary)
parts.append('Content-Disposition: form-data; name="method"')
parts.append('')
parts.append('sendPhoto')
parts.append('--' + boundary)
parts.append('Content-Disposition: form-data; name="chat_id"')
parts.append('')
parts.append(str(chat_id))
parts.append('--' + boundary)
parts.append('Content-Disposition: form-data; name="photo"; filename="%s"' % 'img.jpg')
parts.append('Content-Type: image/jpeg')
parts.append('')
parts.append(base64.b64encode(img).decode())
parts.append('--' + boundary + '--')
parts.append('')
body = '\r\n'.join(parts)
return {
'statusCode': 200,
'headers': {
'content-type': 'multipart/form-data; boundary=' + boundary
},
'body': body,
'isBased64Encoded': 'true'
}
И добился формирования следующего ответа, но не понимаю, что из этого не нравится телеграму:
HTTP/1.1 200 OK
Server: nginx
Date: Sun, 06 Oct 2019 14:26:32 GMT
Content-Type: multipart/form-data; boundary=Asrf456BGe4h
Transfer-Encoding: chunked
Connection: keep-alive
X-Content-Type-Options: nosniff
X-Function-Id: ...
X-Function-Version-Id: ...
X-Request-Id: ...
Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
X-Frame-Options: SAMEORIGIN
--Asrf456BGe4h
Content-Disposition: form-data; name="method"
sendPhoto
--Asrf456BGe4h
Content-Disposition: form-data; name="chat_id"
1111111
--Asrf456BGe4h
Content-Disposition: form-data; name="photo"; filename="img.jpg"
Content-Type: image/jpeg
iVBORw0KGgoAAAANSUhEUgAABLAAAAJ2CAYAAABPQHtcAAAABGdBTUEAALGPC/
.../A0wmf2FFW4KcAAAAAElFTkSuQmCC
--Asrf456BGe4h--
Явного упоминания такой готовности в доках уже телеграма нет, я пробовал sendPhoto в таком виде:
exports.input = function (data){
let body = JSON.parse(data.body);
let answer = {
"method":"sendPhoto",
"photo": "https://habrastorage.org/webt/hr/f7/nl/hrf7nll2xn4c9leojqsc95uv7ji.png",
"chat_id": body.message.chat.id,
"reply_to_message_id" : body.message.message_id,
"text" : "Привет, Habr!"
};
return {
"statusCode": 200,
"headers": {
'Content-Type': 'application/json'
},
"body": JSON.stringify(answer),
"isBase64Encoded": false
}
}
Как подсказали ниже/выше, для небольших картинок (меньше 5 Мб) можно указать просто URL.
Если набор изображений более-менее стабильный и отбирается вручную, можно заранее отправить их своему боту в Telegram, через метод getUpdates посмотреть на fileID этих картинок и дальше вызывать sendPhoto с этими fileID, тогда отправка будет вообще мгновенной, ведь файл уже лежит на серверах Telegram.
У меня URL картинки всегда один, а содержимое отличается (веб камера) и телеграм запоминает первое содержимое и дальше всегда его отдает.
Может быть, костыль, но что если добавлять к URL картинки какой-нибудь невзрачный параметр? Типа https://example.com/pic.jpg?yourvalue=abcxyz
Serverless Telegram бот в Яндекс.облаке, или 4.6 копейки за 1000 сообщений