如何为DialogFlow添加自定义Payload?Angular聊天机器人求助
我来帮你搞定这个需求!要让你的DialogFlow + Angular聊天机器人输出卡片、列表这类富媒体回复,核心就是两步:在DialogFlow里配置自定义Payload,然后在Angular前端解析并渲染这些内容。下面一步步来实操:
第一步:在DialogFlow中配置自定义Payload
当你创建或编辑意图时,切换到「响应」标签页,点击「添加响应」,选择「自定义Payload」。这里我们可以用类似Messenger的模板格式来定义卡片、列表结构,举两个常用例子:
卡片模板示例
直接在Payload编辑器里输入以下JSON(可根据需求调整字段):
{ "richContent": [ [ { "type": "card", "title": "产品详情", "subtitle": "智能手表", "image": { "src": "https://example.com/watch.jpg" }, "actionLink": "https://example.com/product/123" } ] ] }
列表模板示例
如果要返回列表样式,用这个结构:
{ "richContent": [ [ { "type": "list", "title": "推荐产品", "items": [ { "title": "智能手表", "subtitle": "续航7天", "actionLink": "https://example.com/product/123" }, { "title": "无线耳机", "subtitle": "主动降噪", "actionLink": "https://example.com/product/456" } ] } ] ] }
小贴士:你可以根据需要扩展字段,比如添加按钮、调整样式字段,只要保持结构清晰,方便前端解析就行。
第二步:Angular前端解析并渲染Payload
假设你已经有了和DialogFlow通信的服务,接下来要处理返回的响应数据,并渲染对应的富媒体组件。
1. 解析响应中的Payload
在聊天服务里,获取DialogFlow返回的fulfillmentMessages,从中提取自定义Payload:
// chat.service.ts import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { map } from 'rxjs/operators'; @Injectable({ providedIn: 'root' }) export class ChatService { constructor(private http: HttpClient) {} sendMessage(message: string) { return this.http.post<any>('YOUR_DIALOGFLOW_WEBHOOK_URL', { queryInput: { text: { text: message, languageCode: 'zh-CN' } } }).pipe( map(response => { // 提取自定义Payload const fulfillmentMessages = response.queryResult.fulfillmentMessages; const customPayload = fulfillmentMessages.find(msg => msg.payload); return customPayload ? customPayload.payload : null; }) ); } }
2. 组件中添加渲染逻辑
在聊天组件里,调用服务获取Payload,然后根据类型渲染不同的UI:
// chat.component.ts import { Component } from '@angular/core'; import { ChatService } from './chat.service'; @Component({ selector: 'app-chat', templateUrl: './chat.component.html' }) export class ChatComponent { messages: any[] = []; constructor(private chatService: ChatService) {} sendMessage(input: string) { if (!input.trim()) return; this.messages.push({ type: 'user', text: input }); this.chatService.sendMessage(input).subscribe(payload => { if (payload?.richContent) { this.messages.push({ type: 'bot', payload: payload.richContent[0][0] }); } else { // 无Payload时返回普通文本 this.messages.push({ type: 'bot', text: '暂无相关内容哦' }); } }); } }
3. HTML模板渲染富媒体
在组件HTML里,用*ngSwitch区分不同Payload类型,渲染卡片或列表:
<!-- chat.component.html --> <div class="chat-container"> <div *ngFor="let msg of messages" class="message-row"> <div [ngClass]="msg.type === 'user' ? 'user-message' : 'bot-message'"> <ng-container *ngIf="msg.type === 'user'"> {{ msg.text }} </ng-container> <ng-container *ngIf="msg.type === 'bot'"> <div *ngIf="msg.payload" [ngSwitch]="msg.payload.type"> <!-- 卡片渲染 --> <div *ngSwitchCase="'card'" class="card"> <img [src]="msg.payload.image.src" alt="卡片图片"> <div class="card-content"> <h3>{{ msg.payload.title }}</h3> <p>{{ msg.payload.subtitle }}</p> <a [href]="msg.payload.actionLink" target="_blank">查看详情</a> </div> </div> <!-- 列表渲染 --> <div *ngSwitchCase="'list'" class="list"> <h3>{{ msg.payload.title }}</h3> <ul> <li *ngFor="let item of msg.payload.items"> <a [href]="item.actionLink" target="_blank"> <h4>{{ item.title }}</h4> <p>{{ item.subtitle }}</p> </a> </li> </ul> </div> <!-- 默认文本 --> <div *ngSwitchDefault>{{ msg.text }}</div> </div> <div *ngIf="!msg.payload">{{ msg.text }}</div> </ng-container> </div> </div> <div class="input-area"> <input #messageInput type="text" placeholder="输入消息..."> <button (click)="sendMessage(messageInput.value); messageInput.value = '';">发送</button> </div> </div>
4. 添加基础样式(可选)
给卡片和列表加些样式,贴近Messenger风格:
/* chat.component.css */ .card { border: 1px solid #eee; border-radius: 8px; max-width: 300px; overflow: hidden; } .card img { width: 100%; height: 180px; object-fit: cover; } .card-content { padding: 12px; } .card-content h3 { margin: 0 0 8px; font-size: 16px; } .card-content p { margin: 0 0 12px; color: #666; font-size: 14px; } .card-content a { color: #1877f2; text-decoration: none; } .list { max-width: 300px; border: 1px solid #eee; border-radius: 8px; padding: 12px; } .list h3 { margin: 0 0 12px; font-size: 16px; } .list ul { list-style: none; padding: 0; margin: 0; } .list li { padding: 8px 0; border-bottom: 1px solid #eee; } .list li:last-child { border-bottom: none; } .list li a { color: #000; text-decoration: none; } .list li h4 { margin: 0 0 4px; font-size: 14px; } .list li p { margin: 0; color: #666; font-size: 12px; } .bot-message { background-color: #f0f2f5; border-radius: 18px; padding: 8px 12px; margin: 8px 0; max-width: 70%; align-self: flex-start; } .user-message { background-color: #1877f2; color: white; border-radius: 18px; padding: 8px 12px; margin: 8px 0; max-width: 70%; align-self: flex-end; } .chat-container { display: flex; flex-direction: column; max-width: 500px; margin: 20px auto; height: 600px; overflow-y: auto; padding: 10px; border: 1px solid #eee; border-radius: 8px; } .input-area { display: flex; gap: 8px; margin-top: 10px; } .input-area input { flex: 1; padding: 8px 12px; border: 1px solid #eee; border-radius: 20px; } .input-area button { padding: 8px 16px; background-color: #1877f2; color: white; border: none; border-radius: 20px; cursor: pointer; }
一些注意事项
- 测试时先在DialogFlow模拟器里发送消息,确认自定义Payload是否正确返回,再到Angular里调试。
- 如果你用的是DialogFlow CX,配置Payload的位置略有不同,但核心逻辑一致——在意图的响应中添加自定义Payload。
- 可以根据需求扩展更多富媒体类型,比如按钮模板、轮播卡片等,只要在Payload里定义对应的
type和字段,前端对应渲染即可。
内容的提问来源于stack exchange,提问作者jerome
相关产品推荐
相关产品推荐

