Google Home Mini ãå®ããªã£ã¦ããã®ã§è²·ãã¾ããã
#Echoæå¾ æ¥ãªã pic.twitter.com/PuGa5B3o4S
— ãã (@iseebi) December 9, 2017
ã¹ã¿ã¼ãã¬ãã¯ã好ããªåã¨ãã¦ã¯èµ·åã¯ã¼ãããã³ã³ãã¥ã¼ã¿ã¼ãã«ã§ãã Amazon Echo ãæ¬å½ãªã®ã§ãããå ¨ãæå¾ ãããªãã®ã§ä»æ¹ãããã¾ããã
radiko ããã¼ã¦ã¼ã¶ã¼ãªã®ã§ radiko ã®åçã»åæ¢ããã¤ã¹ã³ãã³ãã§ã§ããã¨ããã®ã楽ãã¿ã«ãã¦ãã¾ããããradiko ãã¬ãã¢ã ã使ããªãã®ã§ FM802 ããããããªãã®ã§ãã¾ãæå³ãããã¾ãããã¾ããé³æ¥½ã«ã¤ãã¦ã Google Music ãå¥ç´ããã°èªåã®æ²ãã¢ãããã¼ãã§ããããã«ãªããããªã®ã§ãããæ 980 å追å ããã®ã¯ Netflix*1 ããããã¡ãã£ã¨â¦ããã¨ãã¤ã¹ã§ãããããã¨ã¨ããã¨å®¶é»ã®æä½ã§ãããNature Remo ãè²·ã£ã¦ã¾ã çºéãããªãã®ã§ãã°ãããé ãã§ãã
ãã¦ãä¼ç¤¾ã§ãå¤ãã®æ¹ã§ãã¨æ調åæªãã¦ãä¼ã¿ããã¨ãã£ãã¨ãã¯é£çµ¡ãããã¨æãã¾ããä¾ãã°ããããé£çµ¡ãå¿ è¦ãªã·ããªãªã ã¨ãã¾ããâ¦ããã¾ã§ã·ããªãªã§ãã
- ä¸å¸ã«é»è©±é£çµ¡ãã¦æ¿èªãå¾ã
- åé¡ãªããã°ã¡ã¼ã«ã§å ¨ä½é£çµ¡ãã
ã¡ã¼ã«ã®éä¿¡ã ãã§ããã° IFTTT ã«ãããã¾ãããæ¬æã«æ¹è¡å ¥ãã¦ãæ¹è¡ããã¾ãããæ§å¼ãéãããæ¥æ¬ã®ä¼æ¥ã¨ãã¦ã¯ãªããªãå³ããã§ãã ãã£ããã®ããã¼å ¨ä½ãä½ã£ã¦ãããGoogle Homeã«ãååä¼ãããã¨è¨ã£ããä¸å¸ã«é»è©±é£çµ¡ãã¦æ¿èªãåããOKããã£ããã¡ã¼ã«ãã¦ããããããªä»çµã¿ãä½ã£ã¦ã¿ã¾ããã
ããã¼ã®è¨è¨
ãã®ãããªããã¼ãçµã¿ç«ã¦ããã¨ã«ãã¾ããã
- èµ·åããªã¬ã¼ã¯ãIFTTT ãããã¤ã¹ã³ãã³ãã§åã㦠Webhook ãå©ããã¨ã«ãã¾ãã
- Webhook ãåããå ã§ã¯ Twilio API ã使ã£ã¦ä¸å¸ã«é»è©±ãããã¾ã
- é£çµ¡ãåããä¸å¸ãæã®æé帯ã¯éå¤ãªã©ã§å¿ããã¨æãã¾ãããªã®ã§åç´ã«é»è©±ãåãã°æ¿èªãä½ããã¼ãæ¼ãã°è¦ä»¶ãããã®ã§æãè¿ãã¦ãããã¨ããããã«ãã¾ãã
- æ¿èªããããã¡ã¼ã«ãéãã¾ã
- çµæã¯èªåã® LINE ã«é£ã°ãã¾ãã
HTTP ã§åãåããã¨ã«ãªãã¾ãããä»å㯠Azure Functions ã使ã£ã¦ã¿ã¾ãããTwilio ã§ã¯ä¼è©±ã®å 容ã TwiML ã¨ããå½¢å¼ã® XML ã§æ¸ãã¾ãããä¸çªæåã®é»è©±ããããã¨ããã§ã®æ å ±åå¾ã®ããã« BLOB ã¹ãã¬ã¼ã¸ãä¸å¸ã®è¿çãä¿åããããã«ãã¼ãã«ã¹ãã¬ã¼ã¸ã使ãã¾ããã
Azure Functions ã«ã¤ãã¦
Azure Functions ã«ã¤ãã¦ã¯ãã®è¨äºããã®ãªã³ã¯å ã«ããå 容ãã¾ã¨ã¾ã£ã¦ã¦ä¾¿å©ã§ããã
è¦æ¨ãã¾ã¨ããã¨ã
- éè¦ãªæ
å ±ã¯ã¢ããªã±ã¼ã·ã§ã³è¨å®ã«æ¸ãã
ConfigurationManager.AppSettings["xxx"]
ããåå¾ããã- æ¨æºãªæãã®ã¢ã»ã³ããªã¯ãã¡ã¤ã«ã®å
é ã«
#r "System.Configuration"
çãæ¸ãã¨åç §ã§ããã
- æ¨æºãªæãã®ã¢ã»ã³ããªã¯ãã¡ã¤ã«ã®å
é ã«
- NuGet ããã±ã¼ã¸ã¯ project.json ãä½ãã¨èªã¿è¾¼ããããã®ã¨ãã¯
#r
æ¶é¤ - å®ä½ã¯ 1 é¢æ°ãã¨ã«ãã©ã«ããä½ããã¦ãããApp Service ã¨ãã£ã¿ã¼ãéãã¨ãã®ãã©ã«ãã®ä¸ã®é層㫠csx ãã¡ã¤ã«ãä½ããã¨ãã§ãããã®ãã¡ã¤ã«ã¯ç¸å¯¾ãã¹ã§ãã¡ã¤ã«ã®å
é ã«
#load "..\hoge.csx"
ã§ãã¼ãã§ããå ±éå¦çãæ¸ããã
Twilio ã«ã¤ãã¦
Twilio ã®ãã¤ã³ãããã£ã¨ã
- ã¾ãé»è©±çªå·ãåå¾ããã108å/æã®ç¶æè²»ããããã
- é話æéã¯æºå¸¯é»è©±ã«ããã㨠16.2 å/å
- TwiML ã¨ãã XML ã§çºè©±å 容ãè¨è¿°ãããæåã®ã³ã¼ã«ã®ã¨ãã«èªã¿è¾¼ã¿å ã® URL ãæå®ããããçªå·ããã·ã¥ã®å¿ç㧠POST ããã¨ãã«çµæè¿çããã¨ãã«ãã®å½¢å¼ã§è¿ãã
- 使ã£ã HTTP ãªã¯ã¨ã¹ãã®ãã°ãå ¨é¨ãããã°ã©ããã«Voiceãã®ããã°ãã«æ®ãã®ã§ãããã°ã«ä¾¿å©ã
- ãã©ã¤ã¢ã«ä¸ã¯ç¢ºèªæ¸ã¿ã®çªå·ã«ãããããããªãããã®ç¢ºèªã®é»è©±ãAPI課éããã
- ã¢ã«ã¦ã³ããã¢ã¯ãã£ãã¼ãããã¨ãã©ã¤ã¢ã«ã®æ®é«ã¯å¬ãä¸ãã«ãªã
å®è£
ã§ã¯å®è£ ãè¦ã¦ããã¾ãããã
å ±éå¦çã®æºå
ã¾ããAzure Functions ã¯ãJSON ã§ããã°ç´æ¥å¦çã§ãããããã®ã§ãããTwilio 㯠HTTP ãã©ã¼ã å½¢å¼ã§ãªã¯ã¨ã¹ããéã£ã¦ãã¾ãã®ã§ãããããã¼ã¹ããä»çµã¿ãç¨æãã¾ãã
Azure Functions ã®è¨å®ãã¼ã¸ãããApp Service ã¨ãã£ã¿ã¼ããéãã¾ãããã®ãããã«ããã¾ãã
WWWROOT ç´ä¸ã«ãã¡ã¤ã«ãä½æãã¾ãã
using System; using System.Collections.Generic; using System.Threading.Tasks; public static async Task<Dictionary<string, string>> ParseHttpForm(this HttpRequestMessage req) { var keyValues = new Dictionary<string, string>(); var reqString = await req.Content.ReadAsStringAsync(); foreach (var item in reqString.Split('&')) { var nameValueItem = item.Split('='); var valueStr = Uri.UnescapeDataString(nameValueItem[1].Replace("+", " ")); keyValues.Add(nameValueItem[0], valueStr); } return keyValues; }
ã¾ãããã®å
ConfigurationManager.AppSettings
ã«ããå®æ°å¤ã¯ãã¢ããªã±ã¼ã·ã§ã³è¨å®ãã«æ¸ãã¦ããã¾ãããã®ãããã«ããã¾ãã
ä»åã¯æçµçã«ãã®ãããªå¤ãå®ç¾©ãã¾ããã
é»è©±ãããã - CallBossByTwilio
ã§ã¯ãFunction ãä½ã£ã¦ããã¾ãããé¢æ°ãã®ã¨ããããã¤ã³ãããã¨ç¾ãããï¼ããã¿ã³ãã¯ãªãã¯ãã¦ãHTTP Triggerããé¸ã³ãC# ã® CallBossByTwilio ãä½ãã¾ãã
Twilio ã® SDK ã使ãããã®ã§ãå³ãã¤ã³ã®ããã¡ã¤ã«ã®è¡¨ç¤ºããéãã¦ãproject.jsonãã追å ãã¾ããåæç¶æ ã§ã¯ããããåå¨ããªããã¡ã¤ã«ãªã®ã§ãæ°è¦ä½æããå¿ è¦ãããã¾ããproject.json ãä½ã£ã¦å 容ãåæ ããã¨ãèªåçã« nuget restore ãåããproject.json.lock ãä½æããã¾ãã
{ "frameworks": { "net46":{ "dependencies": { "Twilio": "5.9.1" } } } }
run.csx ã®å 容ã¯ãã®ããã«ãã¾ãã
#r "System.Configuration" using System; using System.Configuration; using System.Net; using Twilio; using Twilio.Rest.Api.V2010.Account; using Twilio.Types; using System.Collections.Generic; public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log) { var accountSid = ConfigurationManager.AppSettings["TWILIO_ACCOUNT_SID"]; var authToken = ConfigurationManager.AppSettings["TWILIO_AUTH_TOKEN"]; var telNumber = ConfigurationManager.AppSettings["TWILIO_TEL_NUMBER"]; var bossTelNumber = ConfigurationManager.AppSettings["BOSS_TEL_NUMBER"]; var twimlFileUri = new Uri(ConfigurationManager.AppSettings["URL_BOSS_CALL_TWIML"]); var fallbackUri = new Uri(ConfigurationManager.AppSettings["URL_TWILIO_FALLBACK"]); var callbackUri = new Uri(ConfigurationManager.AppSettings["URL_TWILIO_CALLBACK"]); TwilioClient.Init(accountSid, authToken); var res = await CallResource.CreateAsync( to: new PhoneNumber(bossTelNumber), from: new PhoneNumber(telNumber), url: twimlFileUri, method: "get", fallbackUrl: fallbackUri, fallbackMethod: "post", statusCallback: callbackUri, statusCallbackMethod: "post", statusCallbackEvent: new List<string> { "completed" } ); return req.CreateResponse(HttpStatusCode.OK, res.Sid); }
ãã®ã¨ããurl ã¯é»è©±ã«åºãã¨ãã«æµããã TwiML ã®åå¾å ãfallbackUri ã¯ã¨ã©ã¼çã®æã«å¼ã°ãã URLãstatusCallback ã¯å種ã¤ãã³ãã®æã«å¼ã°ãã URL ã§ããä»åãã¤ãã³ããã¯é話å¦çå®äºã® completed ã®ã¿ãã³ã¼ã«ããã¯ããããã«ãã¾ããã
TwiML ã¯ä»¥ä¸ã®ãããªå 容ã«ãã¾ãããä¸å¸ã«ä¼ããã¨ãé³å£°ã§ä¼ããæ¿èªã§ãããã°é»è©±ãåããä½ãããã®ã§ããã°ã©ãããã¿ã³ã 1 ã¤æ¼ãã¦ãããã®ã§ããããåãä»ããããã«ãã¾ãã
<?xml version="1.0" encoding="UTF-8"?> <Response> <Say voice="alice" language="ja-JP">ãã¯ãããããã¾ããä¼å¢ã§ããä½èª¿ä¸è¯ã®ããååãã ããã¾ãããããããã°ãã®ã¾ã¾é»è©±ããåããã ãããä¸å ·åã®ããå ´åã¯ããããã®çªå·ãæ¼ãã¦ãã ããã</Say> <Gather input="dtmf" numDigits="1" action="[TwilioBossUnauthorizedã®URL]" method="POST" /> </Response>
æ©æ¢°é³å£°ã ã¨å¾®å¦ã ãªã¨ããæãã§ããããmp3 ãã¡ã¤ã«ã«èªåã®å£°ãé²é³ãã<Play>
ã§åçãããã¨è¯ãã§ãããã詳細㯠TwiML ã® Play ã®ãªãã¡ã¬ã³ã¹ã§ã
ãã® TwiML ãã©ãããåå¾ããããã¨ããã¨ããã¡ãã Functions ã§è¿ãã¦ãè¯ãã®ã§ãããå 容ãå¤ãããªãã®ã§ BLOB ã¹ãã¬ã¼ã¸ã«ç½®ãã¦ãã¾ããã¨ã«ãã¾ãããã¹ãã¬ã¼ã¸ã¢ã«ã¦ã³ããä½ããBLOB ãµã¼ãã¹ã«ã¢ãããã¼ããã¦ããã¾ãã
ä½æããé¢æ°ã® URL ã¯ãã¡ã¤ã«ã®å³ä¸ãªã³ã¯ããåå¾ã§ãã¾ãã
NGå¿çãä¿åãã - TwilioBossUnauthorized
ãã¦ãä¸å¸ã NG ã§å¿çããå ´åã¯ãå ã»ã©ã® TwiML ã® Gather ã«æå®ããã URL ã«ã³ã¼ã«ããã¯ãéããã¾ããNG å¿çã®ãã£ãé話ã«ã¤ãã¦ã¯ãã®æ å ±ãã©ããã«è¨é²ãã¦æ¬¡ã®å¦çã«æ¸¡ãå¿ è¦ãããã¾ãã
æ¼ãããçªå·ã Digits ã«å ¥ã£ã¦ãã¾ãããä»åã¯ä½¿ãã¾ããã
Twilioã®é話ã«ã¯é話ãã¨ã«ã¦ãã¼ã¯ãª CallSid ãä»ä¸ããã¾ãã®ã§ãNG å¿çã®ãã£ãé話ã®ä¸è¦§ãã©ããã«è¨é²ãã¦ãããã¨ã«ãã¾ããå ã»ã© TwiML ãç½®ããã¹ãã¬ã¼ã¸ã¢ã«ã¦ã³ãã®ãã¼ãã«ãµã¼ãã¹ãã使ããã¨ã«ãã¾ããã
ãã¼ãã«ãµã¼ãã¹ã¸ã®æ¥ç¶ã¯æ¥ç¶æååãå¿ è¦ã«ãªãã¾ããããã®ãããã«ããã¾ãã®ã§ã³ãã¼ãã¦ã¢ããªã±ã¼ã·ã§ã³è¨å®ã«æ¸ãè¾¼ãã§ããã¾ãã
次ã«ããã¼ãã«ã¹ãã¬ã¼ã¸ã«ä¿åãããã¼ã¿ã®ã¢ãã«ã¯ã©ã¹ãä½æãã¾ããApp Service ã¨ãã£ã¿ã¼ãéãã¦ãParseHttpForm.csx ã¨åãæã« CallEntity.csx ãä½æãã¾ãã
using Microsoft.WindowsAzure.Storage; using Microsoft.WindowsAzure.Storage.Table; public class CallEntity : TableEntity { public string CallSid { get; set; } public CallEntity(string callSid) { this.PartitionKey = nameof(CallEntity); this.RowKey = callSid; CallSid = callSid; } public CallEntity() { } }
ã§ã¯é¢æ°ãä½ãã¾ããããã¾ã project.json ããã
{ "frameworks": { "net46":{ "dependencies": { "WindowsAzure.Storage": "8.6.0" } } } }
run.csx ã¯ãã¡ãã
#r "System.Configuration" #load "..\ParseHttpForm.csx" #load "..\CallEntity.csx" using System.Collections.Generic; using System.Configuration; using System.Net; using System.Net.Http; using Microsoft.WindowsAzure.Storage; using Microsoft.WindowsAzure.Storage.Table; public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log) { var storageAccountString = ConfigurationManager.AppSettings["STORAGE_CONNECT_STRING"]; var keyValues = await req.ParseHttpForm(); log.Info($"answer: {keyValues["Digits"]}"); var storageAccount = CloudStorageAccount.Parse(storageAccountString); var tableClient = storageAccount.CreateCloudTableClient(); var tableReference = tableClient.GetTableReference("TwilioGozenkyuBossUnauthorizes"); await tableReference.CreateIfNotExistsAsync(); try { await tableReference.ExecuteAsync(TableOperation.Insert(new CallEntity(keyValues["CallSid"]))); } catch (Exception) { // 409 Conflict } var res = new HttpResponseMessage(System.Net.HttpStatusCode.OK); res.Content = new StringContent( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<Response>" + "<Say voice =\"alice\" language=\"ja-JP\">æ¿ç¥ãã¾ãããæ¹ãã¦ãé»è©±ãããã¾ãã</Say>" + "<Hangup />" + "</Response>", System.Text.Encoding.UTF8, "application/xml"); return res; }
ãã¼ãã«ã« CallSid ãæ¸ãè¾¼ãã§ãã¬ã¹ãã³ã¹ã®æ»ãå¤ã¨ã㦠TwiML ãè¿ãã¦ãã¾ããTwilio ã§ã¯ãã¤ãã¼ãªã³ã¯ãããããããªå½¢ã§ TwiML ãç¹ãã§ãããã¨ãã§ãã¾ãã
ã¾ãããã® TwiML ã§ã¯ Hangup
ã使ã£ã¦é»è©±ãåæããé話ãçµäºããã¦ãã¾ãã
é話ã®çµæãå¦çãã¦ã¡ã¼ã«ãéã - TwilioCallCompleted
{ "frameworks": { "net46":{ "dependencies": { "WindowsAzure.Storage": "8.6.0", "MailKit": "1.22.0" } } } }
#r "System.Configuration" #load "..\ParseHttpForm.csx" #load "..\CallEntity.csx" using System.Collections.Generic; using System.Configuration; using System.Net; using System.Net.Http; using Microsoft.WindowsAzure.Storage; using Microsoft.WindowsAzure.Storage.Table; using MailKit.Net.Smtp; using MailKit; using MimeKit; public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log) { var storageAccountString = ConfigurationManager.AppSettings["STORAGE_CONNECT_STRING"]; var lineKey = ConfigurationManager.AppSettings["LINE_KEY"]; var emailAddress = ConfigurationManager.AppSettings["MAIL_FROM"]; var toAddresses = ConfigurationManager.AppSettings["MAIL_TO"].Split(';'); var mailServer = ConfigurationManager.AppSettings["SMTP_SERVER"]; var mailServerUser = ConfigurationManager.AppSettings["SMTP_USER"]; var mailServerPassword = ConfigurationManager.AppSettings["SMTP_PASSWORD"]; var bossTelNumber = ConfigurationManager.AppSettings["BOSS_TEL_NUMBER"]; var keyValues = await req.ParseHttpForm(); // ä¸å¸ã NG ãåºããã確èªãã var storageAccount = CloudStorageAccount.Parse(storageAccountString); var tableClient = storageAccount.CreateCloudTableClient(); var tableReference = tableClient.GetTableReference("TwilioGozenkyuBossUnauthorizes"); await tableReference.CreateIfNotExistsAsync(); var result = await tableReference.ExecuteAsync(TableOperation.Retrieve(nameof(CallEntity), keyValues["CallSid"])); var approved = (result.Result == null); if (!approved) { // NG ã ã£ãããLINE Notify ã§ãã®æ¨ãéç¥ãã var httpClient = new HttpClient(); var lineReq = new HttpRequestMessage(HttpMethod.Post, "https://notify-api.line.me/api/notify"); lineReq.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", lineKey); lineReq.Content = new FormUrlEncodedContent(new Dictionary<string, string> { { "message", "ååä¼ã«ã¤ãã¦ãä¸å¸ãNGãåºãã¾ãããé»è©±ãã¦ç¢ºèªãã¦ãã ãã\n" + bossTelNumber }, }); await httpClient.SendAsync(lineReq); return req.CreateResponse(HttpStatusCode.OK, ""); } // OK ã ã£ããã¡ã¼ã«ãéä¿¡ãã var message = new MimeMessage(); message.From.Add(new MailboxAddress("Shin Ise", emailAddress)); foreach (var toAddress in toAddresses) { message.To.Add(new MailboxAddress(toAddress)); } message.Subject = $"[å¤æ é£çµ¡] ä¼å¢ {DateTimeOffset.Now.ToString("MM/dd")} ååä¼"; message.Body = new TextPart("plain") { Text = @"åä½ ãç²ããã¾ã§ãã ä¼å¢ã§ãã ä½èª¿ä¸è¯ã®ãããååä¸æ§åãè¦ã¦ããåºç¤¾ãã¾ãã ãè¿·æãããããã¾ããããããããé¡ããããã¾ãã " }; using (var client = new SmtpClient()) { client.ServerCertificateValidationCallback = (s, c, h, e) => true; client.Connect(mailServer, 587, false); client.AuthenticationMechanisms.Remove("XOAUTH2"); client.Authenticate(mailServerUser, mailServerPassword); client.Send(message); client.Disconnect(true); } // çµæã LINE Notify ã§éç¥ãã { var httpClient = new HttpClient(); var lineReq = new HttpRequestMessage(HttpMethod.Post, "https://notify-api.line.me/api/notify"); lineReq.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", lineKey); lineReq.Content = new FormUrlEncodedContent(new Dictionary<string, string> { { "message", "ååä¼ã¡ã¼ã«ãéãã¾ããã" }, }); await httpClient.SendAsync(lineReq); } return req.CreateResponse(HttpStatusCode.OK, ""); }
ããã§ã¯ 4 ã¤ã®å¦çããã¦ãã¾ãã
- ãã¼ãã«ã¹ãã¬ã¼ã¸ã«ç¾å¨ã® CallSid ã®ãã¼ã¿ãããã確èªãããããã°ä¸å¸ã NG ãåºããã¨è¨ããã¨ã«ãªãã
- NG ã ã£ããããã®æ¨ã LINE Notify ã§éç¥ããã
- OK ã ã£ãããML ã«ã¡ã¼ã«ãéããéãå
ã® ML ã¯è¤æ°ãããããªãã®ã§ã; ã§åºåããããã«ãã¦ããã
- ã¡ã¼ã«ã®éä¿¡ã«ã¯ MailKit ã使ãã¾ããã
- ããã«ãçµæã LINE Notify ã§éç¥ããã
LINE Notify ã«ã¤ãã¦ã¯ãã¼ã½ãã«ã¢ã¯ã»ã¹ãã¼ã¯ã³ãçºè¡ãã¦ã¢ããªã±ã¼ã·ã§ã³è¨å®ã«æ¸ãè¾¼ãã§ãã¾ããLINE Notify ã® API ã¯ã·ã³ãã«ã§ãç°¡åã«ãã¼ã¯ã³ãåãã¦ä¾¿å©ã§ããã
å¦ç失æãå¦çãã - TwilioFallback
ãã¦ãTwilioã®å¦çä¸ã«å¤±æããå ´å㯠FallbackUrl ã«ã¢ã¯ã»ã¹ãçºçãã¾ããä»å㯠LINE Notify ã§ãã®å 容ãéç¥ãããã¨ã«ãã¾ããã
#r "System.Configuration" #load "..\ParseHttpForm.csx" using System; using System.Configuration; using System.Collections.Generic; using System.Net; public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log) { var keyValues = await req.ParseHttpForm(); var t = ""; foreach (var kv in keyValues) { t += $"{kv.Key}: {kv.Value}\n"; } var client = new HttpClient(); var lineReq = new HttpRequestMessage(HttpMethod.Post, "https://notify-api.line.me/api/notify"); lineReq.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", lineKey); lineReq.Content = new FormUrlEncodedContent(new Dictionary<string, string> { { "message", "ååä¼é£çµ¡ã®é»è©±ã§ã¨ã©ã¼ãçºçãã¾ãã\n" + t }, }); await client.SendAsync(lineReq); }
Google Home ããã®æ¥ç¶ãå®ç¾©ãã
ãã¨ã¯ Google Home ããå¼ã³åºããããã« IFTTT ãè¨å®ããã ãã§ãã
Trigger ã Google AssistantãSay simple phaseã«ãã¦ããååä¼ ãããã«å¯¾ãã¦ãååä¼é£çµ¡ããã¾ããã¨ããè¿ãã«ãã¾ãã
å®ç¾©ããã®ã«ãã¾ãåå¿ãã¦ãããªãã¨ã㯠Google Home ã¢ããªã®ã¢ã«ã¦ã³ãã¡ãã¥ã¼ããããã¤ã¢ã¯ãã£ããã£ãã確èªããã¨ãå®éã«ã©ãããåãçãã«ãªã£ãã®ãã確èªã§ãã¾ããåã¯ãã®ãååä¼ãã¨ããããã®éã«åè§ã¹ãã¼ã¹ãå ¥ãã®ã«æ°ã¥ããªãã¦ããªããããã¾ããã
Webhook ã¯ãCallBossByTwilio ã® URL ãå ¥ãã¦ããã¾ãã
å®æï¼
ããã§å®æã§ãï¼
ãã¹ãããã¨ãã¯èªåã®æºå¸¯é»è©±ãã¡ã¼ã«ã¢ãã¬ã¹ã§ç¢ºèªãã¦ã¿ã¾ãããã
æå¾ã«
ãã®è¨äºã¯ããã¾ã§ã·ããªãªã示ãããã®ã§ãããå®éã«ããã¨ãã¯ä¼ç¤¾ã®å¶åº¦ãä¸å¸ã®ç解ãå¾ãããããªã©ã¯ãèªèº«ã§å¤æãã ããã
ã¾ãã以ä¸ã®å¦çã¯èæ ®å¤ã«ãªã£ã¦ãã¾ãã®ã§ãå¿ è¦ã«å¿ãã¦æ¡å¼µãã¦ã¿ã¦ãã ããã
- ä¸å¸ãé»è©±ã«åºãªãã£ã (answered ã®ã¤ãã³ããåãã¦ããã®ç¶æ ãä¿æãã¦ããå¿ è¦ãããã§ããã)
- é»è©±ä¸ã ã£ã (CallStatus ã busy ã«ãªã)
*1:ã¹ã¿ã¼ãã¬ãã¯å¥½ãã¨ãã¦ã¯ææ°ã·ãªã¼ãºã®ãã£ã¹ã«ããªã¼ãè¦ãããã«å¿ é