Actions On GoolgeのBrowse Carousel使い方

## これは何？
Actions On GoogleのBrowse Carouselを実装した時の知見です。

## Browse Carouselとは
最近のアップデートでGoogle AssistantのRich responsesにBrowse Carouselというものが追加されました。
[New creative ways to build with Actions on Google | Google Developer](https://developers.googleblog.com/2018/03/new-creative-ways-to-build-with-actions.html)

普通のカルーセルとの違い、カルーセルのタイルをタップすることでWebリンクを表示することができます。
詳しい仕様は公式をドキュメントをご覧ください。
[Browsing carousel | Actioins On Google](https://developers.google.com/actions/assistant/responses#browsing_carousel)

### Client Libraryを最新にする
AoGのNode.js Client Libraryを使う場合はver1.10.0以上にアップデートが必要です。
Client LibraryがBrowseCarouselに対応したのがver1.10.0のためです。
[Release Version 1.10.0 · actions-on-google/actions-on-google-nodejs](https://github.com/actions-on-google/actions-on-google-nodejs/releases/tag/1.10.0)

### 実装例
[askWithCarousel](https://developers.google.com/actions/reference/nodejs/DialogflowApp#askWithCarousel)ではなく、[ask](https://developers.google.com/actions/reference/nodejs/DialogflowApp#ask)でいいみたいです。

```
const response = app.buildRichResponse()
	.addSimpleResponse('Browsing Carouselです');

const carouselResponse = app.buildBrowseCarousel();
			
for (let i = 1; i <= 10; i++ ) {
	carouselResponse.addItems(app.buildBrowseItem()
		.setTitle('Title' + i)
		.setDescription('Description' + i)
		.setImage('https://www.gstatic.com/mobilesdk/170329_assistant/assistant_color_96dp.png', 'Alt-text')
		.setOpenUrlAction('https://www.google.co.jp/'));
}

response.addBrowseCarousel(carouselResponse);
app.ask(response);
```
![BrowseCarousel.png](https://qiita-image-store.s3.amazonaws.com/0/127708/2bfb17be-83a4-c436-fc84-9e882ccd569a.png)


### Tile Consistency
タイルのコンポーネントは以下の要素を設定できますが、 全てのタイルは同じ構成である必要があります。

- Title (required)
- Image (optional)
- Description (optional)
- Footer (optional)

APIから取ってきた値を設定しようとした時に一部の値がなくてそれをそのまま設定してしまうと、以下のようなエラーが発生します。

```
"debugInfo": "expected_inputs[0].input_prompt.rich_initial_prompt.items[1].carousel_browse: 'carousel_browse' requires all items to contain an image or all items to not contain an image.."
```

### tileの数は2~10
カルーセルに設定できるタイルの数は最小2個、最大10個までです。

タイルが1つだけだと、以下のようなエラーが発生します。
表示するアイテムが１つの時はBasicCardを使うのが良いかと思います。

```
"debugInfo": "expected_inputs[0].input_prompt.rich_initial_prompt.items[1].carousel_browse: 'carousel_browse' requires at least 2 items.."
```

### GoogleHomeは非対応
GoogleHomeでBrowse Carouselを含むレスポンスを受け取ると、以下のエラーが発生します。

```
"debugInfo": "expected_inputs[0].input_prompt.rich_initial_prompt: 'carousel_browse' is only supported for clients that support a web browser.."
```

GoogleHomeに向けてレスポンスを送るときはCapabilityをチェックして最適なレスポンスを送るようにする必要があります。
[Response branching](https://developers.google.com/actions/assistant/surface-capabilities#response_branching)
[SurfaceCapabilities](https://developers.google.com/actions/reference/nodejs/AssistantApp#SurfaceCapabilities)

```javascript
// WebURLを開けるSurfaceかどうか判定
let hasWebBroswer = app.hasSurfaceCapability(app.SurfaceCapabilities.WEB_BROWSER);
```

### 補足
debugInfoはSimulatorのDEBUGタブで見れます。便利です。
<img width="679" alt="debuginfo.png" src="https://qiita-image-store.s3.amazonaws.com/0/127708/d3de6960-cbfb-9889-dfbf-5e768df73e5c.png">

###Appendix   
[Class: BrowseCarousel  |  Actions on Google  |  Google Developers](https://developers.google.com/actions/reference/nodejs/BrowseCarousel)
[Actions on Google: Conversation Component Sample](https://github.com/actions-on-google/conversation-components-nodejs)