跳至主要内容
未公开页面
此页面未公开列出。搜索引擎不会对其建立索引,只有拥有直接链接的用户才能访问。

页面获取 Webhook

page.get Webhook 用于获取 Game Hub 页面的布局:需要渲染的区块行,以及可选的用于填充这些区块的商店商品。当页面内容由游戏逻辑决定而不是在 Hub Builder 中搭建时,它非常有用。

当玩家打开已连接 page.get Webhook 的页面时,将触发该 Webhook。此类页面没有自己的区块:保存在 Aghanim 中的区块始终为空,玩家看到的是您的服务器返回的布局。

在校验购买时也会请求该 Webhook,用于确认玩家正在购买的商品仍以相同条件在售。在这类请求中,布局会被忽略,只有商品会被使用。

要求

如需接入 Aghanim 的 page.get Webhook,请按照以下要求配置您的 Webhook 服务器:

  • HTTPS 端点,可接收 POST Webhook 请求。
  • 监听由 Aghanim 生成并 签名 的事件。
  • 使用 2xx 状态码表示成功处理,使用 4xx 或 5xx 状态码表示拒绝或错误。
  • 在 10 秒内响应。该 Webhook 是在玩家等待页面加载时被请求的。
  • 同步处理该请求。与 player.verify、store.get 和 daily_reward.get 一样,page.get 作为单次尝试交付,不适用重试计划。

配置步骤

  1. 为 page.get Webhook 处理开发一个函数。
  2. 部署您的端点使其可访问。
  3. 进入您的 Aghanim 账户后,依次导航至 游戏 → Webhooks → Add webhook,然后选择 page.get 事件类型来注册您的端点。
  4. 在 Game Hub Builder 的区段设置中,通过 Advanced → Webhook 选择该 Webhook,页面即从中获取布局。

该设置可从区段侧边栏底部的 Add section 打开,这种方式会一次完成创建页面并选择 Webhook;已有区段则通过其所在行的 ⋯ 菜单 → Edit 打开。连接 Webhook 后,该页面上已搭建的区块会被删除且无法恢复。

或者,您也可以使用 Create Webhook API 方法在 Aghanim 中注册端点,并使用 Update Page API 方法设置 webhook_id 来连接页面。页面响应中的 layout_source 字段为只读。

响应不会被缓存:每次浏览页面都会请求该 Webhook,因此布局可以因玩家和请求而异。

触发器值

值描述
hub.page.open当玩家打开使用 Webhook 布局的页面时。
hub.purchase当玩家开始购买来自该 Webhook 的商品时。
order.captured当该商品的付款被确认时。
test在 Dashboard 中使用 "Send test event" 时。

在 hub.purchase 和 order.captured 中,请求不携带页面信息:id 和 slug 为空,Aghanim 只会一次性读取您响应中所有区块的商品。请以与展示给玩家时相同的条件返回相同的商品——响应中缺失的商品,或条件不同的商品,都会导致购买失败。

没有页面信息时,Aghanim 无法判断由哪个 Webhook 提供了布局,因此会请求游戏中第一个已启用的 page.get Webhook。如果游戏中存在多个此类 Webhook,校验购买的可能是并未提供该页面的那一个。

有关 page.get 与其他事件类型的关系,请参阅完整的事件与触发器对照表。

Request Schema

下面是一个 page.get Webhook 请求示例:

POST /your/webhook/uri HTTP/1.1
Content-Type: application/json
Host: your-webhook-endpoint.com
User-Agent: Aghanim/0.1.0
X-Aghanim-Signature: 2e45ed4dede5e09506717490655d2f78e96d4261040ef48cc623a780bda38812
X-Aghanim-Signature-Timestamp: 1725548450

{
"event_type": "page.get",
"event_data": {
"player_id": "2D2R-OP3C",
"is_anonymous": false,
"locale": "en",
"id": "pg_2eAeXgQGcaie",
"slug": "daily-offers"
},
"event_time": 1725548450,
"event_id": "whevt_eCacGbJVbvToOgzjXUgOCitkQE",
"idempotency_key": null,
"request_id": "d1593e9c-c291-4004-8846-6679c2e5810b",
"sandbox": false,
"trigger": "hub.page.open",
"transaction_id": "whtx_eCacGbJVbvT",
"context": null,
"game_id": "gm_exTAyxPsVwh"
}

事件 Schema

键名类型描述
event_idstring阿哈利姆生成的唯一事件标识符。
game_idstring您的游戏在阿哈利姆中的唯一标识符。
event_typestring事件的类型, page.get 在此情境下。
event_timenumberThe time the event was sent, in Unix epoch time. May differ across duplicate deliveries of the same event.
event_dataEventData包含事件特定数据的字段,其中可能包含用于继承对象的各种键值。
idempotency_keystring|null即使出现重试情况,也能确保 Webhook 操作只执行一次。 可以是 null 具体取决于事件类型。
request_idstring|null如果事件是通过 API 请求触发的,此字段将包含对应的请求 ID。
sandboxboolean标识事件是否来自沙盒测试环境的指示器。
triggerstring|null触发该事件发送的触发器。
transaction_idstring阿哈利姆生成的交易标识符。在同一交易过程中触发的多个事件可能共享相同的交易 ID。
contextEventContext|null事件的相关上下文信息。

EventContext Schema

键名类型描述
orderOrderContext|null与事件相关的订单信息(如果适用)。
playerPlayerContext|null(可选)玩家信息。如需启用,请在webhook设置中选择“添加玩家上下文”。

EventData Schema

键名类型描述
player_idstring用于玩家身份验证的唯一 玩家 ID。仅在游戏未使用多重身份验证时发送。
playerobject使用多重身份验证时的玩家 ID 组成字段。发送该字段时不发送 player_id。
is_anonymousboolean指示当前用户是否未通过身份验证(匿名)。
localestring当前玩家的区域设置代码(ISO 639-1)。在 Locales 中查找可能的区域设置完整列表。
idstring由 Aghanim 生成的唯一页面 ID。当请求与页面浏览无关时为空。
slugstring玩家请求的页面 slug。当请求与页面浏览无关时为空。

Response Schema

成功处理后,您的服务器应返回 2xx 范围内的状态码以及以下 JSON 数据:

键名类型描述是否必需
blocks[[Block]]自上而下渲染的区块行。最多 50 行,每行最多 10 个区块。是

页面的组成完全由您的服务器控制:blocks 的每个元素为一行,行的顺序以及行内区块的顺序就是玩家看到的顺序。例如,[[ImageBannerBlock], [StoreBlock]] 会在商店上方渲染横幅,而 [[StoreBlock], [ImageBannerBlock]] 会先渲染商店。

支持三种区块类型,通过 block 字段区分:StoreBlock、ImageBannerBlock 和 DailyRewardsBlock。包含其他区块类型的响应将被拒绝,页面会在没有区块的情况下渲染。

StoreBlock Schema

键名类型描述是否必需
blockstring区块类型标识符。必须为 StoreBlock。是
idstring您自己为该区块设置的标识符。否
store_keystring该区块所渲染商店的键。当区块携带 items 时必填。否
items[Item|BundleItem]该区块的商品,格式与 store.get 响应相同。每个区块最多 300 个商品。否

若没有 store_key,该区块将渲染您在 Aghanim 中配置的游戏商店设置。

ImageBannerBlock Schema

键名类型描述是否必需
blockstring区块类型标识符。必须为 ImageBannerBlock。是
image_urlstring横幅图片。是
titlestring显示在横幅上的标题。否
textstring显示在横幅上的文本。否
button_textstring横幅按钮的文本。否
linkstring横幅跳转的路径,相对于 Game Hub 根目录(例如,/store)。否
idstring您自己为该区块设置的标识符。否

请求中包含玩家的 locale,因此图片和文本应直接返回已本地化的内容——玩家看到的就是您响应中的值。

DailyRewardsBlock Schema

键名类型描述是否必填
blockstring区块类型判别字段,必须为 DailyRewardsBlock。是
variantstring区块的渲染布局:expanded、compact 或 compact_mobile,默认为 expanded。否
non_compliancebooleancompact 布局是否使用 non-compliance 按钮,其他布局会忽略该字段。否
idstring您自己为该区块设置的标识符。否

该区块渲染您在 Aghanim 中配置的游戏每日奖励方案。page.get 响应只负责把它放到页面上并决定其外观,奖励内容来自方案本身;若方案由 Webhook 驱动,则来自 daily_reward.get Webhook。

商店商品

在 StoreBlock 中传入 items,即可在一次响应中同时提供布局和商店内容。这些商品会经过与 store.get 商品相同的价格、赠品和购买限制处理,并且 Aghanim 不会再为它们所填充的商店请求 store.get。

每个带 items 的区块都通过 store_key 指定其商店——即 Aghanim Dashboard → Stores → 对应商店 → Settings 中商店的 Key。

商店类型必须通过 Key 旁边的 Type 字段设为 Webhook。类型在创建商店时选定,之后无法更改。创建这类商店时还需要指定一个 store.get Webhook,但当商品随 page.get 一起送达时它不会被调用。

无论区块是否携带商品,store_key 在一次响应的所有商店区块中都必须唯一,因此每个携带商品的区块都需要独立的商店。键重复属于结构错误:整个响应会被拒绝,页面渲染为空。

每个页面最多可有 5 个区块携带商品,"items": [] 同样算作携带商品。

items 的三种状态各不相同:

  • 没有 items 字段——该区块渲染它所指定的商店;未指定时,则渲染游戏中配置的商店内容。Webhook 类型的商店由其自身的 store.get 调用填充。
  • "items": []——商店渲染为空。
  • 非空列表——商店只渲染这些商品。

当 store_key 未匹配到游戏中的任何商店、匹配到已归档或已删除的商店,或匹配到的商店类型不是 Webhook 时,这些商品会被丢弃。区块本身仍会被渲染,并由游戏中配置的商店内容填充。

同一 SKU 若发送到一个页面的两个区块,会在每个区块中各渲染一次,共两次。商品不会跨区块去重。

成功响应示例

{
"blocks": [
[
{
"block": "ImageBannerBlock",
"id": "summer-banner",
"image_url": "https://example.com/summer-sale.png",
"title": "Summer sale",
"link": "/store"
}
],
[
{
"block": "StoreBlock",
"id": "daily-store",
"store_key": "daily-deals",
"items": [
{
"sku": "crystals"
},
{
"sku": "shield",
"start_at": 1630000000,
"end_at": 1635000000
},
{
"sku": "fly_bundle",
"price": 2000,
"name": "Fly Bundle",
"description": "Fly Bundle Description",
"image_url": "https://example.com/fly-bundle.png",
"nested_items": [
{
"sku": "nested_item_sku_1"
},
{
"sku": "nested_item_sku_2",
"quantity": 200
}
]
}
]
}
],
[
{
"block": "StoreBlock",
"id": "regular-store"
}
]
]
}

错误处理

页面接口不会因为该 Webhook 而失败。如果您的服务器超时、返回非 2xx 状态,或返回不符合响应结构的数据,玩家仍会收到页面——但布局为空,本次页面浏览的区块会丢失。投递失败不会重试:布局只在玩家等待页面时才有意义。您可以在 Aghanim Dashboard → Game → Webhooks 的 Webhook 日志中查看请求以及被拒绝的响应。

需要技术支持?
联系我们的集成技术团队: [email protected]