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