1. Pengantar
Buat pengalaman AI Agentic interaktif yang lancar dan dapat digunakan pelanggan Anda langsung dari aplikasi pesan yang telah mereka gunakan. Temukan cara mengembangkan dan men-deploy aplikasi cerdas yang berjalan lancar di seluruh antarmuka web dan saluran pesan modern.
Yang akan Anda build
Integrasi antara "Restaurant Concierge" yang lengkap, aplikasi berbasis ADK yang didukung oleh Gemini yang membantu pelanggan menelusuri menu restoran dan memesan tempat, serta aplikasi chat Telegram. Anda dapat berinteraksi dengan bot Telegram dan meminta deskripsi bahasa alami seperti "Saya ingin sesuatu yang pedas dan vegetarian". Bot kemudian akan terhubung ke agen ADK yang membaca dan menulis ke database Cloud SQL PostgreSQL sepenuhnya melalui MCP Toolbox for Databases, yang menangani semua akses database — termasuk pembuatan embedding otomatis untuk penelusuran vektor. Sementara itu, pengguna akan dapat melihat bahwa bot mengakui pesan dan mengetik ... typing untuk respons saat menunggu respons dari agen ADK.

Yang akan Anda pelajari
- Men-deploy "Restaurant Concierge" yang berfungsi, aplikasi berbasis ADK yang didukung oleh Gemini
- Menyiapkan bot chat Telegram menggunakan BotFather
- Menulis aplikasi Python untuk memproses webhook bot
- Mengirim tindakan chat untuk memberikan
... typingnotifikasi di Telegram pada pesan pengguna, dan melakukan polling untuk mengirim... typingsecara berkala saat menunggu respons sebenarnya - Memanggil endpoint Cloud Run
Restaurant Conciergeuntuk memproses permintaan pengguna - Menangani respons dari agen ADK, dan mengirim pesan ke Telegram serta menutup buffer
- Men-deploy aplikasi Python ke Cloud Run
- Berinteraksi dengan bot Telegram Anda
Prasyarat
- Akun Google Cloud dengan akun penagihan uji coba
- Pemahaman dasar tentang Python
- Pengalaman sebelumnya dengan deployment ADK dan Cloud Run akan sangat membantu
- Akun Telegram
- (Direkomendasikan) Menyelesaikan codelab berikut :
- RAG Agentic dengan ADK, MCP Toolbox, dan Cloud SQL -> Anda dapat terus membangun agen dari codelab ini, kode awal yang disediakan identik
- (ATAU) Agen dalam Skala Besar: Arsitektur Multi-Agen dengan Protokol A2A di Agent Runtime dan Integrasi ADK -> jika Anda ingin memperkaya agen lebih lanjut menggunakan arsitektur multi-agen
2. Penyiapan Lingkungan - Melanjutkan dari codelab sebelumnya
Narasi yang kami berikan dalam codelab ini sebenarnya merupakan kelanjutan dari codelab prasyarat ini: RAG Agentic dengan ADK, MCP Toolbox, dan Cloud SQL atau Agen dalam Skala Besar: Arsitektur Multi-Agen dengan Protokol A2A di Agent Runtime dan Integrasi ADK. Anda dapat melanjutkan pekerjaan dari codelab sebelumnya
Kita dapat mulai membangun di direktori kerja codelab sebelumnya ( direktori kerja harus berupa build-agent-adk-toolbox-cloudsql atau adk-a2a-agent-runtime-starter). Untuk menghindari kebingungan, mari kita ganti nama direktori dengan nama direktori yang sama yang kita gunakan saat memulai dari awal
Jika Anda melanjutkan dari lab RAG Agentic dengan ADK, MCP Toolbox, dan Cloud SQL :
mv ~/build-agent-adk-toolbox-cloudsql ~/build-agent-adk-telegram
Atau jika Anda melanjutkan dari lab Agen dalam Skala Besar: Arsitektur Multi-Agen dengan Protokol A2A di Agent Runtime dan Integrasi ADK
mv ~/adk-a2a-agent-runtime-starter ~/build-agent-adk-telegram
Kemudian, ubah direktori kerja kita ke direktori tersebut
cloudshell workspace ~/build-agent-adk-telegram && cd ~/build-agent-adk-telegram
source .env
Setelah itu, pastikan restaurant-agent Anda telah di-deploy dan memiliki URL publik yang dapat diakses
AGENT_URL=$(gcloud run services describe restaurant-agent \
--region="$REGION" \
--format='value(status.url)')
echo " ✓ Agent service deployed"
echo " Agent URL: $AGENT_URL"
echo ""
Jika dapat mengakses URL, Anda dapat melanjutkan ke bagian berikutnya: Create Telegram Bot
3. Penyiapan Lingkungan - Memulai dari awal dengan repo awal
Langkah ini menyiapkan lingkungan Cloud Shell Anda, mengonfigurasi project Google Cloud Anda, dan meng-clone repositori awal.
Membuka Cloud Shell
Buka Cloud Shell di browser Anda. Cloud Shell menyediakan lingkungan yang telah dikonfigurasi sebelumnya dengan semua alat yang Anda perlukan untuk codelab ini. Klik Authorize saat diminta
Kemudian, klik "View" -> "Terminal" untuk membuka terminal.Antarmuka Anda akan terlihat mirip dengan ini

Ini akan menjadi antarmuka utama kita, IDE di atas, terminal di bawah
Menyiapkan direktori kerja Anda
Clone repositori awal, semua kode yang Anda tulis di codelab ini ada di sini:
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
Buat file .env dari template yang disediakan:
cp .env.example .env
Untuk menyederhanakan penyiapan project di terminal, download skrip penyiapan project ini ke direktori kerja Anda:
curl -sL https://raw.githubusercontent.com/alphinside/cloud-trial-project-setup/main/setup_verify_trial_project.sh -o setup_verify_trial_project.sh
Jalankan skrip. Skrip ini akan memverifikasi akun penagihan uji coba Anda, membuat project baru (atau memvalidasi project yang ada), menyimpan project ID Anda ke file .env di direktori saat ini, dan menetapkan project aktif di gcloud.
bash setup_verify_trial_project.sh && source .env
Skrip ini akan:
- Memverifikasi bahwa Anda memiliki akun penagihan uji coba yang aktif
- Memeriksa project yang ada di
.env(jika ada) - Membuat project baru atau menggunakan kembali project yang ada
- Menautkan akun penagihan uji coba ke project Anda
- Menyimpan project ID ke
.env - Menetapkan project sebagai project
gcloudaktif
Verifikasi bahwa project telah ditetapkan dengan benar dengan memeriksa teks berwarna kuning di samping direktori kerja Anda di perintah terminal Cloud Shell. Project ID Anda akan ditampilkan.

Penyiapan Infrastruktur Awal
Pertama, kita perlu menginstal dependensi Python menggunakan uv. Ini adalah pengelola project dan paket Python cepat yang ditulis dalam Rust ( dokumentasi uv ). Codelab ini menggunakannya untuk kecepatan dan kesederhanaan dalam memelihara project Python
uv sync
Kemudian, jalankan skrip penyiapan lengkap, yang membuat instance Cloud SQL, mengisi data, dan men-deploy layanan Toolbox yang akan bertindak sebagai status awal agen restoran kita
bash scripts/full_setup.sh > logs/full_setup.log 2>&1 &
Ini akan:
- Membuat instance Cloud SQL dan mengisi database (Fase 1)
- Membuat konfigurasi lingkungan agen dan memulai layanan Toolbox lokal (Fase 2)
- Men-deploy layanan Toolbox dan Agen ke Cloud Run (Fase 3)
Setelah deployment ini selesai, Anda dapat mengakses UI Dev ADK di 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 ""
Buka UI dev ADK, pilih restaurant_agent, dan uji dengan kueri seperti contoh berikut:
What Italian dishes do you have?
Atau,
I want something spicy and creamy
Sekarang, tindakan berikutnya adalah bagaimana kita dapat beralih dari antarmuka pengembangan web saja ke saluran pesan Telegram
4. Membuat Bot Telegram
Telegram adalah platform pesan gratis yang terkenal dan banyak digunakan untuk engagement berbasis komunitas. Salah satu alasannya adalah, platform ini menawarkan banyak cara untuk berintegrasi dengan mudah, sehingga orang dapat dengan mudah membuat bot mereka sendiri dengan berbagai fungsi yang berbeda.
Dalam kasus ini, kita akan menggunakan BotFather untuk membuat bot kita sendiri untuk pertama kalinya. Perlu diingat bahwa meskipun kita menggunakan Telegram untuk sesi ini, metode yang sama dapat digunakan untuk WhatsApp atau platform pesan lainnya yang dipilih.
Menggunakan BotFather untuk Membuat Bot Anda Sendiri
Arahkan browser web Anda dan buka https://telegram.me/BotFather untuk mulai membuat bot Telegram Anda sendiri.

Mulai Berinteraksi dengan BotFather
Mengirim Perintah /start
Untuk mulai menggunakan BotFather dan mulai membuat bot pertama Anda, Anda harus memanggil pesan /start ke BotFather. Kemudian, pesan tersebut akan membagikan semua perintah yang dimilikinya agar Anda dapat berinteraksi lebih lanjut.
/start
Memulai Pembuatan Bot dengan Perintah /newbot
Mari kita buat bot baru dengan mengirim perintah /newbot ke BotFather. BotFather akan meminta Anda untuk memberi nama bot Anda, lalu meminta Anda untuk memberikan username bot yang selalu mengharuskan nama tersebut diakhiri dengan bot . Misalnya, TetrisBot atau tetris_bot. Nama ini harus unik.

Setelah pembuatan bot berhasil, Anda akan menerima pesan berikut dari 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
Catat YOUR_TELEGRAM_API_KEY. Kita akan menggunakannya di bagian berikutnya.
5. Mengembangkan Aplikasi Webhook Telegram
Mari kita siapkan direktori kerja untuk mulai mengembangkan aplikasi webhook Telegram Anda
mkdir ~/build-agent-adk-telegram/telegram-integration
cd ~/build-agent-adk-telegram
Menambahkan Dependensi yang diperlukan
Buat skrip requirements.txt dengan konten berikut untuk menyediakan dependensi yang memadai untuk skrip pemroses webhook Telegram.
cloudshell edit ./telegram-integration/requirements.txt
Kemudian, tambahkan dependensi berikut
python-telegram-bot[webhooks]
httpx
Membuat skrip untuk Pemroses Webhook Telegram
Setelah kita menginstal dependensi. Sekarang kita dapat membuat skrip main.py Python untuk aplikasi integrasi
cloudshell edit ~/build-agent-adk-telegram/telegram-integration/main.py
Kemudian, salin kode berikut ke dalamnya
# ./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()
Memahami kode Integrasi Bot Telegram

Saat pengguna mengirim pesan, pipeline berikut akan berjalan di bagian handle_message()
Langkah 1: Identitas &Turunan Sesi
Bot memetakan ID Pengguna Telegram ke ID ADK unik untuk menjaga sesi pengguna tetap berbeda:
user_id = f"tg_{raw_user_id}"
session_id = f"tg_sess_{raw_user_id}"
Langkah 2: Status "Mengetik" Asinkron (Baris 53–58)
Untuk memastikan pengalaman pengguna yang sangat responsif saat agen ADK memproses perintah (yang dapat memerlukan waktu beberapa detik), bot akan memulai loop latar belakang asinkron:
asyncio.Eventdibuat instance-nya sebagaistop_event.asyncio.create_taskmembuatsend_typing_loop(...)di latar belakang.- Loop mengirim tindakan
ChatAction.TYPINGke Telegram setiap 4 detik hinggastop_eventditetapkan.
Langkah 3: Verifikasi &Pembuatan Sesi ADK (Baris 61–72)
Sebelum menjalankan agen, bot akan memeriksa apakah sesi sudah ada:
- Mengirim permintaan
GETke/apps/{appName}/users/{userId}/sessions/{sessionId}. - Jika responsnya adalah
404 Not Found, sesi akan dibuat melalui permintaanPOSTke URL yang sama dengan isi JSON kosong. - Jika status selain
200atau404ditampilkan, pengecualian akan muncul.
Langkah 4: Mengirim Permintaan ke Agen (Baris 74–85)
Payload pesan diteruskan ke endpoint ADK /run:
- Endpoint:
POST /run - Batas waktu permintaan ditetapkan ke
60.0detik untuk memungkinkan penalaran yang kompleks atau latensi upstream. - Struktur Payload:
{
"appName": "restaurant_agent",
"userId": "tg_<user_id>",
"sessionId": "tg_sess_<user_id>",
"newMessage": {
"role": "user",
"parts": [{"text": "<user_message>"}]
}
}
Langkah 5: Mengurai Respons (Baris 87–101)
Server ADK menampilkan daftar peristiwa pesan. Bot memeriksa array yang ditampilkan:
- Bot mengambil peristiwa terakhir dalam daftar (
events[-1]). - Bot membuka konten teks melalui
event["content"]["parts"][0]["text"]. - Jika tidak ada peristiwa yang ditampilkan atau struktur teks tidak ada, teks placeholder deskriptif akan ditetapkan.
Langkah 6: Penonaktifan &Pengiriman Respons (Baris 103–111)
- Di blok
finally,stop_eventditetapkan, sehingga menghentikan loop tindakan mengetik. - Bot menunggu penyelesaian
typing_taskuntuk memastikan resource bersih. - Terakhir, bot membalas chat Telegram dengan teks respons yang diurai.
6. Men-deploy Aplikasi Webhook Telegram ke Cloud Run
Selanjutnya, kita akan men-deploy Pemroses Webhook Telegram ke Cloud Run, sehingga bot kita dapat berkomunikasi dengannya
Membuat Dockerfile
Pertama, kita perlu membuat Dockerfile.
cloudshell edit ~/build-agent-adk-telegram/telegram-integration/Dockerfile
Kemudian, salin kode berikut ke dalamnya
# 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"]
Layanan ini dikontainerisasi menggunakan python:3.11-slim agar ukuran image tetap kecil:
- Menginstal dependensi dari
requirements.txt(python-telegram-bot[webhooks]danhttpx). - Mengekspos port standar
8080. - Meluncurkan
python main.py.
Menyiapkan Variabel Lingkungan
Setelah itu, mari kita periksa kembali apakah agen kita berhasil di-deploy
AGENT_URL=$(gcloud run services describe restaurant-agent \
--region="$REGION" \
--format='value(status.url)')
echo " ✓ Agent service deployed"
echo " Agent URL: $AGENT_URL"
echo ""
Selanjutnya, mari kita masukkan TELEGRAM_BOT_TOKEN yang sebelumnya kita dapatkan ke .env
echo "TELEGRAM_BOT_TOKEN=YOUR_TELEGRAM_API_KEY" >> .env
Kemudian, mari kita isi data .env dengan nilai lain yang kita perlukan.
echo "ADK_SERVER_URL=$AGENT_URL" >> .env
echo "ADK_APP_NAME=restaurant_agent" >> .env
echo "SERVICE_NAME=telegram-integration" >> .env
source .env
Membuat Skrip Deployment
Mari kita buat skrip deployment yang akan memberikan pemeriksaan lengkap dan men-deploy aplikasi ke Cloud Run
cloudshell edit ~/build-agent-adk-telegram/telegram-integration/deploy.sh
Lalu, salin kode berikut ke file
#!/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."
Skrip Deployment Ganda (deploy.sh)
Saat men-deploy ke Google Cloud Run, bot harus menentukan URL-nya sendiri (SERVICE_URL) di lingkungannya sehingga dapat mendaftarkannya sebagai target webhook dengan Telegram. Untuk mengatasi dependensi melingkar ini (URL tidak diketahui hingga deployment, tetapi layanan memerlukan URL untuk melakukan booting tanpa kegagalan health check), deploy.sh melakukan deployment dua tahap:
- Langkah 1: Deployment Awal: Melakukan booting container dengan DNS placeholder (
https://google.com) sehingga layanan berhasil dimulai, terikat ke port lokal, dan lulus health check Cloud Run awal. - Langkah 2: Mengambil URL: Mengekstrak endpoint Cloud Run yang baru dibuat secara terprogram menggunakan
gcloud run services describe. - Langkah 3: Memperbarui Konfigurasi: Memperbarui variabel lingkungan dengan URL layanan aktif yang sebenarnya. Tindakan ini memicu update berkelanjutan yang bersih di Cloud Run dan mendaftarkan target webhook yang benar dengan aman ke Telegram API.
Men-deploy ke Cloud Run
Skrip deployment mencetak URL Agen. Buka di browser Anda untuk mengakses UI dev ADK yang sama yang berjalan di Cloud Run.
cd ~/build-agent-adk-telegram
bash ./telegram-integration/deploy.sh
Jika semuanya berjalan lancar, inilah saatnya Anda dapat mulai melakukan chat ke bot Anda langsung dari aplikasi chat Telegram. Temukan bot yang baru saja Anda buat dan mulai berinteraksi dengannya:
What Italian dishes do you have?
Atau,
I want something spicy and creamy
Perhatikan bot yang mengirim status "...is typing", lalu segera, bot akan menampilkan pesan dari ADK yang Anda buat sebelumnya.

7. Selamat!
Anda telah membangun, men-deploy, dan mengintegrasikan sepenuhnya asisten menu restoran pintar berbasis ADK, agen AI dengan Telegram, melalui komunikasi server klien HTTP, dan memungkinkan orang untuk membuat kueri menu favorit mereka dan memesan tempat di restoran.
Yang telah Anda pelajari
- Men-deploy dan mengonfigurasi Restaurant Concierge, agen berbasis ADK, dan MCP Toolbox ke Cloud Run
- Cara menyiapkan bot Telegram menggunakan BotFather
- Cara menulis skrip Python untuk memproses webhook Telegram dan berinteraksi dengan agen ADK untuk meneruskan kueri dan respons pengguna dengan tepat
- Cara menerapkan
"... typing"di Telegram untuk memberi sinyal bahwa pesan sedang diproses sebagai masukan real-time kepada pengguna saat menunggu respons agen ADK. - Cara Men-deploy skrip Python ke Cloud Run dan dapat berinteraksi dengannya
Pembersihan
Untuk menghindari tagihan ke akun Google Cloud Anda, hapus resource yang dibuat di codelab ini.
Opsi 1: Menghapus project (direkomendasikan)
gcloud projects delete $GOOGLE_CLOUD_PROJECT
Opsi 2: Menghapus setiap resource
# 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
