July 8, 2025

🌦️ Погода с эмодзи и переводом на русском для Telegram-бота на Google Apps Script

В современном мире, где информация должна быть не только точной, но и визуально привлекательной, создание удобного и красивого прогноза погоды становится важной задачей. В этой статье мы рассмотрим, как создать Telegram-бота, который будет отправлять прогноз погоды с эмодзи и переводом на русский язык, используя Google Apps Script и WeatherAPI.

🌍 Как это работает

📡 Получение данных о погоде

Система получает актуальный прогноз погоды через WeatherAPI — один из самых популярных сервисов для работы с метеорологическими данными. Преимущество этого API в том, что он поддерживает русский язык, что делает его идеальным выбором для русскоязычных пользователей.

✨ Форматирование результата

После получения данных скрипт обрабатывает их и формирует красивое сообщение, дополненное эмодзи для лучшей визуализации. Например:

  • ☀️ — ясная погода
  • 🌧️ — дождь
  • ❄️ — снег

Также автоматически добавляется перевод описания погоды на русский язык, что делает информацию максимально понятной.

📩 Отправка в Telegram

Готовое сообщение можно сразу отправить в Telegram-бота или канал, чтобы пользователи получали актуальную погоду в удобном формате.

🔑 Начало работы

1️⃣ Регистрация на WeatherAPI

Для использования API необходимо:

  1. Зарегистрироваться на сайте www.weatherapi.com.
  2. Получить API-ключ, который потребуется для запросов.

⚠️ Важно! Бесплатный тариф имеет ограничения:

2️⃣ Настройка Google Apps Script

Скрипт написан на JavaScript и работает в среде Google Apps Script, что позволяет легко интегрировать его с Telegram через вебхуки.

📜 Разбор кода

🌤️ Получение погоды с WeatherAPI

function getWeather(city) {
  const API_KEY = `ВАШ_API_КЛЮЧ`;
  const url = `http://api.weatherapi.com/v1/forecast.json?key=${API_KEY}&q=${city}&days=3&aqi=no&alerts=no&lang=ru`;
  const response = UrlFetchApp.fetch(url);
  const data = JSON.parse(response.getContentText());
  return data;
}

Здесь мы отправляем запрос к API, передавая:

  • Город (можно указывать название или координаты).
  • Количество дней (максимум 3 для бесплатного тарифа).
  • Язык ответа (lang=ru для русского).

🎨 Преобразование кода погоды в эмодзи и текст

/**
 * Возвращает эмодзи и перевод описания погоды по коду и времени суток
 * @param {number} code - weatherapi code
 * @param {boolean} isDay - true если день, false если ночь
 * @returns {{emoji: string, text: string}}
 */
function getWeatherIconAndTextRu(code, isDay) {
  const map = {
    1000: { day: ['☀️', 'ясно'], night: ['🌙', 'ясно'] },
    1003: { day: ['🌤', 'малооблачно'], night: ['🌤', 'малооблачно'] },
    1006: { day: ['☁️', 'облачно'], night: ['☁️', 'облачно'] },
    1009: { day: ['🌫', 'пасмурно'], night: ['🌫', 'пасмурно'] },
    1030: { day: ['🌫', 'туман'], night: ['🌫', 'туман'] },
    1063: { day: ['🌦', 'возможен дождь'], night: ['🌦', 'возможен дождь'] },
    1066: { day: ['🌨', 'возможен снег'], night: ['🌨', 'возможен снег'] },
    1069: { day: ['🌨', 'возможен мокрый снег'], night: ['🌨', 'возможен мокрый снег'] },
    1072: { day: ['🌧', 'возможен ледяной дождь'], night: ['🌧', 'возможен ледяной дождь'] },
    1087: { day: ['⛈', 'возможна гроза'], night: ['⛈', 'возможна гроза'] },
    1114: { day: ['🌬', 'метель'], night: ['🌬', 'метель'] },
    1117: { day: ['🌨', 'сильная метель'], night: ['🌨', 'сильная метель'] },
    1135: { day: ['🌫', 'туман'], night: ['🌫', 'туман'] },
    1147: { day: ['🌫', 'изморозь'], night: ['🌫', 'изморозь'] },
    1150: { day: ['🌦', 'небольшая морось'], night: ['🌦', 'небольшая морось'] },
    1153: { day: ['🌦', 'морось'], night: ['🌦', 'морось'] },
    1168: { day: ['🌧', 'ледяная морось'], night: ['🌧', 'ледяная морось'] },
    1171: { day: ['🌧', 'сильная ледяная морось'], night: ['🌧', 'сильная ледяная морось'] },
    1180: { day: ['🌦', 'небольшой дождь'], night: ['🌦', 'небольшой дождь'] },
    1183: { day: ['🌦', 'дождь'], night: ['🌦', 'дождь'] },
    1186: { day: ['🌧', 'умеренный дождь'], night: ['🌧', 'умеренный дождь'] },
    1189: { day: ['🌧', 'умеренный дождь'], night: ['🌧', 'умеренный дождь'] },
    1192: { day: ['🌧', 'сильный дождь'], night: ['🌧', 'сильный дождь'] },
    1195: { day: ['🌧', 'ливень'], night: ['🌧', 'ливень'] },
    1198: { day: ['🌧', 'ледяной дождь'], night: ['🌧', 'ледяной дождь'] },
    1201: { day: ['🌧', 'сильный ледяной дождь'], night: ['🌧', 'сильный ледяной дождь'] },
    1204: { day: ['🌨', 'мокрый снег'], night: ['🌨', 'мокрый снег'] },
    1207: { day: ['🌨', 'сильный мокрый снег'], night: ['🌨', 'сильный мокрый снег'] },
    1210: { day: ['🌨', 'небольшой снег'], night: ['🌨', 'небольшой снег'] },
    1213: { day: ['🌨', 'снег'], night: ['🌨', 'снег'] },
    1216: { day: ['🌨', 'умеренный снег'], night: ['🌨', 'умеренный снег'] },
    1219: { day: ['🌨', 'умеренный снег'], night: ['🌨', 'умеренный снег'] },
    1222: { day: ['🌨', 'сильный снег'], night: ['🌨', 'сильный снег'] },
    1225: { day: ['❄️', 'очень сильный снег'], night: ['❄️', 'очень сильный снег'] },
    1237: { day: ['🧊', 'ледяная крупа'], night: ['🧊', 'ледяная крупа'] },
    1240: { day: ['🌦', 'кратковременный дождь'], night: ['🌦', 'кратковременный дождь'] },
    1243: { day: ['🌧', 'сильный ливень'], night: ['🌧', 'сильный ливень'] },
    1246: { day: ['🌧', 'очень сильный ливень'], night: ['🌧', 'очень сильный ливень'] },
    1249: { day: ['🌨', 'кратковременный мокрый снег'], night: ['🌨', 'кратковременный мокрый снег'] },
    1252: { day: ['🌨', 'сильный кратковременный мокрый снег'], night: ['🌨', 'сильный кратковременный мокрый снег'] },
    1255: { day: ['🌨', 'кратковременный снег'], night: ['🌨', 'кратковременный снег'] },
    1258: { day: ['🌨', 'сильный кратковременный снег'], night: ['🌨', 'сильный кратковременный снег'] },
    1261: { day: ['🧊', 'кратковременная ледяная крупа'], night: ['🧊', 'кратковременная ледяная крупа'] },
    1264: { day: ['🧊', 'сильная ледяная крупа'], night: ['🧊', 'сильная ледяная крупа'] },
    1273: { day: ['⛈', 'дождь с грозой'], night: ['⛈', 'дождь с грозой'] },
    1276: { day: ['⛈', 'сильный дождь с грозой'], night: ['⛈', 'сильный дождь с грозой'] },
    1279: { day: ['⛈', 'снег с грозой'], night: ['⛈', 'снег с грозой'] },
    1282: { day: ['⛈', 'сильный снег с грозой'], night: ['⛈', 'сильный снег с грозой'] },
  };
  const entry = map[code] || { day: ['❔', 'неизвестно'], night: ['❔', 'неизвестно'] };
  return isDay ? { emoji: entry.day[0], text: entry.day[1] } : { emoji: entry.night[0], text: entry.night[1] };
}

Этот код сопоставляет код погоды с соответствующим эмодзи и текстовым описанием, учитывая, день сейчас или ночь.

📝 Форматирование сообщения для Telegram

/**
 * Преобразует объект погоды из getWeather в красивое текстовое сообщение для Telegram
 * @param {Object} weatherData - результат функции getWeather
 * @returns {string} - текстовое сообщение
 */
function formatWeatherMessage(weatherData) {
  // Получаем основные данные
  const city = weatherData.location.name;
  const current = weatherData.current;
  const forecast = weatherData.forecast.forecastday;

  // Текущая погода
  const temp = Math.round(current.temp_c);
  const feels = Math.round(current.feelslike_c);
  const condObj = getWeatherIconAndTextRu(current.condition.code, !!current.is_day);
  const wind = (current.wind_kph / 3.6).toFixed(2); // м/с
  const humidity = current.humidity;

  // Заголовок и сейчас
  let msg = `${condObj.emoji} Погода ${city}\n\n`;
  msg += `${condObj.emoji} Сейчас: +${temp}° | ${condObj.text}\n`;
  msg += `🧖‍♂️ Ощущается как: +${feels}°\n`;
  msg += `↖️ Ветер: ${wind} м/с\n`;
  msg += `💦 Влажность: ${humidity}%\n\n`;

  // Сегодня (вечер)
  const today = forecast[0];
  const todayEvening = today.hour.find(h => h.time.split(' ')[1] === '18:00') || today.hour[18];
  if (todayEvening) {
    const cond = getWeatherIconAndTextRu(todayEvening.condition.code, !!todayEvening.is_day);
    msg += `Сегодня\n${cond.emoji} Вечером: +${Math.round(todayEvening.temp_c)}° | ${cond.text}\n\n`;
  }

  // Завтра (ночь, утро, день, вечер)
  if (forecast.length > 1) {
    const tomorrow = forecast[1];
    const night = tomorrow.hour[0];
    const morning = tomorrow.hour[6];
    const day = tomorrow.hour[12];
    const evening = tomorrow.hour[18];
    msg += `Завтра\n`;
    if (night) {
      const cond = getWeatherIconAndTextRu(night.condition.code, !!night.is_day);
      msg += `${cond.emoji} Ночью: +${Math.round(night.temp_c)}° | ${cond.text}\n`;
    }
    if (morning) {
      const cond = getWeatherIconAndTextRu(morning.condition.code, !!morning.is_day);
      msg += `${cond.emoji} Утром: +${Math.round(morning.temp_c)}° | ${cond.text}\n`;
    }
    if (day) {
      const cond = getWeatherIconAndTextRu(day.condition.code, !!day.is_day);
      msg += `${cond.emoji} Днём: +${Math.round(day.temp_c)}° | ${cond.text}\n`;
    }
    if (evening) {
      const cond = getWeatherIconAndTextRu(evening.condition.code, !!evening.is_day);
      msg += `${cond.emoji} Вечером: +${Math.round(evening.temp_c)}° | ${cond.text}\n\n`;
    }
  }

  // Краткий прогноз на следующие дни
  for (let i = 2; i < forecast.length; i++) {
    const day = forecast[i];
    const date = new Date(day.date);
    const dayNum = date.getDate().toString().padStart(2, '0');
    const monthNum = (date.getMonth() + 1).toString().padStart(2, '0');
    const min = Math.round(day.day.mintemp_c);
    const max = Math.round(day.day.maxtemp_c);
    const cond = getWeatherIconAndTextRu(day.day.condition.code, true);
    msg += `${cond.emoji} ${dayNum} ${getMonthName(monthNum)} +${min}..+${max}° | ${cond.text}\n`;
  }

  return msg.trim();
}

Этот код формирует читаемое сообщение, включающее:

  • Текущую погоду (температура, ощущения, ветер, влажность).
  • Прогноз на сегодня.
  • Подробный прогноз на завтра (ночь, утро, день, вечер).
  • Краткий прогноз на следующие дни (если доступно).

📅 Вспомогательная функция для названия месяца

function getMonthName(monthNum) {
  const months = {
    '01': 'янв', '02': 'фев', '03': 'мар', '04': 'апр', '05': 'май', '06': 'июн',
    '07': 'июл', '08': 'авг', '09': 'сен', '10': 'окт', '11': 'ноя', '12': 'дек'
  };
  return months[monthNum] || '';
}

Она преобразует числовой месяц в сокращенное название на русском.

🚀 Как использовать

  1. Скопируйте код в свой проект Google Apps Script.
  2. Вызовите функцию formatWeatherMessage(getWeather('ВашГород')).
  3. Отправьте результат в Telegram через бота или используйте его в других целях.

🔍 Пример вывода

☀️ Погода Москва  

☀️ Сейчас: +23° | ясно  
🧖‍♂️ Ощущается как: +25°  
↖️ Ветер: 2.5 м/с  
💦 Влажность: 60%  

Сегодня  
🌤️ Вечером: +20° | малооблачно  

Завтра  
🌙 Ночью: +16°  
🌤️ Утром: +18°  
☀️ Днём: +24°  
🌤️ Вечером: +21°  

🌤️ 15 июн +17..+25° | малооблачно  
🌧️ 16 июн +15..+20° | дождь  
пример вывода в чате

📌 Заключение

Этот скрипт позволяет легко получать красивый прогноз погоды с эмодзи и отправлять его в Telegram. Вы можете доработать его, добавив:

  • Уведомления при изменении погоды.
  • Поддержку большего количества дней (на платном тарифе WeatherAPI).
  • Интеграцию с Google Таблицами для хранения истории погоды.

Попробуйте и сделайте свой бот еще удобнее! 🌈