search
LoginSignup
1

More than 1 year has passed since last update.

posted at

updated at

Cisco WebexでQuizを出題する仕組みを作ってみた

この記事はシスコの有志による Cisco Systems Japan Advent Calendar 2020 1枚目の 17日目として投稿しています。

2020年版(1枚目): https://qiita.com/advent-calendar/2020/cisco
2020年版(2枚目): https://qiita.com/advent-calendar/2020/cisco2

以下、昨年までのものです。

2019年版: https://qiita.com/advent-calendar/2019/cisco
2018年版: https://qiita.com/advent-calendar/2018/cisco
2017年版: https://qiita.com/advent-calendar/2017/cisco

はじめに

Cisco Webexで以下のようにQuizを出題するBotアプリケーションを作ってみました。トレーニングやセミナーの中で参加者の理解度を計ったり、レクリエーションに使えるのではないかと思っています:yum:

image.png

Botアプリケーションのデプロイ先はVercel Serverless Functionsにします。

[Vercle] Serverless Functions
https://vercel.com/docs/serverless-functions/introduction

Cisco Webex Botの作り方とBotアプリケーションをVercel Serverless Functionsにデプロイする方法は以下にまとめたので先にご一読ください。

[Qiita] Vercel Serverless FunctionsでCisco Webex Botを作る
https://qiita.com/tetsusat/items/6cd2234fecd5af9441c4

Quizは以下のようなYAML形式のファイルを作成してアプリケーションのビルド時に読み込ませています。

config/quiz.yaml
---
title: CiscoカルトQ
quiz:
  - question: かつてCiscoのCDO(最高開発責任者)を務めたMario MazzolaがCiscoに買収される以前に社長兼CEO務めていた会社は以下のいずれか?
    choices:
      - Kalpana
      - Grand Junction
      - Crescendo Communications
      - Granite Systems
      - StrataCom
    answers: c
...

Botアプリケーションの全体像

Botアプリケーションの全体像を前半と後半に分けてみていきます。

前半はBotにメンションで呼びかけてQuizを出題してくれるまでで、下図の赤枠で囲んだ部分になります。

image.png

このメンションを受けるために、あらかじめ用意しておいたBotのAccess Tokenでメッセージが作成されたときに呼び出されるWebhookを作成します。パラメータは以下のような感じです。

  • name: Webhook for messages(任意)
  • targetUrl: https://{your_app}.vercel.app/api/webhook1
  • resourace: messages
  • event: created
  • filter: mentionedPeople=me

実際にBotを呼びかけるとこのWebhookが呼ばれます。コンテンツの具体例は以下のようになります。

{
  id: 'Y2lzY29zcGFyazovL3VzL1dFQkhPT0svNzYzZTk5ZjAtYzliOS00ZjNhLWIwNjQtMWU2ZTdjOWI2Mjhh',
  name: 'Cult Q message webhook',
  targetUrl: 'https://{your_app}.vercel.app/api/webhook1',
  resource: 'messages',
  event: 'created',
  filter: 'mentionedPeople=Y2lzY29zcGFyazovL3VzL1BFT1BMRS9hYjIwNzljNS00YTUyLTQyMDctODhmNi1iODdmNTAzYzNiYWU',
  orgId: 'Y2lzY29zcGFyazovL3VzL09SR0FOSVpBVElPTi8xZWI2NWZkZi05NjQzLTQxN2YtOTk3NC1hZDcyY2FlMGUxMGY',
  createdBy: 'Y2lzY29zcGFyazovL3VzL1BFT1BMRS9hYjIwNzljNS00YTUyLTQyMDctODhmNi1iODdmNTAzYzNiYWU',
  appId: 'Y2lzY29zcGFyazovL3VzL0FQUExJQ0FUSU9OL0MzMmM4MDc3NDBjNmU3ZGYxMWRhZjE2ZjIyOGRmNjI4YmJjYTQ5YmE1MmZlY2JiMmM3ZDUxNWNiNGEwY2M5MWFh',
  ownedBy: 'creator',
  status: 'active',
  created: '2020-12-01T09:47:12.257Z',
  actorId: 'Y2lzY29zcGFyazovL3VzL1BFT1BMRS82NTc2Njg1YS1hNGE1LTQzMjktYjMwOS1hODEwMjNiNzdmMzk',
  data: {
    id: 'Y2lzY29zcGFyazovL3VzL01FU1NBR0UvNDc3ODYzZTAtM2RkNi0xMWViLTk2NDUtZGZmMzhkNDRlNTli',
    roomId: 'Y2lzY29zcGFyazovL3VzL1JPT00vNmNlMzZiODAtYTFhOC0xMWU2LWFkZDYtMzU1NmUzN2QyNzJj',
    roomType: 'group',
    personId: 'Y2lzY29zcGFyazovL3VzL1BFT1BMRS82NTc2Njg1YS1hNGE1LTQzMjktYjMwOS1hODEwMjNiNzdmMzk',
    personEmail: '<removed>',
    mentionedPeople: [
      'Y2lzY29zcGFyazovL3VzL1BFT1BMRS9hYjIwNzljNS00YTUyLTQyMDctODhmNi1iODdmNTAzYzNiYWU'
    ],
    created: '2020-12-14T06:33:29.630Z'
  }
}

コンテンツの中のdata.idを取り出して、Cisco WebexのAPIを通じてメッセージの詳細を取得します。

メッセージの具体例は以下のようになります。

{
  id: 'Y2lzY29zcGFyazovL3VzL01FU1NBR0UvNDc3ODYzZTAtM2RkNi0xMWViLTk2NDUtZGZmMzhkNDRlNTli',
  roomId: 'Y2lzY29zcGFyazovL3VzL1JPT00vNmNlMzZiODAtYTFhOC0xMWU2LWFkZDYtMzU1NmUzN2QyNzJj',
  roomType: 'group',
  text: 'cultq quiz 1',
  personId: 'Y2lzY29zcGFyazovL3VzL1BFT1BMRS82NTc2Njg1YS1hNGE1LTQzMjktYjMwOS1hODEwMjNiNzdmMzk',
  personEmail: '<removed>',
  html: '<p><spark-mention data-object-type="person" data-object-id="Y2lzY29zcGFyazovL3VzL1BFT1BMRS9hYjIwNzljNS00YTUyLTQyMDctODhmNi1iODdmNTAzYzNiYWU">cultq</spark-mention> quiz 1</p>',
  mentionedPeople: [
    'Y2lzY29zcGFyazovL3VzL1BFT1BMRS9hYjIwNzljNS00YTUyLTQyMDctODhmNi1iODdmNTAzYzNiYWU'
  ],
  created: '2020-12-14T06:33:29.630Z'
}

コンテンツの中のtextcultq quiz 1からクイズIDが分かるので、前述のconfig/quiz.yamlからこれに対応するクイズを見つけます。ちなみに、cultqはBot名なので、登録したBot名に応じてここは変わります。

応答するフォーム形式のメッセージはMessages APIのattachmentsを付与する形で実現します。attachmentsコンテンツはAdaptive Cards仕様を使ってを定義します。

[Cisco WebEx for Developer] Buttons and Cards
https://developer.webex.com/docs/api/guides/cards

Cisco WebexのAPIを通じてメッセージを送信します。送信するルームは前述のWebhookのあったコンテンツの中のroomIdから取得できます。

前半は以上までとなります。

後半はQuizにフォームから回答を選択してSubmitすると回答の正誤に応じてスレッドに返事してくれるまでで、下図の赤枠で囲んだ部分になります。

image.png

ユーザーがフォームをSubmitすることをAttachment Actionと呼びます。クイズの回答内容を取得できるようにAttachment Actionが作成されたときに呼び出されるWebhookを作成します。パラメータは以下のような感じです。

  • name: Webhook for attachment actions(任意)
  • targetUrl: https://{your_app}.vercel.app/api/webhook2
  • resourace: attachmentActions
  • event: created

ユーザーがフォームをSubmitするとこのWebhookが呼ばれます。コンテンツの具体例は以下のようになります。

{
  id: 'Y2lzY29zcGFyazovL3VzL1dFQkhPT0svM2U3Y2YxM2QtZDFlOC00YmEyLTg5MjEtNjg0ZDVhYTAyZjgz',
  name: 'Cult Q attachment webhook',
  targetUrl: 'https://{your_app}.vercel.app/api/webhook2',
  resource: 'attachmentActions',
  event: 'created',
  orgId: 'Y2lzY29zcGFyazovL3VzL09SR0FOSVpBVElPTi8xZWI2NWZkZi05NjQzLTQxN2YtOTk3NC1hZDcyY2FlMGUxMGY',
  createdBy: 'Y2lzY29zcGFyazovL3VzL1BFT1BMRS9hYjIwNzljNS00YTUyLTQyMDctODhmNi1iODdmNTAzYzNiYWU',
  appId: 'Y2lzY29zcGFyazovL3VzL0FQUExJQ0FUSU9OL0MzMmM4MDc3NDBjNmU3ZGYxMWRhZjE2ZjIyOGRmNjI4YmJjYTQ5YmE1MmZlY2JiMmM3ZDUxNWNiNGEwY2M5MWFh',
  ownedBy: 'creator',
  status: 'active',
  created: '2020-12-02T12:05:01.672Z',
  actorId: 'Y2lzY29zcGFyazovL3VzL1BFT1BMRS82NTc2Njg1YS1hNGE1LTQzMjktYjMwOS1hODEwMjNiNzdmMzk',
  data: {
    id: 'Y2lzY29zcGFyazovL3VzL0FUVEFDSE1FTlRfQUNUSU9OLzhhYzc4ZTIwLTNkZGUtMTFlYi05M2FiLWE1Nzk0M2Q3MzRkZg',
    type: 'submit',
    messageId: 'Y2lzY29zcGFyazovL3VzL01FU1NBR0UvNDg4YTIyMDAtM2RkNi0xMWViLTgzOWMtYWZjYjI0YTJiMmZk',
    personId: 'Y2lzY29zcGFyazovL3VzL1BFT1BMRS82NTc2Njg1YS1hNGE1LTQzMjktYjMwOS1hODEwMjNiNzdmMzk',
    roomId: 'Y2lzY29zcGFyazovL3VzL1JPT00vNmNlMzZiODAtYTFhOC0xMWU2LWFkZDYtMzU1NmUzN2QyNzJj',
    created: '2020-12-14T07:32:38.530Z'
  }
}

コンテンツの中のdata.idを取り出して、Cisco WebexのAPIを通じてAttachment Actionの詳細を取得します。

Attachment Actionの具体例は以下のようになります。

{
  id: 'Y2lzY29zcGFyazovL3VzL0FUVEFDSE1FTlRfQUNUSU9OLzhhYzc4ZTIwLTNkZGUtMTFlYi05M2FiLWE1Nzk0M2Q3MzRkZg',
  type: 'submit',
  messageId: 'Y2lzY29zcGFyazovL3VzL01FU1NBR0UvNDg4YTIyMDAtM2RkNi0xMWViLTgzOWMtYWZjYjI0YTJiMmZk',
  inputs: { '1': 'c' },
  personId: 'Y2lzY29zcGFyazovL3VzL1BFT1BMRS82NTc2Njg1YS1hNGE1LTQzMjktYjMwOS1hODEwMjNiNzdmMzk',
  roomId: 'Y2lzY29zcGFyazovL3VzL1JPT00vNmNlMzZiODAtYTFhOC0xMWU2LWFkZDYtMzU1NmUzN2QyNzJj',
  created: '2020-12-14T07:32:38.530Z'
}

コンテンツの中のinputsからユーザーがSubmitしたクイズの番号と回答が分かるので、前述のconfig/quiz.yamlと比較して回答が正誤を確認します。

ちなみ、複数選択可にしておくと、inputs: { '2': 'b,c' }みたいにカンマ区切りになります。

最後に、正誤に応じてCisco WebexのAPIを通じてスレッドとしてメッセージを送信します。直前に取得したAttachment Actionのコンテンツの中のmessageIdのから親コンテンツのidが分かるのでparentIdにこれを指定することでスレッドとしてメッセージを送れます。

成果物

実際のアプリケーションは以下に公開してます。とりあえず動作するプロトタイプ位なイメージでおおらかな気持ちでみていただけると幸いです:sweat_smile:

[GitHub] tetsusat/webex-bot-quiz
https://github.com/tetsusat/webex-bot-quiz

おしまい

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
1