PowerShellと会話する

、、、ってか、docomo質問雑談APIと会話するだけですが、、、。


こんなことができます!

PS > Get-Answer こんにちは
こんにちわん
PS > Get-Answer 日本の人口は?
日本の人口は128057352人です。
1 128057352人 総務省「平成22年国勢調査」より

なんや、「こんにちわん」って。ああん?

追記 2015/02/09
stuncloudさんが、PowerShell的に正しいのをアップしてくれました。
https://stuncloud.wordpress.com/2015/02/07/powershell_docomos_talking_api/
.Netの各言語にしたいなら、私の方が訳しやすいですが。

スクリプト、、、の前に

docomo Developer support | NTTドコモ
に登録しないと使えません。
登録はメールアドレスくらいでOKでした。
なのでまぁ、ちゃちゃっと。
さらに、アプリケーションを申請しないといけないのですが、商用利用しませんし今回使う雑談対話と知識Q&Aはパートナー審査もありませんので、適当で通るようです。
必須項目は、、、

  • アプリケーション名、好きにどうぞ。「雑談テスト」とかで通りました。
  • アプリケーション概要、これもお好きに。「雑談APIのお試しをしたいです。よろしくお願いします」で通りました。
  • サービス開始予定日、当日にしました
  • アプリケーションタイプ、PowerShellからだし「ネイティブアプリケーション」にしました。
  • コールバックURL、必要としない場合の「https://dummy」にしました。
  • 提供者名、OAuth使わないから関係ないです。「June」にしました。
  • サポートメールアドレス、これも関係ないですが、同じメールアドレスを入れました。

となっています。
多分、アプリ審査のないAPI使用だと、即時でAPIKEYが発行されます。

スクリプト

JSONの解釈にSystem.Web.Script.Serialization.JavaScriptSerializerを使うので、System.Web.Extensionsをロードします。
グローバルの$docomoApi変数を使います。
取得したAPIKEYを、$docomoApi.keyに設定してください。
また、雑談APIは個人情報を元に応答があるようなので、$docomoApi.d以下の項目は、適当に書いてください。
必須なものはありません。
詳細は、APIの説明を読んでくださいね。

function Get-Answer() {
	Param (
		[string]$Question,
		[switch]$Dialog,
		[switch]$New
	)

	if(!('System.Web.Script.Serialization.JavaScriptSerializer' -as [type])) {
		Add-Type -AssemblyName System.Web.Extensions
	}
	if(!$docomoApi) {
		$global:docomoApi = @{}
		$docomoApi.key = '取得したAPIKEYを設定してね'
		$docomoApi.jss = New-Object System.Web.Script.Serialization.JavaScriptSerializer
		$docomoApi.d = @{}
		$docomoApi.d.utt = ''
		$docomoApi.d.context = ''
		$docomoApi.d.nickname = 'のび太'
		$docomoApi.d.nickname_y = 'ノビタ'
		$docomoApi.d.sex = ''
		$docomoApi.d.bloodtype = 'O'
		#$docomoApi.d.birthdateY = 2005
		$docomoApi.d.birthdateM = 8
		$docomoApi.d.birthdateD = 7
		$docomoApi.d.age = 10
		$docomoApi.d.constellations = '獅子座'
		$docomoApi.d.place = '東京'
		$docomoApi.d.mode = 'dialog'
		$docomoApi.d.t = ''
	}

	if($New) {
		$docomoApi.d.context = ''
		$docomoApi.d.mode = 'dialog'
	}

	$res = $null
	if($docomoApi.d.mode -ne 'srtr' -and !$Dialog) {
		$webreq = [System.Net.WebRequest]::Create(('https://api.apigw.smt.docomo.ne.jp/knowledgeQA/v1/ask?q={0}&APIKEY={1}' -f [System.Web.HttpUtility]::UrlEncode($Question),$docomoApi.key))
		$webres = $webreq.GetResponse()
		$sr = New-Object System.IO.StreamReader $webres.GetResponseStream(),[System.Text.Encoding]::UTF8
		$res = $docomoApi.jss.DeserializeObject($sr.ReadToEnd())
		$webres.Close()
	}
	if($res -and $res.code -and $res.code.StartsWith('S')) {
		$res.message.textForDisplay
		for($i = 0; $i -lt $res.answers.Length; $i++) {
			'{0} {1} {2} {3}' -f $res.answers[$i].rank,$res.answers[$i].answerText,$res.answers[$i].linkUrl,$res.answers[$i].linkText
		}
	} else {
		# エラーなので、雑談APIにまわす
		$docomoApi.d.utt = $Question
		$postData = [System.Text.Encoding]::UTF8.GetBytes($docomoApi.jss.Serialize($docomoApi.d))
		$webreq = [System.Net.WebRequest]::Create(('https://api.apigw.smt.docomo.ne.jp/dialogue/v1/dialogue?APIKEY={0}' -f $docomoApi.key))
		$webreq.Method = 'POST'
		$webreq.ContentType = 'application/json'
		$webreq.ContentLength = $postData.Length
		$sr = $webreq.GetRequestStream()
		$sr.Write($postData, 0, $postData.Length)
		$sr.Close()
		$webres = $webreq.GetResponse()
		$sr = New-Object System.IO.StreamReader $webres.GetResponseStream(),[System.Text.Encoding]::UTF8
		$res = $docomoApi.jss.DeserializeObject($sr.ReadToEnd())
		$webres.Close()
		$docomoApi.d.context = $res.context
		$docomoApi.d.mode = $res.mode
		$res.utt
	}
}


さてさて

PS > Get-Answer 生命、宇宙、そして万物についての究極の疑問の答えは?
Wikipediaに生命というページがあります。
1 http://ja.wikipedia.org/wiki/%E7%94%9F%E5%91%BD http://ja.wikipedia.org/wiki/%E7%94%9F%E5%91%BD フリー百科事典『ウィキペディアWikipedia)』

、、、使えねぇ、、、。

少し解説

基本的には、知識Q&AのAPIを呼ぼうとするので、ゆるーく雑談を楽しみたい場合は「-Dialog」オプションをつけてください。


「Get-Answer しりとりしよう」とか言うとしりとりモードに入ってしまいます。
わざと負けても抜けることができますが、負けたくない場合は、「-New」オプションをつけてモードを抜けてください。
あと、雑談の状態でエラーが出ると、モードがおかしくなるので、その場合も「-New」で。