public ClovaController(IConfiguration configuration, ILoggerFactory loggerFactory, IHttpClientFactory httpClientFactory) { _client = new ClovaClient(); _configuration = configuration; _httpClientFactory = httpClientFactory; _logger = loggerFactory.CreateLogger <ClovaController>(); }
public static async Task <IActionResult> LongTimeFunction( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, [OrchestrationClient] DurableOrchestrationClient client, Microsoft.Azure.WebJobs.ExecutionContext context, ILogger log) { var cekResponse = new CEKResponse(); var clovaClient = new ClovaClient(); var cekRequest = await clovaClient.GetRequest(req.Headers["SignatureCEK"], req.Body); switch (cekRequest.Request.Type) { case RequestType.LaunchRequest: { // UserId をインスタンス ID として新しい関数を実行 await client.StartNewAsync(nameof(LongTimeOrchestrationFunction), cekRequest.Session.User.UserId, context.FunctionAppDirectory); cekResponse.AddText("時間のかかる処理を実行しました。結果はLINEでお知らせします。"); break; } case RequestType.IntentRequest: default: { // インテントリクエスト他は特に用意しない cekResponse.AddText("すみません。よくわかりませんでした。"); break; } } return(new OkObjectResult(cekResponse)); }
public static async Task <IActionResult> Run( [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log) { CEKResponse response = null;; if (req.Headers.TryGetValue("SignatureCEK", out var signature)) { var client = new ClovaClient(); var request = await client.GetRequest(signature, req.Body); // IntentRequestのみここにくる if (request.Request.Type == RequestType.IntentRequest) { // メイン処理 var result = IntentHandler.Handle(request.Request.Intent.Name); response = result.GetClovaResponse(); } else { // エラー response = new CEKResponse(); response.AddText("よくわかりませんでしたが、たぶんラッキーな1日になると思いますよ。"); response.ShouldEndSession = true; } } else { // エラー response = new CEKResponse(); response.AddText("よくわかりませんでしたが、きっと大丈夫ですよ。"); response.ShouldEndSession = true; } return(new OkObjectResult(response)); }
public static async Task <IActionResult> Run( [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log) { // リクエストのボディの JSON を検証して C# のクラスに変換。 var clovaClient = new ClovaClient(); var clovaRequest = await clovaClient.GetRequest(req.Headers["SignatureCEK"], req.Body); // 返事を作成 var clovaResponse = new CEKResponse(); switch (clovaRequest.Request.Type) { case RequestType.LaunchRequest: // 起動時の処理 clovaResponse.AddText("こんにちは。何を占ってほしいですか?"); clovaResponse.AddText("健康運と恋愛運と金運を占えるよ。"); clovaResponse.AddText("例えば健康運を占ってって聞いてみてね。"); clovaResponse.ShouldEndSession = false; // スキルを終わらせないように設定する break; case RequestType.SessionEndedRequest: // 終了時の処理。今回は無し。case 自体不要だけど説明用に今回は追加してる break; case RequestType.IntentRequest: // インテントの処理 switch (clovaRequest.Request.Intent.Name) { case "FortuneTellingIntent": // 占いのインテント // 占い対象がスロットに無い場合は総合運勢を占う var fortune = "総合運勢"; if (clovaRequest.Request.Intent.Slots.TryGetValue("FortuneSlot", out var fortuneSlot)) { // 占いの対象がある場合は、それをスロットから取得する fortune = fortuneSlot.Value; } // 占いの結果を返す var result = new[] { "大吉", "中吉", "小吉", "末吉" }[new Random().Next(4)]; clovaResponse.AddText($"{fortune} は {result} です。"); break; default: // 認識できなかったインテント clovaResponse.AddText("こめんなさい。よくわかりませんでした。例えば健康運を占ってと言うと健康運を占います。"); clovaResponse.ShouldEndSession = false; // スキルを終わらせないように設定する break; } break; } // レスポンスとして作成した返事の内容を返す return(new OkObjectResult(clovaResponse)); }
public static async Task <IActionResult> Clova( [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log) { var clovaClient = new ClovaClient(); var request = await clovaClient.GetRequest(req.Headers["SignatureCEK"], req.Body); var response = await HandleRequestAsync(request); return(new OkObjectResult(response)); }
public static async Task <IActionResult> Run( [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, [OrchestrationClient] DurableOrchestrationClientBase starter, ILogger log) { var client = new ClovaClient(); var cekRequest = await client.GetRequest(req.Headers["SignatureCEK"], req.Body); var application = new Application(new ClovaAdapter(), starter, log); return(new OkObjectResult(await application.ExecuteAsync(cekRequest))); }
public static async Task <IActionResult> Line([HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, ExecutionContext context, ILogger log) { var client = new ClovaClient(); var cekRequest = await client.GetRequest(req.Headers["SignatureCEK"], req.Body); var cekResponse = new CEKResponse(); switch (cekRequest.Request.Type) { case RequestType.LaunchRequest: cekResponse.AddText(IntroductionMessage); cekResponse.ShouldEndSession = false; break; case RequestType.IntentRequest: { var r = await HandleIntentAsync(cekRequest.Request.Intent.Name); cekResponse.AddText(r.ResponseMessage); // 最新記事が見つかったので LINE にプッシュ通知する if (r.Blog != null) { var config = new ConfigurationBuilder() .SetBasePath(context.FunctionAppDirectory) .AddJsonFile("local.settings.json", true) .AddEnvironmentVariables() .Build(); var secret = config.GetValue <string>("LineMessagingApiSecret"); var messagingClient = new LineMessagingClient(secret); await messagingClient.PushMessageAsync( to : cekRequest.Session.User.UserId, messages : new List <ISendMessage> { new TextMessage($"ちょまどさんの最新記事はこちら!"), new TextMessage($@"タイトル『{r.Blog.Title}』 {r.Blog.Url}"), }); } } break; } return(new OkObjectResult(cekResponse)); }
public static async Task <IActionResult> Run( [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, [Table("LocationLogs")] CloudTable locationLogs, ExecutionContext context, ILogger log) { var config = AppConfiguration.GetConfiguration(context); var client = new ClovaClient(); var request = await client.GetRequest(req.Headers["SignatureCEK"], req.Body); switch (request.Request.Type) { case RequestType.LaunchRequest: return(await ExecuteLaunchRequestAsync(request, locationLogs, config)); } return(new BadRequestResult()); }
public async Task <IActionResult> Post() { var client = new ClovaClient(); var cekRequest = await client.GetRequest( Request.Headers["SignatureCEK"], Request.Body); var cekResponse = new CEKResponse(); switch (cekRequest.Request.Type) { case RequestType.LaunchRequest: { cekResponse.AddText("スキル設定画面で設定したパソコンのアプリケーションを起動します。"); cekResponse.ShouldEndSession = false; break; } case RequestType.IntentRequest: { switch (cekRequest.Request.Intent.Name) { case "LaunchAppIntent": var name = cekRequest.Request.Intent.Slots["name"]; if (SchemeMap.ContainsKey(name.Value)) { var ignore = InvokeAppAsync(cekRequest.Session.User.AccessToken, SchemeMap[name.Value]); cekResponse.AddText($"{name.Value}を起動しました。"); } break; } break; } case RequestType.SessionEndedRequest: { break; } } return(new OkObjectResult(cekResponse)); }
public ClovaController() { client = new ClovaClient(); }
public static async Task <IActionResult> CEKEndpoint( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, [OrchestrationClient] DurableOrchestrationClient client, ExecutionContext context, ILogger log) { var cekResponse = new CEKResponse(); var clovaClient = new ClovaClient(); var cekRequest = await clovaClient.GetRequest(req.Headers["SignatureCEK"], req.Body); var userId = cekRequest.Session.User.UserId; log.LogInformation(cekRequest.Request.Type.ToString()); switch (cekRequest.Request.Type) { case RequestType.LaunchRequest: { cekResponse.AddText("腹話術を開始します。準備はいいですか?"); cekResponse.ShouldEndSession = false; break; } case RequestType.IntentRequest: { switch (cekRequest.Request.Intent.Name) { case "Clova.GuideIntent": cekResponse.AddText("LINEに入力をした内容をしゃべります。。。" + "LINEでセリフを事前にテンプレートとして登録したり、" + "英語や韓国語への翻訳モードに変更することもできます。" + "準備はいいですか?"); cekResponse.ShouldEndSession = false; break; case "Clova.YesIntent": case "ReadyIntent": // 友だち追加チェック try { await messagingClient.GetUserProfileAsync(userId); } catch { cekResponse.AddText("連携するLINEアカウントが友だち追加されていません。" + "Clovaアプリの本スキルのページから、連携するLINEアカウントを友だち追加してください。"); break; } await client.StartNewAsync(nameof(WaitForLineInput), userId, null); cekResponse.AddText("LINEに入力をした内容をしゃべります。好きな内容をLINEから送ってね。"); // 無音無限ループに入る KeepClovaWaiting(cekResponse); break; case "Clova.PauseIntent": case "PauseIntent": // 無限ループ中の一時停止指示に対し、スキル終了をする await client.TerminateAsync(userId, "intent"); cekResponse.AddText("腹話術を終了します。"); break; case "Clova.NoIntent": case "Clova.CancelIntent": case "NotReadyIntent": // オーケストレーターが起動していないなら終了 { var status = await client.GetStatusAsync(userId); if (status?.RuntimeStatus != OrchestrationRuntimeStatus.ContinuedAsNew && status?.RuntimeStatus != OrchestrationRuntimeStatus.Pending && status?.RuntimeStatus != OrchestrationRuntimeStatus.Running) { cekResponse.AddText("腹話術を終了します。"); } else { KeepClovaWaiting(cekResponse); } break; } case "Clova.FallbackIntent": case "NoActionIntent": // 「ね」が準備OKのインテントに振り分けられてしまったので別途インテントに定義しておく default: // オーケストレーター起動中なら無音無限ループ // これを行わないとClovaが通常の返しをしてしまう { var status = await client.GetStatusAsync(userId); if (status?.RuntimeStatus == OrchestrationRuntimeStatus.ContinuedAsNew || status?.RuntimeStatus == OrchestrationRuntimeStatus.Pending || status?.RuntimeStatus == OrchestrationRuntimeStatus.Running) { KeepClovaWaiting(cekResponse); } break; } } break; } case RequestType.EventRequest: { // オーディオイベントの制御 // Clovaでのオーディオ再生が終わった際に呼び出される if (cekRequest.Request.Event.Namespace == "AudioPlayer") { if (cekRequest.Request.Event.Name == "PlayFinished") { // 終わっていなければ無音再生リクエストを繰り返す var status = await client.GetStatusAsync(userId); if (status.RuntimeStatus == OrchestrationRuntimeStatus.ContinuedAsNew || status.RuntimeStatus == OrchestrationRuntimeStatus.Pending || status.RuntimeStatus == OrchestrationRuntimeStatus.Running) { KeepClovaWaiting(cekResponse); } else if (status.RuntimeStatus == OrchestrationRuntimeStatus.Completed) { // 完了していた場合(=LINEからの外部イベント処理が実行された場合) // 再度セッション継続 KeepClovaWaiting(cekResponse); var translationStatus = await client.GetStatusAsync("translation_" + userId); if (translationStatus?.RuntimeStatus == OrchestrationRuntimeStatus.ContinuedAsNew || translationStatus?.RuntimeStatus == OrchestrationRuntimeStatus.Running || translationStatus?.RuntimeStatus == OrchestrationRuntimeStatus.Pending) { var lang = translationStatus.CustomStatus.ToString(); // ユーザー入力 var body = new object[] { new { Text = status.Output.ToObject <string>() } }; var requestBody = JsonConvert.SerializeObject(body); // 翻訳 using (var request = new HttpRequestMessage()) { request.Method = HttpMethod.Post; request.RequestUri = new Uri(Consts.AzureCognitiveTranslatorEndpoint + lang); request.Content = new StringContent(requestBody, Encoding.UTF8, "application/json"); request.Headers.Add("Ocp-Apim-Subscription-Key", Consts.AzureCognitiveTranslatorKey); var response = await httpClient.SendAsync(request); // 結果の取得とデシリアライズ var jsonResponse = await response.Content.ReadAsStringAsync(); var result = JsonConvert.DeserializeObject <List <TranslatorResult> >(jsonResponse); // 入力内容を話させる cekResponse.AddText(result[0].Translations[0].Text, lang switch { "en" => Lang.En, "ko" => Lang.Ko, "ja" => Lang.Ja, _ => throw new InvalidOperationException() }); }
public static async Task <IActionResult> CEKEndpoint( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, [OrchestrationClient] DurableOrchestrationClient client, ExecutionContext context, ILogger log) { var cekResponse = new CEKResponse(); var clovaClient = new ClovaClient(); var cekRequest = await clovaClient.GetRequest(req.Headers["SignatureCEK"], req.Body); var userId = cekRequest.Session.User.UserId; log.LogInformation(cekRequest.Request.Type.ToString()); switch (cekRequest.Request.Type) { case RequestType.LaunchRequest: { await client.StartNewAsync(nameof(WaitForLineInput), userId, null); cekResponse.AddText("LINEに入力をした内容をしゃべります。"); // 無音無限ループに入る KeepClovaWaiting(cekResponse); break; } case RequestType.IntentRequest: { // インテントリクエストは特に用意しない break; } case RequestType.EventRequest: { // オーディオイベントの制御 // Clovaでのオーディオ再生が終わった際に呼び出される if (cekRequest.Request.Event.Namespace == "AudioPlayer") { if (cekRequest.Request.Event.Name == "PlayFinished") { // 終わっていなければ無音再生リクエストを繰り返す var status = await client.GetStatusAsync(userId); if (status.RuntimeStatus == OrchestrationRuntimeStatus.ContinuedAsNew || status.RuntimeStatus == OrchestrationRuntimeStatus.Pending || status.RuntimeStatus == OrchestrationRuntimeStatus.Running) { KeepClovaWaiting(cekResponse); } else if (status.RuntimeStatus == OrchestrationRuntimeStatus.Completed) { // 完了していた場合(=LINEからの外部イベント処理が実行された場合) // 再度セッション継続 KeepClovaWaiting(cekResponse); // 入力内容を話させる cekResponse.AddText(status.Output.ToObject <string>()); // オーケストレーターを再実行 await client.StartNewAsync(nameof(WaitForLineInput), userId, null); } else if (status.RuntimeStatus == OrchestrationRuntimeStatus.Failed) { // 失敗していたら結果をしゃべって終了 cekResponse.AddText("失敗しました。"); } else if (status.RuntimeStatus == OrchestrationRuntimeStatus.Terminated) { // Botからのスキル停止指示 cekResponse.AddText("腹話術を終了します。"); } } else if (cekRequest.Request.Event.Name == "PlayPaused") { await client.TerminateAsync(userId, "PlayPaused"); } } break; } case RequestType.SessionEndedRequest: { // スキル終了の場合は処理もキャンセル await client.TerminateAsync(userId, "SessionEndedRequest"); cekResponse.AddText("終了します。"); break; } } return(new OkObjectResult(cekResponse)); }
public static async Task <IActionResult> Lab( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, [OrchestrationClient] DurableOrchestrationClient client, ExecutionContext context, ILogger log) { var config = ConfigurationManager.GetConfiguration(context); var clovaClient = new ClovaClient(); var cekRequest = await clovaClient.GetRequest( req.Headers["SignatureCEK"], req.Body, config.IsSkipRequestValidation ); var cekResponse = new CEKResponse(); switch (cekRequest.Request.Type) { case RequestType.LaunchRequest: { // UserId をインスタンス ID として新しい関数を実行 await client.StartNewAsync(nameof(LongTimeOrchestrationFunction), cekRequest.Session.User.UserId, null); cekResponse.AddText("時間のかかる処理を実行しました。結果を教えてと聞くと結果を答えます。"); cekResponse.ShouldEndSession = false; break; } case RequestType.IntentRequest: { switch (cekRequest.Request.Intent.Name) { case "GetResultIntent": // インスタンス ID が UserId の状態を取得 var status = await client.GetStatusAsync(cekRequest.Session.User.UserId); // 状態に応じて応答を設定 switch (status.RuntimeStatus) { case OrchestrationRuntimeStatus.Canceled: cekResponse.AddText("キャンセルされてます"); break; case OrchestrationRuntimeStatus.Completed: cekResponse.AddText($"終わりました。結果は{status.Output.ToObject<string>()}です。"); break; case OrchestrationRuntimeStatus.ContinuedAsNew: cekResponse.AddText("やり直してます。もうちょっと待ってね。進捗どうですかと聞いてください。"); cekResponse.ShouldEndSession = false; break; case OrchestrationRuntimeStatus.Failed: cekResponse.AddText("失敗しました。"); break; case OrchestrationRuntimeStatus.Pending: cekResponse.AddText("もうちょっと待ってね。進捗どうですかと聞いてください。"); cekResponse.ShouldEndSession = false; break; case OrchestrationRuntimeStatus.Running: cekResponse.AddText("もうちょっと待ってね。進捗どうですかと聞いてください。"); cekResponse.ShouldEndSession = false; break; case OrchestrationRuntimeStatus.Terminated: cekResponse.AddText("失敗しました。"); break; } break; default: cekResponse.AddText("すみません。よくわかりませんでした。"); break; } break; } case RequestType.SessionEndedRequest: { // 途中で終了されたら終わらせておく await client.TerminateAsync(cekRequest.Session.User.UserId, "User canceled"); break; } } return(new OkObjectResult(cekResponse)); }
public static async Task <IActionResult> LongTimeFunction( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, [OrchestrationClient] DurableOrchestrationClient client, ExecutionContext context, ILogger log) { var cekResponse = new CEKResponse(); var clovaClient = new ClovaClient(); var cekRequest = await clovaClient.GetRequest(req.Headers["SignatureCEK"], req.Body); var userId = cekRequest.Session.User.UserId; switch (cekRequest.Request.Type) { case RequestType.LaunchRequest: { // sessionId をインスタンス ID として新しい関数を実行 await client.StartNewAsync(nameof(LongTimeOrchestrationFunction), userId, null); cekResponse.AddText("時間のかかる処理を実行しました。少々お待ちください。"); // 無音無限ループに入る KeepClovaWaiting(cekResponse); break; } case RequestType.IntentRequest: { // インテントリクエストは特に用意しない cekResponse.AddText("すみません。よくわかりませんでした。"); break; } case RequestType.EventRequest: { // オーディオイベントの制御 // Clovaでのオーディオ再生が終わった際に呼び出される if (cekRequest.Request.Event.Namespace == "AudioPlayer") { if (cekRequest.Request.Event.Name == "PlayFinished") { var status = await client.GetStatusAsync(userId); log.LogInformation(status.RuntimeStatus.ToString()); // 終わっていなければ無音再生リクエストを繰り返す if (status.RuntimeStatus == OrchestrationRuntimeStatus.ContinuedAsNew || status.RuntimeStatus == OrchestrationRuntimeStatus.Pending || status.RuntimeStatus == OrchestrationRuntimeStatus.Running) { KeepClovaWaiting(cekResponse); cekResponse.ShouldEndSession = false; } else if (status.RuntimeStatus == OrchestrationRuntimeStatus.Completed) { // 終了していたら結果をしゃべって終了 cekResponse.AddText($"終わりました。結果は{status.Output.ToObject<string>()}です。"); } else if (status.RuntimeStatus == OrchestrationRuntimeStatus.Failed) { // 失敗していたら結果をしゃべって終了 cekResponse.AddText("失敗しました。"); } } else if (cekRequest.Request.Event.Name == "PlayStopped") { await client.TerminateAsync(userId, "Cancel"); } } break; } case RequestType.SessionEndedRequest: { // スキル終了の場合は処理もキャンセル await client.TerminateAsync(userId, "Cancel"); break; } } return(new OkObjectResult(cekResponse)); }
public static async Task <IActionResult> Line( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, ExecutionContext context, ILogger log) { var client = new ClovaClient(); var cekRequest = await client.GetRequest(req.Headers["SignatureCEK"], req.Body); var cekResponse = new CEKResponse(); switch (cekRequest.Request.Type) { // 起動時に飛んでくる intent case RequestType.LaunchRequest: cekResponse.AddText(IntroductionMessage[0]); cekResponse.ShouldEndSession = false; break; // ユーザ定義の intent case RequestType.IntentRequest: { // slot を抜き出す CEK.CSharp.Models.Slot when = null; cekRequest.Request.Intent.Slots?.TryGetValue(key: "when", value: out when); // intent ごとに処理を振り分け var texts = await HandleIntentAsync(cekRequest.Request.Intent.Name, when?.Value ?? "今日", Platforms.Clova); if (texts.Any()) { foreach (var text in texts) { cekResponse.AddText(text); } } else { cekResponse.AddText("予定はありません。"); } // 予定があったら LINE にプッシュ通知する if (texts.Any()) { var config = Models.AuthenticationConfigModel.ReadFromJsonFile("appsettings.json"); var secret = config.LineMessagingApiSecret; var textMessages = new List <ISendMessage>(); textMessages.Add(new TextMessage("ちょまどさんの予定はこちら!")); foreach (var text in texts) { textMessages.Add(new TextMessage(text)); } var messagingClient = new LineMessagingClient(secret); await messagingClient.PushMessageAsync( //to: cekRequest.Session.User.UserId, to : config.MessagingUserId, messages : textMessages ); } } break; } return(new OkObjectResult(cekResponse)); }
public QuizController() { clova = new ClovaClient(); }