وبهوکها به API مربوط به Gemini اجازه میدهند تا هنگام تکمیل عملیات ناهمزمان یا عملیات طولانیمدت (LRO) اعلانهای بلادرنگ را به سرور شما ارسال کند. این امر جایگزین نیاز به نظرسنجی از API برای بهروزرسانی وضعیت میشود و تأخیر و سربار را کاهش میدهد.
وبهوکها برای عملیاتی مانند کارهای دستهای ، تعاملات و تولید ویدیو در دسترس هستند.
چگونه کار میکند؟
به جای اینکه مرتباً از GET /operations برای بررسی اتمام یک کار استفاده کنید، میتوانید Gemini API Webhooks را طوری پیکربندی کنید که بلافاصله پس از وقوع یک رویداد، یک درخواست HTTP POST به آدرس اینترنتی شنونده شما ارسال کند.
رابط برنامهنویسی کاربردی Gemini از دو روش برای پیکربندی وبهوکها پشتیبانی میکند:
- وبهوکهای استاتیک : نقاط پایانی سطح پروژه که با رابط برنامهنویسی Gemini WebhookService پیکربندی شدهاند. برای یکپارچهسازیهای جهانی (مثلاً اطلاعرسانی به Slack، همگامسازی پایگاه داده و غیره) مناسب هستند.
- وبهوکهای پویا : سطح درخواست، ارسال یک URL وبهوک را در پیکربندی یک فراخوانی شغل خاص لغو میکند. ایدهآل برای مسیریابی مشاغل خاص به نقاط انتهایی اختصاصی.
وبهوکهای استاتیک
وبهوکهای استاتیک برای کل پروژه ثبت میشوند و برای هر رویداد منطبق، فعال میشوند.
ایجاد یک وب هوک
شما میتوانید با استفاده از SDK یا REST API، نقاط پایانی (endpoints) ایجاد کنید.
مهم : هنگام ایجاد یک وبهوک، API فقط یک بار رمز امضا را برمیگرداند. شما باید این را به طور ایمن (مثلاً در متغیرهای محیطی خود) ذخیره کنید تا بعداً امضاها را تأیید کنید. اگر رمز امضا را گم کنید، باید آن را بچرخانید .
پایتون
from google import genai
client = genai.Client()
webhook = client.webhooks.create(
name="MyBatchWebhook",
subscribed_events=["batch.completed", "batch.failed"],
uri="https://my-api.com/gemini-callback",
)
# Store webhook.new_signing_secret securely
webhook_secret = webhook.new_signing_secret
print(f"Created webhook: {webhook.name}, {webhook.id}")
جاوا اسکریپت
import { GoogleGenAI } from "@google/genai";
const client = new GoogleGenAI();
async function createWebhook() {
const webhook = await client.webhooks.create({
name: "MyBatchWebhook",
subscribed_events: ["batch.completed", "batch.failed"],
uri: "https://my-api.com/gemini-callback",
});
// Store webhook.signingSecret securely
const webhookSecret = webhook.new_signing_secret;
console.log(`Created webhook: ${webhook.name}, ${webhook.id}`);
}
createWebhook();
استراحت
curl -X POST \
"https://generativelanguage.googleapis.com/v1/webhooks" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GOOGLE_API_KEY" \
-d '{
"name": "MyBatchWebhook",
"uri": "https://my-api.com/gemini-callback",
"subscribed_events": ["batch.completed", "batch.failed"]
}'
برای جزئیات بیشتر در مورد تنظیم سرور خود برای دریافت دادهها، به بخش مدیریت درخواستهای وبهوک مراجعه کنید.
یک وب هوک دریافت کنید
جزئیات مربوط به یک وبهوک خاص را با نام منبع آن بازیابی کنید.
پایتون
from google import genai
client = genai.Client()
webhook = client.webhooks.get(id="<your_webhook_id>")
print(f"Webhook: {webhook.name}")
print(f"URI: {webhook.uri}")
print(f"Events: {webhook.subscribed_events}")
جاوا اسکریپت
import { GoogleGenAI } from "@google/genai";
const client = new GoogleGenAI(); // Assumes process.env.GEMINI_API_KEY is set
async function getWebhook() {
const webhook = await client.webhooks.get("<your_webhook_id>");
console.log(`Webhook: ${webhook.name}`);
console.log(`URI: ${webhook.uri}`);
console.log(`Events: ${webhook.subscribed_events}`);
}
getWebhook();
استراحت
curl -X GET \
"https://generativelanguage.googleapis.com/v1/webhooks/<your_webhook_id>" \
-H "x-goog-api-key: $GOOGLE_API_KEY"
فهرست کردن وب هوکها
تمام وبهوکهای پیکربندیشده برای پروژه فعلی را به همراه صفحهبندی اختیاری فهرست کنید.
پایتون
from google import genai
client = genai.Client()
webhooks = client.webhooks.list()
for wh in webhooks:
print(f"{wh.id}: {wh.name} -> {wh.uri}")
جاوا اسکریپت
import { GoogleGenAI } from "@google/genai";
const client = new GoogleGenAI();
async function listWebhooks() {
const webhooks = await client.webhooks.list();
for (const wh of webhooks) {
console.log(`${wh.id}: ${wh.name} -> ${wh.uri}`);
}
}
listWebhooks();
استراحت
curl -X GET \
"https://generativelanguage.googleapis.com/v1/webhooks" \
-H "x-goog-api-key: $GOOGLE_API_KEY"
بهروزرسانی یک وبهوک
ویژگیهای یک وبهوک موجود مانند نام نمایشی، آدرس هدف یا رویدادهای مشترک را بهروزرسانی کنید.
پایتون
from google import genai
client = genai.Client()
updated_webhook = client.webhooks.update(
id="<your_webhook_id>",
subscribed_events=["batch.completed", "batch.failed", "batch.cancelled"],
)
print(f"Updated webhook: {updated_webhook.name}")
جاوا اسکریپت
import { GoogleGenAI } from "@google/genai";
const client = new GoogleGenAI();
async function updateWebhook() {
const updatedWebhook = await client.webhooks.update(
"<your_webhook_id>",
{
subscribed_events: ["batch.completed", "batch.failed", "batch.cancelled"],
}
);
console.log(`Updated webhook: ${updatedWebhook.name}`);
}
updateWebhook();
استراحت
curl -X PATCH \
"https://generativelanguage.googleapis.com/v1/webhooks/<your_webhook_id>" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GOOGLE_API_KEY" \
-d '{
"subscribed_events": ["batch.completed", "batch.failed", "batch.cancelled"]
}'
حذف یک وب هوک
یک نقطه پایانی وبهوک را از پروژه حذف کنید. این کار تحویل رویدادهای آینده به آن نقطه پایانی را متوقف میکند.
پایتون
from google import genai
client = genai.Client()
client.webhooks.delete(id="<your_webhook_id>")
print("Webhook deleted.")
جاوا اسکریپت
import { GoogleGenAI } from "@google/genai";
const client = new GoogleGenAI();
async function deleteWebhook() {
await client.webhooks.delete("<your_webhook_id>");
console.log("Webhook deleted.");
}
deleteWebhook();
استراحت
curl -X DELETE \
"https://generativelanguage.googleapis.com/v1/webhooks/<your_webhook_id>" \
-H "x-goog-api-key: $GOOGLE_API_KEY"
چرخاندن یک راز امضا
رمز امضای یک وبهوک را بچرخانید. میتوانید پیکربندی کنید که آیا رمزهای فعال قبلی بلافاصله یا پس از یک دوره مهلت ۲۴ ساعته لغو شوند.
مهم : رمز امضای جدید فقط یک بار در زمان چرخش بازگردانده میشود. قبل از بهروزرسانی منطق تأیید خود، آن را به طور ایمن ذخیره کنید.
پایتون
from google import genai
from google.genai import types
client = genai.Client()
response = client.webhooks.rotate_signing_secret(
id="<your_webhook_id>",
revocation_behavior="REVOKE_PREVIOUS_SECRETS_AFTER_H24",
)
# Store response.secret securely, then update your server's verification config
print("New signing secret generated. Update your server configuration.")
جاوا اسکریپت
import { GoogleGenAI } from "@google/genai";
const client = new GoogleGenAI();
async function rotateSigningSecret() {
const response = await client.webhooks.rotateSigningSecret(
"<your_webhook_id>",
{
revocation_behavior: "REVOKE_PREVIOUS_SECRETS_AFTER_H24",
}
);
// Store response.secret securely, then update your server's verification config
console.log("New signing secret generated. Update your server configuration.");
}
rotateSigningSecret();
استراحت
curl -X POST \
"https://generativelanguage.googleapis.com/v1/webhooks/<your_webhook_id>/rotate_secret" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GOOGLE_API_KEY" \
-d '{
"revocation_behavior": "REVOKE_PREVIOUS_SECRETS_AFTER_H24"
}'
مدیریت درخواستهای وبهوک روی سرور
وقتی رویدادی اتفاق میافتد که شما در آن مشترک هستید، URL وبهوک شما یک درخواست HTTP POST دریافت میکند. نقطه پایانی شما باید ظرف چند ثانیه با یک کد وضعیت 2xx پاسخ دهد تا از تلاش مجدد جلوگیری شود. برای اطمینان از تحویل، API Gemini به طور خودکار درخواستهای ناموفق را به مدت 24 ساعت با استفاده از روش بازگشت نمایی (exponential backoff) دوباره امتحان میکند.
Gemini به شدت از مشخصات استاندارد Webhooks برای هدرهای امنیتی پیروی میکند. با استفاده از امضاهای هدر امضا شده و رمز امضای استاتیک ذخیره شده، بار داده را روی سرور خود تأیید کنید. برای اطلاعات بار داده به بخش پوشش Webhook مراجعه کنید.
در اینجا مثالی از استفاده از Flask برای شنونده HTTP آورده شده است:
پایتون
# pip install flask standardwebhooks
import os
from flask import Flask, request, jsonify
# Standard verification wrapper for Standard Webhook Headers
from standardwebhooks.webhooks import Webhook, WebhookVerificationError
app = Flask(__name__)
SIGNING_SECRET = os.environ.get('WEBHOOK_SIGNING_SECRET')
@app.route('/gemini-callback', methods=['POST'])
def gemini_callback():
payload = request.get_data(as_text=True)
headers = request.headers
try:
wh = Webhook(SIGNING_SECRET)
event = wh.verify(payload, headers)
except WebhookVerificationError as e:
return jsonify({"error": "Signature invalid"}), 400
# Process thin payload contents
if event.get("type") in ("batch.completed", "video.generated"):
uri = event['data']['output_file_uri']
print(f"Batch finished! Results at: {uri}")
return jsonify({"status": "received"}), 200
if __name__ == "__main__":
app.run(port=8000)
جاوا اسکریپت
// npm install standardwebhooks
import { Webhook } from "standardwebhooks";
import express from "express";
const app = express();
const client = new GoogleGenAI({ webhookSecret: process.env.WEBHOOK_SIGNING_SECRET });
// Don't use express.json() because signature verification needs the raw text body
app.use(express.text({ type: "application/json" }));
app.post("/gemini-callback", async (req, res) => {
const payload = await req.text();
const headers: Record<string, string> = {};
req.headers.forEach((value, key) => {
headers[key] = value;
});
try {
const wh = new Webhook(process.env.WEBHOOK_SIGNING_SECRET);
const event = wh.verify(payload, headers) as Record<string, any>;
// Process thin payload contents
if (event.type === "batch.completed" || event.type === "video.generated") {
const uri = event.data.output_file_uri;
console.log(`Job finished! Results at: ${uri}`);
}
res.status(200).json({ status: "received" });
} catch (e) {
console.error("Webhook verification failed:", e);
res.status(400).send("Invalid signature");
}
});
app.listen(8000, () => {
console.log("Webhook server is running on port 8000");
});
وب هوکهای پویا
وبهوکهای پویا به شما امکان میدهند یک نقطه پایانی وبهوک را به یک پیکربندی درخواست خاص متصل کنید، که برای صفهای هماهنگسازی عامل ایدهآل است. وبهوکهای پویا به جای رمزهای متقارن، از امضاهای نامتقارن کلید عمومی JWKS استفاده میکنند.
ارسال درخواست پویا
هنگام اجرای یک کار ناهمزمان (مثلاً ایجاد یک دسته)، یک webhook_config اضافه کنید.
پایتون
from google import genai
from google.genai import types
client = genai.Client()
file_batch_job = client.batches.create(
model="gemini-3-flash-preview",
src="files/uploaded_file_id",
config={
"display_name": "My Setup",
"webhook_config": {
"uris": ["https://my-api.com/gemini-webhook-dynamic"],
"user_metadata":{"job_group": "nightly-eval", "priority": "high"}
}
}
)
جاوا اسکریپت
import { GoogleGenAI } from "@google/genai";
const client = new GoogleGenAI();
async function createBatchWithWebhook() {
const fileBatchJob = await client.batches.create({
model: "gemini-3-flash-preview",
src: "files/uploaded_file_id",
config: {
displayName: "My Setup",
webhookConfig: {
uris: ["https://my-api.com/gemini-webhook-dynamic"],
user_metadata: {"job_group": "nightly-eval", "priority": "high"}
},
},
});
}
استراحت
curl -X POST \
"https://generativelanguage.googleapis.com/v1/models/gemini-3-flash-preview:batchCreate" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GOOGLE_API_KEY" \
-d '{
"src": "files/uploaded_file_id",
"config": {
"display_name": "My Setup",
"webhook_config": {
"uris": ["https://my-api.com/gemini-webhook-dynamic"],
"user_metadata": {"job_group": "nightly-eval", "priority": "high"}
}
}
}'
تأیید امضاهای پویا (JWKS)
درخواستهای وبهوک پویا، امضای JSON Web Token (JWT) را منتشر میکنند. شنونده شما باید امضا را استخراج کرده و آن را با استفاده از نقاط پایانی گواهی عمومی گوگل تأیید کند.
پایتون
import jwt
import requests
from flask import Flask, request, jsonify
app = Flask(__name__)
# Google public cert list endpoint
JWKS_URI = "https://generativelanguage.googleapis.com/.well-known/jwks.json"
def load_google_public_key(kid):
response = requests.get(JWKS_URI).json()
for key_item in response.get('keys', []):
if key_item.get('kid') == kid:
# Convert JWK to Cert wrapper
return jwt.algorithms.RSAAlgorithm.from_jwk(key_item)
return None
@app.route('/gemini-webhook-dynamic', methods=['POST'])
def dynamic_handler():
payload = request.get_data(as_text=True)
headers = request.headers
token = headers.get('Webhook-Signature')
if not token:
return jsonify({"error": "No signature header"}), 400
try:
# Extract kid from JWT header
unverified_headers = jwt.get_unverified_header(token)
pub_key = load_google_public_key(unverified_headers.get('kid'))
if not pub_key:
return jsonify({"error": "Key cert not found"}), 400
# Verify Signature against expected audience (e.g., your project client ID)
event = jwt.decode(
token,
pub_key,
algorithms=["RS256"],
audience="your-configured-audience"
)
except Exception as e:
return jsonify({"error": "Invalid Dynamic signature", "details": str(e)}), 400
print("Verified Dynamic payload success.")
return jsonify({"status": "received"}), 200
جاوا اسکریپت
import { GoogleGenAI } from "@google/genai";
import express from "express";
import jwt from "jsonwebtoken";
import jwksClient from "jwks-rsa";
const app = express();
app.use(express.text({ type: 'application/json' }));
const client = jwksClient({
jwksUri: "https://generativelanguage.googleapis.com/.well-known/jwks.json"
});
function getKey(header, callback) {
client.getSigningKey(header.kid, (err, key) => {
const signingKey = key.getPublicKey();
callback(null, signingKey);
});
}
app.post('/gemini-webhook-dynamic', (req, res) => {
const token = req.headers['webhook-signature'];
if (!token) {
return res.status(400).json({ error: "No signature header" });
}
jwt.verify(
token,
getKey,
{
algorithms: ["RS256"],
audience: "your-configured-audience"
},
(err, decoded) => {
if (err) {
return res.status(400).json({ error: "Invalid Dynamic signature", details: err.message });
}
console.log("Verified Dynamic payload success.");
res.status(200).json({ status: "received" });
}
);
});
پاکت وب هوک
برای جلوگیری از ازدحام پهنای باند، وبهوکهای Gemini از یک مدل payload نازک برای تحویل دادهها استفاده میکنند. تحویلها به جای خود فایل خروجی خام، یک snapshot حاوی جزئیات وضعیت و اشارهگرهایی به نتایج ارسال میکنند.
در اینجا یک نمونه از قالب بارگذاری آمده است:
{
"type": "batch.completed",
"version": "v1",
"timestamp": "2026-01-22T12:00:00Z",
"data": {
"id": "batch_123456",
"output_file_uri": "gs://my-bucket/results.jsonl",
"error_count": 0
}
}
مرجع کاتالوگ رویداد
رویدادهای زیر برای پشتیبانی از مشاغل فعال میشوند:
| نوع رویداد | ماشه | کالای بار ( data ) |
|---|---|---|
batch.succeeded | پردازش با موفقیت به پایان رسید. | id ، output_file_uri |
batch.cancelled | درخواست لغو شده توسط کاربر | id |
batch.expired | دسته در بازه زمانی 24 ساعت پردازش (پایان) نشده است | id |
batch.failed | کار دستهای با شکست مواجه شد (خطای سیستمی یا اعتبارسنجی). | id ، error_code ، error_message |
interaction.requires_action | فراخوانی تابع، کاربر باید کاری انجام دهد | id |
interaction.completed | LRO در تعاملات API موفق شد | id |
interaction.failed | LRO در تعاملات API ناموفق بود (خطای سیستم یا اعتبارسنجی). | id ، error_code ، error_message |
interaction.cancelled | لغو تعاملات API در LRO | id |
video.generated | تولید ویدیو از LRO به پایان رسید. | file_id ، video_uri |
بهترین شیوهها
برای اطمینان از عملکرد قابل اعتماد و مقیاسپذیر:
- بررسی دقیق محافظت در برابر تکرار : همه درخواستها دارای یک هدر
webhook-timestampهستند. همیشه این timestamp را در لایه پیکربندی سرور خود اعتبارسنجی کنید تا بارهای داده قدیمیتر از ۵ دقیقه را رد کنید (برای کاهش حملات تکرار). - پردازش ناهمزمان : بلافاصله پس از تشخیص امضای معتبر، با
2xx OKپاسخ دهید و عملیات تجزیه را به صورت داخلی در صف قرار دهید. زمانهای طولانی انتظار شنونده، چرخه تلاش مجدد تحویل را آغاز میکند. - مدیریت حذف دادههای تکراری : وبهوکهای استاندارد «حداقل یک بار» این کار را انجام میدهند. از هدر
webhook-idثابت برای مدیریت دادههای تکراری بالقوه در جریانهای تراکم بالاتر استفاده کنید.
بعدش چی؟
- API دستهای : از وبهوکها برای خودکارسازی نقاط پایانی با حجم بالا استفاده کنید.