github.com/456vv/valexa@v1.0.2-0.20200706152242-1fb922d71ce5/Alexa.go (about) 1 package valexa 2 3 import ( 4 "net/http" 5 "fmt" 6 "sync" 7 ) 8 9 10 type Alexa struct{ 11 //如:https://www.xxx.com/?appid=amzn1.ask.skill.594232d8-4095-499b-9ba3-11701107834s&type=1 12 //这个 appid 是程序属性名称,其中的值是 amzn1.ask.skill.594232d8-4095-499b-9ba3-11701107834s 13 //这个 type 是程序类型属性名称,暂时仅支持 Echo,值也就是 1。其它值不支持 14 //在Alexa后台,Configuration->Global Fields->Endpoint->Service Endpoint Type->选择HTTPS 15 //Default 填入 https://www.xxx.com/?appid=amzn1.ask.skill.594232d8-4095-499b-9ba3-11701107834s&type=1 16 AppIdAttr string //程序的名称,如:appid 17 echoApps *sync.Map //map[ID名]*EchoApplication 18 } 19 20 //设置Echo程序 21 // alexaAppId string Alexa程序ID名 22 // app *EchoApplication Echo对象 23 func (T *Alexa) SetEchoApp(alexaAppId string, app *EchoApplication){ 24 if T.echoApps == nil { 25 T.echoApps = &sync.Map{} 26 } 27 if app == nil { 28 T.echoApps.Delete(alexaAppId) 29 return 30 } 31 T.echoApps.Store(alexaAppId, app) 32 } 33 34 //服务处理 35 // w http.ResponseWriter http响应对象 36 // r *http.Request http请求对象 37 func (T *Alexa) ServeHTTP(w http.ResponseWriter, r *http.Request){ 38 var( 39 query = r.URL.Query() 40 appId = query.Get(T.AppIdAttr) 41 ) 42 if appId == "" { 43 http.Error(w, fmt.Sprintf("valexa: 请求数据参数不完整,缺少程序ID名(AppIdAttr=%s)", appId), 400) 44 return 45 } 46 47 if T.echoApps == nil { 48 http.Error(w, fmt.Sprintf("valexa: 服务器配置为空,请使用 .SetEchoApp 方法来设置配置。"), 400) 49 return 50 } 51 inf, ok := T.echoApps.Load(appId) 52 if !ok { 53 http.Error(w, fmt.Sprintf("valexa: 该程序Id(AppIdAttr=%s)不是有效的", appId), 400) 54 return 55 } 56 echoApp := inf.(*EchoApplication) 57 58 crb := &checkRequestBody{R:r} 59 //如果调试ID不相等,则验证Body 60 if !echoApp.IsDevelop { 61 //验证数据 62 _, err := crb.verifyBody(echoApp) 63 if err != nil { 64 http.Error(w, err.Error(), 400) 65 return 66 } 67 } 68 echoReq, err := crb.echoRequest(echoApp) 69 if err != nil { 70 http.Error(w, err.Error(), 400) 71 return 72 } 73 //处理语音服务 74 eialexa := &EchoIntent{ 75 Request : echoReq, 76 Response : NewEchoResponse(), 77 App : echoApp, 78 } 79 eialexa.ServeHTTP(w, r) 80 } 81 82 83 //strSliceContains 从切片中查找匹配的字符串 84 // 参: 85 // ss []string 切片 86 // s string 需要从切片中查找的字符 87 func strSliceContains(ss []string, s string) bool { 88 for _, v := range ss { 89 if v == s { 90 return true 91 } 92 } 93 return false 94 } 95 96