
Microsoft社が提供する、Azure AI 翻訳サービスとローコード開発ツール「Power Platform」のアプリ機能(Power Apps)を使用した、ドキュメント翻訳アプリの作成例を紹介します。
これにより、アプリからアップロードしたファイル(pdfやwordなど)のAIによる翻訳結果ファイルを取得できるようになります。
- 操作環境:
- OS:Windows 11
- Webブラウザー:Edge
- 使用プラン:
- Power Apps:Microsoft 365 Business Premium(試用版)
- Azure:従量課金制
- Azure AI 翻訳:F0(フリー)
アプリ実装:作成画面
タイトル・アイコン変更
フォーム画面のタイトルを選択し、右側プロパティの[ディスプレイ>テキスト]を選択し、アプリ名を入力します(この例ではドキュメント翻訳)。

作成画面の[×]アイコンとタイトルの位置を変更します。
さらに、2つのアイコンをそれぞれ選択し、右側プロパティの[ディスプレイ>アイコン]を選択し、それぞれ変更します。
- キャンセル⇒リセット
- チェック⇒フォルダー

データソース選択
左側ツリービューの[ScreenCreate<EditForm1]を選択し、[データソースの選択]にて、前の記事で作成したSharePointリストを選択します。

添付ファイル部品を含む部品の追加・移動
添付ファイルのデータ領域を選択して右クリックし、[コピー]を選択します。

左側ツリービューの[ScreenCreate]の[・・・]を選択し、[貼り付け>貼り付け]を選択します。
作成画面直下に添付ファイルの部品がコピーされました。名前を[fileInput]に変更します。

今回、編集フォームは使用しませんので(添付ファイルの部品を取得するため一時利用した)、左側ツリービューの[ScreenCreate>EditForm1]の[・・・]を選択し、[削除]を選択します。
上メニューの[挿入]から、以下の部品を選択します。
- テキストラベル:5個
- ドロップダウン:1個
- ボタン:1個

さらに、部品の配置やラベル名等を調整します。
| 部品名 | 部品の種類 | Height | Weight | X | Y | Text | その他の設定項目 |
|---|---|---|---|---|---|---|---|
| lblUpload | テキストラベル | 640 | 70 | 0 | 88 | "【対象ドキュメントアップロード】" | Size:21 |
| fileInput | 添付ファイル | 580 | 176 | 31 | 157 | (後ほど設定) | |
| lblTranslate | テキストラベル | 560 | 70 | 0 | 349 | "【翻訳後言語選択・翻訳】" | Size:21 |
| drpLanguage | ドロップダウン | 370 | 70 | 25 | 419 | (後ほど設定) | |
| btnTranslate | ボタン | 197 | 70 | 409 | 419 | "翻訳" | (後ほど設定) |
| lblTranslateMessage | テキストラベル | 611 | 70 | 16 | 489 | message | Size:16 |
| lblCategory | テキストラベル | 640 | 70 | 0 | 583 | "【翻訳済ドキュメントダウンロード】" | Size:21 |
| TextSearchBox1 | テキスト入力 | 611 | 70 | 16 | 651 | "リンクが表示されたら、クリックして翻訳済ドキュメントをダウンロードしてください。" | Size:16 |
各部品の設定
一通り部品の配置等を調整すると、以下のようなイメージになります。
添付ファイルの部品を選択し、右側プロパティの[詳細設定]の下記項目を設定します。
- AddAttachmentText:"ここにファイルを添付(1個)"
- Items:(元のソースの頭に//を付けてコメントアウト)
- MaxAttachments:1
- BoarderColor: (元のソースの頭に//を付けてコメントアウト)
- DisplayMode: (元のソースの頭に//を付けてコメントアウト)
- Tooltip: "翻訳したいドキュメントのファイルをアップロードしてください。"

ドロップダウンの部品を選択し、左上プロパティの下記項目を設定します。
- Items:["日本語:ja", "英語:en",・・・]
*詳細は後述します
- Tooltip: "翻訳したいドキュメントの翻訳後言語を選択してください。"

ドキュメント翻訳の対応言語は公式記事に掲載されています。このデータをExcelやテキストエディタ等にコピー&ペーストし、["言語:言語コード","言語:言語コード"]のデータに加工したものをItemsプロパティに貼り付けます。

ドロップダウンのItemsプロパティに対応言語の選択肢を設定したイメージです。

以下部品のプロパティに対し、部品や内部変数の値をリセットする設定を追加します。
- ScreenCreate:OnVisible
- IconReset:OnSelect
Reset(fileInput);
Reset(drpLanguage);
UpdateContext({message:"ここにドキュメント翻訳のステータスが表示されます。"})

右上のフォルダーアイコンのOnSelectプロパティを以下のように設定します(履歴画面に遷移)。
Navigate(ScreenHistory, ScreenTransition.None)

アプリ実装:フロー
Power Appsからのデータ受取、変数定義
左メニューの[フロー]アイコンを選択し、[フローを新規作成する]を選択します。
[+ 一から作成]を選択します。

[Power Apps (V2)]ステップについて、アプリから受け取る項目を以下の通り設定します。
- テキスト:req-user
- テキスト:req-language
- ファイル:req-file-input
[新しいステップ]を選択し、後続ステップの追加・設定を進めていきます。

ドキュメント翻訳APIの処理で必要となる、AI翻訳サービスのキーの値を定義します。
[組み込み>データ操作>作成]ステップを選択し、以下の通り設定します。
- 入力:(前々回の記事の工程5で控えたキー1の値)

アプリから受け取った言語の変数を配列に格納します(配列の二番目に格納される言語コードがドキュメント翻訳APIの処理で必要となるため)。
[組み込み>変数>変数]ステップを選択し、以下の通り設定します。
- 名前:arrayLanguage
- 種類:アレイ
- 値(式):split(triggerBody()['text_1'],':')
*分かり辛いですが、text_1という変数名が一番最初のステップの引数req-languageに相当します

Azure Storageの処理
Azureストレージのsourceコンテナー上に同じファイル名のドキュメントが存在すると、同コンテナーにファイルを配置する時にエラーが発生するため、ここで既存のファイルを削除します。
[blob]で検索し、[Azure Blob Storage>BLOBを削除する (V2)]ステップを選択します。
初回は[Azure Blob Storage]の認証情報の入力を求められますので、以下の通り設定します。
- 認証の種類:Access Key
- Azure Storageアカウント名:前々回の記事の工程6で設定したストレージアカウント
- アクセスキー:前々回の記事の工程6の最後の方で控えたキー1
認証が通ったら、以下の通り設定します。 - ストレージアカウント:前々回の記事の工程6で設定したストレージアカウント
- BLOB(式): concat('/source/',triggerBody()['file']['name'])

前のステップでコンテナー上のファイル削除を行う際、対象ファイルがないと処理に失敗します。削除の成功・失敗にかかわらずフローを進められるようにします。
[組み込み>コントロール>スコープ]ステップを選択します。
[・・・]を選択し、[実行条件の構成]を選択します。
[に成功しました]と[に失敗しました]だけにチェックをつけ、[完了]を選択します。
なお、スコープ内にはアクションは追加しません。

sourceコンテナーと同様に、targetコンテナーのファイル削除のステップも追加します。
[blob]で検索し、[Azure Blob Storage>BLOBを削除する (V2)]ステップを選択し、以下の通り設定します。
- ストレージアカウント:前々回の記事の工程6で設定したストレージアカウント
- BLOB(式): concat('/target/',triggerBody()['file']['name'])

sourceコンテナーと同様に、 targetコンテナーのスコープのステップも追加します。
[組み込み>コントロール>スコープ]ステップを選択します。
[・・・]を選択し、[実行条件の構成]を選択します。
[に成功しました]と[に失敗しました]だけにチェックをつけ、[完了]を選択します。
なお、スコープ内にはアクションは追加しません。

sourceコンテナーに翻訳対象のドキュメントを配置するステップを追加します。
[blob]で検索し、[Azure Blob Storage>BLOBを作成する (V2)]ステップを選択し、以下の通り設定します。
- ストレージアカウント:前々回の記事の工程6で設定したストレージアカウント
- フォルダーのパス:/source
- BLOB名(式):triggerBody()['file']['name']
- BLOBコンテンツ(項目):req-file-input

ドキュメント翻訳APIの処理、翻訳後ファイル取得
ドキュメント翻訳APIの処理で必要となる、sourceコンテナーのSAS URI作成のステップを追加します。
[blob]で検索し、[Azure Blob Storage>パスを使用してSAS URIを作成する (V2)]ステップを選択し、以下の通り設定します。
- ストレージアカウント:前々回の記事の工程6で設定したストレージアカウント
- BLOBパス(項目):[BLOBを作成する (V2)-source]のPath
- アクセス許可:Read,Write,List
- 有効期限(式):addMinutes(utcNow(),9,'yyyy-MM-ddTHH:mm:ss')

sourceコンテナーと同様に、targetコンテナー用のSAS URI作成のステップを追加します。
[blob]で検索し、[Azure Blob Storage>パスを使用してSAS URIを作成する (V2)]ステップを選択し、以下の通り設定します。
- ストレージアカウント:前々回の記事の工程6で設定したストレージアカウント
- BLOBパス:/target/
- アクセス許可:Read,Write,List
- 有効期限(式):addMinutes(utcNow(),9,'yyyy-MM-ddTHH:mm:ss')

ドキュメント翻訳APIの処理を定義します。
[組み込み>HTTP>HTTP)]ステップを選択し、以下の通り設定します。
- 方法:POST
- URI:{前々回の記事の工程5で控えたドキュメント翻訳のWebAPIのURL} + "translator/text/batch/v1.1/batches"
- ヘッダー:
- Ocp-Apim-Subscription-Key(項目):このフローの二番目のステップ(データ操作>作成)で定義したキー1
- Content-Type: application/json
本文の設定は以下の通りです。
{
"inputs": [
{
"storageType": "File",
"source": {
"sourceUrl": "{sourceコンテナーのSASUrl}"
},
"targets": [
{
"targetUrl": "{targetコンテナーのSASUrl}",
"language": "{言語コード}"
}
]
}
]
}

ドキュメント翻訳APIの仕様は公式記事に掲載されています。必要箇所を抜粋します。

翻訳処理が完了する前に次のステップに進まないよう、待ち時間のステップを追加します。
[組み込み>スケジュール>遅延]ステップを選択し、以下の通り設定します。
- カウント:30
- 単位:秒
targetコンテナーに格納された翻訳後ファイルを取得するステップを追加します。
[blob]で検索し、[Azure Blob Storage>BLOBコンテンツを取得する(V2)]ステップを選択し、以下の通り設定します。
- ストレージアカウント:前々回の記事の工程6で設定したストレージアカウント
- BLOB(式): concat('/target/',triggerBody()['file']['name'])
- コンテンツタイプの推測:いいえ

SharePointリストへのデータ追加
SharePointリストに作成日時を記録するため、タイムゾーン変換後の値を取得するステップを追加します。
[組み込み>日時>タイムゾーンの変換]ステップを選択し、以下の通り設定します。
- 基準時間(式):utcNow()
- 変換元のタイムゾーン:(utc)協定世界時
- 変換先のタイムゾーン:(utc+9:00)大阪、札幌、東京
- 書式設定文字列(カスタム値の入力):yyyy/MM/dd HH:mm

SharePointリストにデータを追加するステップを追加します。
[sharepoint]で検索し、[SharePoint>項目の作成]ステップを選択し、以下の通り設定します。
- サイトのアドレス:(SharePointリストのあるサイト)
- リスト名:(SharePointリスト名)
- create_at(項目):変換後の時間
- create_user(項目):アプリから受け取ったユーザーUPN
- file_name (項目) :翻訳対象ドキュメントのファイル名
- language (項目) :アプリから受け取った翻訳後言語

SharePointリストに翻訳後ドキュメントを添付する際、文字化け対策のため、メディアタイプを取得するステップを追加します。
[組み込み>変数>変数を初期化する]ステップを選択し、以下の通り設定します。
- 名前:txtMediaType
- 種類:文字列
- 値(項目):sourceコンテナーのファイルのMediaType
メディアタイプによる分岐のステップを追加します。
[組み込み>コントロール>条件]ステップを選択し、以下の通り設定します。
- 項目:txtMediaType
- 式:次の値に等しい
- 値:text/plain

公式ブログの通り、この後、text/plainのファイルだけ文字化け対策をした上でSharePointリストに添付します。
text/plainのファイルをSharePointリストに添付するステップを追加します。
[sharepoint]で検索し、[SharePoint>項目の作成]ステップを選択し、以下の通り設定します。
- サイトのアドレス:(SharePointリストのあるサイト)
- リスト名:(SharePointリスト名)
- ID(項目): SharePointリストのID
- ファイル名(項目):翻訳対象ドキュメントのファイル名
- ファイルコンテンツ (式) : concat(decodeUriComponent('%EF%BB%BF'),outputs('BLOB-コンテンツを取得する-(V2)-target')?['body'])

text/plain以外のファイルをSharePointリストに添付するステップを追加します。
[sharepoint]で検索し、[SharePoint>項目の作成]ステップを選択し、以下の通り設定します。
- サイトのアドレス:(SharePointリストのあるサイト)
- リスト名:(SharePointリスト名)
- ID(項目): SharePointリストのID
- ファイル名(項目):翻訳対象ドキュメントのファイル名
- ファイルコンテンツ (式) :[BLOB-コンテンツを取得する-(V2)-target]のファイルコンテンツ

Power Appsへの結果データ引き渡し
最後に、アプリにデータを渡すステップを追加します。
[組み込み>Power Apps>Power App またはフローに応答する]ステップを選択し、以下の通り設定します。
- テキスト:res-message:ドキュメント翻訳が完了しました。
- テキスト:res-id:SharePointリストのID(項目)
*添付ファイルの識別IDと間違えないよう注意

フロー全体の確認
フロー全体は以下の通りとなります。

図表12-21の全体ステップの下から二番目の条件分岐の中はこのようになっています。
フローを保存してアプリの画面に戻ります。

次の記事に続きます。
当ブログ内の連載記事