対話型のBotを作成するとき、入力を受け付ける手段としては「プロンプト」パッケージが用意されています。入力項目が少ない場合であれば、「プロンプト」パッケージでもいいのですが、入力項目が増えてくると独自の入力フォームが欲しくなることがあります。また、入力項目にパスワードがあるような場合、「プロンプト」パッケージの[Mask keystroke]機能が イマイチ なので、断然、独自の入力フォームが欲しくなります。
ここでは、Windows Formを表示して入力を受け付けるPowerShellスクリプトをBotから実行して、入力内容を取得する処理を紹介します。
処理の分担とデータ入出力の流れ
Task BotとPowerShellスクリプトの処理分担と、データがどのように流れるかを下図に示します。
ここで紹介しているBotのデモ動画は こちら で参照できます。
PowerShellスクリプトのアップロードとパス定義手順
ここでは、Control RoomにアップロードしたPowerShellスクリプトを実行する仕様にしたいので、まず、PowerShellスクリプトをControl Roomにアップロードする手順を説明します。
PowerShellスクリプトのアップロード
ローカルフォルダに作成したPowerShellスクリプトファイル「PSS_000101_InputMemberInformation.ps1」をControl Roomにアップロードします。
PowerShellスクリプトファイルのアップロード先フォルダとして、あらかじめ「Bots\Blog\Script\Script_PowerShell」を作成しています。(フォルダの作成手順は省略します。)
ローカルフォルダに作成したPowerShellスクリプトファイルを選択して[開く]ボタンをクリックします。
パス定義
Control RoomにアップロードしたPowerShellスクリプトへのパスをファイル型変数に設定します。
[名前]、[タイプ]を入力したら、[デフォルト値]に[Control Roomファイル]を選択して、[参照]ボタンをクリックします。
Control Roomのフォルダを展開して該当ファイルを選択して、[確認]ボタンをクリックします。
Task Botの作成
アクションリストの全体概要
下記がアクションリストの全体概要です。PowerShellスクリプトの呼び出しには、「Python script」パッケージを利用しています。アクションの詳細設定内容については、(2)以降で、「Python script」パッケージのアクション(5, 7行目)のみに限定して説明します。
Pythonスクリプトをインラインで定義
「Python」パッケージの「Open」アクション
【詳細設定】
[Manual input]を選択して、[Enter script here]に関数「inputProfile」を定義しています。筆者の環境にはPython2.7をインストールしているので、[Python runtime version]は「2」を選択しました。
【Pythonスクリプト詳細】
関数「inputProfile」は、引数「ScriptFilePath」でPowerShellスクリプトへのパス情報を受け取る仕様にしています。
def inputProfile(ScriptFilePath): import subprocess cmd = "powershell.exe -ExecutionPolicy RemoteSigned -WindowStyle Hidden -nologo -File \"" + ScriptFilePath + "\"" result = subprocess.call(cmd, shell=True)
Pythonスクリプトの関数実行
「Python」パッケージの「Execution function」アクション
【詳細設定】
[Enter name of function to be executed]に関数名「inputProfile」、[Arguments to the function]にファイル型変数「F_PSS_000101」を設定しています。
PowerShellスクリプト詳細
以下のコードで動作確認をしましたので、参考情報として掲載しておきます。
$OutputEncoding = [Text.Encoding]::Default $wsobj = New-Object -ComObject wscript.shell #Windows Formswをロードする。 Add-Type -AssemblyName System.Windows.Forms #================================================== #フォームに表示する項目要素を定義する。 #================================================== #ツールのウインドウを定義する。 $form = New-Object System.Windows.Forms.Form $form.Size = "400,300" $form.StartPosition = "CenterScreen" $form.Text = "会員情報入力" #[会員番号]表示ラベルを定義する。 $Label_Id = New-Object System.Windows.Forms.Label $Label_Id.Location = "10,10" $Label_Id.Size = "60,30" $Label_Id.Text = "会員番号:" $Text_Id = New-Object System.Windows.Forms.TextBox $Text_Id.Location = "80,10" $Text_Id.Size = "200,30" #クリップボードから取得した内容を設定する。 $Text_Id.Text = Get-Clipboard -Format Text $Text_Id.Enabled = $False #[パスワード]入力ボックスを定義する。 $Label_Pw = New-Object System.Windows.Forms.Label $Label_Pw.Location = "10,50" $Label_Pw.Size = "60,30" $Label_Pw.Text = "パスワード:" $Text_Pw = New-Object System.Windows.Forms.TextBox $Text_Pw.Location = "80,50" $Text_Pw.Size = "200,30" $Text_Pw.Text = "" $Text_Pw.PasswordChar = "*" #[氏名]入力ボックスを定義する。 $Label_Name = New-Object System.Windows.Forms.Label $Label_Name.Location = "10,90" $Label_Name.Size = "40,30" $Label_Name.Text = "氏名:" $Text_Name = New-Object System.Windows.Forms.TextBox $Text_Name.Location = "80,90" $Text_Name.Size = "200,30" $Text_Name.Text = "" #[Email]入力ボックスを定義する。 $Label_Email = New-Object System.Windows.Forms.Label $Label_Email.Location = "10,130" $Label_Email.Size = "40,30" $Label_Email.Text = "Email:" $Text_Email = New-Object System.Windows.Forms.TextBox $Text_Email.Location = "80,130" $Text_Email.Size = "200,30" $Text_Email.Text = "" #[OK]ボタンを定義する。 $OKButton = New-Object System.Windows.Forms.Button $OKButton.Location = "90,180" $OKButton.Size = "75,30" $OKButton.Text = "OK" $OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK #[キャンセル]ボタンを定義する。 $CancelButton = New-Object System.Windows.Forms.Button $CancelButton.Location = "180,180" $CancelButton.Size = "75,30" $CancelButton.Text = "キャンセル" $CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel #================================================== #フォームに項目要素を追加する。 #================================================== $form.Controls.Add($Label_Id) $form.Controls.Add($Text_Id) $form.Controls.Add($Label_Pw) $form.Controls.Add($Text_Pw) $form.Controls.Add($Label_Name) $form.Controls.Add($Text_Name) $form.Controls.Add($Label_Email) $form.Controls.Add($Text_Email) $form.Controls.Add($OKButton) $form.Controls.Add($CancelButton) #キーにボタンコントロールを紐づける。 $form.AcceptButton = $OKButton $form.CancelButton = $CancelButton #フォームを際前面に表示するように設定する。 $form.Topmost = $True #================================================== #フォームを表示する。 #================================================== #クリップボードに「Timeout」を設定する。 "TimeOut" | Clip $result = $form.ShowDialog() #================================================== #ボタンをクリックしたときの処理を定義する。 #================================================== #OKボタンが押された場合、入力値をクリップボードに出力する。 if ($result -eq "OK") { $CRLF = "`r`n" $Text_Pw.Text + $CRLF + $Text_Name.Text + $CRLF + $Text_Email.Text | Clip }else{ #キャンセル]ボタンがクリックされた場合は、「Cancel」をクリップボードに出力する。 "Cancel" | Clip }
【余談】
今回は、subprocessモジュールを使ってPowerShellスクリプトを呼び出しましたので、実行したPowerShellが終了するまで7行目から次のアクションに進むことはありませんでした。