1. Введение
Создавайте бесшовные интерактивные интерфейсы Agentic AI, с которыми ваши клиенты смогут взаимодействовать непосредственно из уже используемого ими приложения для обмена сообщениями. Узнайте, как разрабатывать и развертывать интеллектуальные приложения, которые бесперебойно работают в веб-интерфейсах и современных каналах обмена сообщениями.
Что вы построите
Интеграция полноценного приложения «Ресторанный консьерж» на базе ADK и Gemini, помогающего посетителям просматривать меню ресторана и бронировать столики, с чатом Telegram. Вы можете взаимодействовать с ботом Telegram и запрашивать описания на естественном языке, например: «Я хочу что-нибудь острое и вегетарианское». Затем бот подключается к агенту ADK, который считывает и записывает данные в базу данных Cloud SQL PostgreSQL полностью через MCP Toolbox for Databases, который обрабатывает весь доступ к базе данных, включая автоматическую генерацию векторных представлений для векторного поиска. При этом пользователь сможет видеть, что бот подтверждает сообщение и набирает ... typing ожидая ответа от агента ADK.

Что вы узнаете
- Разверните работающее приложение «Ресторанный консьерж» на основе ADK, работающее на платформе Gemini.
- Настройка чат-бота в Telegram с помощью BotFather
- Напишите приложение на Python для прослушивания веб-хуков бота.
- Отправьте действие в чате
... typingв Telegram при получении сообщения от пользователя, и периодически отправляйте уведомление о... typingожидая реального ответа. - Облачная платформа Call
Restaurant Conciergeобрабатывает запросы пользователей. - Обработать возврат от агента ADK, отправить сообщение в Telegram и закрыть буфер.
- Разверните приложение Python в облачной среде.
- Взаимодействуйте со своим Telegram-ботом.
Предварительные требования
- Учетная запись Google Cloud с пробной платной учетной записью.
- Базовые знания Python.
- Предварительный опыт работы с ADK и развертыванием Cloud Run будет полезен.
- Аккаунт в Telegram
- (Рекомендуется) Выполнены следующие практические задания:
- Agentic RAG с ADK, MCP Toolbox и Cloud SQL -> вы можете продолжить создание своего агента, используя этот пример кода, предоставленный стартовый код идентичен.
- (ИЛИ) Агенты в масштабе: многоагентная архитектура с протоколом A2A в среде выполнения агентов и интеграцией ADK -> если вы хотите дополнительно расширить функциональность агента, используя многоагентную архитектуру.
2. Настройка среды — продолжение предыдущего практического занятия.
Представленные в этом практическом занятии материалы являются продолжением предыдущего практического занятия: «Agentic RAG с ADK, MCP Toolbox и Cloud SQL» или «Agents at Scale: Multi-Agent Architecture with A2A Protocol on Agent Runtime and ADK Integration» . Вы можете продолжить работу, начатую в предыдущем практическом занятии.
Мы можем начать сборку в предыдущей рабочей директории Codelab (рабочая директория должна называться build-agent-adk-toolbox-cloudsql или adk-a2a-agent-runtime-starter ). Чтобы избежать путаницы, переименуем директорию, присвоив ей то же имя, которое мы используем при начале работы с нуля.
Если вы продолжаете работу с лабораторной программы Agentic RAG с использованием ADK, MCP Toolbox и Cloud SQL :
mv ~/build-agent-adk-toolbox-cloudsql ~/build-agent-adk-telegram
В противном случае, если вы продолжаете изучение темы «Масштабируемые агенты: многоагентная архитектура с протоколом A2A в среде выполнения агентов и интеграция с ADK» из лабораторной работы,
mv ~/adk-a2a-agent-runtime-starter ~/build-agent-adk-telegram
Затем смените на неё наш рабочий каталог.
cloudshell workspace ~/build-agent-adk-telegram && cd ~/build-agent-adk-telegram
source .env
После этого убедитесь, что ваш restaurant-agent уже развернут и имеет общедоступный URL-адрес для доступа.
AGENT_URL=$(gcloud run services describe restaurant-agent \
--region="$REGION" \
--format='value(status.url)')
echo " ✓ Agent service deployed"
echo " Agent URL: $AGENT_URL"
echo ""
Если вы можете получить доступ к URL-адресу, то можете переходить к следующему разделу: Create Telegram Bot
3. Настройка среды — Новый старт с использованием стартового репозитория.
На этом этапе подготавливается среда Cloud Shell, настраивается проект Google Cloud и клонируется стартовый репозиторий.
Открытая облачная оболочка
Откройте Cloud Shell в браузере. Cloud Shell предоставляет предварительно настроенную среду со всеми необходимыми инструментами для выполнения этого практического задания. При появлении запроса нажмите «Авторизовать».
Затем нажмите « Вид » -> « Терминал », чтобы открыть терминал. Ваш интерфейс должен выглядеть примерно так.

Это будет наш основной интерфейс: IDE сверху, терминал снизу.
Настройте рабочую директорию.
Клонируйте стартовый репозиторий, весь код, который вы напишете в этом практическом занятии, будет находиться здесь:
rm -rf ~/build-agent-adk-telegram
git clone https://github.com/alphinside/adk-a2a-agent-runtime-starter.git build-agent-adk-telegram
cloudshell workspace ~/build-agent-adk-telegram && cd ~/build-agent-adk-telegram
Создайте файл .env на основе предоставленного шаблона:
cp .env.example .env
Чтобы упростить настройку проекта в терминале, загрузите этот скрипт настройки проекта в свою рабочую директорию:
curl -sL https://raw.githubusercontent.com/alphinside/cloud-trial-project-setup/main/setup_verify_trial_project.sh -o setup_verify_trial_project.sh
Запустите скрипт. Он проверит вашу учетную запись для оплаты пробной версии, создаст новый проект (или проверит существующий), сохранит идентификатор вашего проекта в файл .env в текущем каталоге и установит активный проект в gcloud .
bash setup_verify_trial_project.sh && source .env
Сценарий будет:
- Убедитесь, что у вас есть активный пробный аккаунт для оплаты.
- Проверьте наличие существующего проекта в
.env(если таковой имеется). - Создайте новый проект или используйте существующий.
- Свяжите пробный аккаунт с вашим проектом.
- Сохраните идентификатор проекта в файл
.env - Установите этот проект в качестве активного проекта
gcloud
Убедитесь, что проект настроен правильно, проверив желтый текст рядом с вашим рабочим каталогом в командной строке терминала Cloud Shell. Там должен отображаться идентификатор вашего проекта.

Начальная настройка инфраструктуры
Сначала нам нужно установить зависимости Python с помощью uv — это быстрый менеджер пакетов и проектов Python, написанный на Rust (документация uv). В этом практическом задании он используется для повышения скорости и упрощения поддержки проекта Python.
uv sync
Затем запустите полный скрипт настройки, который создаст экземпляр Cloud SQL, заполнит данные и развернет службу Toolbox, которая будет выступать в качестве начального состояния нашего агента для ресторанов.
bash scripts/full_setup.sh > logs/full_setup.log 2>&1 &
Это позволит:
- Создайте экземпляр Cloud SQL и заполните базу данных данными (этап 1).
- Сгенерируйте конфигурацию среды агента и запустите локальную службу Toolbox (этап 2).
- Развертывание сервисов Toolbox и Agent в Cloud Run (этап 3)
После завершения развертывания вы сможете получить доступ к пользовательскому интерфейсу разработчика ADK по URL-адресу Cloud Run.
source .env
AGENT_URL=$(gcloud run services describe restaurant-agent \
--region="$REGION" \
--format='value(status.url)')
echo " ✓ Agent service deployed"
echo " Agent URL: $AGENT_URL"
echo ""
Откройте пользовательский интерфейс разработчика ADK, выберите restaurant_agent и протестируйте с помощью запросов, подобных приведенному ниже примеру:
What Italian dishes do you have?
Или,
I want something spicy and creamy
Теперь следующий шаг — как нам перейти от использования только веб-интерфейса для разработки к использованию мессенджера Telegram.
4. Создайте Telegram-бота.
Telegram — это известная бесплатная платформа для обмена сообщениями, широко используемая для взаимодействия в сообществах. Одна из причин — это множество способов интеграции, благодаря которым люди могут легко создавать собственных ботов с разнообразными функциями.
В нашем случае мы впервые будем использовать BotFather для создания собственного бота. Имейте в виду, что хотя мы используем Telegram для этого занятия, тот же метод можно использовать для WhatsApp или других мессенджеров по вашему выбору.
Используйте BotFather для создания собственного бота.
Откройте веб-браузер и перейдите по ссылке https://telegram.me/BotFather , чтобы начать создавать своего собственного Telegram-бота.

Начните взаимодействовать с The BotFather
Отправьте команду /start
Чтобы начать работу с BotFather и создать своего первого бота, вам нужно отправить BotFather сообщение /start , после чего он начнет передавать вам все команды для дальнейшего взаимодействия с ним.
/start
Инициируйте создание бота с помощью команды /newbot
Давайте создадим нашего нового бота, отправив команду /newbot в BotFather. Он попросит вас назвать бота, а затем указать username бота, которое всегда должно заканчиваться на bot . Например, TetrisBot или tetris_bot . Это имя должно быть уникальным.

После успешного создания бота вы получите следующее сообщение от BotFather.
Done! Congratulations on your new bot. You will find it at t.me/AdkTelegramTest_bot. You can now add a description, about section and profile picture for your bot, see /help for a list of commands. By the way, when you've finished creating your cool bot, ping our Bot Support if you want a better username for it. Just make sure the bot is fully operational before you do this. Use this token to access the HTTP API:
<YOUR_TELEGRAM_API_KEY>
Keep your token secure and store it safely, it can be used by anyone to control your bot. For a description of the Bot API, see this page: https://core.telegram.org/bots/api
Обратите внимание на значение YOUR_TELEGRAM_API_KEY мы будем использовать его в следующем разделе.
5. Разработайте приложение для веб-перехватчиков Telegram.
Давайте подготовим рабочую директорию для начала разработки вашего приложения Telegram WebHook.
mkdir ~/build-agent-adk-telegram/telegram-integration
cd ~/build-agent-adk-telegram
Добавьте необходимые зависимости.
Создайте скрипт requirements.txt со следующим содержимым, чтобы указать необходимые зависимости для скрипта прослушивателя веб-перехватчика Telegram.
cloudshell edit ./telegram-integration/requirements.txt
Затем добавьте следующие зависимости.
python-telegram-bot[webhooks]
httpx
Создайте скрипт для обработчика веб-хуков Telegram.
После установки необходимых зависимостей мы можем создать скрипт main.py на Python для интеграционного приложения.
cloudshell edit ~/build-agent-adk-telegram/telegram-integration/main.py
Затем скопируйте в него следующий код.
# ./telegram-integration/main.py
import asyncio
import os
import sys
from telegram import Update
from telegram.ext import Application, CommandHandler, MessageHandler, filters, CallbackContext
from telegram.constants import ChatAction
import httpx
# Read token from environment variable
TOKEN = os.environ.get("TELEGRAM_BOT_TOKEN")
ADK_SERVER_URL = os.environ.get("ADK_SERVER_URL", "http://localhost:8000")
ADK_APP_NAME = os.environ.get("ADK_APP_NAME", "restaurant_agent")
# Parse base URL out of ADK_SERVER_URL
BASE_URL = ADK_SERVER_URL.rstrip('/')
if BASE_URL.endswith('/run'):
BASE_URL = BASE_URL[:-4]
elif BASE_URL.endswith('/query'):
BASE_URL = BASE_URL[:-6]
if not TOKEN:
print("Error: TELEGRAM_BOT_TOKEN environment variable not set.")
print("Please set it before running the application.")
sys.exit(1)
async def start(update: Update, context: CallbackContext) -> None:
"""Send a message when the command /start is issued."""
await update.message.reply_text('Hi! I am your ADK Integration Bot. Send me a message and I will forward it to the ADK server.')
async def send_typing_loop(chat_id: int, bot, stop_event: asyncio.Event):
"""Send typing action periodically until the stop event is set."""
while not stop_event.is_set():
try:
await bot.send_chat_action(chat_id=chat_id, action=ChatAction.TYPING)
# The research suggested repeating every 4 seconds
await asyncio.sleep(4)
except Exception as e:
print(f"Error sending chat action: {e}")
await asyncio.sleep(1) # Wait a bit before retrying if error
async def handle_message(update: Update, context: CallbackContext) -> None:
"""Handle incoming user messages."""
user_message = update.message.text
chat_id = update.message.chat_id
raw_user_id = str(update.message.from_user.id)
# Derive unique user_id and session_id for this user
user_id = f"tg_{raw_user_id}"
session_id = f"tg_sess_{raw_user_id}"
print(f"Received message from {user_id}: {user_message}")
# Create a stop event for the typing loop
stop_event = asyncio.Event()
# Start the typing loop as a background task
typing_task = asyncio.create_task(send_typing_loop(chat_id, context.bot, stop_event))
try:
async with httpx.AsyncClient() as client:
# 1. Check if the session exists
session_url = f"{BASE_URL}/apps/{ADK_APP_NAME}/users/{user_id}/sessions/{session_id}"
session_check = await client.get(session_url, timeout=10.0)
if session_check.status_code == 404:
# 2. If session doesn't exist, create it
print(f"Session {session_id} not found. Creating session...")
session_create = await client.post(session_url, json={}, timeout=10.0)
if session_create.status_code != 200:
raise Exception(f"Failed to create session: {session_create.status_code} {session_create.text}")
elif session_check.status_code != 200:
raise Exception(f"Error checking session: {session_check.status_code} {session_check.text}")
# 3. Run the ADK agent
run_url = f"{BASE_URL}/run"
payload = {
"appName": ADK_APP_NAME,
"userId": user_id,
"sessionId": session_id,
"newMessage": {
"role": "user",
"parts": [{"text": user_message}]
}
}
response = await client.post(run_url, json=payload, timeout=60.0)
if response.status_code == 200:
events = response.json()
if isinstance(events, list) and len(events) > 0:
# The last event contains the final text response
last_event = events[-1]
content = last_event.get("content", {})
parts = content.get("parts", [])
if parts and "text" in parts[0]:
reply_text = parts[0]["text"]
else:
reply_text = "ADK agent returned an empty or non-text response."
else:
reply_text = "No events returned from ADK agent."
else:
reply_text = f"Error communicating with ADK server (Status: {response.status_code})."
except Exception as e:
reply_text = f"Failed to connect to ADK server: {e}"
finally:
# Stop the typing loop
stop_event.set()
await typing_task
# Send the final response back to the user
await update.message.reply_text(reply_text)
def main() -> None:
"""Start the bot."""
# Create the Application and pass it your bot's token.
application = Application.builder().token(TOKEN).build()
# on different commands - answer in Telegram
application.add_handler(CommandHandler("start", start))
# on non command i.e message - echo the message on Telegram
application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message))
# Check if running in webhook mode (e.g., on Cloud Run)
port = os.environ.get("PORT")
service_url = os.environ.get("SERVICE_URL")
if port and service_url:
if not service_url.startswith("http"):
service_url = f"https://{service_url}"
print(f"Starting bot in WEBHOOK mode on port {port} with url {service_url}")
application.run_webhook(
listen="0.0.0.0",
port=int(port),
url_path=TOKEN,
webhook_url=f"{service_url}/{TOKEN}",
allowed_updates=Update.ALL_TYPES
)
else:
print("Starting bot in POLLING mode")
# Run the bot until the user presses Ctrl-C
application.run_polling(allowed_updates=Update.ALL_TYPES)
if __name__ == "__main__":
main()
Разбираемся в коде интеграции Telegram-бота.

Когда пользователь отправляет сообщение, в функции handle_message() выполняется следующий конвейер обработки.
Шаг 1: Идентификация и определение сессии
Бот сопоставляет идентификатор пользователя Telegram с уникальными идентификаторами ADK, чтобы различать пользовательские сессии:
user_id = f"tg_{raw_user_id}"
session_id = f"tg_sess_{raw_user_id}"
Шаг 2: Асинхронный статус "набора текста" (строки 53–58)
Для обеспечения высокой скорости отклика пользователя во время обработки запроса агентом ADK (что может занять несколько секунд), бот запускает асинхронный фоновый цикл:
- Объект
asyncio.Eventсоздается какstop_event. -
asyncio.create_taskзапускаетsend_typing_loop(...)в фоновом режиме. - Цикл отправляет действие
ChatAction.TYPINGв Telegram каждые 4 секунды, пока не будет установлено значениеstop_event.
Шаг 3: Проверка и создание сессии ADK (строки 61–72)
Перед запуском агента бот проверяет, существует ли уже сессия:
- Отправляет
GETзапрос по адресу/apps/{appName}/users/{userId}/sessions/{sessionId}. - Если в ответ приходит ошибка
404 Not Found, сессия создается с помощьюPOSTзапроса к тому же URL-адресу с пустым JSON-телом. - Если возвращается статус, отличный от
200или404, генерируется исключение.
Шаг 4: Отправка запроса агенту (строки 74–85)
Содержимое сообщения перенаправляется на конечную точку ADK /run :
- Конечная точка :
POST /run - Время ожидания запроса установлено на
60.0секунд, чтобы учесть сложные логические рассуждения или задержку со стороны вышестоящего сервера. - Структура полезной нагрузки :
{
"appName": "restaurant_agent",
"userId": "tg_<user_id>",
"sessionId": "tg_sess_<user_id>",
"newMessage": {
"role": "user",
"parts": [{"text": "<user_message>"}]
}
}
Шаг 5: Анализ ответа (строки 87–101)
Сервер ADK возвращает список событий сообщений. Бот анализирует возвращенный массив:
- Он извлекает последнее событие из списка (
events[-1]). - Переход к текстовому содержимому осуществляется через
event["content"]["parts"][0]["text"]. - Если события не возвращаются или отсутствует структура текста, устанавливается описательный текст-заполнитель.
Шаг 6: Демонтаж и отправка ответного сигнала (строки 103–111)
- В блоке
finallyустанавливается значениеstop_event, что останавливает цикл ввода текста. - Бот ожидает завершения задачи
typing_task, чтобы обеспечить чистоту ресурсов. - В заключение бот отправляет в чат Telegram разобранный текст ответа.
6. Разверните приложение Telegram Webhook в Cloud Run.
Далее мы развернем Telegram Webhook Listener в Cloud Run, чтобы наш бот мог с ним взаимодействовать.
Создайте Dockerfile.
Сначала нам нужно создать Dockerfile.
cloudshell edit ~/build-agent-adk-telegram/telegram-integration/Dockerfile
Затем скопируйте в него следующий код.
# Use an official Python runtime as a parent image
FROM python:3.11-slim
# Prevent Python from writing pyc files to disc and buffering stdout/stderr
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
# Set the working directory in the container
WORKDIR /app
# Install system dependencies if needed
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
&& rm -rf /var/lib/apt/lists/*
# Copy the dependencies file to the working directory
COPY requirements.txt .
# Install any needed packages specified in requirements.txt
RUN pip install --no-cache-dir -r requirements.txt
# Copy the rest of the application code
COPY main.py .
# Expose the port that Cloud Run will provide via environment variable
EXPOSE 8080
# Run main.py when the container launches
CMD ["python", "main.py"]
Сервис контейнеризирован с использованием python:3.11-slim , чтобы уменьшить размер образа:
- Устанавливает зависимости из
requirements.txt(python-telegram-bot[webhooks]иhttpx). - Предоставляет доступ к стандартному порту
8080. - Запускает
python main.py
Подготовьте переменные среды.
После этого давайте ещё раз проверим, успешно ли развёрнулся наш агент.
AGENT_URL=$(gcloud run services describe restaurant-agent \
--region="$REGION" \
--format='value(status.url)')
echo " ✓ Agent service deployed"
echo " Agent URL: $AGENT_URL"
echo ""
Далее, давайте добавим полученный ранее TELEGRAM_BOT_TOKEN в файл .env
echo "TELEGRAM_BOT_TOKEN=YOUR_TELEGRAM_API_KEY" >> .env
Затем давайте заполним данные в файле .env другими необходимыми нам значениями.
echo "ADK_SERVER_URL=$AGENT_URL" >> .env
echo "ADK_APP_NAME=restaurant_agent" >> .env
echo "SERVICE_NAME=telegram-integration" >> .env
source .env
Создание скрипта развертывания
Давайте создадим скрипт развертывания, который обеспечит полную проверку и развернет приложение в Cloud Run.
cloudshell edit ~/build-agent-adk-telegram/telegram-integration/deploy.sh
И скопируйте следующий код в файл.
#!/usr/bin/env bash
# ./telegram-integration/deploy.sh
# Exit immediately if a command exits with a non-zero status
set -euo pipefail
# Color codes for neat terminal output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0;37m' # No Color
# Load environment variables from .env if it exists
if [ -f .env ]; then
echo -e "${GREEN}✔ Loading environment variables from .env...${NC}"
export $(grep -v '^#' .env | xargs)
fi
echo -e "${BLUE}====================================================${NC}"
echo -e "${BLUE} Google Cloud Run Deployment: Telegram Bot ${NC}"
echo -e "${BLUE}====================================================${NC}"
# 1. Check for gcloud CLI
if ! command -v gcloud &> /dev/null; then
echo -e "${RED}Error: 'gcloud' CLI is not installed.${NC}"
echo "Please install the Google Cloud SDK and try again."
echo "See: https://cloud.google.com/sdk/docs/install"
exit 1
fi
# 2. Check active gcloud account/auth
ACTIVE_ACCOUNT=$(gcloud auth list --filter=status:ACTIVE --format="value(account)" 2>/dev/null || true)
if [ -z "$ACTIVE_ACCOUNT" ]; then
echo -e "${RED}Error: No active Google Cloud account found.${NC}"
echo "Please run: gcloud auth login"
exit 1
fi
# 3. Detect / Prompt for GCP Project
DEFAULT_PROJECT=${GCP_PROJECT_ID:-$(gcloud config get-value project 2>/dev/null || true)}
if [ -n "${DEFAULT_PROJECT}" ]; then
echo -e "${GREEN}✔ Using GCP Project: $DEFAULT_PROJECT${NC}"
GCP_PROJECT="$DEFAULT_PROJECT"
else
echo -n "Enter GCP Project ID: "
read -r GCP_PROJECT
fi
if [ -z "$GCP_PROJECT" ]; then
echo -e "${RED}Error: GCP Project ID is required.${NC}"
exit 1
fi
# Set active project
gcloud config set project "$GCP_PROJECT" &> /dev/null
# 4. Configure Service Parameters
DEFAULT_SERVICE=${SERVICE_NAME:-"telegram-integration"}
if [ -n "${SERVICE_NAME:-}" ]; then
echo -e "${GREEN}✔ Using Cloud Run Service Name: $SERVICE_NAME${NC}"
else
echo -n "Enter Cloud Run Service Name [Default: $DEFAULT_SERVICE]: "
read -r SERVICE_NAME
SERVICE_NAME=${SERVICE_NAME:-$DEFAULT_SERVICE}
fi
DEFAULT_REGION=${REGION:-"us-central1"}
if [ -n "${REGION:-}" ]; then
echo -e "${GREEN}✔ Using Cloud Run Region: $REGION${NC}"
else
echo -n "Enter Cloud Run Region [Default: $DEFAULT_REGION]: "
read -r REGION
REGION=${REGION:-$DEFAULT_REGION}
fi
DEFAULT_ADK_APP=${ADK_APP_NAME:-"restaurant_agent"}
if [ -n "${ADK_APP_NAME:-}" ]; then
echo -e "${GREEN}✔ Using ADK App Name: $ADK_APP_NAME${NC}"
ADK_APP="$ADK_APP_NAME"
else
echo -n "Enter ADK App Name [Default: $DEFAULT_ADK_APP]: "
read -r ADK_APP
ADK_APP=${ADK_APP:-$DEFAULT_ADK_APP}
fi
# 5. Retrieve/Prompt for Telegram Bot Token
if [ -n "${TELEGRAM_BOT_TOKEN:-}" ]; then
echo -e "${GREEN}✔ Found TELEGRAM_BOT_TOKEN in environment.${NC}"
BOT_TOKEN="$TELEGRAM_BOT_TOKEN"
else
echo -e "${YELLOW}TELEGRAM_BOT_TOKEN is not set in your environment.${NC}"
echo -n "Enter your Telegram Bot Token (input will be hidden): "
read -s -r BOT_TOKEN
echo ""
fi
if [ -z "$BOT_TOKEN" ]; then
echo -e "${RED}Error: Telegram Bot Token is required.${NC}"
exit 1
fi
# 6. Retrieve/Prompt for ADK Server URL
DEFAULT_ADK_URL="http://localhost:8000"
if [ -n "${ADK_SERVER_URL:-}" ]; then
echo -e "${GREEN}✔ Found ADK_SERVER_URL in environment: $ADK_SERVER_URL${NC}"
ADK_URL="$ADK_SERVER_URL"
else
echo -n "Enter your ADK Server URL [Default: $DEFAULT_ADK_URL]: "
read -r ADK_URL
ADK_URL=${ADK_URL:-$DEFAULT_ADK_URL}
fi
# Enable required GCP services
echo -e "\n${YELLOW}Checking and enabling required GCP services...${NC}"
gcloud services enable run.googleapis.com cloudbuild.googleapis.com artifactregistry.googleapis.com --project "$GCP_PROJECT"
# Determine source directory dynamically
SOURCE_DIR="."
if [ -d "telegram-integration" ]; then
SOURCE_DIR="telegram-integration"
echo -e "${GREEN}✔ Found source directory: telegram-integration${NC}"
elif [ -f "Dockerfile" ]; then
SOURCE_DIR="."
echo -e "${GREEN}✔ Dockerfile found in current directory. Using current directory as source.${NC}"
else
echo -e "${RED}Error: Could not find source directory 'telegram-integration' or Dockerfile in current directory.${NC}"
exit 1
fi
# 7. First-pass Deployment with placeholder SERVICE_URL
# This boots the container in Webhook mode (so health check binds to port)
# but uses a high-reliability placeholder URL (google.com) to pass DNS verification checks.
echo -e "\n${YELLOW}Deploying to Cloud Run (Step 1/2: Initial Deploy)...${NC}"
gcloud run deploy "$SERVICE_NAME" \
--source "$SOURCE_DIR" \
--region "$REGION" \
--allow-unauthenticated \
--set-env-vars "TELEGRAM_BOT_TOKEN=$BOT_TOKEN,ADK_SERVER_URL=$ADK_URL,ADK_APP_NAME=$ADK_APP,SERVICE_URL=https://google.com" \
--project "$GCP_PROJECT"
# 8. Retrieve the actual service URL
echo -e "\n${YELLOW}Retrieving service URL...${NC}"
SERVICE_URL=$(gcloud run services describe "$SERVICE_NAME" --region "$REGION" --project "$GCP_PROJECT" --format 'value(status.url)')
echo -e "${GREEN}✔ Service URL is: $SERVICE_URL${NC}"
# 9. Update service environment variables with the real SERVICE_URL
# This triggers a rolling update and registers the correct webhook with Telegram automatically!
echo -e "\n${YELLOW}Updating configuration with final Webhook URL (Step 2/2)...${NC}"
gcloud run services update "$SERVICE_NAME" \
--region "$REGION" \
--set-env-vars "TELEGRAM_BOT_TOKEN=$BOT_TOKEN,ADK_SERVER_URL=$ADK_URL,ADK_APP_NAME=$ADK_APP,SERVICE_URL=$SERVICE_URL" \
--project "$GCP_PROJECT"
echo -e "\n${GREEN}====================================================${NC}"
echo -e "${GREEN} Deployment Completed Successfully! 🎉 ${NC}"
echo -e "${GREEN}====================================================${NC}"
echo -e "Service Name: ${BLUE}$SERVICE_NAME${NC}"
echo -e "Region: ${BLUE}$REGION${NC}"
echo -e "Active URL: ${BLUE}$SERVICE_URL${NC}"
echo -e "Webhook Path: ${BLUE}$SERVICE_URL/<bot-token>${NC}"
echo -e "ADK Backend: ${BLUE}$ADK_URL${NC}"
echo -e "ADK App Name: ${BLUE}$ADK_APP${NC}"
echo -e "${GREEN}====================================================${NC}"
echo "Your Telegram Bot has been configured to use webhooks."
echo "Any message sent to your bot will now trigger this Cloud Run instance."
Скрипт двойного развертывания (deploy.sh)
При развертывании в Google Cloud Run боту необходимо указать свой собственный URL (SERVICE_URL) в переменных окружения, чтобы зарегистрировать его в качестве целевого объекта веб-перехватчика в Telegram. Для разрешения этой циклической зависимости (URL неизвестен до развертывания, но сервису требуется этот URL для запуска без сбоев проверки работоспособности) deploy.sh выполняет двухэтапное развертывание:
- Шаг 1: Первоначальное развертывание : Запускает контейнер с временным DNS-сервером (
https://google.com), чтобы служба успешно запустилась, привязалась к локальному порту и прошла первоначальные проверки работоспособности Cloud Run. - Шаг 2: Получение URL-адреса : Программно извлекает вновь созданную конечную точку Cloud Run с помощью
gcloud run services describe. - Шаг 3: Обновление конфигурации : Обновляет переменные среды, указывая фактический URL-адрес работающего сервиса. Это запускает чистое поэтапное обновление в Cloud Run и безопасно регистрирует правильный целевой веб-перехватчик в API Telegram.
Развертывание в облаке. Запуск.
Скрипт развертывания выводит URL-адрес агента. Откройте его в браузере, чтобы получить доступ к тому же пользовательскому интерфейсу разработчика ADK, работающему в Cloud Run.
cd ~/build-agent-adk-telegram
bash ./telegram-integration/deploy.sh
Если все пройдет хорошо, то сейчас самое время начать общаться со своим ботом прямо из приложения Telegram, найти только что созданного бота и начать с ним взаимодействовать:
What Italian dishes do you have?
Или,
I want something spicy and creamy
Следите за тем, как бот отправляет статус "...печатает", и вскоре он вернет сообщение из созданного вами ранее ADK!

7. Поздравляем!
Вы разработали, развернули и полностью интегрировали наш интеллектуальный помощник по меню ресторана на основе ADK с ИИ-агентом в Telegram, используя HTTP-соединение клиент-сервер, и позволяете людям запрашивать меню и бронировать столик в ресторане.
Что вы узнали
- Развертывание и настройка Restaurant Concierge, агента на основе ADK и MCP Toolbox для работы в облаке.
- Как настроить Telegram-бота с помощью BotFather
- Как написать скрипты на Python для прослушивания веб-хуков Telegram и взаимодействия с агентом ADK для передачи запросов пользователей и получения соответствующих ответов?
- Как реализовать функцию
"... typing"в Telegram для оповещения пользователей о том, что сообщения обрабатываются в режиме реального времени, пока ожидается ответ от агента ADK. - Как развернуть скрипт Python в облаке и взаимодействовать с ним.
Уборка
Чтобы избежать списания средств с вашего аккаунта Google Cloud, удалите ресурсы, созданные в этом практическом задании.
Вариант 1: Удалить проект (рекомендуется)
gcloud projects delete $GOOGLE_CLOUD_PROJECT
Вариант 2: Удаление отдельных ресурсов
# If you follow from previous A2A Agent Runtime codelab
# Delete the Agent Runtime deployment (skip if not found)
uv run python -c "
import vertexai
from google.genai import types
vertexai.init(project='$GOOGLE_CLOUD_PROJECT', location='$REGION')
client = vertexai.Client(
project='$GOOGLE_CLOUD_PROJECT', location='$REGION',
http_options=types.HttpOptions(api_version='v1beta1'),
)
try:
agent = client.agent_engines.get(name='$RESERVATION_AGENT_RESOURCE_NAME')
agent.delete(force=True)
print('Agent Runtime deployment deleted.')
except Exception as e:
print(f'No agent deployment found or already deleted, skipping. ({e})')
"
# Delete GCS staging bucket (skip if STAGING_BUCKET is not set)
if [ -n "$STAGING_BUCKET" ]; then
gsutil rm -r gs://$STAGING_BUCKET
else
echo "STAGING_BUCKET not set, skipping bucket deletion."
fi
# Delete Cloud Run services
gcloud run services delete restaurant-agent --region=$REGION --quiet
gcloud run services delete toolbox-service --region=$REGION --quiet
gcloud run services delete telegram-integration --region=$REGION --quiet
# Delete Cloud SQL instance
gcloud sql instances delete $DB_INSTANCE --quiet
