Кириллица с telegram API \uXXXX

Zlor
Offline
Зарегистрирован: 27.03.2020

Есть скетчик, читает msg с телеграм-бота.

Использует библиотеку uTKGBotLib-ардуино.

С английскм всё как надо.

С кириллицей всё как не надо: msg приходит в виде \u041f\u0440\u0438\u0432\u0435\u0442! (Привет!).

Был прикручен перекодировщик.

Который корректно перекодирует "\u041f\u0440\u0438\u0432\u0435\u0442!",

но не переколирует содержимое переменной Bot.received_msg.text (строки 106-107).

В чём моя(и) ошибка(и)?

Спастбо за возможную помощь.

/* Libraries */
// Standard C/C++ libraries
#include <string.h>

// Device libraries (Arduino ESP32/ESP8266 Cores)
#include <Arduino.h>
#include <ESP8266WiFi.h>
// Custom libraries
#include <utlgbotlib.h>

// WiFi Parameters (с
#define WIFI_SSID "*****"
#define WIFI_PASS "*****"
#define MAX_CONN_FAIL 50
#define MAX_LENGTH_WIFI_SSID 31
#define MAX_LENGTH_WIFI_PASS 63

// Telegram Bot Token (Get from Botfather)
#define TLG_TOKEN "*******:**************"

// Enable Bot debug level (0 - None; 1 - Bot Level; 2 - Bot+HTTPS Level)
#define DEBUG_LEVEL_UTLGBOT 0

/* Functions Prototypes */
void wifi_init_stat(void);
bool wifi_handle_connection(void);

/* Globals */
// Create Bot object
uTLGBot Bot(TLG_TOKEN);

/* Main Function */
void setup(void)
{
    // Enable Bot debug
    Bot.set_debug(DEBUG_LEVEL_UTLGBOT);

    // Initialize Serial
    Serial.begin(115200);

    // Initialize WiFi station connection
    wifi_init_stat();

    // Wait WiFi connection
    Serial.println("Waiting for WiFi connection.");
    while(!wifi_handle_connection())
    {
        Serial.println(".");
        delay(1000);
    }

    // Bot getMe command
    Bot.getMe();
String unicodeStr = "";    
}

//------------------------------------------------------------
String convertUnicode(String unicodeStr){
  String out = "";
  int len = unicodeStr.length();
  char iChar;
  char* error;
  for (int i = 0; i < len; i++){
     iChar = unicodeStr[i];
     if(iChar == '\\'){ // got escape char
       iChar = unicodeStr[++i];
       if(iChar == 'u'){ // got unicode hex
         char unicode[6];
         unicode[0] = '0';
         unicode[1] = 'x';
         for (int j = 0; j < 4; j++){
           iChar = unicodeStr[++i];
           unicode[j + 2] = iChar;
         }
         long unicodeVal = strtol(unicode, &error, 16); //convert the string
         out += (char)unicodeVal;
       } else if(iChar == '/'){
         out += iChar;
       } else if(iChar == 'n'){
         out += '\n';
       }
     } else {
       out += iChar;
     }
  }
  return out;
}
//------------------------------------------------------------      

void loop()
{
    // Check if WiFi is connected
    if(!wifi_handle_connection())
    {
        // Wait 100ms and check again
        delay(100);
        return;
    }

    // Test Bot getUpdate command and receive messages
    while(Bot.getUpdates())
    {
        Serial.print("Received message:");
        Serial.println(Bot.received_msg.text);
        Serial.print("Decoded message:");
//      Serial.println(convertUnicode("\u041f\u0440\u0438\u0432\u0435\u0442!"));
        Serial.println(convertUnicode(Bot.received_msg.text));

        // Feed the Watchdog
        yield();
    }

    // Wait 1s for next iteration
    delay(1000);
}

/* Functions */
// Init WiFi interface
void wifi_init_stat(void)
{
    Serial.println("Initializing TCP-IP adapter...");
    Serial.print("Wifi connecting to SSID: ");
    Serial.println(WIFI_SSID);

    WiFi.mode(WIFI_STA);
    WiFi.begin(WIFI_SSID, WIFI_PASS);

    Serial.println("TCP-IP adapter successfuly initialized.");
}

/* WiFi Change Event Handler */
bool wifi_handle_connection(void)
{
    static bool wifi_connected = false;

    // Device is not connected
    if(WiFi.status() != WL_CONNECTED)
    {
        // Was connected
        if(wifi_connected)
        {
            Serial.println("WiFi disconnected.");
            wifi_connected = false;
        }

        return false;
    }
    // Device connected
    else
    {
        // Wasn't connected
        if(!wifi_connected)
        {
            Serial.println("");
            Serial.println("WiFi connected");
            Serial.print("IP address: ");
            Serial.println(WiFi.localIP());

            wifi_connected = true;
        }

        return true;
    }
}

 

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Zlor пишет:

В чём моя(и) ошибка(и)?

В том, что ты не привел пример содержимого Bot.received_msg.text.

Zlor
Offline
Зарегистрирован: 27.03.2020

Привёл.
В строке 106, в кавычках.
Если раскомментировать стр. 106 и закомментировать 107 - всё работает коррректно.
Сама последовательность \uXXXX... перекодируется, но не перекодируется значение переменной Bot.received_msg.text, которое именно этим \uXXXX... и является.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Как выглядят данные Bot.received_msg.text, если их представить как массив байт в формате HEX ?

И что значит "не перекодирует" ? Конкретнее.

Zlor
Offline
Зарегистрирован: 27.03.2020

brokly пишет:

Как выглядят данные Bot.received_msg.text, если их представить как массив байт в формате HEX ?


Увы, я настолько предметом не владею.
Если подскажете, что и куда вставить, чтоб получить искомое - сделаю и дам ответ.
Про не перекодирует.
Телеграм api вместо "Привет!" выдает последовательнось "\uXXX...", которую я привёл в строке 106. Насколько я понял, это или UTF-8 или UTF-16. Эта последовательность и должна перекодироваться в "Привет!", я писал об этом в старттопике.
Если String convertUnicode скормить напрямую эту последовательность - всё Ок.
Если переменную, содержащую эту последовательность - на выходе ничего.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Что выводит в консоль 104 строка ?

Zlor
Offline
Зарегистрирован: 27.03.2020

\u041f\u0440\u0438\u0432\u0435\u0442!

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Как правило попытка объяснить это словами, человеку которые не готов, занимает дохрена времени.....

Попробуйте и подумайте сами

 

char* msg1="\u041f\u0440\u0438\u0432\u0435\u0442";
char* msg2="\\u041f\\u0440\\u0438\\u0432\\u0435\\u0442";
Serial.println(msg1);
Serial.println(msg2);

Заметьте строка результат которой вы получаете в 104 это msg2, а не msg1.