himanago

Azure・C#などのMS系技術やLINE関連技術など、好きな技術について書くブログ

Microsoft Teams のチームで同じファイルフォルダを参照するチャネルを複数つくる裏技

はじめに

Microsoft Teams のチームコラボレーション機能便利ですよね。

今回はそれにまつわる裏技をたまたまみつけたので紹介します。

なんと、この裏技を使うと同じファイルフォルダを参照するチャネルを複数つくることができます。

手順

さっそくやってみます。名前などは例なので、実際試す際はお好きなものに変えてください。

1. 「共有されるフォルダ」という名前のチャネルを作成

f:id:himanago:20210706013313p:plain

2. チャネルの名前を「フォルダを共有するチャネルA」に変更

f:id:himanago:20210706013344p:plain

3. 新たにもう一つ「共有されるフォルダ」という名前のチャネルを作成

f:id:himanago:20210706013418p:plain

4. あとからつくったチャネルの名前を「フォルダを共有するチャネルB」に変更

f:id:himanago:20210706013455p:plain

これだけです!

結果

同じフォルダを参照するチャネルが複数できている!

「フォルダを共有するチャネルA」
f:id:himanago:20210706013854p:plain

「フォルダを共有するチャネルB」
f:id:himanago:20210706013916p:plain

片方にファイルをアップすると、もう片方にも同じファイルが!

解説

なぜこうなるのかを簡単に解説していきます。

Teams のチームではトピックごとに「チャネル」を作って会話、ファイル共有ができますが、チャネルで共有されるファイルの置き場の実体は SharePoint にあります(「SharePoint で開く」から見れます)。

f:id:himanago:20210706014117p:plain

f:id:himanago:20210706014325p:plain

このフォルダ、チャネル作成時にチャネル名と同じ名前で SharePoint に作られるんですが、その後チャネル名を変更してもフォルダ名はまったく変わりません。

これがけっこう不便で、チャネル名とフォルダ名が一致しなくて直接アプリなどから保存するときに迷ったり、仮で作ってしまったチャネル名が残り続ける…なんてことがあります。

どうも「○○」という名前のチャネル作成したときに、「このチャネルは SharePoint 上の○○という名前のフォルダをファイルタブに表示する」という紐付けが決まる動きになっていて、チャネル名を変えようとフォルダ名を変えようと何をしても変わらないようなのです。

そのため、SharePoint 上で「○○フォルダ」を削除したりフォルダ名を変更したりするとチャネルのファイルタブが参照できなくなり、もう一度「○○フォルダ」を作ると、ちゃんと作成時に「○○」という名前だったチャネルに紐づいてくれます。

この性質を利用したのが今回の裏技。

作成時に「共有されるフォルダ」という名前だったチャネルを複数つくることで、SharePoint 上の同じフォルダ「共有されるフォルダ」を参照してくれるようになります。

作成時の名前の重複チェックはしていないため、こういった状態を作り出すことが可能なんですね。

おわりに

会話場所は分けたいけどファイルは分散させたくない…というチャネルを作りたくなることは意外とあるのでは?と思うので、そういう場面で試してみるとよいかもです。

SharePoint 側との紐付けの仕様が変わらない限りはこのままな動きが続くかなとは思っていますが、もしバグとして修正された場合にこの方法で作ったフォルダ・チャネルがどうなるかはわからないので、試す際は自己責任でお願いします。

Java 系 Web アプリの移行先としての Azure Static Web Apps + Micronaut for Azure Functions その 1

はじめに

Java 系 の Web アプリケーションを Azure で動かしたいと考えたとき、Web Apps や Azure Spring Cloud を使ってそのまま動かすのもありですが、最近 GA した Azure Static Web Apps を使ってよりサーバーレスにもっていけたりしないかな?と考えてみています。

Static Web Apps は Angular / React / Vue などで作ったシングルページアプリケーションのデプロイに最適なサービスで、静的サイトのホスティング + Azure Functions によるバックエンド API のセットで構成されています。

しかしこのバックエンド API、通常は Static Web Apps 専用の Functions が裏に用意されるのですが、現状 JS / C# / Python しかサポートされていません。

docs.microsoft.com

しかし、GA された Static Web Apps には、有料のスタンダードプランで使うことのできる「Bring your own functions」機能があり、これなら別途用意した Azure Functions をバックエンド API としてつなぐことができるため、Java の Azure Functions を使うことができます。

docs.microsoft.com

これを使って別途 Functions で作成した Java ベースなバックエンドを Static Web App につないでしまおうという寸法ですが、既存の Java のバックエンドのコードをどれだけ Functions に流用できるかが勝負です。

この流用をしやすくするために、Micronaut というマイクロサービスフレームワークが適しているのではないか?と考えています。

ちょうど業務のほうでも、以前から Azure 上で Grails 1 の Web アプリケーションを運用していて、もろもろのコストを考えてもう少しサーバーレスなかたちに移行したいと考えていたので、それを想定しつつ Java 系 Web アプリの移行先としての Azure Static Web Apps + Micronaut for Azure Functions を考えてみたいと思います。

なお、フロントエンドは Vue.js を使っていきます(これしかまともに書けない…)。

Micronaut とは

JVM ベースのマイクロサービス開発向けフレームワークです。

前にも少し紹介させていただきましたが、Azure Functions を公式にサポートしていて、Micronaut フレームワークを使って Function App の開発ができます。

himanago.hatenablog.com

Micronaut の利点としては、

  • Java/Kotlin/Groovy といった JVM 言語のメジャーどころが選べる
  • DI サポート
  • (DI を使っても)起動が高速

というのが挙げられます。

今回は Grails からの移行ということで、同じ Groovy 言語が使える、DI があるので移行元で使っていたサービスクラスをそのまま流用できるなどの利点が見込めそうです(これがこの構成をとるいちばんの理由)。

ローカルでの環境構築・開発

ということで、ローカルに環境を作って動かすところまでやってみます。

今回は Mac 想定で進めるので、Windows だと多少コマンドなど異なるかもしれません。そのあたりはご注意ください。

今回の検証環境:

  • OS: macOS Catalina 10.15.7
  • JDK: 8.0.292-zulu
  • Micronaut: 2.5.7

開発環境構築

まずは以下をいれておきます。

VS Code拡張機能

エディターは VS Code を使います。

以下の拡張機能を入れておきます。

SDKMAN!

Java や Groovy、Micronaut などをインストール・アップデートできる SDK マネージャーです。

Home - SDKMAN! the Software Development Kit Manager

未インストールであれば

curl -s "https://get.sdkman.io" | bash

でインストールし、インストール済みであれば以下で更新しておきます。

sdk update

JDK

Java 8 を使う必要があるので、JDK 8 を入れておきます。

sdk install java 8.0.292-zulu
sdk default  java 8.0.292-zulu

java -version して入れた JDK が出てくるようになっていれば OK です。

SDKMAN ではなくインストーラー経由で別バージョンの JDK を入れている場合はなおすのがちょっと面倒かもしれませんので、JDK は SDKMAN で管理するように切り替えておくとよいでしょう。

Micronaut

続いて Micronaut の本体です。

sdk install micronaut

vue-cli

Vue.js 開発用。Vue を使わない場合は当然不要です。

npm install -g @vue/cli

Static Web Apps CLI

ローカルで Static Web Apps を動かしたりできる CLI ツールです。

npm install -g @azure/static-web-apps-cli

とりあえず、使うツールは以上です。

フロントエンド(Vue.js)プロジェクトの作成

適当なフォルダに、Vue.js のアプリをつくります。ターミナルから

vue create static-web-app-micronaut-sample

を実行します。

Manually select features で、今回はこんなかんじにしておきます(このあたりはなんでもよいはず)。

? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, Router
? Choose a version of Vue.js that you want to start the project with 2.x
? Use history mode for router? (Requires proper server setup for index fallback in production) Yes
? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files

できあがったら、 cd して code を開きます。

cd static-web-app-micronaut-sample/
code .

ここから先は VS Code で作業です。

バックエンド(Micronaut)プロジェクトの作成

フロントエンドの Vue のプロジェクトを VS Code で開いたところですが、ここでバックエンドのプロジェクトを作成します。

フロントエンドとバックエンドは同一リポジトリにあげる monorepo で運用すると楽なので、Vue のプロジェクトのフォルダ内に Micronaut のプロジェクトを作っていきます。

VS Code のターミナルから、以下のコマンドを実行します。

mn create-function-app --build=gradle --jdk=8 --lang=groovy --test=spock --features=azure-function com.example.swa.api

パッケージ名とかは適当ですが、最後の api という部分が生成されるフォルダ名になるので、バックエンド・API あることがわかりやすい名前にしておくとよいでしょう。

ほぼ Java の簡易版なコード & Grails からの移行を見越している、ということでここでは言語を Groovy にしていますが、もちろん Java でも Kotlin でも大丈夫です。

ちなみに、上記のコマンドはこちらのサイトで生成可能です。

micronaut.io

使いたい機能を選択すると、オプションつきのコマンド文字列が得られます。ひながたを ZIP で落とすことも可能。

では、少し実装をいじっていきます。

GreetingService.groovy

DI を試したいので、簡単なサービスクラスを作っておきます。

package com.example.swa.services

import javax.inject.Singleton

@Singleton
class GreetingService {
    String greet(String name) {
        "Hello, ${name}!"
    }
}

Function.groovy

ひながたにある Function.groovy をそのまま使って、DI によるサービスクラスの利用をやってみます。

package com.example.swa

import com.microsoft.azure.functions.HttpStatus
import com.microsoft.azure.functions.ExecutionContext
import com.microsoft.azure.functions.HttpRequestMessage
import com.microsoft.azure.functions.HttpMethod
import com.microsoft.azure.functions.HttpResponseMessage
import com.microsoft.azure.functions.annotation.AuthorizationLevel
import com.microsoft.azure.functions.annotation.FunctionName
import com.microsoft.azure.functions.annotation.HttpTrigger
import com.example.swa.services.GreetingService
import io.micronaut.azure.function.AzureFunction
import java.util.Optional
import javax.inject.Inject

public class Function extends AzureFunction {
    @Inject
    GreetingService service

    @FunctionName("HttpTrigger")
    public HttpResponseMessage hello(
            @HttpTrigger(
                    name = "req",
                    methods = [HttpMethod.GET],
                    authLevel = AuthorizationLevel.ANONYMOUS)
                    HttpRequestMessage<Optional<String>> request,
            ExecutionContext context) {

            String message = service.greet("sample")

            request.createResponseBuilder(HttpStatus.OK).body(message).build()
    }
}

クラスの先頭で GreetingService を DI しているだけのシンプルな処理で、これを HttpTrigger という名前の関数にしています。

HelloWorld.vue

Vue.js で最初から作られている src/components/HelloWorld.vue に以下のような処理を追記します。

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <p>from api: {{ apiMessage }}</p>
  <!-- 中略 -->
</template>

<script>
import axios from 'axios'

export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  data: () => {
    return {
      apiMessage: ''
    }
  },
  created: function() {
    axios.get('/api/HttpTrigger')
      .then(response => {
        console.log(response.data);
        this.apiMessage = response.data;
      }).catch(err => {
        console.log(err.response);
        this.apiMessage = err.response.statusText;
      });
  }
}
</script>
<!-- 以下略 -->

axios を使って /api/HttpTrigger を叩いて、返ってきた内容を画面に表示させています。

npm install axios しておきましょう。

Static Web Apps のいいところのひとつが、こうやってフロントエンドと同一のルートからのパスで API が叩けるところですね。

ローカルでの実行

ここまできたら実行してみましょう。

コマンドから、まずはフロントエンドとバックエンドを VS Code でそれぞれ別のターミナルから立ち上げます。

フロントエンド(Vue.js)

npm run serve

バックエンド(Micronaut)

ターミナルをもうひとつ開き、以下のコマンドを実行します。

cd api
./gradlew clean azureFunctionsRun

Static Web App としての実行

SWA CLI の機能で、同一のルートにフロントエンドもバックエンドも配置されている状況を再現できます。

さらにターミナルを立ち上げて、以下のコマンドを実行します。

swa start http://localhost:8080/ --api http://localhost:7071

するとこのように、Static Web Apps 同様、同一の URL にフロントエンドもバックエンドもあるような状態をローカルでエミュレートしてくれます。

f:id:himanago:20210705010139p:plain

表示された URL にアクセスすると、このように表示されます。

f:id:himanago:20210705010434p:plain

ちゃんと Micronaut の API も呼んでくれているのがわかりますね。

まとめ

Micronaut 自体がおもしろいフレームワークですが、Azure Static Web Apps との組み合わせもなかなか強力そうな予感がしています!

今回はとりあえずローカル実行するところまで書いてみましたが、長くなりそうなので続きは別記事にしていきたいと思います。

このあとは、

  • Azure AD の適用
  • Azure へのデプロイ
  • CI/CD まわり

あたりを検証していこうかなと思っています。


  1. GrailsJVM 言語の Groovy ベースの Web アプリケーションフレームワークで、いってしまえば Java 系です。

Microsoft MVP for Microsoft Azure を再受賞しました

遅ればせながらですが、2021 年 7 月 1 日 にMicrosoft MVP for Microsoft Azure を再受賞しました。

2019 年 11 月に初受賞だったのでもうすぐ 2 年経つのですが、更新は初となります。

mvp.microsoft.com

受賞後すぐにコロナ禍となり思うようにコミュニティ活動に参加できなくなり、それと相まって MVP としてどんな活動をしたらいいのか迷ってしまいほとんど何もできない日々が続いてしまっていました(正直、更新辞退もよぎりました)。

でも、Microsoft MVP は「Microsoft の技術を好きな人が、自分の好きな技術を広める活動をしたことに対する Microsoft からの感謝の表彰(サンキューアワード)」。

その原点に立ち返って、好きなものをたくさん触ってたくさん発信する活動をしていけばいいのかな、と思っています。

自分が好きなのはやっぱり Azure のサービス同士や他のサービスとの組み合わせなので、そこは変わらず、これからまたどんどん試して発信していきたいと思います。

今後とも、どうぞよろしくお願いいたします。

2021年前半のLINE系登壇振り返り(DurableBotEngineとかセキュリティとか)

はじめに

だいぶご無沙汰です。

去年のおわりごろから本業が忙しかった&コロナ禍でプライベートな時間があまり作れず、なかなか勉強会にも参加できない・アウトプットできない日々が続いておりました。

それでも LINE Developer Community 中心に登壇等々でお声がけいただいて、なんとかコミュニティ活動を続けてこれました(ありがとうございます)。

今回は、登壇して資料公開だけして終わっていたものを、まとめて載せておきます。

2/27 [ビジュアルプログラミング] LINE × Azureハンズオン!(AIも活用したゲームを作ろう)

イベントページ

linedevelopercommunity.connpass.com

Logic Apps と Cognitive Services を組み合わせた LINE Bot 開発のハンズオンで、Logic Apps の簡単な事前説明を担当させていただきました。

スライド

www.slideshare.net

コメント

Logic Apps はコーディングなしで作れる強みと、サービス同士を簡単につなげてしまう強みはやっぱり大きいです。

LINE Bot との組み合わせは、手軽な Bot をつくるなら十分選択肢になるのではないかな、と思います。

ハンズオンや学習のテーマとしてもちょうどよいですね。

3/17 第5回 LINE Bot・ミニアプリ自慢LT大会

イベントページ

linedevelopercommunity.connpass.com

スライド

www.slideshare.net

アーカイブ

youtu.be

38:00 あたりから。

コメント

実験的ではあるのですが、Durable Functions のステート管理を利用して Bot のマルチターンな対話コンテキスト管理をする C#フレームワーク「DurableBotEngine」なるものを作ってみたので、その紹介です。

詳細な使い方など、少し機能を整備したあとに公開しようと思っているのですが、なかなか手が回らず…(近々ブログにまとめるとスライドに書いてたのに…)。

コードは以下に置いてあって、NuGet からも落とせます。

GitHub - himanago/DurableBotEngine

現状 LINE Messaging API 専用なのですが、他のチャットボットにも展開できたらなあとも思っています。

5/7 Azureの進化でさらに捗るLINE開発!Ignite Recap for Build onLINE

イベントページ

linedevelopercommunity.connpass.com

スライド

www.slideshare.net

アーカイブ

youtu.be

55:45あたりから。最後に登壇者全員でトークもしました。

コメント

LINE「Bot」のセキュリティを考えたいねという問題提起です。LINE そのもののセキュリティに言及されることはけっこう多いですが、Bot のほうもきちんとセキュリティを考えないといけないです。

プロフィール情報やトークの送信内容は Bot サーバーでそのまま見ることができるし、グループに Bot を追加すればグループ内のトークBot 側に筒抜け。

個人情報のことをきちんと考えているか怪しい LINE Bot はつかわないほうがよいですし、Bot 開発者・運用者としてはそのように怪しまれないようきちんと個人情報管理を行い、LINE のガイドラインに従いつつプライバシーポリシーなどを作る必要があると思います。

また、不要な個人情報はとらない・残さない。使いたいなら利用範囲を明示してきちんとユーザーの同意を得るようなフローにするとよいでしょう。

手軽に開発・運用・利用できてしまう LINE Bot だからこそ、このあたりが軽視されがちがな?と思っての発表でした。

番外編:LINE API Use Case

こちらのサイトの、「お店の予約」「テーブルオーダー」「会員証」のユースケースについて、Azure のシステム図・シーケンス図(の元ネタ)を書かせていただきました。

lineapiusecase.com

もともとは、勝手に AWS 版の図を真似して作ったのを拾ってもらったのがきっかけでした(以下イベントで発表)。

イベントページ(2020/12/11 MS Tech Camp #3)

mspjp.connpass.com

スライド

www.slideshare.net

コメント

もともとの登壇資料には、本家サイトに採用されなかった自治体の構成図も載せてます(実はこれが自分的には気に入ってたりするんだけど)。

Azure Static Web Apps が最近 GA して、この構成もとりやすくなった気がしています(特に、Bring your own functions が大きい)。

おわりに

今年の前半戦を振り返ってみるとこれだけでしたが、7月からの後半戦は、もうちょっと積極的に動いていけそうかな…と見込んでます。

やりたいこともわりとたくさんあるし、いろいろ進めているものもあるので、すこしずつ、アウトプットしてゆこうと思います。

LPF REV UP 2020「あなたならどう使う?最新Azureレシピ for LINE Platform」フォローアップ(後半)

はじめに

年が明けて 2021年となりはや1ヶ月。。

年を跨ぎつつまたもや間が空いてしまいましたが、REV UP 2020 でのセッション内容の振り返り後半を書いていきます。
※前半はこちら

f:id:himanago:20201231154120p:plain

Azure × Messaging API(サブ編)

前回は「メイン編」と称して LINE Bot のバックエンドとして使えるサービスを紹介しましたが、「サブ編」ではそれと組み合わせると便利な Azure サービスを紹介します。組み合わせて使うものということで、具体的なレシピも多めに紹介していきます。

Azure Cosmos DB

まずは Azure における NoSQL データベース、Cosmos DB です。

f:id:himanago:20201231022131p:plain

無料枠ができ俄然使いやすくなった Cosmos DB は、小規模サービスとして開発することも多い LINE Bot でも特におすすめできるようになりました(もちろん、登場当初と同じように惑星規模のサービスにも対応できます)。

f:id:himanago:20210129002954p:plain

Cosmos DB の便利な機能は Change Feed(変更フィード)です。Cosmos DB のコレクションへデータ追加・変更があったことを検知し、Azure Functions などにつなげることができます。

docs.microsoft.com

これを利用することで CQRS パターン(コマンド・クエリ責任分離)が実装でき、特に LINE Bot においてはデータの変更をトリガーとして Bot から Push メッセージを送信したり、逆に Bot の操作によって起きたデータの変更を別のアプリ・サービスに通知することができます。

もちろんデータ操作とその結果通知は同一の処理で行っても良いですが、サーバーレス・イベント駆動なアーキテクチャでシステムを組む場合は、データ操作と通知を別々の処理として実装しておくことで、それぞれの処理がシンプルになりつつそれぞれ独立したスケールが可能となります。

docs.microsoft.com

レシピ:リッチメニューの切り替え

Change Feed を使った LINE Bot レシピをひとつ紹介です。

f:id:himanago:20201231022151p:plain

Messaging API ではリッチメニューをユーザーごとに動的に切り替えることのできる API が用意されていますが、Bot を利用している中で、ユーザーの状態に応じてリッチメニューを切り替えたいというケースです。

そのリッチメニューの切り替えを、ユーザーによる Bot の利用によるデータの更新(Bot のメインの処理)と、その結果に応じたリッチメニューの切り替えを分けて実装します。

リッチメニューの切り替えはデータ更新をトリガーとして動く関数(Change Feed によって起動する Cosmos DB トリガーの Azure Functions)とすることで、作りがシンプルになりながら、処理がお互い依存しなくなるため拡張性も高くなります(たとえば、システム管理機能や別の Web アプリなどをユーザーの Bot 利用以外でデータが更新されたときにも、同じリッチメニュー切り替え処理が動いてくれる)。

Azure SignalR Service

つづいては SignalR Service です。

f:id:himanago:20201231022158p:plain

こちらは Web ページなどのクライアントに対してサーバー側の変更を通知しリアルタイム更新を促すためのしくみを提供するサービスで、直接 LINE Bot に対して何かできるわけではありません。

ですが、Azure Functions・Cosmos DB とセットで使うと簡単におもしろいことができます。

f:id:himanago:20201231022205p:plain

SignalR Service は Functions と統合されており、「出力バインディング」によって少ないコードでクライアントへのリアルタイム通知処理が実現できます。

docs.microsoft.com

さらに Cosmos DB の変更フィード(Change Feed)と組み合わせれば、データの変更をクライアントにリアルタイムで通知する処理がとても手軽に実現できます。

これによって、たとえば LINE Bot を入力・Webページを出力とするようなシステムが本当に簡単に構築できます。

レシピ:LINE Botからのメッセージをリアルタイム表示

f:id:himanago:20201231022218p:plain

それがこちら。

Bot からのメッセージをリアルタイムに表示する Web ページを簡単に開発できるのですが、以前公開したハンズオンがまさにこの構成なので、まだこの構成を試したことがない方は、ぜひつながっていく感動を味わってほしいです。

github.com

Azure Cognitive Services

続いて Azure Cognitive Services です。

f:id:himanago:20201231022501p:plain

これはコグニティブ機能を実現する「AI パーツ」ということで、REST API やクライアント SDK から簡単に利用できるもので、ちょっと AI っぽい処理を追加したいな、というときにオススメのものになります。

QnA Maker

f:id:himanago:20201231022452p:plain

特に LINE Bot にオススメなのは、QnA Maker です。事前に用意したナレッジベースを元に、ユーザーからの質問に回答する AI を作成することができるものになります。

ナレッジベースは FAQ ページ等から自動生成して、さらにそこからカスタマイズしていくこともできます。

docs.microsoft.com

LUIS

f:id:himanago:20201231022515p:plain

Bot でよく使うのは、自然言語処理の LUIS(Language Understanding)です。

サンプルの文章を登録して、そのインテント(意図)とエンティティ(文章中の、パラメータ的な意味のある要素)を指定して、自然言語のテキストを理解できるようにするものになります。

これを使うことで自然な会話ができる Bot を作ることができます。Bot Service / Bot Framework Composer の裏でも LUIS が使われているので、Azure における Bot 開発では合わせて使うことが多いものになります。

docs.microsoft.com

Computer Vision

続いて画像系のサービスですが、LINE Bot のある機能と相性がいい Computer Vision を紹介します。

docs.microsoft.com

f:id:himanago:20201231022521p:plain

Computer Vision は画像分析に関する機能を提供するサービスですが、この中に「サムネイル生成」の API があります。

大きな画像を投げると、そこから重要な部分(関心領域)を残してトリミングをして小さいサイズの画像作ってくれます。

docs.microsoft.com

LINE Bot で画像メッセージを送るとき、オリジナル画像と小さいサイズのサムネイル用のプレビュー画像の2つを指定しますよね。このプレビュー用画像を生成するのに、この機能がぴったりなんです。

Azure Blob Storage

続いて Blob Storage です。

f:id:himanago:20201231022538p:plain

ひとつ前に紹介した画像メッセージにも絡みますが、Blob Storage が静的リソースの置き場に適しています。

docs.microsoft.com

f:id:himanago:20201231022548p:plain

LINE Bot の画像メッセージや動画メッセージなどでどのデータを送るか指定する際には、その URL を指定します。

任意の画像を用意し、その URL を得る 1 番簡単な方法は、Blob Storage に画像を置き、パブリックアクセスを許可する設定にすることです。

公開 URL が1つ1つのファイルに対して得られるので、それを LINE Bot で送ってやればよいです。

しかし、問答無用で公開する設定にするのが憚られる場面もあるでしょう。一つのファイルの URL から、同じストレージ上の別ファイルの URL を推測されてしまう危険性もあります。

こういった危険を避けるための方法として紹介したいのが、SAS トークンを使ったセキュア運用です。

f:id:himanago:20201231022557p:plain

SAS(Shared Access Signatures)で Azure Storage のへのアクセス制限をかけることができ、リクエストの有効性を確認する「SAS トークン」をBlob単位・アクセス単位で生成し、URL に付与することで Blob コンテナーのパブリックアクセスレベルを「プライベート」のまま、SAS トークン入りの URL を知っている人のみにアクセスできるようにすることができます。

docs.microsoft.com

こちらに関しては、以前に記事を書いたのであわせてみていただけたらと思います。

himanago.hatenablog.com

コンテナのパブリックアクセスレベルが匿名アクセスできないような形になっていても、このトークンつきの URL からならアクセスできるので、LINE Bot で画像等を送信する時にこのトークンを発行して、そのURLを送ってあげると、よりセキュアに運用できるんじゃないかな、ということでぜひ使ってみてほしい機能です。

レシピ:画像メッセージ用リソースの作成

Computer Vision を活用したレシピです。

f:id:himanago:20201231022609p:plain

サムネイル画像を Logic App で作成するような連携処理を組むことで、LINE Bot で使用するリソースを効率よく作ることができます。

…と思ってスライドを作ったんですが、 「Blob に画像を置いたらサムネイルが自動で作られる」というふうに Logic App でフローを組むほうが手軽かつ便利そうです(そのうち記事を書きます)。

Azure × LIFF/ミニアプリ

概要

f:id:himanago:20201231023224p:plain

LIFF と Azure の組み合わせについては、そもそも LIFF が Web アプリになりますので、通常の動的な Web アプリであれば、Web Apps で全然開発が可能です。

認証の統合ができるようになっているので、Azure AD B2C で LINE ログインと連携したものを組み込むことで、LIFF アプリとしていい感じに動くので便利です。

docs.microsoft.com

Azure AD B2C

f:id:himanago:20201231023253p:plain

Azure AD B2C では、外部の ID プロバイダーとの連携を Azure に組み込むためのものですが、LINE ログインも「カスタムポリシー」を作成すれば実現可能になっています。

カスタムポリシーの作成は結構難しいのですが、これを作れば Web アプリへの LIFF・LINE ログインの統合ができます。

docs.microsoft.com

Azure Static Web Apps

f:id:himanago:20201231023303p:plain

バックエンドで Java .NET が動くような動的な Web アプリであれば、Web Apps を使いますが、静的な Web アプリであれば、Static Web Apps がおすすめです。

docs.microsoft.com

f:id:himanago:20201231023327p:plain

静的な Web アプリは、クライアントサイドで JavaScript が動いて実現するようなウェブサイトのことですが、もともと Azure には静的サイトホスティングのために Blob Storage で Web ページとして公開できる機能がありました。

docs.microsoft.com

ただ、機能としては貧弱だったので、より高機能な Static Web Apps が登場しました。

Static Web Apps は、GitHub との統合によって、リポジトリの更新のたびに自動でビルド・デプロイされるようになっています。

f:id:himanago:20201231023336p:plain

また、同時にバックエンドの API が開発できるようになっており、LIFF と Bot・連携機能まで同時に開発したりなどができます。

f:id:himanago:20201231023346p:plain

まだプレビューですが、GA のタイミングではもっと便利になるのではと思ってすごく期待しております(個人的には Azure DevOps 対応を待っています。GitHub を見る限り、もうすぐな様子)。

※以前ハンズオンイベントで簡単にまとめたスライドを作って発表しましたのでこちらもよろしければご参考に。

www.slideshare.net

その他便利な Azure サービス

そのほか、開発・運用サポートの面で LINE プラットフォームと相性がいいサービスを紹介です。

Azure Key Vault

f:id:himanago:20201231023639p:plain

シークレット情報や設定内容などを保存するのに便利。

docs.microsoft.com

Azure DevOps

f:id:himanago:20201231023657p:plain

ソースコード管理からプロジェクト管理、CI/CD パイプラインなどを提供。Azure 以外でも組み合わせて使えるので広く使われてほしいサービスです。

5人まで無料だし、Azure サブスクリプションとは関係なしに使えるので、ぜひ!

Application Insights

f:id:himanago:20201231023708p:plain

「Azure Monitor」と呼ばれる、監視系サービス群のひとつ。使用しているアプリのログを貯めておいたり、アラートを受け取ることができます。

docs.microsoft.com

アプリケーションマップという、システムで使用しているサービスの全体像と障害箇所を確認できる機能もあります。

docs.microsoft.com

アラートはすばやく障害を検知するために、Logic Apps と連携してそこから Teams や Slack といったチャットを投げるように組んでおくのがおすすめです。

もちろん障害通知専用の LINE Bot を作っても OK。障害通知だけなので Push も確実に無料枠に収まります(おさまらないならそれはシステムがやばい…)。

[実装例] Azure × LINE Platform によるチャットシステムの構築

最後に実装例です。

Azure と LINE プラットフォームによるチャットシステムの構築です。

f:id:himanago:20201231024402p:plain

このような Web 画面を用意して、Web と LINE Bot でやりとりをする、というものです。

上で Cosmos DB と SignalR Service で画面を更新する話を書きましたが、LINE → 画面がそれ。

f:id:himanago:20201231024413p:plain

そして画面 → Web はその逆です。

f:id:himanago:20201231024425p:plain

画面側から送ったメッセージにも、この Change Feed の流れをそのまま活かして Push メッセージが送れます。

Azure Communication Service

上のような構成で Bot と Web 画面で双方向にやり取りができるようなシステムを作ることができますが、最近プレビューで登場してた Communication Service を使うと、これだけで往復の処理が作れるようになります。

f:id:himanago:20201231024431p:plain

docs.microsoft.com

実装についてはこちらの記事に書いています。

himanago.hatenablog.com

実際に動かしたデモです。セッション当日はうまくいかなかったので(スマホミラーリングが止まってしまった…)、終了後に突貫で撮ったものがこれです。

デモのもとになったサンプルアプリはこちらです。

docs.microsoft.com

まとめ

f:id:himanago:20201231024751p:plain

Azure は PaaS がやっぱり強い!ので、(特に小規模向けや個人開発などでは)あまり複雑なことを考えたり設定したりしなくても、コツさえつかめば簡単に動くものが作れてしまいます。

おなじく手軽に UI が手に入る LINE Bot と組み合わせることで、すぐに面白いものが作れます。なので、どんどん LINE × Azure を試してほしいと思っています。

おわりに

長い…

とりあえず、いままで Azure × LINE でいろいろやってきて、それの総まとめ的なものにしたかったセッションです。

詰め込みすぎた感はありますが、詰め込めるだけ詰め込んでしまいたい!という気持ちでした。

実はまだまだ紹介し足りない部分も多いですが(たとえば大規模向けの話とか…)、ひとまず今回まではここまでです。ありがとうございました。

LPF REV UP 2020「あなたならどう使う?最新Azureレシピ for LINE Platform」フォローアップ(前半)

2020年ももう終わりですね…。
2020年を振り返り…たいところですが、直近11月・12月を振り返っていなかったので振り返っておきます。

はじめに

1か月半ほど前になってしまいますが、LPF REV UP 2020 という LINE 系コミュニティの大型イベントで登壇しました。 revup.jp

こちらは LINE Developer Community(東京)、LINE Developer Group Kansai(関西)、LINE Developer Group Q-shu(九州)の合同カンファレンスで、オンラインイベントながら東京/大阪/福岡の3トラックで行われたわりと大きいイベントでした。

本記事はこちらで登壇させていただいた、「あなたならどう使う?最新Azureレシピ for LINE Platform」というセッションのフォローアップ記事になります。

f:id:himanago:20201231154120p:plain

スライドと本記事双方で Azure の公式ドキュメントへのリンクを掲載していますので、詳細情報へのアクセスの足掛かりとしても使っていただけたら、と思います。

まずは、先にスライドと動画を置いておきます。

スライド(SlideShare

www2.slideshare.net

セッション動画(YouTube

youtu.be

内容解説

以下、スライドを並べながら、セッション当日言いきれなかった部分など補足しながら説明していきます。

セッションの概要

f:id:himanago:20201231014303p:plain

今回のセッションでは、LINE API を使った開発を Microsoft Azure で行った場合の Tips を知っている限りたくさん集めました。

※セッション概要

Microsoft Azureをはじめとしたパブリッククラウドには便利なサービスがたくさんあり、それらをうまく組み合わせれば機能・コストに優れたサービス・システム構築が可能となります。 しかし、クラウドプラットフォームには把握し切れないほどの種類のサービスが存在し、どれをどのように使えば効果的なのかわかりにくいことがあるかと思います。 本セッションでは、「LINE Platform との組み合わせ」をテーマにAzureサービスの "使いドコロ" を、LINE Bot / LIFF 開発事例を交えて紹介します。

内容は以下の通り。

f:id:himanago:20201231014314p:plain

本記事も同じ流れで書いていきますが、今回は前半戦ということで、「Azure × Messaging API」のメイン編について書いていきます。

Azure × Messaging API(メイン編)

まずは基本の、LINE Bot のバックエンド(Webhook エンドポイント)として使えるサービス群の紹介です。

Messaging API の Webhook エンドポイント

f:id:himanago:20201231014729p:plain

LINE Bot を構築するときは、Messaging API を使ってユーザーからのメッセージ送信等のアクションに対応する処理を作りますが、HTTPSJSON でのやりとりになるので、HTTPSJSON の送受信ができるようなものであれば使うことができます。

f:id:himanago:20201231014736p:plain

Azure では大きくコードを書かないものコードを書くものに大別でき、それぞれいくつかずつ見ていきます。

Azure Logic Apps

f:id:himanago:20201231014931p:plain

Logic Apps は、Azure が誇るノーコード/ローコードサービスで、多種多様なサービス同士をコーディングなしでつなげていくことを得意とします。

さまざまなイベントをトリガーに動作する自動化フローが組めますが、HTTP 受信時に動くものも作れるので、LINE Bot のバックエンドとしても使えます。

docs.microsoft.com

f:id:himanago:20201231014937p:plain

Logic Apps の利点として Azure 内外のサービスとの連携が挙げられるのですが、Logic Apps は JSON データの扱いも得意なので、Logic Apps に用意されている既製のアクション・トリガーがないものでも JSON でやりとりさえできれば簡単に連携ができるようになります。

JSON の定義を登録すると(サンプルデータを利用できます)、JSON に含まれるプロパティなどを後続処理で選択できるようになり、慣れると簡単に JSON を使うサービス同士の連携が組めるようになります。

LINE Bot(Messaging API)との連携も簡単です。

f:id:himanago:20201231014951p:plain

サービス間の連携が得意な Logic Apps なので、コードで連携処理をひとつひとつ書いていくよりも断然早く実現できるので、そういった場合に使うのがおすすめです。

docs.microsoft.com

f:id:himanago:20201231015002p:plain

このような特徴から、Logic Apps を使う場面としては他サービスとの連携を行いたい場合に使うとよいでしょう。

対話を何往復かするような複雑な対話フローをもつ LINE Bot の場合は、Logic Apps 単体で組み上げるのは大変ですが、連携の強みを活かすために一部処理のみに Logic Apps を採用する、というのは十分に考えられます。

補足

「Webhook のエンドポイント」という観点からはずれますが、さまざまなイベントをトリガーにできるため、それを LINE に Push Message で通知するような Bot も容易に作ることができます。

Bot Framework Composer

f:id:himanago:20201231015028p:plain

続いて Bot Framework Composer です。

f:id:himanago:20201231015041p:plain

こちらは自分のローカル環境にインストールして使うエディターでチャットボットの対話フローを定義するノーコードツールです。

docs.microsoft.com

f:id:himanago:20201231015201p:plain

Bot Framework Emulator を使って動作確認しながら開発していきます。

f:id:himanago:20201231015208p:plain

ノーコードなツールとはいえ、実体は Bot Framework で、Git など開発者向けツールを前提としたものであるので、基本的には開発者向けのツールといえます。

また、できあがったチャットボットを Azure にデプロイすると、Cosmos DB や LUIS、Bot Service といった複数のサービスの組み合わせで実現されるため、それぞれのサービスの使用方法を知っている必要があります。

なお、Azure にデプロイしたチャットボットは Azure Bot Service を使用するので、LINE Bot との接続も簡単です。

Azure Web Apps

続いてコードを書く系のサービスです。

HTTPSJSON の送受信をする仕組みをシンプルに Web アプリで実現する方法です。

f:id:himanago:20201231015231p:plain

Azure には Web Apps という Web アプリ実行用の非常に優秀な PaaS が用意されています。

こちらに LINE Bot のバックエンドをデプロイしたり、既存 Web アプリに LINE Bot 機能を追加したりすることが考えられます。

docs.microsoft.com

f:id:himanago:20201231015239p:plain

OS や言語、フレームワークもいろいろなものが使えるので、自分の得意な環境で LINE Bot を開発できます。

ここで書ききれないほどのメリットがありますが、特に Azure DevOps 等と組み合わせた CI/CD、スロット機能を使ったブルーグリーンデプロイメントが強力で実運用で非常に役立ちます(このあたりは次の Azure Functions と共通です)。

Azure Functions

続いて Azure Functions です。個人的には、最も手軽な Bot バックエンドとして特におすすめしたいサービスです。

f:id:himanago:20201231015252p:plain

いわゆる「サーバーレス」なコード実行環境で、書いたコードがすぐに動くのでシンプルな LINE Bot を作るのに最適なサービスです。

docs.microsoft.com

f:id:himanago:20201231145742p:plain

単体で HTTP の通信ができることが便利で、これだけですぐに Webhook エンドポイントとして使用できます。

そのほかにも入出力バインディングによって他サービスとの組み合わせも手軽にできます。

使用できる言語は C#JavaScript(TypeScript)、F#、JavaPowerShellPython ですが、カスタムハンドラーを使えば好きな言語で実装することができます(裏に Web サーバーを独自に立てる)。

docs.microsoft.com

docs.microsoft.com

f:id:himanago:20201231015317p:plain

また、3つの異なるホスティングプランがあることも特徴です。

コールドスタートを気にしなければ、Consumption プランが最も安価ですが、コールドスタートを気にするのであれば(+ある程度のランニングコストを許容するなら)App Service プランや Premium プランを選択しましょう。

docs.microsoft.com

Durable Functions

Azure Functions には、Durable Functions という拡張機能が使えます。

f:id:himanago:20201231015325p:plain

こちらはサーバーレスな関数の組み合わせでステートフルな(Functions 側で状態を保持した)処理が書けるもので、例のような処理が作れます。

2020/12 現在で使用できる言語は C#JavaScript(TypeScript)、PythonPowerShell(プレビュー)です。

docs.microsoft.com

f:id:himanago:20201231015509p:plain

基本的には、通常の Function(スターター関数と呼ぶ)からオーケストレーター関数を呼び出し、それがアクティビティ関数と呼ばれる実処理を担当する関数を呼びながら状態を都度保持していく仕組みとなっています。

f:id:himanago:20201231015518p:plain

それぞれの関数で使えるこれらの機能を組み合わせて、ステートフルなフローを実現します。

初見ではイメージが付きづらいかもしれませんが、コードのみでフローを作れるという点が非常に強力です。

レシピ:Durable Functionsによる LIFF 連携

個人的によく使う組み合わせなのですが、LIFF(LINE トークルーム内で使用できる Web アプリ)の処理と LINE Bot の処理を連携させる際に、Durable Functions が便利です。

f:id:himanago:20201231015554p:plain

Bot、LIFF 双方のバックエンドを Azure Functions で作り、イベント待機・イベント発火によって待ち合わせをします。LIFF も Bot も共通の LINE ユーザー ID がとれるので、それをキー(Durable Functions ではオーケストレーターの「インスタンス ID」を LINE ユーザー ID にする)に同一ユーザーの処理を連携できます。

こちらは以前のセッションでも紹介したものの一部になります。以下の記事で登壇内容を解説していますので合わせてみてみてください。

himanago.hatenablog.com

なお、Durable Functions の最近のアップデート(v2.4.0)で Durable Client Factory という機能が追加されました。これは、なんと Durable Functions の機能を利用するクライアントクラスの生成を実現する機能で、Azure Functions 外からも利用できます。

これにより Azure Functions でない、たとえば ASP.NET Core で開発した Web App だったり、Bot Framework で作った Bot Service だったりから Durable Functions の機能を呼び出すことができるので、Azure Functions 同士でなくてもこの待ち合わせの連携処理を利用することができるようになるようです。

公式より、ASP.NET Core から呼び出すサンプル(C#)が公開されているので、こちらを見るとわかります。 azure-functions-durable-extension/samples/todolist-aspnetcore at dev · Azure/azure-functions-durable-extension · GitHub

オリジナルフレームワーク「DurableBotEngine」について

実はこの Durable Functions のステートフルな機能を利用して、LINE Bot の対話フローを管理するためのフレームワークを開発しています。

現在は自然言語処理に Dialogflow(Google)の利用が前提となっていますが、LUIS(Azure)も使えるようにしようと思っています。

f:id:himanago:20201231015615p:plain

個人で開発していますが、実プロダクトにも入れる想定で利用をしていて、現在安定的に使えるよう開発を進めています。

こちらについては、もう少し整ったら使い方など書いていけたらと思っています。

www.nuget.org

つづきます

ひとまず、ここまでを前半として、続きは後半にて書いていきます。

後半部分は年内公開間に合わずで、年をまたぐことになってしまいましたが、次回も、そして来年も、よろしければどうぞよろしくお願いします。

Azure Blob Storage の SAS トークンを使って LINE Bot でセキュアに画像を送る

はじめに

Messaging API では、画像や動画の送信などの際、それらが置かれたパブリックな URL を指定することで実現します。

Azure を用いて LINE Bot を開発する場合は、画像等のリソースをパブリックアクセスレベルを「コンテナー」にした Blob Storage コンテナーに置くだけでパブリックな URL が得られて便利ですが、グローバルに公開してしまうことはセキュリティ上の懸念につながります。

そこで、少しでもセキュアに Blob Storage から Messaging API へのリソース連携を行うため、SAS トークンを使ったアクセス制限をかけてみます。

SAS トークンとは

SAS とは、Shared Access Signatures の略で、Azure Storage のリソースへのアクセス制限をかける機能です。

docs.microsoft.com

これを使うと、URL に付与して署名されているかどうかを検証できる「SAS トークン」が生成できます。SAS トークンつきの URL であれば、Blob コンテナーのパブリックアクセスレベルが匿名アクセスのできない「プライベート」になっていてもアクセスできるようになります。

では、LINE Bot のバックエンドで SAS トークンを生成することで、 Messaging API での画像送信を少しセキュアにしてみましょう。

実装してみる

バックエンドのひながた

Bot のバックエンドは Azure Functions で作り、言語は C# でいくことにします。Bot 用プロジェクトのひながたはこちらの記事参照。

LINE Bot を Azure Functions (C#) で作る際のオウム返しテンプレ - himanago

今回はシンプルに、何かしらメッセージを送ると Blob Storage に置いてある特定の画像を返信する、という Bot にします。

サービス SAS を使用する

SAS にはいくつか種類がありますが、今回使うのは「サービス SAS」です。

.NET でサービス SAS 使う方法が書いてあるドキュメントはこちら。

docs.microsoft.com

BLOB 用のサービス SAS を作成

上記のドキュメントの「Create a service SAS for a blob」の部分を参考に、実装をします。

「Azure.Storage.Blobs」パッケージ(v12)を追加し、以下のようにコードを追加します。

Configuration/LineBotSettings.cs

namespace AzureSecuredImageLineBotSample.Configurations
{
    public class LineBotSettings
    {
        public string ChannelSecret { get; set; }
        public string ChannelAccessToken { get; set; }
        public string StorageConnectionString { get; set; }
        public string BlobContainerName { get; set; }
        public string StorageAccountKey => StorageConnectionString.Split("AccountKey=")[1].Split(";")[0];
    }
}

設定は面倒なので同じファイルにまとめてしまいます…。

実際の設定値はポータルのアプリケーション設定から、名前を LineBotSettings:ChannelAccessToken などの形式にして設定しておきましょう(4 つ)。

Startup.cs

using Azure.Storage.Blobs;
using AzureSecuredImageLineBotSample.Configurations;
using LineDC.Messaging;
using LineDC.Messaging.Webhooks;
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

[assembly: FunctionsStartup(typeof(AzureSecuredImageLineBotSample.Startup))]
namespace AzureSecuredImageLineBotSample
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            var config = new ConfigurationBuilder()
                .AddJsonFile("local.settings.json", true)
                .AddEnvironmentVariables()
                .Build();

            var settings = config.GetSection(nameof(LineBotSettings)).Get<LineBotSettings>();

            // Blob Storage 用に追加
            var blobServiceClient = new BlobServiceClient(settings.StorageConnectionString);
            var blobContainerClient = blobServiceClient.GetBlobContainerClient(settings.BlobContainerName);
            builder.Services.AddSingleton(blobContainerClient);

            builder.Services
                .AddSingleton(settings)
                .AddSingleton<ILineMessagingClient>(_ => LineMessagingClient.Create(settings.ChannelAccessToken))
                .AddSingleton<IWebhookApplication, LineBotApp>();
        }
    }
}

LineBotApp.cs

using Azure.Storage;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Specialized;
using Azure.Storage.Sas;
using AzureSecuredImageLineBotSample.Configurations;
using LineDC.Messaging;
using LineDC.Messaging.Messages;
using LineDC.Messaging.Webhooks;
using LineDC.Messaging.Webhooks.Events;
using Microsoft.Azure.WebJobs.Logging;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace AzureSecuredImageLineBotSample
{
    public class LineBotApp : WebhookApplication
    {
        private ILogger Logger { get; }
        private BlobContainerClient BlobContainerClient { get; }
        private LineBotSettings Settings { get; }

        public LineBotApp(ILineMessagingClient lineMessagingClient, LineBotSettings settings, ILoggerFactory loggerFactory,
            BlobContainerClient blobContainerClient)
            : base(lineMessagingClient, settings.ChannelSecret)
        {
            Logger = loggerFactory.CreateLogger(LogCategories.CreateFunctionUserCategory(nameof(WebhookEndpoint)));
            BlobContainerClient = blobContainerClient;
            Settings = settings;
        }

        protected override async Task OnMessageAsync(MessageEvent ev)
        {
            var key = new StorageSharedKeyCredential(BlobContainerClient.AccountName, Settings.StorageAccountKey);
            var originalContentUrl = GetBlobSasUri("original.png", key);
            var previewImageUrl = GetBlobSasUri("preview.png", key);

            Logger?.LogTrace($"OnMessageAsync => Type: {ev.Source.Type}, Id: {ev.Source.Id}");
            await Client.ReplyMessageAsync(ev.ReplyToken, new List<ISendMessage>
            {
                new ImageMessage(originalContentUrl, previewImageUrl)
            });
        }

        private string GetBlobSasUri(string blobName, StorageSharedKeyCredential key)
        {
            // Create a SAS token
            var sasBuilder = new BlobSasBuilder
            {
                BlobContainerName = BlobContainerClient.Name,
                BlobName = blobName,
                Resource = "b",
            };

            sasBuilder.StartsOn = DateTimeOffset.UtcNow.AddMinutes(-15);
            sasBuilder.ExpiresOn = DateTimeOffset.UtcNow.AddMinutes(10);
            sasBuilder.SetPermissions(BlobContainerSasPermissions.Read);

            // Use the key to get the SAS token.
            var sasToken = sasBuilder.ToSasQueryParameters(key).ToString();

            return $"{BlobContainerClient.GetBlockBlobClient(blobName).Uri}?{sasToken}";
        }
    }
}

SAS トークンを含む URL は GetBlobSasUri で作成します。

ここでは、SAS トークンは有効期限を 10 分としています(開始は時刻ずれを考慮して 15 分前を設定)。

ただし、LINE Bot の画像には、送ったメッセージをユーザーが見たときにはじめてリクエストが飛ぶので、あまり短すぎるとユーザーが見る前に期限が切れてしまいます。なので、かなり遠い未来の日付を指定してあげるとよいです。1

期限が長くてもリソースごと・メッセージ送信ごとに個別のトークンが生成されるので、正しいトークンを持たないユーザーはアクセスできませんし、URL を推測して他の Blob へアクセスすることもできなくなります。

まとめ

LINE Bot で画像や動画などを扱うことは多いですが、セキュアに運用するために SAS 機能は手軽に導入でき、便利です。

Blob Storage に Bot のリソースを置く場合、特にインターネットにさらしたくないファイルがそこにある場合には、導入していくべきだと思います。


  1. 残念ながら無期限にはできないようです。