VSCode と Teams Toolkit を使って Microsoft Teams で動くサイコロ Bot を作ろう🎲 

![cover-command-bot-1000x420.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663749/c98a4ffe-51b7-adc2-025d-6b39fd66a3a1.png)

みなさんこんにちは。このチュートリアルでは Teams コマンドボットを構築する方法を実用的な例で説明していきます。ここでは、ユーザーが "dice "というコマンドを送信すると、1から6の間のランダムな数字を返すサイコロボットを作成する予定です。

では、さっそく作ってみましょう。🎲

## 🔧 Setting up

Teams Toolkit を初めて使用する場合は、まずこのチュートリアル、 **[VS Code の拡張機能、Teams Toolkit を使ってマイクロソフト Teams のアプリを開発しよう](https://qiita.com/girlie_mac/items/a6f8afc7b6b955e018e0)** に進み、 **始める前に** と **Teams Toolkit のインストール** に従ってください。チュートリアルは旧バージョンの Toolkit 向けに書かれていますが、初期設定の手順は同じです。

今回はYouTubeの動画を作成しましたのでぜひご覧ください。(英語 / CC有り）

<iframe width="560" height="315" src="https://www.youtube.com/embed/BSxanVdealA" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>


## 🏗 コマンドボットのテンプレートから雛形作成

VS Code の Teams Toolkit 拡張機能 から、**Create a new Teams app** をクリックし、メニューから **Command bot** を選択します。以下のスクリーンショットを参照してください。

![Teams Toolkitのスクリーンショット](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oas3exogr0wloho3j2dv.png)

Teams Toolkit が示す手順に従っていきましょう。言語の選択ではこのチュートリアルでは **JavaScript** を使います。次にアプリに名前を付けます。ここでは "RollADice" と名付けます。

この後、Teams Toolkit が scaffolding を生成します。コード構造を見て回りつつファイルに慣れてください。

## ⌨️ Teams でテンプレートのコードをそのまま動かしてみる 

では、Teams クライアントで scaffold されたコードを実行して、ボットのユーザーエクスペリエンスがどのようになるか見てみましょう。

**Run and Debug** メニューから、**Debug (Edge)** (お好みで Chromeでも構いません) を選択し、**Start debugging** の緑の三角をクリックして実行します。またはキーボードの **F5** キーを押してください。

![Screenshot of Teams Toolkit](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6w5c85266k0rckc9mda3.png)

この間に Teams Toolkit が、前提条件の確認、Azure のプロビジョニングとボットの登録、ローカルサーバーをトンネルするための ngrok の実行など、いくつかの作業をしてくれます。初めて利用する場合は、M365アカウントにサインインするよう求められますのでその際は Toolkitの指示に従がってサインインしてださい。

しばらく時間がかかりますが、それが完了すると、ブラウザ上で Teams クライアントを起動して、その後ボットをインストールするように要求されます。ですので、**Add**をクリックして、ボットをインストールします。

![Screenshot of Teams Toolkit](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ghm7rn8lozfugahoqopj.png)

ボットを追加したら、どのように動作するか試してみてください。下のスクリーンショットのようにコマンドの提案ボックスがポップアップ表示されるのに気づくかと思います。これは、ユーザーに対して、ボットで利用できるコマンドのヒントを示すものです。なのでこれをクリックしてボットにコマンドを送信してみてください。

![Screenshot of the bot running on Teams client](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/azc9cf2eclgoo53zangs.png)

## 🎲 Roll-A-Dice Bot を作成

では、VS Code に戻って、サイコロボットにするためにコードを修正していきましょう。

### 🪄 コマンドサジェスチョンの編集

まずコマンドの提案ボックスの内容を編集するのですが、最終的にこうなるようにコードを編集していきます。

![Teams command bot suggestion](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s0in800sqi2vtxw3tjc5.png)

**templates** > **appPackage** > **manifest.template.json** というファイルに移動してください。

これは、サジェストUIの内容が定義されているファイルです。JSONの中の `commandLists` にある `commands` を探し、タイトルと説明を次のように変更します。

```json
"commands": [
  {
    "title": "dice",
    "description": "Roll a dice!"
  }
]
```
ファイルを保存します。

### 💬 コマンドと返答

次に **bot** > **src** > **helloWorldCommandHandler.js** に行ってください。

`HelloWorldCommandHandler` クラスで、`triggerPatterns` が定義されている行を探し、コマンドを "dice" に編集してください。

```js
triggerPatterns = 'dice';
```
コマンドの大文字小文字を気にする必要はありません。"dice", "Dice", "DICE", "DiCe "のいずれもここでは有効なコマンドとなります。

次にボットの返信メッセージを定義します。`handleCommandReceived` 関数で、乱数を生成してメッセージの内容を作成しましょう。

```js
async handleCommandReceived(context, message) {
  // 1〜6までの乱数を発生させる
  const result = Math.floor(Math.random() * 6) + 1;

  // サイコロの目の画像 (ウィキメディアのクリエイティブ・コモンズの画像を使用)
  const images = [
  'https://upload.wikimedia.org/wikipedia/commons/thumb/6/62/Kismet-Ace.png/240px-Kismet-Ace.png',
 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6d/Kismet-Deuce.png/240px-Kismet-Deuce.png',
 'https://upload.wikimedia.org/wikipedia/commons/thumb/f/f2/Kismet-Trey.png/240px-Kismet-Trey.png',
 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Kismet-Four.png/240px-Kismet-Four.png',
 'https://upload.wikimedia.org/wikipedia/commons/thumb/8/8e/Kismet-Five.png/240px-Kismet-Five.png',
 'https://upload.wikimedia.org/wikipedia/commons/thumb/4/4e/Kismet-Six.png/240px-Kismet-Six.png',
    ];

  // 返信メッセージ - Adaptive Card でレンダリング
    const cardData = {
      title: 'Roll a Dice 🎲',
      body: `You've got ${result}!`,
      thumbnail: images[result - 1],
    };

  return MessageBuilder.attachAdaptiveCard(helloWorldCard, cardData);
  }
```

### 🪪 Adaptive Cards で メッセージ UI を構築

ここでは、返信メッセージに結果とともにサイコロの画像をきれいに表示したいので、[Adaptive Cards](https://adaptivecards.io/?WT.mc_id=m365-81923-timura) を使ってメッセージの UI レイアウトをカスタマイズしていきます。

レイアウトは、**bot** > **src** > **adaptiveCards** > **helloworldCommand.json** にあるファイルに JSON で定義されています。ですが、このファイルは後で見ることにして、とりあえずは JSON を作成するためにビジュアルツールを使用していきましょう。

ではブラウザで、開発者ポータルの [dev.teams.microsoft.com/cards](https://dev.teams.microsoft.com/cards?WT.mc_id=m365-81923-timura) にある **Adaptive Cards Editor** ツールセクションに移動し、 **Create new card** をクリックして新しいカードを作成します。

ここでは、**サムネイルカード**のテンプレートを使用します。プレビューペインで、テンプレート内のボタンとテキストを削除し、サムネイル、タイトル、サブタイトルのみを残して、シンプルなUIを作成します。

![Screenshot of Adaptive Cards Editor](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f7a0ld9laouijznam8hk.png)

ここで行った編集は、以下の通りです。
- テンプレートからボタンとテキストを削除
- サムネイルレイアウトのプロパティのサイズを "medium" に設定
- タイトルをダブルクリックし、変数 "${title}" に変更
- タイトルのスタイルプロパティのウェイトを "bolder " に設定
- サブタイトルを "${body}" に変更

これは一例ですので、みなさんの自由に好きなようにカスタマイズしてください。

さて、生成されたJSONを **helloworldCommand.json** にコピーしてください。

YouTube のチュートリアルでは、[4:46](https://www.youtube.com/watch?v=BSxanVdealA&t=286s?WT.mc_id=m365-81923-timura)からの指示に従ってこのツールの使い方を見ることができます。動画では、ビジュアルツールですべてのプロパティを編集する代わりに、まずJSONをコピー＆ペーストしてからいくつかの内容を手動で修正していますが、どちらの方法でも可能です。

### 🤖 Bot を起動

F5 ツールを使って、Teams クライアントでコードを再度実行し、その動作を確認してみましょう。ボットを追加したら "dice " コマンドを送信してみてください。

![Screenshot of a bot running on Teams](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cr8rsz8van8zb68qm6kx.png)

ボットが正常に動作することを期待します 🎲

## 💡 Hacking it More

さて、Teams のコマンドボットの基本が理解していただけたと思いますので、さらにボットに手を加えてより面白いものにすることを提案します。

先ほど作ったボットは6面体のサイコロで、1から6までの数字しか答えられません。しかし、例えば12面体のサイコロ、20面体の正20面体、1000面体のチラゴン、あるいは任意のn面体サイコロなどをユーザーごとに決められると、もっと面白くなると思うのです。

そこで、このサイコロボットを、コマンドと一緒にパラメータを受け取り、そのパタメータの数字までの乱数を返す様にしてみましょう。例えば `dice 12` というコマンドを受け取った場合、ボットは1から12までの数を返すようにできるように、あるいは `dice 1000` コマンドの場合は 1 から 1000 までの数字を返すようにします。

コードを追加してパラメータを読み取るようにコードを修正してみましょう。

```js
const strs = message.text.split(' ');

const max = strs[1] ? parseInt(strs[1]) : 6;
if (isNaN(max)) {
  return MessageBuilder.attachHeroCard(`Invalid number: ${strs[1]}`);
}
const result = Math.floor(Math.random() * max) + 1;

const cardData = {
  title: `Roll a ${max}-sided dice 🎲`,
  body: `You've got ${result}!`,
};

```

![Screenshot of a bot running on Teams](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/84ayucdz5x9okys43ah8.png)

コマンド候補の UI コンテンツも変更することを忘れないでください。是非、コードをさらに変更し、独自のダイス ボットを作成するための機能を追加してみてください。

いろいろな想像力を働かせて、天気予報ボット、暗号通貨ボット、ダジャレボットなど、何か他のものを構築してみてほしいものです。 アイデアは無限大です。

では、面白いボットを作ったら教えてください！ また次のブログ投稿でお会いしましょう 🤙


---

## Learn more

- 📺 YouTube: [Roll A Dice! - Building a Command Bot for Microsoft Teams Using Team Toolkit v4 with VS Code 🎲](https://youtu.be/BSxanVdealA)
- 📄 Docs: [Teams ツールキットの概要](https://learn.microsoft.com/en-us/microsoftteams/platform/toolkit/teams-toolkit-fundamentals?WT.mc_id=m365-81923-timura)
- 📄 Docs: [Teams の開発者ポータル - Overview](https://learn.microsoft.com/en-us/microsoftteams/platform/concepts/build-and-test/teams-developer-portal?WT.mc_id=m365-81923-timura)
- [Beginners' crash course to build apps for Teams using Teams Toolkit for Visual Studio Code](https://devblogs.microsoft.com/microsoft365dev/beginners-crash-course-to-build-apps-for-teams-using-teams-toolkit-for-visual-studio-code/?WT.mc_id=m365-81923-timura)　(英語）- 同僚の Rabia と Zhidi が Teams Toolkit の新機能とツールがどのように開発体験を簡素化するかについて説明しています