🌦️ Погода с эмодзи и переводом на русском для Telegram-бота на Google Apps Script
В современном мире, где информация должна быть не только точной, но и визуально привлекательной, создание удобного и красивого прогноза погоды становится важной задачей. В этой статье мы рассмотрим, как создать Telegram-бота, который будет отправлять прогноз погоды с эмодзи и переводом на русский язык, используя Google Apps Script и WeatherAPI.
🌍 Как это работает
📡 Получение данных о погоде
Система получает актуальный прогноз погоды через WeatherAPI — один из самых популярных сервисов для работы с метеорологическими данными. Преимущество этого API в том, что он поддерживает русский язык, что делает его идеальным выбором для русскоязычных пользователей.
✨ Форматирование результата
После получения данных скрипт обрабатывает их и формирует красивое сообщение, дополненное эмодзи для лучшей визуализации. Например:
Также автоматически добавляется перевод описания погоды на русский язык, что делает информацию максимально понятной.
📩 Отправка в Telegram
Готовое сообщение можно сразу отправить в Telegram-бота или канал, чтобы пользователи получали актуальную погоду в удобном формате.
🔑 Начало работы
1️⃣ Регистрация на WeatherAPI
Для использования API необходимо:
- Зарегистрироваться на сайте www.weatherapi.com.
- Получить 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] || '';
}Она преобразует числовой месяц в сокращенное название на русском.
🚀 Как использовать
- Скопируйте код в свой проект Google Apps Script.
- Вызовите функцию
formatWeatherMessage(getWeather('ВашГород')). - Отправьте результат в Telegram через бота или используйте его в других целях.
🔍 Пример вывода
☀️ Погода Москва ☀️ Сейчас: +23° | ясно 🧖♂️ Ощущается как: +25° ↖️ Ветер: 2.5 м/с 💦 Влажность: 60% Сегодня 🌤️ Вечером: +20° | малооблачно Завтра 🌙 Ночью: +16° 🌤️ Утром: +18° ☀️ Днём: +24° 🌤️ Вечером: +21° 🌤️ 15 июн +17..+25° | малооблачно 🌧️ 16 июн +15..+20° | дождь
📌 Заключение
Этот скрипт позволяет легко получать красивый прогноз погоды с эмодзи и отправлять его в Telegram. Вы можете доработать его, добавив: