Задать вопрос
@awox

Почему urequests выдает ошибку OSError: -40 при get запросе api telegram при этом корректно работает с api openweather?

#MicroPython
#ESP8266

import urequests

url = f"https://api.telegram.org/{token}/sendMessage?chat_id={chat_id}&text=txt1"
#url = f"https://api.openweathermap.org/data/2.5/weather?lat=42.98&lon=47.47&appid={token}"

response = urequests.get(url)
content = response.text
print(content)
  • Вопрос задан
  • 135 просмотров
Подписаться 1 Средний 3 комментария
Помогут разобраться в теме Все курсы
  • Нетология
    Python-разработчик: расширенный курс + нейросети
    12 месяцев
    Далее
  • Академия Eduson
    Python-разработчик
    9 месяцев
    Далее
  • Skillbox
    Профессия Python-разработчик + ИИ
    10 месяцев
    Далее
Решения вопроса 1
@dim5x
ЗИ, ИБ. Помогли? Поблагодарите. Отметьте ответом.
Могу предположить почему это происходит:
ESP8266 использует библиотеку axTLS, которая не умеет в ECC.
No support for Diffie-Hellman (DH) key exchange and Elliptic-curve cryptography (ECC). This means it can’t work with sites which require the use of these features (it works ok with the typical sites that use RSA certificates).
https://docs.micropython.org/en/latest/esp8266/gen...

Сервер OpenWeather разрешает понизить до TLS 1.2 с RSA ключом, что позволяет успешно завершить handshake.
openssl s_client -connect api.openweathermap.org:443 -servername api.openweathermap.org -tls1_2 -cipher RSA


Сервер Telegram более строг, не разрешает RSA-only и требует ECDHE (X25519) -> sslv3 alert handshake failure
openssl s_client -connect api.telegram.org:443 -servername api.telegram.org -tls1_2 -cipher RSA

Как я понимаю, SSL alert number 40 в выводе openssl это и есть ваш OSError: -40.

1. Переходите на ESP32 там отправка работает корректно.
2. Ну, или, если 8266 принципиально использовать, то прикручивать прокси: 8266 -> прокси -> telegram. Хендшейк будет делать прокси вместо ESP.
Для примера:

Прокси на Flask.
from flask import Flask, request
import requests

app = Flask(__name__)

TOKEN = ""
CHAT_ID = ""

@app.route("/send", methods=["GET"])
def send_message():
    text = request.args.get("text", "")
    print(text)
    if not text:
        return "No text provided", 400

    url = f"https://api.telegram.org/bot{TOKEN}/sendMessage"
    try:
        r = requests.get(url, params={"chat_id": CHAT_ID, "text": text}, timeout=5)
        return r.text
    except requests.RequestException as e:
        return str(e), 500


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)

Скрипт для ESP8266.

import urequests
import network
import time

SSID = ""
PASSWORD = ""
PROXY_URL = "http://192.168.0.5:5000/send"  # Ваш IP прокси-сервера в локальной сети

# подключение к Wi-Fi
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(SSID, PASSWORD)
while not wlan.isconnected():
    time.sleep(0.5)
print("Connected, IP:", wlan.ifconfig()[0])
time.sleep(3)
# отправка сообщения через прокси
msg = "Привет_из_ESP8266_5000_142589"
try:
    print(f"{PROXY_URL}?text={msg}")
    response = urequests.get(f"{PROXY_URL}?text={msg}", timeout=10)
    print(response.text)
    response.close()
except Exception as e:
    print("Error:", e)


З.Ы. Не забыть открыть порт 5000 (ну или какой вы там будете использовать) для входящих в файерволе.
3. Вроде есть mbedTLS с поддержкой TLS 1.3. Сам не пробовал, но встречал на гитхабе где-то что соединение на 8266 занимает 7-8 секунд, ибо мощей не хватает ему. link.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы