Ответы пользователя по тегу JavaScript
  • Как исправить ошибку JS undefinit object[3]?

    @GrigoryMorozov
    Проблема возникает из-за того, что первый элемент в массиве objects — пустая строка (ведь objectsCSV начинается с переноса строки, по которому и будет выполняться разбиение).

    В вашем случае можно поступить так:

    var objects = objectsCSV.split('\n').split(1);

    Плюс у вас, судя по всему, неверно формируется строка. Правильный вариант подстановки такой:

    balloonContent: `<a href="/flights/?${object[3]}origin_iata=...`


    Но это не главное. Возникновение подобных ошибок связно со стилем кода, с которым трудно работать, и со сложностями с отладкой (я, например, сразу дописал к коду несколько вызовов console.log, чтобы понять, в чём дело). Попробуйте почитать стайлгайды по JS и руководства по отладке, чтобы избегать подобных ошибок в будущем.
    Ответ написан
  • Как шарить изображения в telegram mini apps js?

    @GrigoryMorozov
    Если мини-приложение запускается с помощью инлайн-кнопки, а вы хотите отправить изображение в чат с ботом, используйте серверный метод answerWebAppQuery. Реализация примерно такая:
    1. Отправляете сгенерированное изображение вместе с параметром initData собственному серверному скрипту
    2. Проверяете параметр initData, извлекаете из него query_id
    3. Сохраняете сгенерированное изображение
    4. Вызываете метод answerWebAppQuery с извлечённым query_id. В качестве параметра result передаёте InlineQueryResultPhoto со ссылкой на сгенерированное изображение
    5. Сгенерированное изображение спустя какое-то время можно удалить

    Альтернативно, если мини-приложение запускается по прямой ссылке, можно использовать клиентский метод switchInlineQuery. Предварительно выполните шаги 1-3 и сохраните ассоциацию пользователя со ссылкой на сгенерированное изображение.

    После вызова клиентского метода мини-приложение закроется, будет предложено выбрать чат (если передавался параметр choose_chat_types), а бот получит событие inline_query. Ответьте на него с помощью серверного метода answerInlineQuery, используя сохранённую ассоциацию (параметр results в данном случае — массив с одним элементом типа InlineQueryResultPhoto, cache_time должен быть небольшим, а is_personal — true).
    Ответ написан
    Комментировать
  • Как реализовать ленивую загрузку TFJS и Face Landmarks Detection?

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

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

    script.async = false;

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

    // Functions
    
    const loadedScripts = new Set();
    
    async function loadScript(url) {
      if (loadedScripts.has(url)) return;
      
      const script = document.createElement('script');
    
      script.src = url;
      script.async = false;
    
      document.head.append(script);
    
      return new Promise((resolve, reject) => {
        script.addEventListener('load', () => {
          loadedScripts.add(url); resolve();
        });
      
        script.addEventListener('error', () => reject(
          new Error(`Error loading script: ${url}`)
        ));
      });
    }
    
    async function loadImage(url) {
      const image = new Image();
    
      image.src = url;
      image.crossOrigin = 'anonymous';
    
      return new Promise((resolve, reject) => {
        image.addEventListener('load', () => {
          resolve(image);
        });
      
        image.addEventListener('error', () => reject(
          new Error(`Error loading image: ${url}`)
        ));
      });
    }
    
    // Example
    
    const image = loadImage('https://habrastorage.org/r/w1560/getpro/habr/upload_files/799/62f/375/79962f375d90db7f7d926ff40d623456.png');
    
    await Promise.all([
      loadScript('https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-core'),
      loadScript('https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-converter'),
      loadScript('https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-webgl'),
      loadScript('https://cdn.jsdelivr.net/npm/@tensorflow-models/face-landmarks-detection@1.0.6/dist/face-landmarks-detection.min.js')
    ]);
    
    const model = faceLandmarksDetection.SupportedModels.MediaPipeFaceMesh;
    
    const detectorConfig = {
      runtime: 'tfjs', 
      solutionPath: 'https://cdn.jsdelivr.net/npm/@mediapipe/face_mesh'
    };
    
    const detector = await faceLandmarksDetection.createDetector(model, detectorConfig);
    const faces = await detector.estimateFaces(await image);
    
    console.log(faces);
    Ответ написан
    1 комментарий
  • Telegram mini app, как реализовать добавление бота в группу?

    @GrigoryMorozov
    Интересный вопрос.

    С помощью реверс-инжиниринга получен ответ: здесь неявно используется deep linking. Более конкретно: после нажатия на кнопку вызывается метод openTelegramLink с параметром https://t.me/UTasksBot?startgroup=1. Открытие такой ссылки (в любом контексте, не только в мини-приложении) позволяет выбрать группу и добавить в неё бота.

    А дальше всё плюс-минус понятно: отслеживаем событие my_chat_member и реагируем на него соответствующим образом. Если нужно узнать об этом событии из веб-приложения, можно использовать сокеты или long polling.
    Ответ написан
    Комментировать
  • Как загрузить в гугл таблицу результаты опроса из телеграм бота?

    @GrigoryMorozov
    К сожалению, просто получить результат опроса каким-то методом невозможно. Но можно настроить получение событий с ответами пользователей и самостоятельно формировать результат. В общих чертах:
    1. Настраиваете получение события poll_answer с помощью периодических запросов методом getUpdates или устанавливаете веб-хук, на который Телеграм сам будет отправлять запросы с этим событием (метод setWebhook; судя по всему, это ваш случай)
    2. Реализовываете логику с сохранением результата опроса (поле poll_answer в Update). Вы будете знать ID опроса, ID пользователя, проголосовавшего в опросе (если опрос неанонимный), и список выбранных им опций. Помните, что пользователь может переголосовать — это штатная функция Телеграма
    3. А уже затем работаете с таблицами. API у Google Таблиц нетривиальный (хотя, конечно, зависит от задачи), но разобраться с ним можно
    Ответ написан