├── LICENSE.txt ├── README.md ├── bot ├── application.go ├── audio_player.go ├── audio_player_test.go ├── bot.go ├── bot_test.go ├── card │ ├── base.go │ ├── image.go │ ├── link_account.go │ ├── list.go │ ├── standard.go │ └── text.go ├── data │ └── http.go ├── directive │ ├── audio_player │ │ ├── const.go │ │ ├── play.go │ │ ├── player_info.go │ │ └── stop.go │ ├── base.go │ ├── display │ │ ├── hint.go │ │ ├── render_template.go │ │ └── template │ │ │ ├── base.go │ │ │ ├── body_template1.go │ │ │ ├── body_template2_3_4.go │ │ │ ├── body_template5.go │ │ │ ├── list.go │ │ │ ├── list_template1_2.go │ │ │ └── text_image.go │ └── video_player │ │ ├── const.go │ │ ├── play.go │ │ └── stop.go ├── event_handler.go ├── model │ ├── dialog.go │ ├── intent.go │ ├── request.go │ ├── request_test.go │ ├── response.go │ ├── response_test.go │ ├── session.go │ └── ssml_builder.go ├── test │ ├── audio-player-event.json │ ├── intent-request.json │ ├── launch.json │ └── video-player-event.json ├── util │ └── util.go ├── video_player.go └── video_player_test.go ├── doc.sh ├── doc ├── application.md ├── bot.md ├── card │ └── card.md ├── directive │ ├── audio-player.md │ ├── display │ │ ├── render-template.md │ │ └── template.md │ └── video-player.md └── model │ ├── dialog.md │ ├── intent.md │ ├── request.md │ ├── response.md │ ├── session.md │ └── ssml-text-builder.md └── example ├── audio_play └── main.go ├── flight ├── city.json └── main.go └── tax └── main.go /LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 度秘BOT SDK for GO 2 | 这是一个帮助开发Bot的SDK,针对php、java、node.js也有对应的版本.SDK封装了对session、nlu、result的处理,使用sdk可以避免由于BOT的协议的升级带来一些麻烦。这个SDK会与DuerOS的协议一起升级,会最大限度减少对您开发bot的影响。 3 | 4 | ## 通过bot-sdk可以快速的开发bot 5 | 我们的目标是通过使用bot-sdk,可以迅速的开发一个bot,而不必过多去关注DuerOS对Bot的复杂协议。我们提供如下功能: 6 | 7 | * 封装了DuerOS的request和response 8 | * 提供了session简化接口 9 | * 提供了nlu简化接口 10 | * slot 操作 11 | * nlu理解交互接口(ask) 12 | * 提供了多轮对话开发接口 13 | * 提供了事件监听接口 14 | * 展现模板、视频、音频指令的封装 15 | 16 | ## 安装、使用BOT SDK进行开发 17 | 度秘BOT SDK使用执行如下命令进行安装: 18 | ```shell 19 | go get github.com/dueros/bot-sdk-go 20 | ``` 21 | 22 | 为了开始使用BOT SDK,你需要先新建一个main文件,比如文件名是main.go。 23 | 24 | ```javascript 25 | import ( 26 | dueros "github.com/dueros/bot-sdk-go/bot" 27 | "github.com/dueros/bot-sdk-go/bot/directive/display" 28 | "github.com/dueros/bot-sdk-go/bot/directive/display/template" 29 | "github.com/dueros/bot-sdk-go/bot/model" 30 | ) 31 | 32 | func main() { 33 | 34 | application := dueros.Application{AppId: "you bot id", Handler: func(body string) string { 35 | bot := dueros.NewBot(body) 36 | 37 | // 意图处理函数 38 | bot.AddIntentHandler("test.inquiry888", 39 | func(this *dueros.Bot, request *model.IntentRequest) { 40 | template := template.NewBodyTemplate1() 41 | template.SetTitle("title") 42 | template.SetPlainContent("欢迎查询") 43 | template.SetBackgroundImageUrl("http://www.baidu.com") 44 | directive := display.NewRenderTemplate(template) 45 | 46 | this.Response.Ask("欢迎查询").Command(directive) 47 | }) 48 | 49 | // 技能被打开的请求处理 50 | bot.OnLaunchRequest(func(this *dueros.Bot, request *model.LaunchRequest) { 51 | this.Response.Tell("欢迎使用查个税") 52 | }) 53 | 54 | return bot.Run() 55 | }} 56 | application.Start(":8888") 57 | } 58 | ``` 59 | 下一步,我们处理意图。Bot-sdk提供了一个函数来handle这些意图。比如,查询个税,创建一个handler,在构造函数中添加: 60 | 61 | 62 | 这里`AddIntentHandler`可以用来建立(intent) => handler的映射,第一个参数是条件,如果满足则执行对应的回调函数(第二个参数)。 63 | 其中,this指向当前的Bot,通过Response来进行回复。`Ask`可以用来向用户澄清,`Command`可以用来返回一个指令。 64 | 65 | ## API 文档 66 | 67 | * [Bot](doc/bot.md) 68 | * [Application](doc/application.md) 69 | * model 70 | * [Request](doc/model/request.md) 71 | * [IntentRequest](doc/model/request.md) 72 | * [LaunchRequest](doc/model/request.md) 73 | * [SessionEndedRequest](doc/model/request.md) 74 | * [EventRequest](doc/model/request.md) 75 | * [Response](doc/model/response.md) 76 | * [Dialog](doc/model/dialog.md) 77 | * [Intent](doc/model/intent.md) 78 | * [Session](doc/model/session.md) 79 | * [SSMLTextBuilder](doc/model/ssml-text-builder.md) 80 | * [展现卡片(card)](doc/card/card.md) 81 | * [展现模版(template)](doc/directive/display/render-template.md) 82 | * [template](doc/directive/display/template.md) 83 | * [播放音频(audio)](doc/directive/audio-player.md) 84 | * [播放视频(video)](doc/directive/video-player.md) 85 | -------------------------------------------------------------------------------- /bot/application.go: -------------------------------------------------------------------------------- 1 | package bot 2 | 3 | import ( 4 | "bytes" 5 | "context" 6 | "crypto" 7 | "crypto/rsa" 8 | "crypto/sha1" 9 | "crypto/x509" 10 | "encoding/base64" 11 | "encoding/json" 12 | "encoding/pem" 13 | "errors" 14 | "io" 15 | "io/ioutil" 16 | "log" 17 | "net/http" 18 | "net/url" 19 | "time" 20 | 21 | "github.com/dueros/bot-sdk-go/bot/model" 22 | ) 23 | 24 | type Application struct { 25 | AppId string 26 | DisableCertificate bool 27 | DisableVerifyJson bool 28 | Handler func(rawRequest string) string 29 | } 30 | 31 | // 创建一个HTTP服务 32 | func (this *Application) ServeHTTP(w http.ResponseWriter, r *http.Request) { 33 | 34 | defer r.Body.Close() 35 | //心跳请求 36 | if r.Method == "HEAD" { 37 | // 返回204 38 | w.WriteHeader(http.StatusNoContent) 39 | return 40 | } 41 | 42 | body, err := ioutil.ReadAll(r.Body) 43 | if err != nil { 44 | log.Fatal(err) 45 | HTTPError(w, "request read failed", "Server Error", http.StatusInternalServerError) 46 | return 47 | } 48 | 49 | r = r.WithContext(context.WithValue(r.Context(), "requestBody", body)) 50 | 51 | if !this.Verify(w, r) { 52 | return 53 | } 54 | 55 | ret := this.Handler(string(body)) 56 | w.Write([]byte(ret)) 57 | } 58 | 59 | // 启动HTTP服务 60 | func (this *Application) Start(host string) { 61 | err := http.ListenAndServe(host, this) 62 | 63 | if err != nil { 64 | log.Fatal(err) 65 | } 66 | } 67 | 68 | // 验证请求是否合法 69 | func (this *Application) Verify(w http.ResponseWriter, r *http.Request) bool { 70 | if !this.DisableVerifyJson && !verifyJSON(w, r, this.AppId) { 71 | return false 72 | } 73 | 74 | if !this.DisableCertificate && !validateRequest(w, r) { 75 | return false 76 | } 77 | return true 78 | } 79 | 80 | func HTTPError(w http.ResponseWriter, logMsg string, err string, errCode int) { 81 | if logMsg != "" { 82 | log.Println(logMsg) 83 | } 84 | 85 | http.Error(w, err, errCode) 86 | } 87 | 88 | // Decode the JSON request and verify it. 89 | func verifyJSON(w http.ResponseWriter, r *http.Request, appId string) bool { 90 | req := model.Request{} 91 | 92 | body := r.Context().Value("requestBody").([]byte) 93 | 94 | if err := json.Unmarshal(body, &req.Common); err != nil { 95 | HTTPError(w, err.Error(), "Bad Request", http.StatusBadRequest) 96 | return false 97 | } 98 | 99 | // Check the timestamp 100 | if !req.VerifyTimestamp() && r.URL.Query().Get("_dev") == "" { 101 | HTTPError(w, "Request too old to continue (>180s).", "Bad Request", http.StatusBadRequest) 102 | return false 103 | } 104 | 105 | // Check the app id 106 | if !req.VerifyBotID(appId) { 107 | HTTPError(w, "DuerOS BotID mismatch!", "Bad Request", http.StatusBadRequest) 108 | return false 109 | } 110 | return true 111 | } 112 | 113 | // Run all mandatory DuerOS security checks on the request. 114 | func validateRequest(w http.ResponseWriter, r *http.Request) bool { 115 | // Check for debug bypass flag 116 | devFlag := r.URL.Query().Get("_dev") 117 | 118 | isDev := devFlag != "" 119 | 120 | if !isDev { 121 | isRequestValid := IsValidRequest(w, r) 122 | if !isRequestValid { 123 | return false 124 | } 125 | } 126 | return true 127 | } 128 | 129 | // IsValidRequest handles all the necessary steps to validate that an incoming http.Request has actually come from 130 | // the DuerOS service. If an error occurs during the validation process, an http.Error will be written to the provided http.ResponseWriter. 131 | // The required steps for request validation can be found on this page: 132 | // https://dueros.baidu.com/didp/doc/dueros-bot-platform/dbp-deploy/authentication_markdown 133 | func IsValidRequest(w http.ResponseWriter, r *http.Request) bool { 134 | certURL := r.Header.Get("SignatureCertUrl") 135 | 136 | // Verify certificate URL 137 | if !verifyCertURL(certURL) { 138 | HTTPError(w, "Invalid cert URL: "+certURL, "Not Authorized", http.StatusUnauthorized) 139 | return false 140 | } 141 | 142 | // Fetch certificate data 143 | certContents, err := readCert(certURL) 144 | if err != nil { 145 | HTTPError(w, err.Error(), "Not Authorized", http.StatusUnauthorized) 146 | return false 147 | } 148 | 149 | // Decode certificate data 150 | block, _ := pem.Decode(certContents) 151 | if block == nil { 152 | HTTPError(w, "Failed to parse certificate PEM.", "Not Authorized", http.StatusUnauthorized) 153 | return false 154 | } 155 | 156 | cert, err := x509.ParseCertificate(block.Bytes) 157 | if err != nil { 158 | HTTPError(w, err.Error(), "Not Authorized", http.StatusUnauthorized) 159 | return false 160 | } 161 | 162 | // Check the certificate date 163 | if time.Now().Unix() < cert.NotBefore.Unix() || time.Now().Unix() > cert.NotAfter.Unix() { 164 | HTTPError(w, "DuerOS certificate expired.", "Not Authorized", http.StatusUnauthorized) 165 | return false 166 | } 167 | 168 | // Check the certificate alternate names 169 | foundName := false 170 | for _, altName := range cert.Subject.Names { 171 | if altName.Value == "dueros-api.baidu.com" { 172 | foundName = true 173 | } 174 | } 175 | 176 | if !foundName { 177 | HTTPError(w, "DuerOS certificate invalid.", "Not Authorized", http.StatusUnauthorized) 178 | return false 179 | } 180 | 181 | // Verify the key 182 | publicKey := cert.PublicKey 183 | encryptedSig, _ := base64.StdEncoding.DecodeString(r.Header.Get("Signature")) 184 | 185 | // Make the request body SHA1 and verify the request with the public key 186 | //var bodyBuf bytes.Buffer 187 | hash := sha1.New() 188 | _, err = io.Copy(hash, bytes.NewReader(r.Context().Value("requestBody").([]byte))) 189 | if err != nil { 190 | HTTPError(w, err.Error(), "Internal Error", http.StatusInternalServerError) 191 | return false 192 | } 193 | 194 | err = rsa.VerifyPKCS1v15(publicKey.(*rsa.PublicKey), crypto.SHA1, hash.Sum(nil), encryptedSig) 195 | if err != nil { 196 | HTTPError(w, "Signature match failed.", "Not Authorized", http.StatusUnauthorized) 197 | return false 198 | } 199 | 200 | return true 201 | } 202 | 203 | func readCert(certURL string) ([]byte, error) { 204 | cert, err := http.Get(certURL) 205 | if err != nil { 206 | return nil, errors.New("Could not download DuerOS cert file.") 207 | } 208 | defer cert.Body.Close() 209 | certContents, err := ioutil.ReadAll(cert.Body) 210 | if err != nil { 211 | return nil, errors.New("Could not read DuerOS cert file.") 212 | } 213 | 214 | return certContents, nil 215 | } 216 | 217 | func verifyCertURL(path string) bool { 218 | link, _ := url.Parse(path) 219 | 220 | if link.Scheme != "https" { 221 | return false 222 | } 223 | 224 | if link.Host != "duer.bdstatic.com" { 225 | return false 226 | } 227 | 228 | return true 229 | } 230 | -------------------------------------------------------------------------------- /bot/audio_player.go: -------------------------------------------------------------------------------- 1 | package bot 2 | 3 | import ( 4 | "github.com/dueros/bot-sdk-go/bot/model" 5 | ) 6 | 7 | // 音频播放相关的事件处理注册 8 | // 设备在播放音频事会上报event,具体可以参考DCS.audio_player.play事件,TODO 9 | // 技能收到的事件数据格式参考技能协议,TODO 10 | 11 | // 音频开始播放事件 12 | func (this *Bot) OnAudioPlaybackStarted(fn func(bot *Bot, request *model.AudioPlayerEventRequest)) { 13 | this.AddEventListener(model.AUDIO_PLAYER_PLAYBACK_STARTED, func(bot *Bot, request interface{}) { 14 | req := request.(model.AudioPlayerEventRequest) 15 | fn(bot, &req) 16 | }) 17 | } 18 | 19 | // 音频停止播放事件 20 | func (this *Bot) OnAudioPlaybackStopped(fn func(bot *Bot, request *model.AudioPlayerEventRequest)) { 21 | this.AddEventListener(model.AUDIO_PLAYER_PLAYBACK_STOPPED, func(bot *Bot, request interface{}) { 22 | req := request.(model.AudioPlayerEventRequest) 23 | fn(bot, &req) 24 | }) 25 | } 26 | 27 | // 音频播放完成事件 28 | func (this *Bot) OnAudioPlaybackFinished(fn func(bot *Bot, request *model.AudioPlayerEventRequest)) { 29 | this.AddEventListener(model.AUDIO_PLAYER_PLAYBACK_FINISHED, func(bot *Bot, request interface{}) { 30 | req := request.(model.AudioPlayerEventRequest) 31 | fn(bot, &req) 32 | }) 33 | } 34 | 35 | // 音频快要播放结束上报的事件 36 | func (this *Bot) OnAudioPlaybackNearlyFinished(fn func(bot *Bot, request *model.AudioPlayerEventRequest)) { 37 | this.AddEventListener(model.AUDIO_PLAYER_PLAYBACK_NEARLY_FINISHED, func(bot *Bot, request interface{}) { 38 | req := request.(model.AudioPlayerEventRequest) 39 | fn(bot, &req) 40 | }) 41 | } 42 | 43 | // 音频周期上报播放进度 44 | func (this *Bot) OnAudioRrogressReportIntevalElapsed(fn func(bot *Bot, request *model.AudioPlayerEventRequest)) { 45 | this.AddEventListener(model.AUDIO_PLAYER_PROGRESS_REPORT_INTERVAL_ELAPSED, func(bot *Bot, request interface{}) { 46 | req := request.(model.AudioPlayerEventRequest) 47 | fn(bot, &req) 48 | }) 49 | } 50 | -------------------------------------------------------------------------------- /bot/audio_player_test.go: -------------------------------------------------------------------------------- 1 | package bot 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | 7 | "github.com/dueros/bot-sdk-go/bot/data" 8 | "github.com/dueros/bot-sdk-go/bot/model" 9 | "github.com/dueros/bot-sdk-go/bot/util" 10 | "log" 11 | ) 12 | 13 | func TestOnAudioPlaybackStarted(t *testing.T) { 14 | body, _ := util.ReadFileAll("test/audio-player-event.json") 15 | rawRequest := string(body) 16 | 17 | bot := NewBot(rawRequest) 18 | 19 | bot.OnAudioPlaybackStarted(func(bot *Bot, request *model.AudioPlayerEventRequest) { 20 | log.Println("OnAudioPlaybackStarted has been called") 21 | if request.GetOffsetInMilliseconds() != 10 { 22 | t.Error("AudioPlayerEventRequest:GetOffsetInMilliseconds value is not 10") 23 | } 24 | 25 | if !reflect.DeepEqual(request.GetAudioPlayerContext(), 26 | data.AudioPlayerContext{Token: "token1", OffsetInMilliseconds: 0, PlayActivity: "PLAYING"}) { 27 | 28 | t.Error("AudioPlayerEventRequest:GetAudioPlayerContext is not AudioPlayerContext") 29 | } 30 | }) 31 | 32 | bot.Run() 33 | } 34 | -------------------------------------------------------------------------------- /bot/bot.go: -------------------------------------------------------------------------------- 1 | package bot 2 | 3 | import ( 4 | "reflect" 5 | 6 | "github.com/dueros/bot-sdk-go/bot/model" 7 | ) 8 | 9 | // 技能基础类 10 | type Bot struct { 11 | intentHandler map[string]func(bot *Bot, request *model.IntentRequest) // 针对intent requset不同intent的处理函数 12 | //eventHandler map[string]func(bot *Bot, request *model.EventRequest) // 针对事件的处理函数 13 | eventHandler map[string]func(bot *Bot, request interface{}) // 针对事件的处理函数 14 | defaultEventHandler func(bot *Bot, request interface{}) 15 | launchRequestHandler func(bot *Bot, request *model.LaunchRequest) // 针对技能打开的处理函数 16 | sessionEndedRequestHandler func(bot *Bot, request *model.SessionEndedRequest) // 针对技能关闭的处理函数 17 | Request interface{} // 对当前request的封装,需要在使用时断言,判断当前的类型 18 | Session *model.Session // 对session的封装 19 | Response *model.Response // 对技能返回的封装 20 | } 21 | 22 | // 创建常驻bot类,可维持在内存状态中, addhandler 和 addEventer事件可以缩减为一次 23 | func NewBot() *Bot { 24 | return &Bot{ 25 | intentHandler: make(map[string]func(bot *Bot, request *model.IntentRequest)), 26 | eventHandler: make(map[string]func(bot *Bot, request interface{})), 27 | } 28 | } 29 | 30 | // 根据每个请求分别处理 31 | func (this *Bot) Handler(request string) string { 32 | this.Request = model.NewRequest(request) 33 | this.Session = model.NewSession(model.GetSessionData(request)) 34 | this.Response = model.NewResponse(this.Session, this.Request) 35 | 36 | this.dispatch() 37 | 38 | return this.Response.Build() 39 | } 40 | 41 | // 添加对intent的处理函数 42 | func (this *Bot) AddIntentHandler(intentName string, fn func(bot *Bot, request *model.IntentRequest)) { 43 | if intentName != "" { 44 | this.intentHandler[intentName] = fn 45 | } 46 | } 47 | 48 | // 添加对事件的处理函数 49 | func (this *Bot) AddEventListener(eventName string, fn func(bot *Bot, request interface{})) { 50 | if eventName != "" { 51 | this.eventHandler[eventName] = fn 52 | } 53 | } 54 | 55 | // 添加事件默认处理函数 56 | // 比如,在播放视频时,技能会收到各种事件的上报,如果不想一一处理可以使用这个来添加处理 57 | func (this *Bot) AddDefaultEventListener(fn func(bot *Bot, request interface{})) { 58 | this.defaultEventHandler = fn 59 | } 60 | 61 | // 打开技能时的处理 62 | func (this *Bot) OnLaunchRequest(fn func(bot *Bot, request *model.LaunchRequest)) { 63 | this.launchRequestHandler = fn 64 | } 65 | 66 | // 技能关闭的处理,比如可以做一些清理的工作 67 | // TIP: 根据协议,技能关闭返回的结果,DuerOS不会返回给用户。 68 | func (this *Bot) OnSessionEndedRequest(fn func(bot *Bot, request *model.SessionEndedRequest)) { 69 | this.sessionEndedRequestHandler = fn 70 | } 71 | 72 | func (this *Bot) dispatch() { 73 | switch request := this.Request.(type) { 74 | case model.IntentRequest: 75 | this.processIntentHandler(request) 76 | return 77 | case model.LaunchRequest: 78 | this.processLaunchHandler(request) 79 | return 80 | case model.SessionEndedRequest: 81 | this.processSessionEndedHandler(request) 82 | return 83 | } 84 | this.processEventHandler(this.Request) 85 | } 86 | 87 | func (this *Bot) processLaunchHandler(request model.LaunchRequest) { 88 | if this.launchRequestHandler != nil { 89 | this.launchRequestHandler(this, &request) 90 | } 91 | } 92 | 93 | func (this *Bot) processSessionEndedHandler(request model.SessionEndedRequest) { 94 | if this.sessionEndedRequestHandler != nil { 95 | this.sessionEndedRequestHandler(this, &request) 96 | } 97 | } 98 | 99 | func (this *Bot) processIntentHandler(request model.IntentRequest) { 100 | intentName, _ := request.GetIntentName() 101 | fn, ok := this.intentHandler[intentName] 102 | 103 | if ok { 104 | fn(this, &request) 105 | return 106 | } 107 | } 108 | 109 | func (this *Bot) processEventHandler(req interface{}) { 110 | rVal := reflect.ValueOf(req) 111 | eventType := rVal.FieldByName("Type").Interface().(string) 112 | 113 | fn, ok := this.eventHandler[eventType] 114 | 115 | if ok { 116 | fn(this, req) 117 | return 118 | } 119 | 120 | if this.defaultEventHandler != nil { 121 | this.defaultEventHandler(this, req) 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /bot/bot_test.go: -------------------------------------------------------------------------------- 1 | package bot 2 | 3 | import ( 4 | "github.com/dueros/bot-sdk-go/bot/util" 5 | "testing" 6 | ) 7 | 8 | func TestAddDefaultEventListener(t *testing.T) { 9 | body, _ := util.ReadFileAll("test/audio-player-event.json") 10 | rawRequest := string(body) 11 | 12 | b := NewBot(rawRequest) 13 | called := false 14 | 15 | b.AddDefaultEventListener(func(bot *Bot, request interface{}) { 16 | called = true 17 | bot.Response.HoldOn() 18 | ret := bot.Response.GetData() 19 | shouldEndSession := ret["shouldEndSession"].(bool) 20 | 21 | if shouldEndSession != false { 22 | t.Error("AddDefaultEventListener HoldOn: shouldEndSession is not false") 23 | } 24 | }) 25 | 26 | b.Run() 27 | 28 | if !called { 29 | t.Error("AddDefaultEventListener has not been called") 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /bot/card/base.go: -------------------------------------------------------------------------------- 1 | package card 2 | 3 | type BaseCard struct { 4 | Type string `json:"type"` 5 | } 6 | -------------------------------------------------------------------------------- /bot/card/image.go: -------------------------------------------------------------------------------- 1 | package card 2 | 3 | type ImageCard struct { 4 | BaseCard 5 | List []map[string]string `json:"list"` 6 | } 7 | 8 | func NewImageCard() *ImageCard { 9 | card := &ImageCard{} 10 | card.Type = "image" 11 | return card 12 | } 13 | 14 | func (this *ImageCard) AddItem(src string, thumbnail string) *ImageCard { 15 | this.List = append(this.List, map[string]string{ 16 | "src": src, 17 | "thumbnail": thumbnail, 18 | }) 19 | return this 20 | } 21 | -------------------------------------------------------------------------------- /bot/card/link_account.go: -------------------------------------------------------------------------------- 1 | package card 2 | 3 | type LinkAccountCard struct { 4 | BaseCard 5 | } 6 | 7 | func NewLinkAccountCard() *LinkAccountCard { 8 | return &LinkAccountCard{BaseCard{ 9 | Type: "LinkAccount", 10 | }} 11 | } 12 | -------------------------------------------------------------------------------- /bot/card/list.go: -------------------------------------------------------------------------------- 1 | package card 2 | 3 | type ListCardItem struct { 4 | Title string `json:"title"` 5 | Content string `json:"content"` 6 | Image string `json:"content"` 7 | Url string `json:"url"` 8 | } 9 | 10 | func NewListCardItem() *ListCardItem { 11 | card := &ListCardItem{} 12 | return card 13 | } 14 | 15 | func (this *ListCardItem) SetTitle(title string) *ListCardItem { 16 | this.Title = title 17 | return this 18 | } 19 | 20 | func (this *ListCardItem) SetContent(content string) *ListCardItem { 21 | this.Content = content 22 | return this 23 | } 24 | 25 | func (this *ListCardItem) SetImage(image string) *ListCardItem { 26 | this.Image = image 27 | return this 28 | } 29 | 30 | func (this *ListCardItem) SetUrl(url string) *ListCardItem { 31 | this.Url = url 32 | return this 33 | } 34 | 35 | type ListCard struct { 36 | List []*ListCardItem `json:"list"` 37 | BaseCard 38 | } 39 | 40 | func NewListCard() *ListCard { 41 | card := &ListCard{} 42 | card.Type = "list" 43 | return card 44 | } 45 | 46 | func (this *ListCard) AddItem(item *ListCardItem) *ListCard { 47 | this.List = append(this.List, item) 48 | return this 49 | } 50 | -------------------------------------------------------------------------------- /bot/card/standard.go: -------------------------------------------------------------------------------- 1 | package card 2 | 3 | type StandardCard struct { 4 | Title string `json:"title"` 5 | Content string `json:"content"` 6 | Image string `json:"image"` 7 | BaseCard 8 | } 9 | 10 | func NewStandardCard() *StandardCard { 11 | card := &StandardCard{} 12 | card.Type = "standard" 13 | return card 14 | } 15 | 16 | func (this *StandardCard) SetTitle(title string) *StandardCard { 17 | this.Title = title 18 | return this 19 | } 20 | 21 | func (this *StandardCard) SetContent(content string) *StandardCard { 22 | this.Content = content 23 | return this 24 | } 25 | 26 | func (this *StandardCard) SetImage(image string) *StandardCard { 27 | this.Image = image 28 | return this 29 | } 30 | -------------------------------------------------------------------------------- /bot/card/text.go: -------------------------------------------------------------------------------- 1 | package card 2 | 3 | type TextCard struct { 4 | BaseCard 5 | Content string `json:"content"` 6 | } 7 | 8 | func NewTextCard(content string) *TextCard { 9 | card := &TextCard{} 10 | card.Type = "txt" 11 | card.SetContent(content) 12 | return card 13 | } 14 | 15 | func (this *TextCard) SetContent(content string) { 16 | this.Content = content 17 | } 18 | -------------------------------------------------------------------------------- /bot/data/http.go: -------------------------------------------------------------------------------- 1 | package data 2 | 3 | type Session struct { 4 | New bool 5 | SessionId string 6 | Attributes map[string]string 7 | } 8 | 9 | type System struct { 10 | User User 11 | Application Application 12 | Device Device 13 | } 14 | 15 | type User struct { 16 | UserId string 17 | AccessToken string 18 | UserInfo UserInfo 19 | } 20 | 21 | type UserInfo struct { 22 | } 23 | 24 | type Application struct { 25 | ApplicationId string 26 | } 27 | 28 | type Device struct { 29 | DeviceId string 30 | SupportedInterfaces map[string]interface{} 31 | } 32 | 33 | type Context struct { 34 | System System 35 | AudioPlayer AudioPlayerContext 36 | VideoPlayer VideoPlayerContext 37 | } 38 | 39 | type AudioPlayerContext struct { 40 | Token string 41 | OffsetInMilliseconds int32 `json:"offsetInMilliSeconds,omitempty"` 42 | PlayActivity string 43 | } 44 | 45 | type VideoPlayerContext struct { 46 | Token string 47 | OffsetInMilliseconds int32 `json:"offsetInMilliseconds,omitempty"` 48 | PlayActivity string 49 | } 50 | 51 | type baseRequest struct { 52 | Type string 53 | RequestId string 54 | Timestamp string 55 | } 56 | 57 | // 公共请求体 58 | type RequestPart struct { 59 | Version string 60 | Session Session 61 | Context Context 62 | Request baseRequest 63 | } 64 | 65 | // 事件请求 66 | type EventRequest struct { 67 | Request struct { 68 | baseRequest 69 | Token string 70 | Url string `json:"url,omitempty"` 71 | Name string `json:"name,omitempty"` 72 | } 73 | } 74 | 75 | type AudioPlayerEventRequest struct { 76 | Request struct { 77 | baseRequest 78 | Token string 79 | OffsetInMilliseconds int32 `json:"offsetInMilliSeconds,omitempty"` //Audio Player Event 80 | } 81 | } 82 | 83 | type VideoPlayerEventRequest struct { 84 | Request struct { 85 | baseRequest 86 | Token string 87 | OffsetInMilliseconds int32 `json:"offsetInMilliseconds,omitempty"` //Audio Player Event 88 | } 89 | } 90 | 91 | // 打开请求 92 | type LaunchRequest struct { 93 | Request baseRequest 94 | } 95 | 96 | // 退出请求 97 | type SessionEndedRequestBody struct { 98 | baseRequest 99 | Reason string 100 | } 101 | 102 | type SessionEndedRequest struct { 103 | Request SessionEndedRequestBody 104 | } 105 | 106 | // intent request 107 | type Query struct { 108 | Type string 109 | Original string 110 | } 111 | 112 | type Slot struct { 113 | Name string `json:"name"` 114 | Value string `json:"value"` 115 | ConfirmationStatus string `json:"confirmationStatus"` 116 | } 117 | 118 | type Intent struct { 119 | Name string `json:"name"` 120 | Slots map[string]Slot `json:"slots"` 121 | ConfirmationStatus string `json:"confirmationStatus"` 122 | } 123 | 124 | type IntentRequestBody struct { 125 | baseRequest 126 | Query Query 127 | DialogState string 128 | Intents []Intent 129 | } 130 | 131 | type IntentRequest struct { 132 | Request IntentRequestBody 133 | } 134 | 135 | //--------response------ 136 | type SessionResponse struct { 137 | Attributes map[string]string `json:"attributes"` 138 | } 139 | 140 | type ContextResponse struct { 141 | Intent Intent `json:"intent"` 142 | } 143 | 144 | type DialogDirective struct { 145 | Type string `json:"type"` 146 | SlotToElicit string `json:"slotToElicit,omitempty"` 147 | SlotToConfirm string `json:"slotToConfirm,omitempty"` 148 | UpdatedIntent Intent `json:"updatedIntent"` 149 | } 150 | 151 | type Speech struct { 152 | Type string `json:"type"` 153 | Text string `json:"text,omitempty"` 154 | Ssml string `json:"ssml,omitempty"` 155 | } 156 | -------------------------------------------------------------------------------- /bot/directive/audio_player/const.go: -------------------------------------------------------------------------------- 1 | package audio_player 2 | 3 | const ( 4 | REPLACE_ALL = "REPLACE_ALL" 5 | REPLACE_ENQUEUED = "REPLACE_ENQUEUED" 6 | ENQUEUE = "ENQUEUE" 7 | 8 | AUDIO_MP3 = "AUDIO_MP3" 9 | AUDIO_M3U8 = "AUDIO_M3U8" 10 | AUDIO_M4A = "AUDIO_M4A" 11 | 12 | AUDIO_TYPE_MUSIC = "MUSIC" 13 | 14 | LYRIC_FORMAT_LRC = "LRC" 15 | ) 16 | -------------------------------------------------------------------------------- /bot/directive/audio_player/play.go: -------------------------------------------------------------------------------- 1 | package audio_player 2 | 3 | import ( 4 | "github.com/dueros/bot-sdk-go/bot/directive" 5 | ) 6 | 7 | var behaviorMap = map[string]bool{ 8 | ENQUEUE: true, 9 | REPLACE_ALL: true, 10 | REPLACE_ENQUEUED: true, 11 | } 12 | 13 | var audioFormatMap = map[string]bool{ 14 | AUDIO_MP3: true, 15 | AUDIO_M3U8: true, 16 | AUDIO_M4A: true, 17 | } 18 | 19 | type PlayDirective struct { 20 | directive.BaseDirective 21 | PlayBehavior string `json:"playBehavior"` 22 | AudioItem struct { 23 | Stream struct { 24 | Url string `json:"url"` 25 | StreamFormat string `json:"streamFormat"` 26 | OffsetInMilliseconds int `json:"offsetInMilliSeconds"` 27 | Token string `json:"token"` 28 | ProgressReportIntervalMs int `json:"progressReportIntervalMs,omitempty"` 29 | } `json:"stream"` 30 | PlayerInfo *PlayerInfo `json:"playerInfo,omitempty"` 31 | } `json:"audioItem"` 32 | } 33 | 34 | func NewPlayDirective(url string) *PlayDirective { 35 | play := &PlayDirective{} 36 | play.Type = "AudioPlayer.Play" 37 | play.PlayBehavior = REPLACE_ALL 38 | play.AudioItem.Stream.Url = url 39 | play.AudioItem.Stream.StreamFormat = AUDIO_MP3 40 | play.AudioItem.Stream.OffsetInMilliseconds = 0 41 | play.AudioItem.Stream.Token = play.GenToken() 42 | play.AudioItem.PlayerInfo = nil 43 | //play.AudioItem.Stream.ProgressReportIntervalMs = 20 44 | return play 45 | } 46 | 47 | func (this *PlayDirective) SetBehavior(behavior string) *PlayDirective { 48 | _, ok := behaviorMap[behavior] 49 | if ok { 50 | this.PlayBehavior = behavior 51 | } 52 | 53 | return this 54 | } 55 | 56 | func (this *PlayDirective) SetToken(token string) *PlayDirective { 57 | this.AudioItem.Stream.Token = token 58 | return this 59 | } 60 | 61 | func (this *PlayDirective) GetToken(token string) string { 62 | return this.AudioItem.Stream.Token 63 | } 64 | 65 | func (this *PlayDirective) SetUrl(url string) *PlayDirective { 66 | this.AudioItem.Stream.Url = url 67 | return this 68 | } 69 | 70 | func (this *PlayDirective) SetOffsetInMilliseconds(milliseconds int) *PlayDirective { 71 | this.AudioItem.Stream.OffsetInMilliseconds = milliseconds 72 | return this 73 | } 74 | 75 | func (this *PlayDirective) SetProgressReportIntervalMs(intervalMs int) *PlayDirective { 76 | this.AudioItem.Stream.ProgressReportIntervalMs = intervalMs 77 | return this 78 | } 79 | 80 | func (this *PlayDirective) SetStreamFormat(format string) *PlayDirective { 81 | _, ok := audioFormatMap[format] 82 | if ok { 83 | this.AudioItem.Stream.StreamFormat = format 84 | } 85 | return this 86 | } 87 | 88 | func (this *PlayDirective) SetPlayerInfo(playerInfo *PlayerInfo) *PlayDirective { 89 | this.AudioItem.PlayerInfo = playerInfo 90 | return this 91 | } 92 | -------------------------------------------------------------------------------- /bot/directive/audio_player/player_info.go: -------------------------------------------------------------------------------- 1 | package audio_player 2 | 3 | type PlayerInfo struct { 4 | Content struct { 5 | AudioItemType string `json:"audioItemType"` 6 | Title string `json:"title"` 7 | TitleSubtext1 string `json:"titleSubtext1"` 8 | TitleSubtext2 string `json:"titleSubtext2"` 9 | Lyric struct { 10 | Url string `json:"url"` 11 | Format string `json:"format"` 12 | } `json:"lyric"` 13 | MediaLengthInMilliseconds uint64 `json:"mediaLengthInMilliseconds,omitempty"` 14 | Art struct { 15 | Src string `json:"src"` 16 | } `json:"art"` 17 | Provider struct { 18 | Name string `json:"name"` 19 | Logo struct { 20 | Src string `json:"src"` 21 | } `json:"logo"` 22 | } `json:"provider"` 23 | } `json:"content"` 24 | } 25 | 26 | func NewPlayerInfo() *PlayerInfo { 27 | playerInfo := &PlayerInfo{} 28 | 29 | playerInfo.Content.AudioItemType = AUDIO_TYPE_MUSIC 30 | 31 | return playerInfo 32 | } 33 | 34 | func (this *PlayerInfo) SetTitle(title string) *PlayerInfo { 35 | this.Content.Title = title 36 | return this 37 | } 38 | 39 | func (this *PlayerInfo) SetTitleSubtext1(text string) *PlayerInfo { 40 | this.Content.TitleSubtext1 = text 41 | return this 42 | } 43 | 44 | func (this *PlayerInfo) SetTitleSubtext2(text string) *PlayerInfo { 45 | this.Content.TitleSubtext2 = text 46 | return this 47 | } 48 | 49 | func (this *PlayerInfo) SetLyric(url string) *PlayerInfo { 50 | this.Content.Lyric.Url = url 51 | this.Content.Lyric.Format = LYRIC_FORMAT_LRC 52 | return this 53 | } 54 | 55 | func (this *PlayerInfo) SetMediaLengthInMs(length uint64) *PlayerInfo { 56 | this.Content.MediaLengthInMilliseconds = length 57 | return this 58 | } 59 | 60 | func (this *PlayerInfo) SetArt(src string) *PlayerInfo { 61 | this.Content.Art.Src = src 62 | return this 63 | } 64 | 65 | func (this *PlayerInfo) SetProviderName(name string) *PlayerInfo { 66 | this.Content.Provider.Name = name 67 | return this 68 | } 69 | 70 | func (this *PlayerInfo) SetProviderLogo(logo string) *PlayerInfo { 71 | this.Content.Provider.Logo.Src = logo 72 | return this 73 | } 74 | -------------------------------------------------------------------------------- /bot/directive/audio_player/stop.go: -------------------------------------------------------------------------------- 1 | package audio_player 2 | 3 | import ( 4 | "github.com/dueros/bot-sdk-go/bot/directive" 5 | ) 6 | 7 | type StopDirective struct { 8 | directive.BaseDirective 9 | } 10 | 11 | func NewStopDirective() *StopDirective { 12 | stop := &StopDirective{} 13 | stop.Type = "AudioPlayer.Stop" 14 | return stop 15 | } 16 | -------------------------------------------------------------------------------- /bot/directive/base.go: -------------------------------------------------------------------------------- 1 | package directive 2 | 3 | import ( 4 | "github.com/satori/go.uuid" 5 | ) 6 | 7 | type BaseDirective struct { 8 | Type string `json:"type"` 9 | } 10 | 11 | func (this *BaseDirective) GenToken() string { 12 | return uuid.Must(uuid.NewV4()).String() 13 | } 14 | -------------------------------------------------------------------------------- /bot/directive/display/hint.go: -------------------------------------------------------------------------------- 1 | package display 2 | 3 | import ( 4 | "github.com/dueros/bot-sdk-go/bot/data" 5 | "github.com/dueros/bot-sdk-go/bot/util" 6 | ) 7 | 8 | type Hint struct { 9 | Type string `json:"type"` 10 | Hints []data.Speech `json:"hints"` 11 | } 12 | 13 | func NewHint(hint ...string) *Hint { 14 | h := &Hint{ 15 | Type: "Hint", 16 | Hints: make([]data.Speech, 0), 17 | } 18 | 19 | h.SetHints(hint) 20 | 21 | return h 22 | } 23 | 24 | func (this *Hint) SetHints(hints []string) *Hint { 25 | for _, value := range hints { 26 | this.AddHint(value) 27 | } 28 | 29 | return this 30 | } 31 | 32 | func (this *Hint) AddHint(hint string) *Hint { 33 | this.Hints = append(this.Hints, util.FormatSpeech(hint)) 34 | 35 | return this 36 | } 37 | -------------------------------------------------------------------------------- /bot/directive/display/render_template.go: -------------------------------------------------------------------------------- 1 | package display 2 | 3 | import ( 4 | "github.com/dueros/bot-sdk-go/bot/directive" 5 | ) 6 | 7 | type RenderTemplate struct { 8 | directive.BaseDirective 9 | Template interface{} `json:"template"` 10 | } 11 | 12 | func NewRenderTemplate(template interface{}) *RenderTemplate { 13 | renderTemplate := &RenderTemplate{} 14 | renderTemplate.Type = "Display.RenderTemplate" 15 | renderTemplate.Template = template 16 | return renderTemplate 17 | } 18 | -------------------------------------------------------------------------------- /bot/directive/display/template/base.go: -------------------------------------------------------------------------------- 1 | package template 2 | 3 | import ( 4 | "github.com/dueros/bot-sdk-go/bot/directive" 5 | ) 6 | 7 | const ( 8 | PLAIN_TEXT = "PlainText" 9 | RICH_TEXT = "RichText" 10 | ) 11 | 12 | var textTypeMap = map[string]bool{ 13 | PLAIN_TEXT: true, 14 | RICH_TEXT: true, 15 | } 16 | 17 | type BaseTemplate struct { 18 | directive.BaseDirective 19 | Token string `json:"token"` 20 | BackgroundImage *Image `json:"backgroundImage,omitempty"` 21 | Title string `json:"title"` 22 | } 23 | 24 | func (this *BaseTemplate) SetTitle(title string) { 25 | this.Title = title 26 | } 27 | 28 | func (this *BaseTemplate) SetBackgroundImageUrl(url string) { 29 | this.SetBackgroundImage(NewImage(url)) 30 | } 31 | 32 | func (this *BaseTemplate) SetBackgroundImage(background *Image) { 33 | this.BackgroundImage = background 34 | } 35 | 36 | type Image struct { 37 | Url string `json:"url"` 38 | WidthPixels int `json:"widthPixels,omitempty"` 39 | HeightPixels int `json:"heightPixels,omitempty"` 40 | } 41 | 42 | func NewImage(url string) *Image { 43 | image := &Image{} 44 | image.Url = url 45 | return image 46 | } 47 | 48 | func (this *Image) SetWidth(width int) *Image { 49 | this.WidthPixels = width 50 | return this 51 | } 52 | 53 | func (this *Image) SetHeight(height int) *Image { 54 | this.HeightPixels = height 55 | return this 56 | } 57 | 58 | type Text struct { 59 | Type string `json:"type"` 60 | Text string `json:"text"` 61 | } 62 | 63 | func NewText(textType, text string) *Text { 64 | ok := textTypeMap[textType] 65 | if !ok { 66 | textType = PLAIN_TEXT 67 | } 68 | 69 | t := &Text{} 70 | t.Type = textType 71 | t.Text = text 72 | return t 73 | } 74 | -------------------------------------------------------------------------------- /bot/directive/display/template/body_template1.go: -------------------------------------------------------------------------------- 1 | package template 2 | 3 | const ( 4 | BOTTOM_LEFT_POSITION = "BOTTOM-LEFT" 5 | CENTER = "CENTER" 6 | TOP_LEFT = "TOP-LEFT" 7 | ) 8 | 9 | var textPositionMap = map[string]bool{ 10 | BOTTOM_LEFT_POSITION: true, 11 | CENTER: true, 12 | TOP_LEFT: true, 13 | } 14 | 15 | type BodyTemplate1 struct { 16 | BaseTemplate 17 | TextContent struct { 18 | Position string `json:"position"` 19 | Text *Text `json:"text"` 20 | } `json:"textContent"` 21 | } 22 | 23 | func NewBodyTemplate1() *BodyTemplate1 { 24 | bodyTemplate := &BodyTemplate1{} 25 | bodyTemplate.Type = "BodyTemplate1" 26 | bodyTemplate.Token = bodyTemplate.GenToken() 27 | bodyTemplate.TextContent.Position = BOTTOM_LEFT_POSITION 28 | return bodyTemplate 29 | } 30 | 31 | func (this *BodyTemplate1) SetContentPosition(position string) *BodyTemplate1 { 32 | ok := textPositionMap[position] 33 | if !ok { 34 | position = BOTTOM_LEFT_POSITION 35 | } 36 | 37 | this.TextContent.Position = position 38 | return this 39 | } 40 | 41 | func (this *BodyTemplate1) SetPlainContent(content string) *BodyTemplate1 { 42 | text := NewText(PLAIN_TEXT, content) 43 | this.TextContent.Text = text 44 | return this 45 | } 46 | -------------------------------------------------------------------------------- /bot/directive/display/template/body_template2_3_4.go: -------------------------------------------------------------------------------- 1 | package template 2 | 3 | type BodyTemplate2 struct { 4 | TextImageTemplate 5 | } 6 | 7 | func NewBodyTemplate2() *BodyTemplate2 { 8 | bodyTemplate := &BodyTemplate2{} 9 | bodyTemplate.Type = "BodyTemplate2" 10 | bodyTemplate.Token = bodyTemplate.GenToken() 11 | return bodyTemplate 12 | } 13 | 14 | type BodyTemplate3 struct { 15 | TextImageTemplate 16 | } 17 | 18 | func NewBodyTemplate3() *BodyTemplate3 { 19 | bodyTemplate := &BodyTemplate3{} 20 | bodyTemplate.Type = "BodyTemplate3" 21 | bodyTemplate.Token = bodyTemplate.GenToken() 22 | return bodyTemplate 23 | } 24 | 25 | type BodyTemplate4 struct { 26 | TextImageTemplate 27 | } 28 | 29 | func NewBodyTemplate4() *BodyTemplate4 { 30 | bodyTemplate := &BodyTemplate4{} 31 | bodyTemplate.Type = "BodyTemplate4" 32 | bodyTemplate.Token = bodyTemplate.GenToken() 33 | return bodyTemplate 34 | } 35 | -------------------------------------------------------------------------------- /bot/directive/display/template/body_template5.go: -------------------------------------------------------------------------------- 1 | package template 2 | 3 | type BodyTemplate5 struct { 4 | BaseTemplate 5 | Images []*Image `json:"images"` 6 | } 7 | 8 | func NewBodyTemplate5() *BodyTemplate5 { 9 | bodyTemplate := &BodyTemplate5{} 10 | bodyTemplate.Images = make([]*Image, 0) 11 | return bodyTemplate 12 | } 13 | 14 | func (this *BodyTemplate5) AddImage(image *Image) *BodyTemplate5 { 15 | this.Images = append(this.Images, image) 16 | return this 17 | } 18 | -------------------------------------------------------------------------------- /bot/directive/display/template/list.go: -------------------------------------------------------------------------------- 1 | package template 2 | 3 | type ListItem struct { 4 | Token string `json:"token"` 5 | Image *Image `json:"image,omitempty"` 6 | TextContent struct { 7 | PrimaryText *Text `json:"primaryText"` 8 | SecondaryText *Text `json:"secondaryText"` 9 | TertiaryText *Text `json:"tertiaryText,omitempty"` 10 | } `json:"textContent"` 11 | } 12 | 13 | func NewListItem() *ListItem { 14 | item := &ListItem{} 15 | return item 16 | } 17 | 18 | func (this *ListItem) SetImage(image *Image) *ListItem { 19 | this.Image = image 20 | return this 21 | } 22 | 23 | func (this *ListItem) SetImageUrl(url string) *ListItem { 24 | image := NewImage(url) 25 | return this.SetImage(image) 26 | } 27 | 28 | func (this *ListItem) SetPlainPrimaryText(text string) *ListItem { 29 | this.TextContent.PrimaryText = NewText(PLAIN_TEXT, text) 30 | return this 31 | } 32 | 33 | func (this *ListItem) SetPlainSecondaryText(text string) *ListItem { 34 | this.TextContent.SecondaryText = NewText(PLAIN_TEXT, text) 35 | return this 36 | } 37 | 38 | func (this *ListItem) SetPlainTertiary(text string) *ListItem { 39 | this.TextContent.TertiaryText = NewText(PLAIN_TEXT, text) 40 | return this 41 | } 42 | 43 | type ListTemplate struct { 44 | BaseTemplate 45 | ListItems []*ListItem `json:"listItems"` 46 | } 47 | 48 | func (this *ListTemplate) AddItem(listItem *ListItem) { 49 | this.ListItems = append(this.ListItems, listItem) 50 | } 51 | -------------------------------------------------------------------------------- /bot/directive/display/template/list_template1_2.go: -------------------------------------------------------------------------------- 1 | package template 2 | 3 | type ListTemplate1 struct { 4 | ListTemplate 5 | } 6 | 7 | func NewListTemplate1() *ListTemplate1 { 8 | listTemplate := &ListTemplate1{} 9 | listTemplate.Type = "ListTemplate1" 10 | listTemplate.Token = listTemplate.GenToken() 11 | return listTemplate 12 | } 13 | 14 | type ListTemplate2 struct { 15 | ListTemplate 16 | } 17 | 18 | func NewListTemplate2() *ListTemplate2 { 19 | listTemplate := &ListTemplate2{} 20 | listTemplate.Type = "ListTemplate2" 21 | listTemplate.Token = listTemplate.GenToken() 22 | return listTemplate 23 | } 24 | -------------------------------------------------------------------------------- /bot/directive/display/template/text_image.go: -------------------------------------------------------------------------------- 1 | package template 2 | 3 | type TextImageTemplate struct { 4 | BaseTemplate 5 | Content *Text `json:"content"` 6 | Image *Image `json:"image"` 7 | } 8 | 9 | func (this *TextImageTemplate) SetPlainContent(content string) { 10 | text := NewText(PLAIN_TEXT, content) 11 | this.Content = text 12 | } 13 | 14 | func (this *TextImageTemplate) SetImageUrl(url string) { 15 | image := NewImage(url) 16 | this.SetImage(image) 17 | } 18 | 19 | func (this *TextImageTemplate) SetImage(image *Image) { 20 | this.Image = image 21 | } 22 | -------------------------------------------------------------------------------- /bot/directive/video_player/const.go: -------------------------------------------------------------------------------- 1 | package video_player 2 | 3 | const ( 4 | REPLACE_ALL = "REPLACE_ALL" 5 | REPLACE_ENQUEUED = "REPLACE_ENQUEUED" 6 | ENQUEUE = "ENQUEUE" 7 | ) 8 | -------------------------------------------------------------------------------- /bot/directive/video_player/play.go: -------------------------------------------------------------------------------- 1 | package video_player 2 | 3 | import ( 4 | "github.com/dueros/bot-sdk-go/bot/directive" 5 | ) 6 | 7 | var behaviorMap = map[string]bool{ 8 | ENQUEUE: true, 9 | REPLACE_ALL: true, 10 | REPLACE_ENQUEUED: true, 11 | } 12 | 13 | type PlayDirective struct { 14 | directive.BaseDirective 15 | PlayBehavior string `json:"playBehavior"` 16 | VideoItem struct { 17 | Stream struct { 18 | Url string `json:"url"` 19 | OffsetInMilliseconds int `json:"offsetInMilliseconds"` 20 | ExpiryTime string `json:"expiryTime,omitempty"` 21 | ProgressReport struct { 22 | ProgressReportDelayInMilliseconds int `json:"progressReportDelayInMilliseconds,omitempty"` 23 | ProgressReportIntervalInMilliseconds int `json:"progressReportIntervalInMilliseconds,omitempty"` 24 | } `json:"progressReport,omitempty"` 25 | Token string `json:"token"` 26 | ExpectedPreviousToken string `json:"expectedPreviousToken,omitempty"` 27 | } `json:"stream"` 28 | } `json:"VideoItem"` 29 | } 30 | 31 | func NewPlayDirective(url string) *PlayDirective { 32 | play := &PlayDirective{} 33 | play.Type = "VideoPlayer.Play" 34 | play.PlayBehavior = REPLACE_ALL 35 | play.VideoItem.Stream.Url = url 36 | play.VideoItem.Stream.OffsetInMilliseconds = 0 37 | play.VideoItem.Stream.Token = play.GenToken() 38 | return play 39 | } 40 | 41 | func (this *PlayDirective) SetBehavior(behavior string) *PlayDirective { 42 | _, ok := behaviorMap[behavior] 43 | if ok { 44 | this.PlayBehavior = behavior 45 | } 46 | 47 | return this 48 | } 49 | 50 | func (this *PlayDirective) SetToken(token string) *PlayDirective { 51 | this.VideoItem.Stream.Token = token 52 | return this 53 | } 54 | 55 | func (this *PlayDirective) GetToken(token string) string { 56 | return this.VideoItem.Stream.Token 57 | } 58 | 59 | func (this *PlayDirective) SetUrl(url string) *PlayDirective { 60 | this.VideoItem.Stream.Url = url 61 | return this 62 | } 63 | 64 | func (this *PlayDirective) SetOffsetInMilliseconds(milliseconds int) *PlayDirective { 65 | this.VideoItem.Stream.OffsetInMilliseconds = milliseconds 66 | return this 67 | } 68 | 69 | func (this *PlayDirective) SetExpiryTime(expiryTime string) *PlayDirective { 70 | this.VideoItem.Stream.ExpiryTime = expiryTime 71 | return this 72 | } 73 | 74 | func (this *PlayDirective) SetReportDelayInMs(reportDelayInMs int) *PlayDirective { 75 | this.VideoItem.Stream.ProgressReport.ProgressReportDelayInMilliseconds = reportDelayInMs 76 | return this 77 | } 78 | 79 | func (this *PlayDirective) SetReportIntervalInMs(reportIntervalInMs int) *PlayDirective { 80 | this.VideoItem.Stream.ProgressReport.ProgressReportIntervalInMilliseconds = reportIntervalInMs 81 | return this 82 | } 83 | 84 | func (this *PlayDirective) SetExpectedPreviousToken(expectedPreviousToken string) *PlayDirective { 85 | this.VideoItem.Stream.ExpectedPreviousToken = expectedPreviousToken 86 | return this 87 | } 88 | -------------------------------------------------------------------------------- /bot/directive/video_player/stop.go: -------------------------------------------------------------------------------- 1 | package video_player 2 | 3 | import ( 4 | "github.com/dueros/bot-sdk-go/bot/directive" 5 | ) 6 | 7 | type StopDirective struct { 8 | directive.BaseDirective 9 | } 10 | 11 | func NewStopDirective() *StopDirective { 12 | stop := &StopDirective{} 13 | stop.Type = "VideoPlayer.Stop" 14 | return stop 15 | } 16 | -------------------------------------------------------------------------------- /bot/event_handler.go: -------------------------------------------------------------------------------- 1 | package bot 2 | 3 | import ( 4 | "github.com/dueros/bot-sdk-go/bot/model" 5 | ) 6 | 7 | // ListTemplate 列表选择事件 8 | // Display.ButtonClicked 事件 9 | // https://dueros.baidu.com/didp/doc/dueros-bot-platform/dbp-custom/display-template_markdown#Display.ElementSelected%E4%BA%8B%E4%BB%B6 10 | func (this *Bot) OnDisplayElementSelected(fn func(bot *Bot, request *model.EventRequest)) { 11 | this.AddEventListener("Display.ElementSelected", func(bot *Bot, request interface{}) { 12 | req := request.(model.EventRequest) 13 | fn(bot, &req) 14 | }) 15 | } 16 | 17 | // Display.ButtonClicked 事件 18 | // ```javascript 19 | //{ 20 | // "type": "Display.ButtonClicked", 21 | // "requestId": "{{STRING}}", 22 | // "timestamp": "{{STRING}}", 23 | // "token": "{{STRING}}", 24 | // "buttonType": "{{ENUM}}" 25 | //} 26 | // ``` 27 | 28 | // LinkAccountSucceeded 事件 29 | // ```javascript 30 | //{ 31 | // "type": "Connections.Response", 32 | // "name": "LinkAccountSucceeded", 33 | // "requestId": "{{STRING}}", 34 | // "timestamp": {{INT32}}, 35 | // "token": "{{STRING}}" 36 | //} 37 | // ``` 38 | func (this *Bot) OnLinkAccountSuccessed(fn func(bot *Bot, request *model.EventRequest)) { 39 | this.AddEventListener("LinkAccountSucceeded", func(bot *Bot, request interface{}) { 40 | req := request.(model.EventRequest) 41 | fn(bot, &req) 42 | }) 43 | } 44 | 45 | // Screen.LinkClicked事件 46 | // https://dueros.baidu.com/didp/doc/dueros-bot-platform/dbp-custom/cards_markdown#Screen.LinkClicked%E4%BA%8B%E4%BB%B6 47 | //{ 48 | // "type": "Screen.LinkClicked", 49 | // "url": "{{STRING}}", 50 | // "requestId": "{{STRING}}", 51 | // "timestamp": {{INT32}} 52 | // "token": "{{STRING}}" 53 | //} 54 | func (this *Bot) OnScreenLinkClicked(fn func(bot *Bot, request *model.EventRequest)) { 55 | this.AddEventListener("Screen.LinkClicked", func(bot *Bot, request interface{}) { 56 | req := request.(model.EventRequest) 57 | fn(bot, &req) 58 | }) 59 | } 60 | -------------------------------------------------------------------------------- /bot/model/dialog.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "github.com/dueros/bot-sdk-go/bot/data" 5 | ) 6 | 7 | type Dialog struct { 8 | data data.IntentRequestBody 9 | Intents []*Intent 10 | DialogState string 11 | directive *data.DialogDirective 12 | } 13 | 14 | func NewDialog(request data.IntentRequestBody) *Dialog { 15 | length := len(request.Intents) 16 | intents := make([]*Intent, length) 17 | for i := 0; i < length; i++ { 18 | intents[i] = NewIntent(request.Intents[i]) 19 | } 20 | return &Dialog{ 21 | data: request, 22 | Intents: intents, 23 | DialogState: request.DialogState, 24 | } 25 | } 26 | 27 | func (this *Dialog) getIntent(index int) *Intent { 28 | l := len(this.Intents) 29 | if l > 0 && index < l { 30 | intent := this.Intents[index] 31 | return intent 32 | } 33 | return nil 34 | } 35 | 36 | func getIndex(index []int) int { 37 | i := 0 38 | if len(index) > 0 { 39 | i = index[0] 40 | } 41 | return i 42 | } 43 | 44 | // 获取用户请求的原始query 45 | func (this *Dialog) GetQuery() (string, bool) { 46 | if this.data.Query.Type == "TEXT" { 47 | return this.data.Query.Original, true 48 | } 49 | return "", false 50 | } 51 | 52 | // 获取当前意图的名字 53 | func (this *Dialog) GetIntentName() (string, bool) { 54 | intent := this.getIntent(0) 55 | if intent != nil { 56 | return intent.Name, true 57 | } 58 | return "", false 59 | } 60 | 61 | // 获取槽位的值,默认取第一组槽位 62 | func (this *Dialog) GetSlotValue(name string, index ...int) string { 63 | // 默认取第一个intent 64 | // 如果有第二个参数,取参数指定index 65 | // 如果有超过三个参数,从第三个参数开始忽略 66 | i := getIndex(index) 67 | 68 | intent := this.getIntent(i) 69 | if intent != nil { 70 | return intent.GetSlotValue(name) 71 | } 72 | return "" 73 | } 74 | 75 | // 获取槽位的确认状态,默认取第一组槽位 76 | func (this *Dialog) GetSlotConfirmationStatus(name string, index ...int) string { 77 | i := getIndex(index) 78 | intent := this.getIntent(i) 79 | 80 | if intent != nil { 81 | return intent.GetSlotStatus(name) 82 | } 83 | return "" 84 | } 85 | 86 | // 获取意图的确认状态 87 | func (this *Dialog) GetIntentConfirmationStatus(index ...int) string { 88 | i := getIndex(index) 89 | intent := this.getIntent(i) 90 | 91 | if intent != nil { 92 | return intent.ConfirmationStatus 93 | } 94 | return "" 95 | } 96 | 97 | // 托管对话. 对话由DuerOS代为处理 98 | func (this *Dialog) Delegate() *Dialog { 99 | this.directive = &data.DialogDirective{ 100 | Type: "Dialog.Delegate", 101 | UpdatedIntent: this.getIntent(0).GetData(), 102 | } 103 | return this 104 | } 105 | 106 | // 对槽位进行confirm 107 | func (this *Dialog) ConfirmSlot(name string) *Dialog { 108 | intent := this.getIntent(0) 109 | slot := intent.GetSlot(name) 110 | 111 | if slot != nil { 112 | this.directive = &data.DialogDirective{ 113 | Type: "Dialog.ConfirmSlot", 114 | SlotToConfirm: name, 115 | UpdatedIntent: intent.GetData(), 116 | } 117 | } 118 | return this 119 | } 120 | 121 | // 对意图进行确认 122 | func (this *Dialog) ConfirmIntent() *Dialog { 123 | this.directive = &data.DialogDirective{ 124 | Type: "Dialog.ConfirmIntent", 125 | UpdatedIntent: this.getIntent(0).GetData(), 126 | } 127 | return this 128 | } 129 | 130 | // 询问槽位 131 | func (this *Dialog) ElicitSlot(name string) *Dialog { 132 | intent := this.getIntent(0) 133 | //slot := intent.GetSlot(name) 134 | 135 | //if slot != nil { 136 | this.directive = &data.DialogDirective{ 137 | Type: "Dialog.ElicitSlot", 138 | SlotToElicit: name, 139 | UpdatedIntent: intent.GetData(), 140 | } 141 | //} 142 | return this 143 | } 144 | 145 | func (this *Dialog) GetDirective() *data.DialogDirective { 146 | return this.directive 147 | } 148 | -------------------------------------------------------------------------------- /bot/model/intent.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "github.com/dueros/bot-sdk-go/bot/data" 5 | ) 6 | 7 | type Intent struct { 8 | data data.Intent 9 | Name string 10 | ConfirmationStatus string 11 | } 12 | 13 | func NewIntent(intent data.Intent) *Intent { 14 | return &Intent{ 15 | data: intent, 16 | Name: intent.Name, 17 | 18 | ConfirmationStatus: intent.ConfirmationStatus, 19 | } 20 | } 21 | 22 | // 根据槽位名获取槽位 23 | func (this *Intent) GetSlot(name string) *data.Slot { 24 | slot, ok := this.data.Slots[name] 25 | if ok { 26 | return &slot 27 | } 28 | return nil 29 | } 30 | 31 | // 根据槽位名获取槽位对应的值 32 | func (this *Intent) GetSlotValue(name string) string { 33 | slot := this.GetSlot(name) 34 | if slot != nil { 35 | return slot.Value 36 | } 37 | return "" 38 | } 39 | 40 | // 根据槽位名获取槽位对应的状态 41 | func (this *Intent) GetSlotStatus(name string) string { 42 | slot := this.GetSlot(name) 43 | if slot != nil { 44 | return slot.ConfirmationStatus 45 | } 46 | return "" 47 | 48 | } 49 | 50 | // 设置槽位的值 51 | func (this *Intent) SetSlotValue(name string, value string) bool { 52 | slot := this.GetSlot(name) 53 | if slot != nil { 54 | slot.Value = value 55 | return true 56 | } else { 57 | // TODO new a slot 58 | } 59 | return false 60 | } 61 | 62 | func (this *Intent) GetData() data.Intent { 63 | return this.data 64 | } 65 | -------------------------------------------------------------------------------- /bot/model/request.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "encoding/json" 5 | "log" 6 | "regexp" 7 | "strconv" 8 | "time" 9 | 10 | "github.com/dueros/bot-sdk-go/bot/data" 11 | ) 12 | 13 | const ( 14 | INENT_REQUEST = "IntentRequest" 15 | LAUNCH_REQUEST = "LaunchRequest" 16 | SESSION_ENDED_REQUEST = "SessionEndedRequest" 17 | 18 | AUDIO_PLAYER_PLAYBACK_STARTED = "AudioPlayer.PlaybackStarted" 19 | AUDIO_PLAYER_PLAYBACK_STOPPED = "AudioPlayer.PlaybackStopped" 20 | AUDIO_PLAYER_PLAYBACK_FINISHED = "AudioPlayer.PlaybackFinished" 21 | AUDIO_PLAYER_PLAYBACK_NEARLY_FINISHED = "AudioPlayer.PlaybackNearlyFinished" 22 | AUDIO_PLAYER_PROGRESS_REPORT_INTERVAL_ELAPSED = "AudioPlayer.ProgressReportIntervalElapsed" 23 | 24 | VIDEO_PLAYER_PLAYBACK_STARTED = "VideoPlayer.PlaybackStarted" 25 | VIDEO_PLAYER_PLAYBACK_STOPPED = "VideoPlayer.PlaybackStopped" 26 | VIDEO_PLAYER_PLAYBACK_FINISHED = "VideoPlayer.PlaybackFinished" 27 | VIDEO_PLAYER_PLAYBACK_NEARLY_FINISHED = "VideoPlayer.PlaybackNearlyFinished" 28 | VIDEO_PLAYER_PLAYBACK_SCHEDULED_STOP_REACHED = "VideoPlayer.PlaybackScheduledStopReached" 29 | VIDEO_PLAYER_PROGRESS_REPORT_INTERVAL_ELAPSED = "VideoPlayer.ProgressReportIntervalElapsed" 30 | ) 31 | 32 | type Request struct { 33 | Type string 34 | Common data.RequestPart 35 | } 36 | 37 | type IntentRequest struct { 38 | Data data.IntentRequest 39 | Dialog *Dialog 40 | Request 41 | } 42 | 43 | type LaunchRequest struct { 44 | Data data.LaunchRequest 45 | Request 46 | } 47 | 48 | type SessionEndedRequest struct { 49 | Data data.SessionEndedRequest 50 | Request 51 | } 52 | 53 | type EventRequest struct { 54 | Data data.EventRequest 55 | Request 56 | } 57 | 58 | type AudioPlayerEventRequest struct { 59 | Data data.AudioPlayerEventRequest 60 | EventRequest 61 | } 62 | 63 | type VideoPlayerEventRequest struct { 64 | Data data.VideoPlayerEventRequest 65 | EventRequest 66 | } 67 | 68 | func (this *EventRequest) GetUrl() string { 69 | return this.Data.Request.Url 70 | } 71 | 72 | func (this *EventRequest) GetName() string { 73 | return this.Data.Request.Name 74 | } 75 | 76 | func (this *AudioPlayerEventRequest) GetOffsetInMilliseconds() int32 { 77 | return this.Data.Request.OffsetInMilliseconds 78 | } 79 | 80 | func (this *VideoPlayerEventRequest) GetOffsetInMilliseconds() int32 { 81 | return this.Data.Request.OffsetInMilliseconds 82 | } 83 | 84 | // 获取意图名 85 | func (this *IntentRequest) GetIntentName() (string, bool) { 86 | return this.Dialog.GetIntentName() 87 | } 88 | 89 | // 槽位填充是否完成 90 | func (this *IntentRequest) IsDialogStateCompleted() bool { 91 | return this.Dialog.DialogState == "COMPLETED" 92 | } 93 | 94 | // 获取用户请求query 95 | func (this *IntentRequest) GetQuery() string { 96 | query, _ := this.Dialog.GetQuery() 97 | return query 98 | } 99 | 100 | // 获取用户id 101 | func (this *Request) GetUserId() string { 102 | return this.Common.Context.System.User.UserId 103 | } 104 | 105 | // 获取设备id 106 | func (this *Request) GetDeviceId() string { 107 | return this.Common.Context.System.Device.DeviceId 108 | } 109 | 110 | // 获取音频播放上下文 111 | func (this *Request) GetAudioPlayerContext() data.AudioPlayerContext { 112 | return this.Common.Context.AudioPlayer 113 | } 114 | 115 | // 获取视频播放上下文 116 | func (this *Request) GetVideoPlayerContext() data.VideoPlayerContext { 117 | return this.Common.Context.VideoPlayer 118 | } 119 | 120 | // 获取access token 121 | func (this *Request) GetAccessToken() string { 122 | return this.Common.Context.System.User.AccessToken 123 | } 124 | 125 | // 获取请求的时间戳 126 | func (this *Request) GetTimestamp() int { 127 | i, err := strconv.Atoi(this.Common.Request.Timestamp) 128 | if err != nil { 129 | log.Fatal(err) 130 | } 131 | return i 132 | } 133 | 134 | // 获取请求id 135 | func (this *Request) GetRequestId() string { 136 | return this.Common.Request.RequestId 137 | } 138 | 139 | // 获取技能id 140 | func (this *Request) GetBotId() string { 141 | return this.Common.Context.System.Application.ApplicationId 142 | } 143 | 144 | // 验证请求时间戳合法性 145 | func (this *Request) VerifyTimestamp() bool { 146 | 147 | if this.GetTimestamp()+180 > int(time.Now().Unix()) { 148 | return true 149 | } 150 | 151 | return false 152 | } 153 | 154 | // 获取设备支持的接口类型 155 | func (this *Request) GetSupportedInterfaces() map[string]interface{} { 156 | return this.Common.Context.System.Device.SupportedInterfaces 157 | } 158 | 159 | func (this *Request) isSupportInterface(support string) bool { 160 | supportedInterfaces := this.GetSupportedInterfaces() 161 | _, ok := supportedInterfaces[support] 162 | 163 | if ok { 164 | return true 165 | } 166 | return false 167 | } 168 | 169 | // 检查是否支持展现 170 | func (this *Request) IsSupportDisplay() bool { 171 | return this.isSupportInterface("Display") 172 | } 173 | 174 | // 检查是否支持音频播放 175 | func (this *Request) IsSupportAudio() bool { 176 | return this.isSupportInterface("AudioPlayer") 177 | } 178 | 179 | // 检查是否支持视频播放 180 | func (this *Request) IsSupportVideo() bool { 181 | return this.isSupportInterface("VideoPlayer") 182 | } 183 | 184 | // 验证技能id合法性 185 | func (this *Request) VerifyBotID(myBotID string) bool { 186 | if this.GetBotId() == myBotID { 187 | return true 188 | } 189 | return false 190 | } 191 | 192 | func getType(rawData string) string { 193 | jsonBlob := []byte(rawData) 194 | d := data.LaunchRequest{} 195 | 196 | if err := json.Unmarshal(jsonBlob, &d); err != nil { 197 | log.Println(err) 198 | } 199 | 200 | return d.Request.Type 201 | } 202 | 203 | func GetSessionData(rawData string) data.Session { 204 | jsonBlob := []byte(rawData) 205 | common := data.RequestPart{} 206 | if err := json.Unmarshal(jsonBlob, &common); err != nil { 207 | log.Println(err) 208 | } 209 | 210 | return common.Session 211 | } 212 | 213 | func NewRequest(rawData string) interface{} { 214 | requestType := getType(rawData) 215 | 216 | jsonBlob := []byte(rawData) 217 | 218 | common := data.RequestPart{} 219 | if err := json.Unmarshal(jsonBlob, &common); err != nil { 220 | log.Println(err) 221 | return false 222 | } 223 | 224 | if requestType == INENT_REQUEST { 225 | request := IntentRequest{} 226 | request.Type = requestType 227 | request.Common = common 228 | if err := json.Unmarshal(jsonBlob, &request.Data); err != nil { 229 | log.Println(err) 230 | return false 231 | } 232 | request.Dialog = NewDialog(request.Data.Request) 233 | 234 | return request 235 | } else if requestType == LAUNCH_REQUEST { 236 | request := LaunchRequest{} 237 | request.Type = requestType 238 | request.Common = common 239 | if err := json.Unmarshal(jsonBlob, &request.Data); err != nil { 240 | log.Println(err) 241 | return false 242 | } 243 | return request 244 | } else if requestType == SESSION_ENDED_REQUEST { 245 | request := SessionEndedRequest{} 246 | request.Type = requestType 247 | request.Common = common 248 | if err := json.Unmarshal(jsonBlob, &request.Data); err != nil { 249 | log.Println(err) 250 | return false 251 | } 252 | return request 253 | } else { 254 | if match, _ := regexp.MatchString("^AudioPlayer", requestType); match { 255 | request := AudioPlayerEventRequest{} 256 | request.Type = requestType 257 | request.Common = common 258 | if err := json.Unmarshal(jsonBlob, &request.Data); err != nil { 259 | log.Println(err) 260 | return false 261 | } 262 | return request 263 | } else if match, _ := regexp.MatchString("^VideoPlayer", requestType); match { 264 | request := VideoPlayerEventRequest{} 265 | request.Type = requestType 266 | request.Common = common 267 | if err := json.Unmarshal(jsonBlob, &request.Data); err != nil { 268 | log.Println(err) 269 | return false 270 | } 271 | return request 272 | } 273 | 274 | request := EventRequest{} 275 | request.Type = requestType 276 | request.Common = common 277 | if err := json.Unmarshal(jsonBlob, &request.Data); err != nil { 278 | log.Println(err) 279 | return false 280 | } 281 | return request 282 | } 283 | return false 284 | } 285 | -------------------------------------------------------------------------------- /bot/model/request_test.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "fmt" 5 | //"log" 6 | "reflect" 7 | "strings" 8 | "testing" 9 | 10 | "github.com/dueros/bot-sdk-go/bot/util" 11 | ) 12 | 13 | func TestGetUserId(t *testing.T) { 14 | functionTest("GetUserId", "4541", t) 15 | } 16 | 17 | func TestGetDeviceId(t *testing.T) { 18 | functionTest("GetDeviceId", "deviceId", t) 19 | } 20 | 21 | func TestGetTimestamp(t *testing.T) { 22 | functionTest("GetTimestamp", 1531750145, t) 23 | } 24 | 25 | func functionTest(funcName string, value interface{}, t *testing.T) { 26 | files := map[string]string{ 27 | "IntentRequest": "../test/intent-request.json", 28 | "LaunchRequest": "../test/launch.json", 29 | "AudioPlayerEventRequest": "../test/audio-player-event.json", 30 | "VideoPlayerEventRequest": "../test/video-player-event.json", 31 | } 32 | 33 | for key, path := range files { 34 | var ret interface{} 35 | req := getRequest(path) 36 | split := strings.Split(reflect.TypeOf(req).String(), ".") 37 | reqType := split[len(split)-1] 38 | if reqType != key { 39 | t.Error(fmt.Sprintf("%s NewRequest not %s", path, funcName)) 40 | } 41 | 42 | switch request := req.(type) { 43 | case LaunchRequest: 44 | ret = reflect.ValueOf(&request).MethodByName(funcName).Call(make([]reflect.Value, 0))[0] 45 | case IntentRequest: 46 | ret = reflect.ValueOf(&request).MethodByName(funcName).Call(make([]reflect.Value, 0))[0] 47 | case AudioPlayerEventRequest: 48 | ret = reflect.ValueOf(&request).MethodByName(funcName).Call(make([]reflect.Value, 0))[0] 49 | case VideoPlayerEventRequest: 50 | ret = reflect.ValueOf(&request).MethodByName(funcName).Call(make([]reflect.Value, 0))[0] 51 | } 52 | 53 | if !reflect.DeepEqual(ret.(reflect.Value).Interface(), value) { 54 | t.Error(fmt.Sprintf("%s error:%s ", funcName, key)) 55 | } 56 | } 57 | } 58 | 59 | func getRequest(path string) interface{} { 60 | body, _ := util.ReadFileAll(path) 61 | rawRequest := string(body) 62 | request := NewRequest(rawRequest) 63 | 64 | return request 65 | } 66 | -------------------------------------------------------------------------------- /bot/model/response.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | "github.com/dueros/bot-sdk-go/bot/data" 7 | "github.com/dueros/bot-sdk-go/bot/util" 8 | ) 9 | 10 | type Response struct { 11 | session *Session 12 | request interface{} 13 | data map[string]interface{} 14 | } 15 | 16 | func NewResponse(session *Session, request interface{}) *Response { 17 | d := make(map[string]interface{}) 18 | return &Response{ 19 | data: d, 20 | session: session, 21 | request: request, 22 | } 23 | } 24 | 25 | /** 26 | * 询问用户时,返回的speech. 27 | * 此时设备的麦克风会进入收音状态,比如设备灯光亮起 28 | * TIP: 一般技能要完成一项任务,还缺少一些信息,主动发起对用户的询问的时候使用 29 | */ 30 | func (this *Response) Ask(speech string) *Response { 31 | this.Tell(speech) 32 | this.HoldOn() 33 | return this 34 | } 35 | 36 | func (this *Response) AskSlot(speech string, slot string) *Response { 37 | this.Ask(speech) 38 | 39 | request, ok := this.request.(IntentRequest) 40 | if ok { 41 | request.Dialog.ElicitSlot(slot) 42 | } 43 | return this 44 | } 45 | 46 | /** 47 | * 回复用户,返回的speech 48 | */ 49 | func (this *Response) Tell(speech string) *Response { 50 | this.data["outputSpeech"] = util.FormatSpeech(speech) 51 | return this 52 | } 53 | 54 | /** 55 | * 回复用户,返回的speech 56 | */ 57 | func (this *Response) Reprompt(speech string) *Response { 58 | this.data["reprompt"] = map[string]interface{}{ 59 | "outputSpeech": util.FormatSpeech(speech), 60 | } 61 | return this 62 | } 63 | 64 | /** 65 | * 返回卡片. 66 | * 针对有屏幕的设备,比如: 电视、show,可以呈现更多丰富的信息给用户 67 | * 卡片协议参考:TODO 68 | */ 69 | func (this *Response) DisplayCard(card interface{}) *Response { 70 | this.data["card"] = card 71 | 72 | return this 73 | } 74 | 75 | /** 76 | * 返回指令. 比如,返回音频播放指令,使设备开始播放音频 77 | * TIP: 可以同时返回多个指令,设备按返回顺序执行这些指令,指令协议参考TODO 78 | */ 79 | func (this *Response) Command(directive interface{}) *Response { 80 | _, ok := this.data["directives"] 81 | if !ok { 82 | this.data["directives"] = make([]interface{}, 0) 83 | } 84 | 85 | directives, ok := this.data["directives"].([]interface{}) 86 | directives = append(directives, directive) 87 | 88 | this.data["directives"] = directives 89 | 90 | return this 91 | } 92 | 93 | /** 94 | * 保持会话. 95 | * 此时设备的麦克风会自动开启监听用户说话 96 | */ 97 | func (this *Response) HoldOn() *Response { 98 | this.data["shouldEndSession"] = false 99 | return this 100 | } 101 | 102 | /** 103 | * 保持会话. 104 | * 关闭麦克风 105 | */ 106 | func (this *Response) CloseMicrophone() *Response { 107 | this.data["expectSpeech"] = true 108 | return this 109 | } 110 | 111 | func (this *Response) Build() string { 112 | //session 113 | attributes := this.session.GetData().Attributes 114 | 115 | ret := map[string]interface{}{ 116 | "version": "2.0", 117 | "session": data.SessionResponse{Attributes: attributes}, 118 | "response": this.data, 119 | } 120 | 121 | //intent request 122 | request, ok := this.request.(IntentRequest) 123 | if ok { 124 | ret["context"] = data.ContextResponse{Intent: request.Dialog.Intents[0].GetData()} 125 | 126 | directive := request.Dialog.GetDirective() 127 | if directive != nil { 128 | this.Command(directive) 129 | } 130 | } 131 | 132 | response, _ := json.Marshal(ret) 133 | 134 | return string(response) 135 | } 136 | 137 | func (this *Response) GetData() map[string]interface{} { 138 | return this.data 139 | } 140 | -------------------------------------------------------------------------------- /bot/model/response_test.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | 7 | "github.com/dueros/bot-sdk-go/bot/data" 8 | "github.com/dueros/bot-sdk-go/bot/util" 9 | //"log" 10 | ) 11 | 12 | func TestAsk(t *testing.T) { 13 | response := getResponse("../test/launch.json") 14 | response.Ask("ask") 15 | 16 | ret := response.GetData() 17 | shouldEndSession := ret["shouldEndSession"].(bool) 18 | 19 | if shouldEndSession != false { 20 | t.Error("Ask: shouldEndSession is not false") 21 | } 22 | 23 | speech := ret["outputSpeech"].(data.Speech) 24 | 25 | if !reflect.DeepEqual(speech, data.Speech{Type: "PlainText", Text: "ask"}) { 26 | t.Error("Ask: output speech is not ask") 27 | } 28 | 29 | t.Log("Ask: passed") 30 | } 31 | 32 | func TestAskSlot(t *testing.T) { 33 | response := getResponse("../test/intent-request.json") 34 | response.AskSlot("ask", "slot1") 35 | response.Build() 36 | 37 | ret := response.GetData() 38 | shouldEndSession := ret["shouldEndSession"].(bool) 39 | 40 | if shouldEndSession != false { 41 | t.Error("AskSlot: shouldEndSession is not false") 42 | } 43 | 44 | speech := ret["outputSpeech"].(data.Speech) 45 | 46 | if !reflect.DeepEqual(speech, data.Speech{Type: "PlainText", Text: "ask"}) { 47 | t.Error("AskSlot: output speech is not ask") 48 | } 49 | 50 | arr, ok := ret["directives"].([]interface{}) 51 | directive, ok := arr[0].(*data.DialogDirective) 52 | 53 | if !ok { 54 | t.Error("AskSlot: no dialog.ElicitSlot") 55 | } 56 | 57 | if directive.Type != "Dialog.ElicitSlot" { 58 | t.Error("AskSlot: directive is not dialog.ElicitSlot ") 59 | } 60 | 61 | if directive.SlotToElicit != "slot1" { 62 | t.Error("AskSlot: directive.SlotToElicit is not slot1") 63 | } 64 | } 65 | 66 | func TestTell(t *testing.T) { 67 | response := getResponse("../test/launch.json") 68 | response.Tell("tell") 69 | 70 | ret := response.GetData() 71 | 72 | speech := ret["outputSpeech"].(data.Speech) 73 | 74 | if !reflect.DeepEqual(speech, data.Speech{Type: "PlainText", Text: "tell"}) { 75 | t.Error("Tell: output speech is not tell") 76 | } 77 | 78 | t.Log("Tell: passed") 79 | } 80 | 81 | func TestReprompt(t *testing.T) { 82 | response := getResponse("../test/launch.json") 83 | response.Reprompt("reprompt") 84 | 85 | ret := response.GetData() 86 | 87 | reprompt, ok := ret["reprompt"].(map[string]interface{}) 88 | if !ok { 89 | t.Error("Reprompt: reprompt is not map structure") 90 | } 91 | 92 | outputSpeech, ok := reprompt["outputSpeech"] 93 | if !ok { 94 | t.Error("Reprompt: reprompt has no outputSpeech") 95 | } 96 | 97 | speech := outputSpeech.(data.Speech) 98 | 99 | if !reflect.DeepEqual(speech, data.Speech{Type: "PlainText", Text: "reprompt"}) { 100 | t.Error("Reprompt: output speech is not reprompt") 101 | } 102 | 103 | t.Log("Reprompt: passed") 104 | } 105 | 106 | func TestDisplayCard(t *testing.T) {} 107 | func TestCommand(t *testing.T) {} 108 | 109 | func TestHoldOn(t *testing.T) { 110 | response := getResponse("../test/launch.json") 111 | response.HoldOn() 112 | 113 | ret := response.GetData() 114 | shouldEndSession := ret["shouldEndSession"].(bool) 115 | 116 | if shouldEndSession != false { 117 | t.Error("HoldOn: shouldEndSession is not false") 118 | } 119 | } 120 | 121 | func TestCloseMicrophone(t *testing.T) { 122 | response := getResponse("../test/launch.json") 123 | response.CloseMicrophone() 124 | 125 | ret := response.GetData() 126 | expectSpeech := ret["expectSpeech"].(bool) 127 | 128 | if expectSpeech != true { 129 | t.Error("CloseMicrophone: expectSpeech is not true") 130 | } 131 | } 132 | 133 | func getResponse(path string) *Response { 134 | body, _ := util.ReadFileAll(path) 135 | rawRequest := string(body) 136 | request := NewRequest(rawRequest) 137 | session := NewSession(GetSessionData(rawRequest)) 138 | 139 | response := NewResponse(session, request) 140 | 141 | return response 142 | } 143 | -------------------------------------------------------------------------------- /bot/model/session.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "github.com/dueros/bot-sdk-go/bot/data" 5 | ) 6 | 7 | type Session struct { 8 | data data.Session 9 | } 10 | 11 | func NewSession(data data.Session) *Session { 12 | if data.Attributes == nil { 13 | data.Attributes = make(map[string]string) 14 | } 15 | 16 | return &Session{ 17 | data: data, 18 | } 19 | } 20 | 21 | // 当前session是否是新的 22 | func (this *Session) IsNew() bool { 23 | return this.data.New 24 | } 25 | 26 | // 获取session id 27 | func (this *Session) GetId() string { 28 | return this.data.SessionId 29 | } 30 | 31 | // 获取session中对应字段的值 32 | func (this *Session) GetAttribute(key string) string { 33 | value, ok := this.data.Attributes[key] 34 | if ok { 35 | return value 36 | } 37 | return "" 38 | } 39 | 40 | // 设置session中对应字段的值 41 | func (this *Session) SetAttribute(key, value string) { 42 | if key == "" { 43 | return 44 | } 45 | 46 | this.data.Attributes[key] = value 47 | } 48 | 49 | func (this *Session) GetData() data.Session { 50 | return this.data 51 | } 52 | -------------------------------------------------------------------------------- /bot/model/ssml_builder.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | ) 7 | 8 | /** 9 | * Details about the Speech Synthesis Markup Language (SSML) can be found on this page: 10 | * https://dueros.baidu.com/didp/doc/dueros-bot-platform/dbp-custom/ssml_markdown 11 | */ 12 | 13 | // Helper Types 14 | 15 | type SSMLTextBuilder struct { 16 | buffer *bytes.Buffer 17 | } 18 | 19 | func NewSSMLTextBuilder() *SSMLTextBuilder { 20 | return &SSMLTextBuilder{bytes.NewBufferString("")} 21 | } 22 | 23 | func (this *SSMLTextBuilder) AppendPlainSpeech(text string) *SSMLTextBuilder { 24 | 25 | this.buffer.WriteString(text) 26 | 27 | return this 28 | } 29 | 30 | func (this *SSMLTextBuilder) AppendAudio(src string) *SSMLTextBuilder { 31 | 32 | this.buffer.WriteString(fmt.Sprintf("", src)) 33 | 34 | return this 35 | } 36 | 37 | /* 38 | func (this *SSMLTextBuilder) AppendBreak(strength, time string) *SSMLTextBuilder { 39 | 40 | if strength == "" { 41 | // The default strength is medium 42 | strength = "medium" 43 | } 44 | 45 | this.buffer.WriteString(fmt.Sprintf("", strength, time)) 46 | 47 | return this 48 | } 49 | 50 | func (this *SSMLTextBuilder) AppendEmphasis(text, level string) *SSMLTextBuilder { 51 | 52 | this.buffer.WriteString(fmt.Sprintf("%s", level, text)) 53 | 54 | return this 55 | } 56 | 57 | func (this *SSMLTextBuilder) AppendParagraph(text string) *SSMLTextBuilder { 58 | 59 | this.buffer.WriteString(fmt.Sprintf("

%s

", text)) 60 | 61 | return this 62 | } 63 | 64 | func (this *SSMLTextBuilder) AppendProsody(text, rate, pitch, volume string) *SSMLTextBuilder { 65 | 66 | this.buffer.WriteString(fmt.Sprintf("%s", rate, pitch, volume, text)) 67 | 68 | return this 69 | } 70 | 71 | func (this *SSMLTextBuilder) AppendSentence(text string) *SSMLTextBuilder { 72 | 73 | this.buffer.WriteString(fmt.Sprintf("%s", text)) 74 | 75 | return this 76 | } 77 | */ 78 | 79 | func (this *SSMLTextBuilder) AppendSilence(time int) *SSMLTextBuilder { 80 | 81 | this.buffer.WriteString(fmt.Sprintf("", time)) 82 | 83 | return this 84 | } 85 | 86 | func (this *SSMLTextBuilder) AppendSubstitution(text, alias string) *SSMLTextBuilder { 87 | 88 | this.buffer.WriteString(fmt.Sprintf("%s", alias, text)) 89 | 90 | return this 91 | } 92 | 93 | func (this *SSMLTextBuilder) AppendBackground(text string, src string, repeat bool) *SSMLTextBuilder { 94 | repeatAttr := "yes" 95 | if !repeat { 96 | repeatAttr = "" 97 | } 98 | 99 | this.buffer.WriteString(fmt.Sprintf("%s", src, repeatAttr, text)) 100 | return this 101 | } 102 | 103 | func (this *SSMLTextBuilder) ApplyBackground(src string, repeat bool) *SSMLTextBuilder { 104 | repeatAttr := "yes" 105 | if !repeat { 106 | repeatAttr = "" 107 | } 108 | 109 | buffer := bytes.NewBufferString("") 110 | buffer.WriteString(fmt.Sprintf("%s", src, repeatAttr, this.buffer.String())) 111 | 112 | this.buffer = buffer 113 | return this 114 | } 115 | 116 | func (this *SSMLTextBuilder) Build() string { 117 | return fmt.Sprintf("%s", this.buffer.String()) 118 | } 119 | -------------------------------------------------------------------------------- /bot/test/audio-player-event.json: -------------------------------------------------------------------------------- 1 | {"version":"v2.0","session":{"new":true,"sessionId":"284606c7-7d67-417f-bdda-be475de85203"},"context":{"System":{"user":{"userId":"4541","userInfo":{"account":{},"nickname":"Happy2LE"}},"application":{"applicationId":"69adc3f2-c69c-0150-45b3-11e558193406"},"device":{"deviceId":"deviceId","supportedInterfaces":{"VoiceInput":{},"VoiceOutput":{},"AudioPlayer":{},"Display":{},"VideoPlayer":{}}},"apiAccessToken":"uLr0rabWoR95WEpeAJrOrdjthrIx90oACd\/iWkwWQ1rX44VoAGpsWVsk6F9Ey259NZyvPos8cQQtyjSpT2qnNCLS+5IqXMMuSybq+ZlXCkjRFWIY\/SiLHdrnr5JGixpW4NxSOj3UJBj6C1\/wTGazapG3x6B2ejjH8C1o8gfum3eeK20u3nZZSb\/xdzLFs2OrMh+hU6dXehYYiU0wFXN2LzlfvTScVGmCKrotyQaK5KXFVcO1UHc7TjIG4g\/8fAlG1iysw+MJoCj2gYr9FFOXlgAY74m3yxFOE7IIwrU5ZFQ=","apiEndPoint":"https:\/\/xiaodu.baidu.com"},"AudioPlayer":{"token":"token1","offsetInMilliSeconds":0,"playActivity":"PLAYING"}},"request":{"token":"token1","offsetInMilliSeconds":10,"type":"AudioPlayer.PlaybackStarted","requestId":"7f2d4b61d7534a27b32799083879f785_0","timestamp":"1531750145","dialogRequestId":""}} 2 | -------------------------------------------------------------------------------- /bot/test/intent-request.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "v2.0", 3 | "session": { 4 | "new": false, 5 | "sessionId": "f1bc4b19-1bcf-410f-9d76-f20214d4dc91", 6 | "attributes": {} 7 | }, 8 | "context": { 9 | "System": { 10 | "user": { 11 | "userId": "4541", 12 | "userInfo": { 13 | "account": {}, 14 | "nickname": "kira" 15 | } 16 | }, 17 | "application": { 18 | "applicationId": "14a6ee9e-3367-f4e3-6698-d8df54c8a104" 19 | }, 20 | "device": { 21 | "deviceId": "deviceId", 22 | "supportedInterfaces": { 23 | "VoiceInput": {}, 24 | "VoiceOutput":{}, 25 | "AudioPlayer": {} 26 | } 27 | }, 28 | "apiAccessToken": "U3ubvE6lyyDHrk46qGi92fKJmePlfzkaaJAQsta/2C575HI2tJF99JxDsJw3GWwR60V6Z9EyidnX8iaKEUr3TiybHozVf+tN+WbKmWvTX+AnLXHS71Q/Vhh987XNbYT7xPIG32Q4JRYZUTbhBrKuYtNmIj8OA1XZyXJ16Stow4dETlrbKGe6oMAjSzc8EVG8ZX7mpbMS0+gxAPJOkppslUV8VT4cG9AhswFHgBF77iccv8xL3dYUogg6bytzJOmXuGoOlGYiMRr2siPrSt9kEvoeekWdJM5THJbVMiegYLA=", 29 | "apiEndPoint": "https://xiaodu.baidu.com" 30 | } 31 | }, 32 | "request": { 33 | "query": { 34 | "type": "TEXT", 35 | "original": "北京出发的机票" 36 | }, 37 | "dialogState": "STARTED", 38 | "intents": [ 39 | { 40 | "name": "flightSearch", 41 | "confirmationStatus": "NONE", 42 | "slots": { 43 | "departure": { 44 | "name": "departure", 45 | "value": "{\"city\":\"北京\",\"country\":\"中国\",\"origin\":\"北京\",\"province\":\"北京\"}", 46 | "values": [ 47 | "{\"city\":\"北京\",\"country\":\"中国\",\"origin\":\"北京\",\"province\":\"北京\"}" 48 | ], 49 | "confirmationStatus": "NONE" 50 | } 51 | } 52 | } 53 | ], 54 | "type": "IntentRequest", 55 | "requestId": "3c53c952cdac46018f26bfb030c7a695_0", 56 | "timestamp": "1531750145", 57 | "dialogRequestId": "ebd702a8-f1ae-4fa1-b253-495aedbc9a3c" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /bot/test/launch.json: -------------------------------------------------------------------------------- 1 | {"version":"v2.0","session":{"new":true,"sessionId":"7ec2f08e-ae82-4290-8b9d-3e5d5209746c"},"context":{"System":{"user":{"userId":"4541","userInfo":{"account":{}}},"application":{"applicationId":"17a64831-b273-8af5-f995-9a805e45cffe"},"device":{"deviceId":"deviceId","supportedInterfaces":{"VoiceInput":{},"VoiceOutput":{},"AudioPlayer":{}}},"apiAccessToken":"T2S0unwE+p1Plfz7QDzGUnA0/IMjqg9bC1lxckCGPK4WvTOfKkzpQXOMtES/D4I7qmBRg8CLbM8OFuBwx/U4zuOH2GKwvWFGbEgEGZZJfZ0EnSfMXmklJoRjs/PjhSK0xPIG32Q4JRYZUTbhBrKuYtNmIj8OA1XZyXJ16Stow4eu3ljTWiTej/BlHUXpP6W7dVOsH61Q1lK699hAmyXy8VaDITfNzKWDbTsE3FXbHkzX30PY3hgSkjUWNq7p4FnxuGoOlGYiMRr2siPrSt9kEhZ7CldSqyOy4Rmsc4GQpGg=","apiEndPoint":"https://xiaodu.baidu.com"}},"request":{"type":"LaunchRequest","requestId":"2055a30c3cee4232a3095e6e1eebcbb1_0","timestamp":"1531750145","dialogRequestId":"34e8d58f-1113-4562-96f6-26b82cd2a94d"}} 2 | -------------------------------------------------------------------------------- /bot/test/video-player-event.json: -------------------------------------------------------------------------------- 1 | {"version":"v2.0","session":{"new":false,"sessionId":"65f8a96d-f6a6-4502-9237-a0da1a7c5e1d","attributes":{}},"context":{"System":{"user":{"userId":"4541","userInfo":{"account":{},"nickname":"Happy2LE"}},"application":{"applicationId":"69adc3f2-c69c-0150-45b3-11e558193406"},"device":{"deviceId":"deviceId","supportedInterfaces":{"VoiceInput":{},"VoiceOutput":{},"AudioPlayer":{},"Display":{},"VideoPlayer":{}}},"apiAccessToken":"uLr0rabWoR95WEpeAJrOrdjthrIx90oACd\/iWkwWQ1rX44VoAGpsWVsk6F9Ey259NZyvPos8cQQtyjSpT2qnNCLS+5IqXMMuSybq+ZlXCkjRFWIY\/SiLHdrnr5JGixpW4NxSOj3UJBj6C1\/wTGazagoggTp8bQeMJprqa65i8hqeK20u3nZZSb\/xdzLFs2OrMh+hU6dXehYYiU0wFXN2LzlfvTScVGmCKrotyQaK5KXFVcO1UHc7TjIG4g\/8fAlG1iysw+MJoCj2gYr9FFOXlgAY74m3yxFOE7IIwrU5ZFQ=","apiEndPoint":"https:\/\/xiaodu.baidu.com"}},"request":{"token":"4e56199f-23c7-ff9a-0995-9ca7986f2aec","offsetInMilliseconds":10,"type":"VideoPlayer.PlaybackStarted","requestId":"432c34d8406b45058db06f553521ea1f_0","timestamp":"1531750145","dialogRequestId":""}} 2 | -------------------------------------------------------------------------------- /bot/util/util.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "io/ioutil" 5 | "os" 6 | "regexp" 7 | 8 | "github.com/dueros/bot-sdk-go/bot/data" 9 | ) 10 | 11 | func FormatSpeech(speech string) data.Speech { 12 | match, _ := regexp.MatchString("^", speech) 13 | 14 | if match { 15 | return data.Speech{ 16 | Type: "SSML", 17 | Ssml: speech, 18 | } 19 | } 20 | 21 | return data.Speech{ 22 | Type: "PlainText", 23 | Text: speech, 24 | } 25 | } 26 | 27 | func ReadFileAll(filePath string) ([]byte, error) { 28 | f, err := os.Open(filePath) 29 | defer f.Close() 30 | 31 | if err != nil { 32 | return nil, err 33 | } 34 | 35 | return ioutil.ReadAll(f) 36 | } 37 | -------------------------------------------------------------------------------- /bot/video_player.go: -------------------------------------------------------------------------------- 1 | package bot 2 | 3 | import ( 4 | "github.com/dueros/bot-sdk-go/bot/model" 5 | ) 6 | 7 | // 视频播放相关的事件处理注册 8 | // 设备在播放视频事会上报event,具体可以参考DCS.video_player.play事件,TODO 9 | // 技能收到的事件数据格式参考技能协议,TODO 10 | 11 | // 视频开始播放事件 12 | func (this *Bot) OnVideoPlaybackStarted(fn func(bot *Bot, request *model.VideoPlayerEventRequest)) { 13 | this.AddEventListener(model.VIDEO_PLAYER_PLAYBACK_STARTED, func(bot *Bot, request interface{}) { 14 | req := request.(model.VideoPlayerEventRequest) 15 | fn(bot, &req) 16 | }) 17 | } 18 | 19 | // 视频停止播放事件 20 | func (this *Bot) OnVideoPlaybackStopped(fn func(bot *Bot, request *model.VideoPlayerEventRequest)) { 21 | this.AddEventListener(model.VIDEO_PLAYER_PLAYBACK_STOPPED, func(bot *Bot, request interface{}) { 22 | req := request.(model.VideoPlayerEventRequest) 23 | fn(bot, &req) 24 | }) 25 | } 26 | 27 | // 视频播放完成事件 28 | func (this *Bot) OnVideoPlaybackFinished(fn func(bot *Bot, request *model.VideoPlayerEventRequest)) { 29 | this.AddEventListener(model.VIDEO_PLAYER_PLAYBACK_FINISHED, func(bot *Bot, request interface{}) { 30 | req := request.(model.VideoPlayerEventRequest) 31 | fn(bot, &req) 32 | }) 33 | } 34 | 35 | // 视频快要播放结束上报的事件 36 | func (this *Bot) OnVideoPlaybackNearlyFinished(fn func(bot *Bot, request *model.VideoPlayerEventRequest)) { 37 | this.AddEventListener(model.VIDEO_PLAYER_PLAYBACK_NEARLY_FINISHED, func(bot *Bot, request interface{}) { 38 | req := request.(model.VideoPlayerEventRequest) 39 | fn(bot, &req) 40 | }) 41 | } 42 | 43 | // 视频周期上报播放进度 44 | func (this *Bot) OnVideoRrogressReportIntevalElapsed(fn func(bot *Bot, request *model.VideoPlayerEventRequest)) { 45 | this.AddEventListener(model.VIDEO_PLAYER_PROGRESS_REPORT_INTERVAL_ELAPSED, func(bot *Bot, request interface{}) { 46 | req := request.(model.VideoPlayerEventRequest) 47 | fn(bot, &req) 48 | }) 49 | } 50 | 51 | // 视频自动暂停后上报 52 | func (this *Bot) OnVideoPlayerScheduledStopReached(fn func(bot *Bot, request *model.VideoPlayerEventRequest)) { 53 | this.AddEventListener(model.VIDEO_PLAYER_PLAYBACK_SCHEDULED_STOP_REACHED, func(bot *Bot, request interface{}) { 54 | req := request.(model.VideoPlayerEventRequest) 55 | fn(bot, &req) 56 | }) 57 | } 58 | -------------------------------------------------------------------------------- /bot/video_player_test.go: -------------------------------------------------------------------------------- 1 | package bot 2 | 3 | import ( 4 | //"reflect" 5 | "testing" 6 | 7 | "github.com/dueros/bot-sdk-go/bot/model" 8 | "github.com/dueros/bot-sdk-go/bot/util" 9 | "log" 10 | ) 11 | 12 | func TestOnVideoPlaybackStarted(t *testing.T) { 13 | body, _ := util.ReadFileAll("test/video-player-event.json") 14 | rawRequest := string(body) 15 | 16 | bot := NewBot(rawRequest) 17 | 18 | bot.OnVideoPlaybackStarted(func(bot *Bot, request *model.VideoPlayerEventRequest) { 19 | log.Println("OnVideoPlaybackStarted has been called") 20 | if request.GetOffsetInMilliseconds() != 10 { 21 | t.Error("VideoPlayerEventRequest:GetOffsetInMilliseconds value is not 10") 22 | } 23 | }) 24 | 25 | bot.Run() 26 | } 27 | -------------------------------------------------------------------------------- /doc.sh: -------------------------------------------------------------------------------- 1 | rm -rf doc 2 | mkdir -p doc/model 3 | mkdir -p doc/directive/display/template 4 | mkdir -p doc/directive/audio_player 5 | mkdir -p doc/directive/video_player 6 | mkdir -p doc/card 7 | 8 | cd bot 9 | 10 | godoc2md github.com/dueros/bot-sdk-go/bot Bot > ../doc/bot.md 11 | godoc2md github.com/dueros/bot-sdk-go/bot Application > ../doc/application.md 12 | godoc2md github.com/dueros/bot-sdk-go/bot/model Dialog > ../doc/model/dialog.md 13 | godoc2md github.com/dueros/bot-sdk-go/bot/model Intent> ../doc/model/intent.md 14 | 15 | godoc2md github.com/dueros/bot-sdk-go/bot/model Request> ../doc/model/request.md 16 | godoc2md github.com/dueros/bot-sdk-go/bot/model LaunchRequest>> ../doc/model/request.md 17 | godoc2md github.com/dueros/bot-sdk-go/bot/model IntentRequest>> ../doc/model/request.md 18 | godoc2md github.com/dueros/bot-sdk-go/bot/model SessionEndedRequest>> ../doc/model/request.md 19 | godoc2md github.com/dueros/bot-sdk-go/bot/model EventRequest>> ../doc/model/request.md 20 | 21 | godoc2md github.com/dueros/bot-sdk-go/bot/model Response> ../doc/model/response.md 22 | godoc2md github.com/dueros/bot-sdk-go/bot/model Session> ../doc/model/session.md 23 | godoc2md github.com/dueros/bot-sdk-go/bot/model SSMLTextBuilder> ../doc/model/ssml-text-builder.md 24 | 25 | godoc2md github.com/dueros/bot-sdk-go/bot/card > ../doc/card/card.md 26 | 27 | godoc2md github.com/dueros/bot-sdk-go/bot/directive/display/template > ../doc/directive/display/template.md 28 | godoc2md github.com/dueros/bot-sdk-go/bot/directive/display RenderTemplate> ../doc/directive/display/render-template.md 29 | godoc2md github.com/dueros/bot-sdk-go/bot/directive/audio_player > ../doc/directive/audio-player.md 30 | godoc2md github.com/dueros/bot-sdk-go/bot/directive/video_player > ../doc/directive/video-player.md 31 | 32 | cd - 33 | 34 | -------------------------------------------------------------------------------- /doc/application.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # bot 4 | `import "github.com/dueros/bot-sdk-go/bot"` 5 | 6 | * [Overview](#pkg-overview) 7 | * [Index](#pkg-index) 8 | * [Subdirectories](#pkg-subdirectories) 9 | 10 | ## Overview 11 | 12 | 13 | 14 | ## Index 15 | * [type Application](#Application) 16 | * [func (this *Application) ServeHTTP(w http.ResponseWriter, r *http.Request)](#Application.ServeHTTP) 17 | * [func (this *Application) Start(host string)](#Application.Start) 18 | * [func (this *Application) Verify(w http.ResponseWriter, r *http.Request) bool](#Application.Verify) 19 | 20 | 21 | #### Package files 22 | [application.go](/src/github.com/dueros/bot-sdk-go/bot/application.go) [audio_player.go](/src/github.com/dueros/bot-sdk-go/bot/audio_player.go) [bot.go](/src/github.com/dueros/bot-sdk-go/bot/bot.go) [event_handler.go](/src/github.com/dueros/bot-sdk-go/bot/event_handler.go) [video_player.go](/src/github.com/dueros/bot-sdk-go/bot/video_player.go) 23 | 24 | 25 | 26 | 27 | 28 | 29 | ## type [Application](/src/target/application.go?s=261:416#L24) 30 | ``` go 31 | type Application struct { 32 | AppId string 33 | DisableCertificate bool 34 | DisableVerifyJson bool 35 | Handler func(rawRequest string) string 36 | } 37 | ``` 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | ### func (\*Application) [ServeHTTP](/src/target/application.go?s=444:518#L32) 48 | ``` go 49 | func (this *Application) ServeHTTP(w http.ResponseWriter, r *http.Request) 50 | ``` 51 | 创建一个HTTP服务 52 | 53 | 54 | 55 | 56 | ### func (\*Application) [Start](/src/target/application.go?s=1012:1055#L60) 57 | ``` go 58 | func (this *Application) Start(host string) 59 | ``` 60 | 启动HTTP服务 61 | 62 | 63 | 64 | 65 | ### func (\*Application) [Verify](/src/target/application.go?s=1167:1243#L69) 66 | ``` go 67 | func (this *Application) Verify(w http.ResponseWriter, r *http.Request) bool 68 | ``` 69 | 验证请求是否合法 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | - - - 79 | Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md) 80 | -------------------------------------------------------------------------------- /doc/bot.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # bot 4 | `import "github.com/dueros/bot-sdk-go/bot"` 5 | 6 | * [Overview](#pkg-overview) 7 | * [Index](#pkg-index) 8 | * [Subdirectories](#pkg-subdirectories) 9 | 10 | ## Overview 11 | 12 | 13 | 14 | ## Index 15 | * [type Bot](#Bot) 16 | * [func NewBot(rawRequest string) *Bot](#NewBot) 17 | * [func (this *Bot) AddDefaultEventListener(fn func(bot *Bot, request interface{}))](#Bot.AddDefaultEventListener) 18 | * [func (this *Bot) AddEventListener(eventName string, fn func(bot *Bot, request interface{}))](#Bot.AddEventListener) 19 | * [func (this *Bot) AddIntentHandler(intentName string, fn func(bot *Bot, request *model.IntentRequest))](#Bot.AddIntentHandler) 20 | * [func (this *Bot) OnAudioPlaybackFinished(fn func(bot *Bot, request *model.AudioPlayerEventRequest))](#Bot.OnAudioPlaybackFinished) 21 | * [func (this *Bot) OnAudioPlaybackNearlyFinished(fn func(bot *Bot, request *model.AudioPlayerEventRequest))](#Bot.OnAudioPlaybackNearlyFinished) 22 | * [func (this *Bot) OnAudioPlaybackStarted(fn func(bot *Bot, request *model.AudioPlayerEventRequest))](#Bot.OnAudioPlaybackStarted) 23 | * [func (this *Bot) OnAudioPlaybackStopped(fn func(bot *Bot, request *model.AudioPlayerEventRequest))](#Bot.OnAudioPlaybackStopped) 24 | * [func (this *Bot) OnAudioRrogressReportIntevalElapsed(fn func(bot *Bot, request *model.AudioPlayerEventRequest))](#Bot.OnAudioRrogressReportIntevalElapsed) 25 | * [func (this *Bot) OnDisplayElementSelected(fn func(bot *Bot, request *model.EventRequest))](#Bot.OnDisplayElementSelected) 26 | * [func (this *Bot) OnLaunchRequest(fn func(bot *Bot, request *model.LaunchRequest))](#Bot.OnLaunchRequest) 27 | * [func (this *Bot) OnLinkAccountSuccessed(fn func(bot *Bot, request *model.EventRequest))](#Bot.OnLinkAccountSuccessed) 28 | * [func (this *Bot) OnScreenLinkClicked(fn func(bot *Bot, request *model.EventRequest))](#Bot.OnScreenLinkClicked) 29 | * [func (this *Bot) OnSessionEndedRequest(fn func(bot *Bot, request *model.SessionEndedRequest))](#Bot.OnSessionEndedRequest) 30 | * [func (this *Bot) OnVideoPlaybackFinished(fn func(bot *Bot, request *model.VideoPlayerEventRequest))](#Bot.OnVideoPlaybackFinished) 31 | * [func (this *Bot) OnVideoPlaybackNearlyFinished(fn func(bot *Bot, request *model.VideoPlayerEventRequest))](#Bot.OnVideoPlaybackNearlyFinished) 32 | * [func (this *Bot) OnVideoPlaybackStarted(fn func(bot *Bot, request *model.VideoPlayerEventRequest))](#Bot.OnVideoPlaybackStarted) 33 | * [func (this *Bot) OnVideoPlaybackStopped(fn func(bot *Bot, request *model.VideoPlayerEventRequest))](#Bot.OnVideoPlaybackStopped) 34 | * [func (this *Bot) OnVideoPlayerScheduledStopReached(fn func(bot *Bot, request *model.VideoPlayerEventRequest))](#Bot.OnVideoPlayerScheduledStopReached) 35 | * [func (this *Bot) OnVideoRrogressReportIntevalElapsed(fn func(bot *Bot, request *model.VideoPlayerEventRequest))](#Bot.OnVideoRrogressReportIntevalElapsed) 36 | * [func (this *Bot) Run() string](#Bot.Run) 37 | 38 | 39 | #### Package files 40 | [application.go](/src/github.com/dueros/bot-sdk-go/bot/application.go) [audio_player.go](/src/github.com/dueros/bot-sdk-go/bot/audio_player.go) [bot.go](/src/github.com/dueros/bot-sdk-go/bot/bot.go) [event_handler.go](/src/github.com/dueros/bot-sdk-go/bot/event_handler.go) [video_player.go](/src/github.com/dueros/bot-sdk-go/bot/video_player.go) 41 | 42 | 43 | 44 | 45 | 46 | 47 | ## type [Bot](/src/target/bot.go?s=98:1126#L10) 48 | ``` go 49 | type Bot struct { 50 | Request interface{} // 对当前request的封装,需要在使用时断言,判断当前的类型 51 | Session *model.Session // 对session的封装 52 | Response *model.Response // 对技能返回的封装 53 | // contains filtered or unexported fields 54 | } 55 | ``` 56 | 技能基础类 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | ### func [NewBot](/src/target/bot.go?s=1128:1163#L22) 65 | ``` go 66 | func NewBot(rawRequest string) *Bot 67 | ``` 68 | 69 | 70 | 71 | 72 | ### func (\*Bot) [AddDefaultEventListener](/src/target/bot.go?s=2186:2266#L52) 73 | ``` go 74 | func (this *Bot) AddDefaultEventListener(fn func(bot *Bot, request interface{})) 75 | ``` 76 | 添加事件默认处理函数 77 | 比如,在播放视频时,技能会收到各种事件的上报,如果不想一一处理可以使用这个来添加处理 78 | 79 | 80 | 81 | 82 | ### func (\*Bot) [AddEventListener](/src/target/bot.go?s=1864:1955#L44) 83 | ``` go 84 | func (this *Bot) AddEventListener(eventName string, fn func(bot *Bot, request interface{})) 85 | ``` 86 | 添加对事件的处理函数 87 | 88 | 89 | 90 | 91 | ### func (\*Bot) [AddIntentHandler](/src/target/bot.go?s=1659:1760#L37) 92 | ``` go 93 | func (this *Bot) AddIntentHandler(intentName string, fn func(bot *Bot, request *model.IntentRequest)) 94 | ``` 95 | 添加对intent的处理函数 96 | 97 | 98 | 99 | 100 | ### func (\*Bot) [OnAudioPlaybackFinished](/src/target/audio_player.go?s=896:995#L28) 101 | ``` go 102 | func (this *Bot) OnAudioPlaybackFinished(fn func(bot *Bot, request *model.AudioPlayerEventRequest)) 103 | ``` 104 | 音频播放完成事件 105 | 106 | 107 | 108 | 109 | ### func (\*Bot) [OnAudioPlaybackNearlyFinished](/src/target/audio_player.go?s=1212:1317#L36) 110 | ``` go 111 | func (this *Bot) OnAudioPlaybackNearlyFinished(fn func(bot *Bot, request *model.AudioPlayerEventRequest)) 112 | ``` 113 | 音频快要播放结束上报的事件 114 | 115 | 116 | 117 | 118 | ### func (\*Bot) [OnAudioPlaybackStarted](/src/target/audio_player.go?s=298:396#L12) 119 | ``` go 120 | func (this *Bot) OnAudioPlaybackStarted(fn func(bot *Bot, request *model.AudioPlayerEventRequest)) 121 | ``` 122 | 音频开始播放事件 123 | 124 | 125 | 126 | 127 | ### func (\*Bot) [OnAudioPlaybackStopped](/src/target/audio_player.go?s=597:695#L20) 128 | ``` go 129 | func (this *Bot) OnAudioPlaybackStopped(fn func(bot *Bot, request *model.AudioPlayerEventRequest)) 130 | ``` 131 | 音频停止播放事件 132 | 133 | 134 | 135 | 136 | ### func (\*Bot) [OnAudioRrogressReportIntevalElapsed](/src/target/audio_player.go?s=1532:1643#L44) 137 | ``` go 138 | func (this *Bot) OnAudioRrogressReportIntevalElapsed(fn func(bot *Bot, request *model.AudioPlayerEventRequest)) 139 | ``` 140 | 音频周期上报播放进度 141 | 142 | 143 | 144 | 145 | ### func (\*Bot) [OnDisplayElementSelected](/src/target/event_handler.go?s=270:359#L10) 146 | ``` go 147 | func (this *Bot) OnDisplayElementSelected(fn func(bot *Bot, request *model.EventRequest)) 148 | ``` 149 | ListTemplate 列表选择事件 150 | Display.ButtonClicked 事件 151 | https://dueros.baidu.com/didp/doc/dueros-bot-platform/dbp-custom/display-template_markdown#Display.ElementSelected%E4%BA%8B%E4%BB%B6 152 | 153 | 154 | 155 | 156 | ### func (\*Bot) [OnLaunchRequest](/src/target/bot.go?s=2331:2412#L57) 157 | ``` go 158 | func (this *Bot) OnLaunchRequest(fn func(bot *Bot, request *model.LaunchRequest)) 159 | ``` 160 | 打开技能时的处理 161 | 162 | 163 | 164 | 165 | ### func (\*Bot) [OnLinkAccountSuccessed](/src/target/event_handler.go?s=956:1043#L38) 166 | ``` go 167 | func (this *Bot) OnLinkAccountSuccessed(fn func(bot *Bot, request *model.EventRequest)) 168 | ``` 169 | LinkAccountSucceeded 事件 170 | ```javascript 171 | { 172 | 173 | 174 | "type": "Connections.Response", 175 | "name": "LinkAccountSucceeded", 176 | "requestId": "{{STRING}}", 177 | "timestamp": {{INT32}}, 178 | "token": "{{STRING}}" 179 | 180 | } 181 | ``` 182 | 183 | 184 | 185 | 186 | ### func (\*Bot) [OnScreenLinkClicked](/src/target/event_handler.go?s=1501:1585#L54) 187 | ``` go 188 | func (this *Bot) OnScreenLinkClicked(fn func(bot *Bot, request *model.EventRequest)) 189 | ``` 190 | Screen.LinkClicked事件 191 | https://dueros.baidu.com/didp/doc/dueros-bot-platform/dbp-custom/cards_markdown#Screen.LinkClicked%E4%BA%8B%E4%BB%B6 192 | { 193 | 194 | 195 | "type": "Screen.LinkClicked", 196 | "url": "{{STRING}}", 197 | "requestId": "{{STRING}}", 198 | "timestamp": {{INT32}} 199 | "token": "{{STRING}}" 200 | 201 | } 202 | 203 | 204 | 205 | 206 | ### func (\*Bot) [OnSessionEndedRequest](/src/target/bot.go?s=2598:2691#L63) 207 | ``` go 208 | func (this *Bot) OnSessionEndedRequest(fn func(bot *Bot, request *model.SessionEndedRequest)) 209 | ``` 210 | 技能关闭的处理,比如可以做一些清理的工作 211 | TIP: 根据协议,技能关闭返回的结果,DuerOS不会返回给用户。 212 | 213 | 214 | 215 | 216 | ### func (\*Bot) [OnVideoPlaybackFinished](/src/target/video_player.go?s=896:995#L28) 217 | ``` go 218 | func (this *Bot) OnVideoPlaybackFinished(fn func(bot *Bot, request *model.VideoPlayerEventRequest)) 219 | ``` 220 | 视频播放完成事件 221 | 222 | 223 | 224 | 225 | ### func (\*Bot) [OnVideoPlaybackNearlyFinished](/src/target/video_player.go?s=1212:1317#L36) 226 | ``` go 227 | func (this *Bot) OnVideoPlaybackNearlyFinished(fn func(bot *Bot, request *model.VideoPlayerEventRequest)) 228 | ``` 229 | 视频快要播放结束上报的事件 230 | 231 | 232 | 233 | 234 | ### func (\*Bot) [OnVideoPlaybackStarted](/src/target/video_player.go?s=298:396#L12) 235 | ``` go 236 | func (this *Bot) OnVideoPlaybackStarted(fn func(bot *Bot, request *model.VideoPlayerEventRequest)) 237 | ``` 238 | 视频开始播放事件 239 | 240 | 241 | 242 | 243 | ### func (\*Bot) [OnVideoPlaybackStopped](/src/target/video_player.go?s=597:695#L20) 244 | ``` go 245 | func (this *Bot) OnVideoPlaybackStopped(fn func(bot *Bot, request *model.VideoPlayerEventRequest)) 246 | ``` 247 | 视频停止播放事件 248 | 249 | 250 | 251 | 252 | ### func (\*Bot) [OnVideoPlayerScheduledStopReached](/src/target/video_player.go?s=1863:1972#L52) 253 | ``` go 254 | func (this *Bot) OnVideoPlayerScheduledStopReached(fn func(bot *Bot, request *model.VideoPlayerEventRequest)) 255 | ``` 256 | 视频自动暂停后上报 257 | 258 | 259 | 260 | 261 | ### func (\*Bot) [OnVideoRrogressReportIntevalElapsed](/src/target/video_player.go?s=1532:1643#L44) 262 | ``` go 263 | func (this *Bot) OnVideoRrogressReportIntevalElapsed(fn func(bot *Bot, request *model.VideoPlayerEventRequest)) 264 | ``` 265 | 视频周期上报播放进度 266 | 267 | 268 | 269 | 270 | ### func (\*Bot) [Run](/src/target/bot.go?s=2735:2764#L67) 271 | ``` go 272 | func (this *Bot) Run() string 273 | ``` 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | - - - 282 | Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md) 283 | -------------------------------------------------------------------------------- /doc/card/card.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # card 4 | `import "github.com/dueros/bot-sdk-go/bot/card"` 5 | 6 | * [Overview](#pkg-overview) 7 | * [Index](#pkg-index) 8 | 9 | ## Overview 10 | 11 | 12 | 13 | ## Index 14 | * [type BaseCard](#BaseCard) 15 | * [type ImageCard](#ImageCard) 16 | * [func NewImageCard() *ImageCard](#NewImageCard) 17 | * [func (this *ImageCard) AddItem(src string, thumbnail string) *ImageCard](#ImageCard.AddItem) 18 | * [type LinkAccountCard](#LinkAccountCard) 19 | * [func NewLinkAccountCard() *LinkAccountCard](#NewLinkAccountCard) 20 | * [type ListCard](#ListCard) 21 | * [func NewListCard() *ListCard](#NewListCard) 22 | * [func (this *ListCard) AddItem(item *ListCardItem) *ListCard](#ListCard.AddItem) 23 | * [type ListCardItem](#ListCardItem) 24 | * [func NewListCardItem() *ListCardItem](#NewListCardItem) 25 | * [func (this *ListCardItem) SetContent(content string) *ListCardItem](#ListCardItem.SetContent) 26 | * [func (this *ListCardItem) SetImage(image string) *ListCardItem](#ListCardItem.SetImage) 27 | * [func (this *ListCardItem) SetTitle(title string) *ListCardItem](#ListCardItem.SetTitle) 28 | * [func (this *ListCardItem) SetUrl(url string) *ListCardItem](#ListCardItem.SetUrl) 29 | * [type StandardCard](#StandardCard) 30 | * [func NewStandardCard() *StandardCard](#NewStandardCard) 31 | * [func (this *StandardCard) SetContent(content string) *StandardCard](#StandardCard.SetContent) 32 | * [func (this *StandardCard) SetImage(image string) *StandardCard](#StandardCard.SetImage) 33 | * [func (this *StandardCard) SetTitle(title string) *StandardCard](#StandardCard.SetTitle) 34 | * [type TextCard](#TextCard) 35 | * [func NewTextCard(content string) *TextCard](#NewTextCard) 36 | * [func (this *TextCard) SetContent(content string)](#TextCard.SetContent) 37 | 38 | 39 | #### Package files 40 | [base.go](/src/github.com/dueros/bot-sdk-go/bot/card/base.go) [image.go](/src/github.com/dueros/bot-sdk-go/bot/card/image.go) [link_account.go](/src/github.com/dueros/bot-sdk-go/bot/card/link_account.go) [list.go](/src/github.com/dueros/bot-sdk-go/bot/card/list.go) [standard.go](/src/github.com/dueros/bot-sdk-go/bot/card/standard.go) [text.go](/src/github.com/dueros/bot-sdk-go/bot/card/text.go) 41 | 42 | 43 | 44 | 45 | 46 | 47 | ## type [BaseCard](/src/target/base.go?s=14:65#L3) 48 | ``` go 49 | type BaseCard struct { 50 | Type string `json:"type"` 51 | } 52 | ``` 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | ## type [ImageCard](/src/target/image.go?s=14:89#L3) 63 | ``` go 64 | type ImageCard struct { 65 | BaseCard 66 | List []map[string]string `json:"list"` 67 | } 68 | ``` 69 | 70 | 71 | 72 | 73 | 74 | 75 | ### func [NewImageCard](/src/target/image.go?s=91:121#L8) 76 | ``` go 77 | func NewImageCard() *ImageCard 78 | ``` 79 | 80 | 81 | 82 | 83 | ### func (\*ImageCard) [AddItem](/src/target/image.go?s=183:254#L14) 84 | ``` go 85 | func (this *ImageCard) AddItem(src string, thumbnail string) *ImageCard 86 | ``` 87 | 88 | 89 | 90 | ## type [LinkAccountCard](/src/target/link_account.go?s=14:55#L3) 91 | ``` go 92 | type LinkAccountCard struct { 93 | BaseCard 94 | } 95 | ``` 96 | 97 | 98 | 99 | 100 | 101 | 102 | ### func [NewLinkAccountCard](/src/target/link_account.go?s=57:99#L7) 103 | ``` go 104 | func NewLinkAccountCard() *LinkAccountCard 105 | ``` 106 | 107 | 108 | 109 | 110 | ## type [ListCard](/src/target/list.go?s=654:724#L35) 111 | ``` go 112 | type ListCard struct { 113 | List []*ListCardItem `json:"list"` 114 | BaseCard 115 | } 116 | ``` 117 | 118 | 119 | 120 | 121 | 122 | 123 | ### func [NewListCard](/src/target/list.go?s=726:754#L40) 124 | ``` go 125 | func NewListCard() *ListCard 126 | ``` 127 | 128 | 129 | 130 | 131 | ### func (\*ListCard) [AddItem](/src/target/list.go?s=814:873#L46) 132 | ``` go 133 | func (this *ListCard) AddItem(item *ListCardItem) *ListCard 134 | ``` 135 | 136 | 137 | 138 | ## type [ListCardItem](/src/target/list.go?s=14:168#L3) 139 | ``` go 140 | type ListCardItem struct { 141 | Title string `json:"title"` 142 | Content string `json:"content"` 143 | Image string `json:"content"` 144 | Url string `json:"url"` 145 | } 146 | ``` 147 | 148 | 149 | 150 | 151 | 152 | 153 | ### func [NewListCardItem](/src/target/list.go?s=170:206#L10) 154 | ``` go 155 | func NewListCardItem() *ListCardItem 156 | ``` 157 | 158 | 159 | 160 | 161 | ### func (\*ListCardItem) [SetContent](/src/target/list.go?s=351:417#L20) 162 | ``` go 163 | func (this *ListCardItem) SetContent(content string) *ListCardItem 164 | ``` 165 | 166 | 167 | 168 | ### func (\*ListCardItem) [SetImage](/src/target/list.go?s=460:522#L25) 169 | ``` go 170 | func (this *ListCardItem) SetImage(image string) *ListCardItem 171 | ``` 172 | 173 | 174 | 175 | ### func (\*ListCardItem) [SetTitle](/src/target/list.go?s=250:312#L15) 176 | ``` go 177 | func (this *ListCardItem) SetTitle(title string) *ListCardItem 178 | ``` 179 | 180 | 181 | 182 | ### func (\*ListCardItem) [SetUrl](/src/target/list.go?s=561:619#L30) 183 | ``` go 184 | func (this *ListCardItem) SetUrl(url string) *ListCardItem 185 | ``` 186 | 187 | 188 | 189 | ## type [StandardCard](/src/target/standard.go?s=14:147#L3) 190 | ``` go 191 | type StandardCard struct { 192 | Title string `json:"title"` 193 | Content string `json:"content"` 194 | Image string `json:"image"` 195 | BaseCard 196 | } 197 | ``` 198 | 199 | 200 | 201 | 202 | 203 | 204 | ### func [NewStandardCard](/src/target/standard.go?s=149:185#L10) 205 | ``` go 206 | func NewStandardCard() *StandardCard 207 | ``` 208 | 209 | 210 | 211 | 212 | ### func (\*StandardCard) [SetContent](/src/target/standard.go?s=354:420#L21) 213 | ``` go 214 | func (this *StandardCard) SetContent(content string) *StandardCard 215 | ``` 216 | 217 | 218 | 219 | ### func (\*StandardCard) [SetImage](/src/target/standard.go?s=463:525#L26) 220 | ``` go 221 | func (this *StandardCard) SetImage(image string) *StandardCard 222 | ``` 223 | 224 | 225 | 226 | ### func (\*StandardCard) [SetTitle](/src/target/standard.go?s=253:315#L16) 227 | ``` go 228 | func (this *StandardCard) SetTitle(title string) *StandardCard 229 | ``` 230 | 231 | 232 | 233 | ## type [TextCard](/src/target/text.go?s=14:81#L3) 234 | ``` go 235 | type TextCard struct { 236 | BaseCard 237 | Content string `json:"content"` 238 | } 239 | ``` 240 | 241 | 242 | 243 | 244 | 245 | 246 | ### func [NewTextCard](/src/target/text.go?s=83:125#L8) 247 | ``` go 248 | func NewTextCard(content string) *TextCard 249 | ``` 250 | 251 | 252 | 253 | 254 | ### func (\*TextCard) [SetContent](/src/target/text.go?s=210:258#L15) 255 | ``` go 256 | func (this *TextCard) SetContent(content string) 257 | ``` 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | - - - 266 | Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md) 267 | -------------------------------------------------------------------------------- /doc/directive/audio-player.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # audio_player 4 | `import "github.com/dueros/bot-sdk-go/bot/directive/audio_player"` 5 | 6 | * [Overview](#pkg-overview) 7 | * [Index](#pkg-index) 8 | 9 | ## Overview 10 | 11 | 12 | 13 | ## Index 14 | * [Constants](#pkg-constants) 15 | * [type PlayDirective](#PlayDirective) 16 | * [func NewPlayDirective(url string) *PlayDirective](#NewPlayDirective) 17 | * [func (this *PlayDirective) GetToken(token string) string](#PlayDirective.GetToken) 18 | * [func (this *PlayDirective) SetBehavior(behavior string) *PlayDirective](#PlayDirective.SetBehavior) 19 | * [func (this *PlayDirective) SetOffsetInMilliseconds(milliseconds int) *PlayDirective](#PlayDirective.SetOffsetInMilliseconds) 20 | * [func (this *PlayDirective) SetPlayerInfo(playerInfo *PlayerInfo) *PlayDirective](#PlayDirective.SetPlayerInfo) 21 | * [func (this *PlayDirective) SetProgressReportIntervalMs(intervalMs int) *PlayDirective](#PlayDirective.SetProgressReportIntervalMs) 22 | * [func (this *PlayDirective) SetStreamFormat(format string) *PlayDirective](#PlayDirective.SetStreamFormat) 23 | * [func (this *PlayDirective) SetToken(token string) *PlayDirective](#PlayDirective.SetToken) 24 | * [func (this *PlayDirective) SetUrl(url string) *PlayDirective](#PlayDirective.SetUrl) 25 | * [type PlayerInfo](#PlayerInfo) 26 | * [func NewPlayerInfo() *PlayerInfo](#NewPlayerInfo) 27 | * [func (this *PlayerInfo) SetArt(src string) *PlayerInfo](#PlayerInfo.SetArt) 28 | * [func (this *PlayerInfo) SetLyric(url string) *PlayerInfo](#PlayerInfo.SetLyric) 29 | * [func (this *PlayerInfo) SetMediaLengthInMs(length uint64) *PlayerInfo](#PlayerInfo.SetMediaLengthInMs) 30 | * [func (this *PlayerInfo) SetProviderLogo(logo string) *PlayerInfo](#PlayerInfo.SetProviderLogo) 31 | * [func (this *PlayerInfo) SetProviderName(name string) *PlayerInfo](#PlayerInfo.SetProviderName) 32 | * [func (this *PlayerInfo) SetTitle(title string) *PlayerInfo](#PlayerInfo.SetTitle) 33 | * [func (this *PlayerInfo) SetTitleSubtext1(text string) *PlayerInfo](#PlayerInfo.SetTitleSubtext1) 34 | * [func (this *PlayerInfo) SetTitleSubtext2(text string) *PlayerInfo](#PlayerInfo.SetTitleSubtext2) 35 | * [type StopDirective](#StopDirective) 36 | * [func NewStopDirective() *StopDirective](#NewStopDirective) 37 | 38 | 39 | #### Package files 40 | [const.go](/src/github.com/dueros/bot-sdk-go/bot/directive/audio_player/const.go) [play.go](/src/github.com/dueros/bot-sdk-go/bot/directive/audio_player/play.go) [player_info.go](/src/github.com/dueros/bot-sdk-go/bot/directive/audio_player/player_info.go) [stop.go](/src/github.com/dueros/bot-sdk-go/bot/directive/audio_player/stop.go) 41 | 42 | 43 | ## Constants 44 | ``` go 45 | const ( 46 | REPLACE_ALL = "REPLACE_ALL" 47 | REPLACE_ENQUEUED = "REPLACE_ENQUEUED" 48 | ENQUEUE = "ENQUEUE" 49 | 50 | AUDIO_MP3 = "AUDIO_MP3" 51 | AUDIO_M3U8 = "AUDIO_M3U8" 52 | AUDIO_M4A = "AUDIO_M4A" 53 | 54 | AUDIO_TYPE_MUSIC = "MUSIC" 55 | 56 | LYRIC_FORMAT_LRC = "LRC" 57 | ) 58 | ``` 59 | 60 | 61 | 62 | 63 | ## type [PlayDirective](/src/target/play.go?s=291:825#L19) 64 | ``` go 65 | type PlayDirective struct { 66 | directive.BaseDirective 67 | PlayBehavior string `json:"playBehavior"` 68 | AudioItem struct { 69 | Stream struct { 70 | Url string `json:"url"` 71 | StreamFormat string `json:"streamFormat"` 72 | OffsetInMilliseconds int `json:"offsetInMilliSeconds"` 73 | Token string `json:"token"` 74 | ProgressReportIntervalMs int `json:"progressReportIntervalMs,omitempty"` 75 | } `json:"stream"` 76 | PlayerInfo *PlayerInfo `json:"playerInfo,omitempty"` 77 | } `json:"audioItem"` 78 | } 79 | ``` 80 | 81 | 82 | 83 | 84 | 85 | 86 | ### func [NewPlayDirective](/src/target/play.go?s=827:875#L34) 87 | ``` go 88 | func NewPlayDirective(url string) *PlayDirective 89 | ``` 90 | 91 | 92 | 93 | 94 | ### func (\*PlayDirective) [GetToken](/src/target/play.go?s=1534:1590#L61) 95 | ``` go 96 | func (this *PlayDirective) GetToken(token string) string 97 | ``` 98 | 99 | 100 | 101 | ### func (\*PlayDirective) [SetBehavior](/src/target/play.go?s=1249:1319#L47) 102 | ``` go 103 | func (this *PlayDirective) SetBehavior(behavior string) *PlayDirective 104 | ``` 105 | 106 | 107 | 108 | ### func (\*PlayDirective) [SetOffsetInMilliseconds](/src/target/play.go?s=1744:1827#L70) 109 | ``` go 110 | func (this *PlayDirective) SetOffsetInMilliseconds(milliseconds int) *PlayDirective 111 | ``` 112 | 113 | 114 | 115 | ### func (\*PlayDirective) [SetPlayerInfo](/src/target/play.go?s=2252:2331#L88) 116 | ``` go 117 | func (this *PlayDirective) SetPlayerInfo(playerInfo *PlayerInfo) *PlayDirective 118 | ``` 119 | 120 | 121 | 122 | ### func (\*PlayDirective) [SetProgressReportIntervalMs](/src/target/play.go?s=1905:1990#L75) 123 | ``` go 124 | func (this *PlayDirective) SetProgressReportIntervalMs(intervalMs int) *PlayDirective 125 | ``` 126 | 127 | 128 | 129 | ### func (\*PlayDirective) [SetStreamFormat](/src/target/play.go?s=2070:2142#L80) 130 | ``` go 131 | func (this *PlayDirective) SetStreamFormat(format string) *PlayDirective 132 | ``` 133 | 134 | 135 | 136 | ### func (\*PlayDirective) [SetToken](/src/target/play.go?s=1414:1478#L56) 137 | ``` go 138 | func (this *PlayDirective) SetToken(token string) *PlayDirective 139 | ``` 140 | 141 | 142 | 143 | ### func (\*PlayDirective) [SetUrl](/src/target/play.go?s=1632:1692#L65) 144 | ``` go 145 | func (this *PlayDirective) SetUrl(url string) *PlayDirective 146 | ``` 147 | 148 | 149 | 150 | ## type [PlayerInfo](/src/target/player_info.go?s=22:665#L3) 151 | ``` go 152 | type PlayerInfo struct { 153 | Content struct { 154 | AudioItemType string `json:"audioItemType"` 155 | Title string `json:"title"` 156 | TitleSubtext1 string `json:"titleSubtext1"` 157 | TitleSubtext2 string `json:"titleSubtext2"` 158 | Lyric struct { 159 | Url string `json:"url"` 160 | Format string `json:"format"` 161 | } `json:"lyric"` 162 | MediaLengthInMilliseconds uint64 `json:"mediaLengthInMilliseconds,omitempty"` 163 | Art struct { 164 | Src string `json:"src"` 165 | } `json:"art"` 166 | Provider struct { 167 | Name string `json:"name"` 168 | Logo struct { 169 | Src string `json:"src"` 170 | } `json:"logo"` 171 | } `json:"provider"` 172 | } `json:"content"` 173 | } 174 | ``` 175 | 176 | 177 | 178 | 179 | 180 | 181 | ### func [NewPlayerInfo](/src/target/player_info.go?s=667:699#L26) 182 | ``` go 183 | func NewPlayerInfo() *PlayerInfo 184 | ``` 185 | 186 | 187 | 188 | 189 | ### func (\*PlayerInfo) [SetArt](/src/target/player_info.go?s=1439:1493#L60) 190 | ``` go 191 | func (this *PlayerInfo) SetArt(src string) *PlayerInfo 192 | ``` 193 | 194 | 195 | 196 | ### func (\*PlayerInfo) [SetLyric](/src/target/player_info.go?s=1151:1207#L49) 197 | ``` go 198 | func (this *PlayerInfo) SetLyric(url string) *PlayerInfo 199 | ``` 200 | 201 | 202 | 203 | ### func (\*PlayerInfo) [SetMediaLengthInMs](/src/target/player_info.go?s=1302:1371#L55) 204 | ``` go 205 | func (this *PlayerInfo) SetMediaLengthInMs(length uint64) *PlayerInfo 206 | ``` 207 | 208 | 209 | 210 | ### func (\*PlayerInfo) [SetProviderLogo](/src/target/player_info.go?s=1658:1722#L70) 211 | ``` go 212 | func (this *PlayerInfo) SetProviderLogo(logo string) *PlayerInfo 213 | ``` 214 | 215 | 216 | 217 | ### func (\*PlayerInfo) [SetProviderName](/src/target/player_info.go?s=1540:1604#L65) 218 | ``` go 219 | func (this *PlayerInfo) SetProviderName(name string) *PlayerInfo 220 | ``` 221 | 222 | 223 | 224 | ### func (\*PlayerInfo) [SetTitle](/src/target/player_info.go?s=808:866#L34) 225 | ``` go 226 | func (this *PlayerInfo) SetTitle(title string) *PlayerInfo 227 | ``` 228 | 229 | 230 | 231 | ### func (\*PlayerInfo) [SetTitleSubtext1](/src/target/player_info.go?s=913:978#L39) 232 | ``` go 233 | func (this *PlayerInfo) SetTitleSubtext1(text string) *PlayerInfo 234 | ``` 235 | 236 | 237 | 238 | ### func (\*PlayerInfo) [SetTitleSubtext2](/src/target/player_info.go?s=1032:1097#L44) 239 | ``` go 240 | func (this *PlayerInfo) SetTitleSubtext2(text string) *PlayerInfo 241 | ``` 242 | 243 | 244 | 245 | ## type [StopDirective](/src/target/stop.go?s=80:134#L7) 246 | ``` go 247 | type StopDirective struct { 248 | directive.BaseDirective 249 | } 250 | ``` 251 | 252 | 253 | 254 | 255 | 256 | 257 | ### func [NewStopDirective](/src/target/stop.go?s=136:174#L11) 258 | ``` go 259 | func NewStopDirective() *StopDirective 260 | ``` 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | - - - 270 | Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md) 271 | -------------------------------------------------------------------------------- /doc/directive/display/render-template.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # display 4 | `import "github.com/dueros/bot-sdk-go/bot/directive/display"` 5 | 6 | * [Overview](#pkg-overview) 7 | * [Index](#pkg-index) 8 | * [Subdirectories](#pkg-subdirectories) 9 | 10 | ## Overview 11 | 12 | 13 | 14 | ## Index 15 | * [type RenderTemplate](#RenderTemplate) 16 | * [func NewRenderTemplate(template interface{}) *RenderTemplate](#NewRenderTemplate) 17 | 18 | 19 | #### Package files 20 | [hint.go](/src/github.com/dueros/bot-sdk-go/bot/directive/display/hint.go) [render_template.go](/src/github.com/dueros/bot-sdk-go/bot/directive/display/render_template.go) 21 | 22 | 23 | 24 | 25 | 26 | 27 | ## type [RenderTemplate](/src/target/render_template.go?s=75:170#L7) 28 | ``` go 29 | type RenderTemplate struct { 30 | directive.BaseDirective 31 | Template interface{} `json:"template"` 32 | } 33 | ``` 34 | 35 | 36 | 37 | 38 | 39 | 40 | ### func [NewRenderTemplate](/src/target/render_template.go?s=172:232#L12) 41 | ``` go 42 | func NewRenderTemplate(template interface{}) *RenderTemplate 43 | ``` 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | - - - 53 | Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md) 54 | -------------------------------------------------------------------------------- /doc/directive/display/template.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # template 4 | `import "github.com/dueros/bot-sdk-go/bot/directive/display/template"` 5 | 6 | * [Overview](#pkg-overview) 7 | * [Index](#pkg-index) 8 | 9 | ## Overview 10 | 11 | 12 | 13 | ## Index 14 | * [Constants](#pkg-constants) 15 | * [type BaseTemplate](#BaseTemplate) 16 | * [func (this *BaseTemplate) SetBackgroundImage(background *Image)](#BaseTemplate.SetBackgroundImage) 17 | * [func (this *BaseTemplate) SetBackgroundImageUrl(url string)](#BaseTemplate.SetBackgroundImageUrl) 18 | * [func (this *BaseTemplate) SetTitle(title string)](#BaseTemplate.SetTitle) 19 | * [type BodyTemplate1](#BodyTemplate1) 20 | * [func NewBodyTemplate1() *BodyTemplate1](#NewBodyTemplate1) 21 | * [func (this *BodyTemplate1) SetContentPosition(position string) *BodyTemplate1](#BodyTemplate1.SetContentPosition) 22 | * [func (this *BodyTemplate1) SetPlainContent(content string) *BodyTemplate1](#BodyTemplate1.SetPlainContent) 23 | * [type BodyTemplate2](#BodyTemplate2) 24 | * [func NewBodyTemplate2() *BodyTemplate2](#NewBodyTemplate2) 25 | * [type BodyTemplate3](#BodyTemplate3) 26 | * [func NewBodyTemplate3() *BodyTemplate3](#NewBodyTemplate3) 27 | * [type BodyTemplate4](#BodyTemplate4) 28 | * [func NewBodyTemplate4() *BodyTemplate4](#NewBodyTemplate4) 29 | * [type BodyTemplate5](#BodyTemplate5) 30 | * [func NewBodyTemplate5() *BodyTemplate5](#NewBodyTemplate5) 31 | * [func (this *BodyTemplate5) AddImage(image *Image) *BodyTemplate5](#BodyTemplate5.AddImage) 32 | * [type Image](#Image) 33 | * [func NewImage(url string) *Image](#NewImage) 34 | * [func (this *Image) SetHeight(height int) *Image](#Image.SetHeight) 35 | * [func (this *Image) SetWidth(width int) *Image](#Image.SetWidth) 36 | * [type ListItem](#ListItem) 37 | * [func NewListItem() *ListItem](#NewListItem) 38 | * [func (this *ListItem) SetImage(image *Image) *ListItem](#ListItem.SetImage) 39 | * [func (this *ListItem) SetImageUrl(url string) *ListItem](#ListItem.SetImageUrl) 40 | * [func (this *ListItem) SetPlainPrimaryText(text string) *ListItem](#ListItem.SetPlainPrimaryText) 41 | * [func (this *ListItem) SetPlainSecondaryText(text string) *ListItem](#ListItem.SetPlainSecondaryText) 42 | * [func (this *ListItem) SetPlainTertiary(text string) *ListItem](#ListItem.SetPlainTertiary) 43 | * [type ListTemplate](#ListTemplate) 44 | * [func (this *ListTemplate) AddItem(listItem *ListItem)](#ListTemplate.AddItem) 45 | * [type ListTemplate1](#ListTemplate1) 46 | * [func NewListTemplate1() *ListTemplate1](#NewListTemplate1) 47 | * [type ListTemplate2](#ListTemplate2) 48 | * [func NewListTemplate2() *ListTemplate2](#NewListTemplate2) 49 | * [type Text](#Text) 50 | * [func NewText(textType, text string) *Text](#NewText) 51 | * [type TextImageTemplate](#TextImageTemplate) 52 | * [func (this *TextImageTemplate) SetImage(image *Image)](#TextImageTemplate.SetImage) 53 | * [func (this *TextImageTemplate) SetImageUrl(url string)](#TextImageTemplate.SetImageUrl) 54 | * [func (this *TextImageTemplate) SetPlainContent(content string)](#TextImageTemplate.SetPlainContent) 55 | 56 | 57 | #### Package files 58 | [base.go](/src/github.com/dueros/bot-sdk-go/bot/directive/display/template/base.go) [body_template1.go](/src/github.com/dueros/bot-sdk-go/bot/directive/display/template/body_template1.go) [body_template2_3_4.go](/src/github.com/dueros/bot-sdk-go/bot/directive/display/template/body_template2_3_4.go) [body_template5.go](/src/github.com/dueros/bot-sdk-go/bot/directive/display/template/body_template5.go) [list.go](/src/github.com/dueros/bot-sdk-go/bot/directive/display/template/list.go) [list_template1_2.go](/src/github.com/dueros/bot-sdk-go/bot/directive/display/template/list_template1_2.go) [text_image.go](/src/github.com/dueros/bot-sdk-go/bot/directive/display/template/text_image.go) 59 | 60 | 61 | ## Constants 62 | ``` go 63 | const ( 64 | PLAIN_TEXT = "PlainText" 65 | RICH_TEXT = "RichText" 66 | ) 67 | ``` 68 | ``` go 69 | const ( 70 | BOTTOM_LEFT_POSITION = "BOTTOM-LEFT" 71 | CENTER = "CENTER" 72 | TOP_LEFT = "TOP-LEFT" 73 | ) 74 | ``` 75 | 76 | 77 | 78 | 79 | ## type [BaseTemplate](/src/target/base.go?s=214:404#L17) 80 | ``` go 81 | type BaseTemplate struct { 82 | directive.BaseDirective 83 | Token string `json:"token"` 84 | BackgroundImage *Image `json:"backgroundImage,omitempty"` 85 | Title string `json:"title"` 86 | } 87 | ``` 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | ### func (\*BaseTemplate) [SetBackgroundImage](/src/target/base.go?s=585:648#L32) 98 | ``` go 99 | func (this *BaseTemplate) SetBackgroundImage(background *Image) 100 | ``` 101 | 102 | 103 | 104 | ### func (\*BaseTemplate) [SetBackgroundImageUrl](/src/target/base.go?s=480:539#L28) 105 | ``` go 106 | func (this *BaseTemplate) SetBackgroundImageUrl(url string) 107 | ``` 108 | 109 | 110 | 111 | ### func (\*BaseTemplate) [SetTitle](/src/target/base.go?s=406:454#L24) 112 | ``` go 113 | func (this *BaseTemplate) SetTitle(title string) 114 | ``` 115 | 116 | 117 | 118 | ## type [BodyTemplate1](/src/target/body_template1.go?s=264:417#L15) 119 | ``` go 120 | type BodyTemplate1 struct { 121 | BaseTemplate 122 | TextContent struct { 123 | Position string `json:"position"` 124 | Text *Text `json:"text"` 125 | } `json:"content"` 126 | } 127 | ``` 128 | 129 | 130 | 131 | 132 | 133 | 134 | ### func [NewBodyTemplate1](/src/target/body_template1.go?s=419:457#L23) 135 | ``` go 136 | func NewBodyTemplate1() *BodyTemplate1 137 | ``` 138 | 139 | 140 | 141 | 142 | ### func (\*BodyTemplate1) [SetContentPosition](/src/target/body_template1.go?s=659:736#L31) 143 | ``` go 144 | func (this *BodyTemplate1) SetContentPosition(position string) *BodyTemplate1 145 | ``` 146 | 147 | 148 | 149 | ### func (\*BodyTemplate1) [SetPlainContent](/src/target/body_template1.go?s=874:947#L41) 150 | ``` go 151 | func (this *BodyTemplate1) SetPlainContent(content string) *BodyTemplate1 152 | ``` 153 | 154 | 155 | 156 | ## type [BodyTemplate2](/src/target/body_template2_3_4.go?s=18:66#L3) 157 | ``` go 158 | type BodyTemplate2 struct { 159 | TextImageTemplate 160 | } 161 | ``` 162 | 163 | 164 | 165 | 166 | 167 | 168 | ### func [NewBodyTemplate2](/src/target/body_template2_3_4.go?s=68:106#L7) 169 | ``` go 170 | func NewBodyTemplate2() *BodyTemplate2 171 | ``` 172 | 173 | 174 | 175 | 176 | ## type [BodyTemplate3](/src/target/body_template2_3_4.go?s=250:298#L14) 177 | ``` go 178 | type BodyTemplate3 struct { 179 | TextImageTemplate 180 | } 181 | ``` 182 | 183 | 184 | 185 | 186 | 187 | 188 | ### func [NewBodyTemplate3](/src/target/body_template2_3_4.go?s=300:338#L18) 189 | ``` go 190 | func NewBodyTemplate3() *BodyTemplate3 191 | ``` 192 | 193 | 194 | 195 | 196 | ## type [BodyTemplate4](/src/target/body_template2_3_4.go?s=482:530#L25) 197 | ``` go 198 | type BodyTemplate4 struct { 199 | TextImageTemplate 200 | } 201 | ``` 202 | 203 | 204 | 205 | 206 | 207 | 208 | ### func [NewBodyTemplate4](/src/target/body_template2_3_4.go?s=532:570#L29) 209 | ``` go 210 | func NewBodyTemplate4() *BodyTemplate4 211 | ``` 212 | 213 | 214 | 215 | 216 | ## type [BodyTemplate5](/src/target/body_template5.go?s=18:94#L3) 217 | ``` go 218 | type BodyTemplate5 struct { 219 | BaseTemplate 220 | Images []*Image `json:"images"` 221 | } 222 | ``` 223 | 224 | 225 | 226 | 227 | 228 | 229 | ### func [NewBodyTemplate5](/src/target/body_template5.go?s=96:134#L8) 230 | ``` go 231 | func NewBodyTemplate5() *BodyTemplate5 232 | ``` 233 | 234 | 235 | 236 | 237 | ### func (\*BodyTemplate5) [AddImage](/src/target/body_template5.go?s=236:300#L14) 238 | ``` go 239 | func (this *BodyTemplate5) AddImage(image *Image) *BodyTemplate5 240 | ``` 241 | 242 | 243 | 244 | ## type [Image](/src/target/base.go?s=689:849#L36) 245 | ``` go 246 | type Image struct { 247 | Url string `json:"url"` 248 | WidthPixels int `json:"widthPixels,omitempty"` 249 | HeightPixels int `json:"heightPixels,omitempty"` 250 | } 251 | ``` 252 | 253 | 254 | 255 | 256 | 257 | 258 | ### func [NewImage](/src/target/base.go?s=851:883#L42) 259 | ``` go 260 | func NewImage(url string) *Image 261 | ``` 262 | 263 | 264 | 265 | 266 | ### func (\*Image) [SetHeight](/src/target/base.go?s=1029:1076#L53) 267 | ``` go 268 | func (this *Image) SetHeight(height int) *Image 269 | ``` 270 | 271 | 272 | 273 | ### func (\*Image) [SetWidth](/src/target/base.go?s=939:984#L48) 274 | ``` go 275 | func (this *Image) SetWidth(width int) *Image 276 | ``` 277 | 278 | 279 | 280 | ## type [ListItem](/src/target/list.go?s=18:310#L3) 281 | ``` go 282 | type ListItem struct { 283 | Token string `json:"token"` 284 | Image *Image `json:"image,omitempty"` 285 | TextContent struct { 286 | PrimaryText *Text `json:"primaryText"` 287 | SecondaryText *Text `json:"secondaryText"` 288 | TertiaryText *Text `json:"tertiaryText,omitempty"` 289 | } `json:"textContent"` 290 | } 291 | ``` 292 | 293 | 294 | 295 | 296 | 297 | 298 | ### func [NewListItem](/src/target/list.go?s=312:340#L13) 299 | ``` go 300 | func NewListItem() *ListItem 301 | ``` 302 | 303 | 304 | 305 | 306 | ### func (\*ListItem) [SetImage](/src/target/list.go?s=380:434#L18) 307 | ``` go 308 | func (this *ListItem) SetImage(image *Image) *ListItem 309 | ``` 310 | 311 | 312 | 313 | ### func (\*ListItem) [SetImageUrl](/src/target/list.go?s=473:528#L23) 314 | ``` go 315 | func (this *ListItem) SetImageUrl(url string) *ListItem 316 | ``` 317 | 318 | 319 | 320 | ### func (\*ListItem) [SetPlainPrimaryText](/src/target/list.go?s=587:651#L28) 321 | ``` go 322 | func (this *ListItem) SetPlainPrimaryText(text string) *ListItem 323 | ``` 324 | 325 | 326 | 327 | ### func (\*ListItem) [SetPlainSecondaryText](/src/target/list.go?s=728:794#L33) 328 | ``` go 329 | func (this *ListItem) SetPlainSecondaryText(text string) *ListItem 330 | ``` 331 | 332 | 333 | 334 | ### func (\*ListItem) [SetPlainTertiary](/src/target/list.go?s=873:934#L38) 335 | ``` go 336 | func (this *ListItem) SetPlainTertiary(text string) *ListItem 337 | ``` 338 | 339 | 340 | 341 | ## type [ListTemplate](/src/target/list.go?s=1012:1096#L43) 342 | ``` go 343 | type ListTemplate struct { 344 | BaseTemplate 345 | ListItems []*ListItem `json:"listItems"` 346 | } 347 | ``` 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | ### func (\*ListTemplate) [AddItem](/src/target/list.go?s=1098:1151#L48) 358 | ``` go 359 | func (this *ListTemplate) AddItem(listItem *ListItem) 360 | ``` 361 | 362 | 363 | 364 | ## type [ListTemplate1](/src/target/list_template1_2.go?s=18:61#L3) 365 | ``` go 366 | type ListTemplate1 struct { 367 | ListTemplate 368 | } 369 | ``` 370 | 371 | 372 | 373 | 374 | 375 | 376 | ### func [NewListTemplate1](/src/target/list_template1_2.go?s=63:101#L7) 377 | ``` go 378 | func NewListTemplate1() *ListTemplate1 379 | ``` 380 | 381 | 382 | 383 | 384 | ## type [ListTemplate2](/src/target/list_template1_2.go?s=245:288#L14) 385 | ``` go 386 | type ListTemplate2 struct { 387 | ListTemplate 388 | } 389 | ``` 390 | 391 | 392 | 393 | 394 | 395 | 396 | ### func [NewListTemplate2](/src/target/list_template1_2.go?s=290:328#L18) 397 | ``` go 398 | func NewListTemplate2() *ListTemplate2 399 | ``` 400 | 401 | 402 | 403 | 404 | ## type [Text](/src/target/base.go?s=1123:1197#L58) 405 | ``` go 406 | type Text struct { 407 | Type string `json:"type"` 408 | Text string `json:"text"` 409 | } 410 | ``` 411 | 412 | 413 | 414 | 415 | 416 | 417 | ### func [NewText](/src/target/base.go?s=1199:1240#L63) 418 | ``` go 419 | func NewText(textType, text string) *Text 420 | ``` 421 | 422 | 423 | 424 | 425 | ## type [TextImageTemplate](/src/target/text_image.go?s=18:129#L3) 426 | ``` go 427 | type TextImageTemplate struct { 428 | BaseTemplate 429 | Content *Text `json:"content"` 430 | Image *Image `json:"image"` 431 | } 432 | ``` 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | ### func (\*TextImageTemplate) [SetImage](/src/target/text_image.go?s=364:417#L19) 443 | ``` go 444 | func (this *TextImageTemplate) SetImage(image *Image) 445 | ``` 446 | 447 | 448 | 449 | ### func (\*TextImageTemplate) [SetImageUrl](/src/target/text_image.go?s=258:312#L14) 450 | ``` go 451 | func (this *TextImageTemplate) SetImageUrl(url string) 452 | ``` 453 | 454 | 455 | 456 | ### func (\*TextImageTemplate) [SetPlainContent](/src/target/text_image.go?s=131:193#L9) 457 | ``` go 458 | func (this *TextImageTemplate) SetPlainContent(content string) 459 | ``` 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | - - - 468 | Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md) 469 | -------------------------------------------------------------------------------- /doc/directive/video-player.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # video_player 4 | `import "github.com/dueros/bot-sdk-go/bot/directive/video_player"` 5 | 6 | * [Overview](#pkg-overview) 7 | * [Index](#pkg-index) 8 | 9 | ## Overview 10 | 11 | 12 | 13 | ## Index 14 | * [Constants](#pkg-constants) 15 | * [type PlayDirective](#PlayDirective) 16 | * [func NewPlayDirective(url string) *PlayDirective](#NewPlayDirective) 17 | * [func (this *PlayDirective) GetToken(token string) string](#PlayDirective.GetToken) 18 | * [func (this *PlayDirective) SetBehavior(behavior string) *PlayDirective](#PlayDirective.SetBehavior) 19 | * [func (this *PlayDirective) SetExpectedPreviousToken(expectedPreviousToken string) *PlayDirective](#PlayDirective.SetExpectedPreviousToken) 20 | * [func (this *PlayDirective) SetExpiryTime(expiryTime string) *PlayDirective](#PlayDirective.SetExpiryTime) 21 | * [func (this *PlayDirective) SetOffsetInMilliseconds(milliseconds int) *PlayDirective](#PlayDirective.SetOffsetInMilliseconds) 22 | * [func (this *PlayDirective) SetReportDelayInMs(reportDelayInMs int) *PlayDirective](#PlayDirective.SetReportDelayInMs) 23 | * [func (this *PlayDirective) SetReportIntervalInMs(reportIntervalInMs int) *PlayDirective](#PlayDirective.SetReportIntervalInMs) 24 | * [func (this *PlayDirective) SetToken(token string) *PlayDirective](#PlayDirective.SetToken) 25 | * [func (this *PlayDirective) SetUrl(url string) *PlayDirective](#PlayDirective.SetUrl) 26 | * [type StopDirective](#StopDirective) 27 | * [func NewStopDirective() *StopDirective](#NewStopDirective) 28 | 29 | 30 | #### Package files 31 | [const.go](/src/github.com/dueros/bot-sdk-go/bot/directive/video_player/const.go) [play.go](/src/github.com/dueros/bot-sdk-go/bot/directive/video_player/play.go) [stop.go](/src/github.com/dueros/bot-sdk-go/bot/directive/video_player/stop.go) 32 | 33 | 34 | ## Constants 35 | ``` go 36 | const ( 37 | REPLACE_ALL = "REPLACE_ALL" 38 | REPLACE_ENQUEUED = "REPLACE_ENQUEUED" 39 | ENQUEUE = "ENQUEUE" 40 | ) 41 | ``` 42 | 43 | 44 | 45 | 46 | ## type [PlayDirective](/src/target/play.go?s=193:930#L13) 47 | ``` go 48 | type PlayDirective struct { 49 | directive.BaseDirective 50 | PlayBehavior string `json:"playBehavior"` 51 | VideoItem struct { 52 | Stream struct { 53 | Url string `json:"url"` 54 | OffsetInMilliseconds int `json:"offsetInMilliseconds"` 55 | ExpiryTime string `json:"expiryTime,omitempty"` 56 | ProgressReport struct { 57 | ProgressReportDelayInMilliseconds int `json:"progressReportDelayInMilliseconds,omitempty"` 58 | ProgressReportIntervalInMilliseconds int `json:"progressReportIntervalInMilliseconds,omitempty"` 59 | } `json:"progressReport,omitempty"` 60 | Token string `json:"token"` 61 | ExpectedPreviousToken string `json:"expectedPreviousToken,omitempty"` 62 | } `json:"stream"` 63 | } `json:"VideoItem"` 64 | } 65 | ``` 66 | 67 | 68 | 69 | 70 | 71 | 72 | ### func [NewPlayDirective](/src/target/play.go?s=932:980#L31) 73 | ``` go 74 | func NewPlayDirective(url string) *PlayDirective 75 | ``` 76 | 77 | 78 | 79 | 80 | ### func (\*PlayDirective) [GetToken](/src/target/play.go?s=1503:1559#L55) 81 | ``` go 82 | func (this *PlayDirective) GetToken(token string) string 83 | ``` 84 | 85 | 86 | 87 | ### func (\*PlayDirective) [SetBehavior](/src/target/play.go?s=1218:1288#L41) 88 | ``` go 89 | func (this *PlayDirective) SetBehavior(behavior string) *PlayDirective 90 | ``` 91 | 92 | 93 | 94 | ### func (\*PlayDirective) [SetExpectedPreviousToken](/src/target/play.go?s=2406:2502#L84) 95 | ``` go 96 | func (this *PlayDirective) SetExpectedPreviousToken(expectedPreviousToken string) *PlayDirective 97 | ``` 98 | 99 | 100 | 101 | ### func (\*PlayDirective) [SetExpiryTime](/src/target/play.go?s=1874:1948#L69) 102 | ``` go 103 | func (this *PlayDirective) SetExpiryTime(expiryTime string) *PlayDirective 104 | ``` 105 | 106 | 107 | 108 | ### func (\*PlayDirective) [SetOffsetInMilliseconds](/src/target/play.go?s=1713:1796#L64) 109 | ``` go 110 | func (this *PlayDirective) SetOffsetInMilliseconds(milliseconds int) *PlayDirective 111 | ``` 112 | 113 | 114 | 115 | ### func (\*PlayDirective) [SetReportDelayInMs](/src/target/play.go?s=2014:2095#L74) 116 | ``` go 117 | func (this *PlayDirective) SetReportDelayInMs(reportDelayInMs int) *PlayDirective 118 | ``` 119 | 120 | 121 | 122 | ### func (\*PlayDirective) [SetReportIntervalInMs](/src/target/play.go?s=2204:2291#L79) 123 | ``` go 124 | func (this *PlayDirective) SetReportIntervalInMs(reportIntervalInMs int) *PlayDirective 125 | ``` 126 | 127 | 128 | 129 | ### func (\*PlayDirective) [SetToken](/src/target/play.go?s=1383:1447#L50) 130 | ``` go 131 | func (this *PlayDirective) SetToken(token string) *PlayDirective 132 | ``` 133 | 134 | 135 | 136 | ### func (\*PlayDirective) [SetUrl](/src/target/play.go?s=1601:1661#L59) 137 | ``` go 138 | func (this *PlayDirective) SetUrl(url string) *PlayDirective 139 | ``` 140 | 141 | 142 | 143 | ## type [StopDirective](/src/target/stop.go?s=80:134#L7) 144 | ``` go 145 | type StopDirective struct { 146 | directive.BaseDirective 147 | } 148 | ``` 149 | 150 | 151 | 152 | 153 | 154 | 155 | ### func [NewStopDirective](/src/target/stop.go?s=136:174#L11) 156 | ``` go 157 | func NewStopDirective() *StopDirective 158 | ``` 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | - - - 168 | Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md) 169 | -------------------------------------------------------------------------------- /doc/model/dialog.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # model 4 | `import "github.com/dueros/bot-sdk-go/bot/model"` 5 | 6 | * [Overview](#pkg-overview) 7 | * [Index](#pkg-index) 8 | 9 | ## Overview 10 | 11 | 12 | 13 | ## Index 14 | * [type Dialog](#Dialog) 15 | * [func NewDialog(request data.IntentRequestBody) *Dialog](#NewDialog) 16 | * [func (this *Dialog) ConfirmIntent() *Dialog](#Dialog.ConfirmIntent) 17 | * [func (this *Dialog) ConfirmSlot(name string) *Dialog](#Dialog.ConfirmSlot) 18 | * [func (this *Dialog) Delegate() *Dialog](#Dialog.Delegate) 19 | * [func (this *Dialog) ElicitSlot(name string) *Dialog](#Dialog.ElicitSlot) 20 | * [func (this *Dialog) GetDirective() *data.DialogDirective](#Dialog.GetDirective) 21 | * [func (this *Dialog) GetIntentConfirmationStatus(index ...int) string](#Dialog.GetIntentConfirmationStatus) 22 | * [func (this *Dialog) GetIntentName() (string, bool)](#Dialog.GetIntentName) 23 | * [func (this *Dialog) GetQuery() (string, bool)](#Dialog.GetQuery) 24 | * [func (this *Dialog) GetSlotConfirmationStatus(name string, index ...int) string](#Dialog.GetSlotConfirmationStatus) 25 | * [func (this *Dialog) GetSlotValue(name string, index ...int) string](#Dialog.GetSlotValue) 26 | * [type IntentRequest](#IntentRequest) 27 | * [func (this *IntentRequest) GetIntentName() (string, bool)](#IntentRequest.GetIntentName) 28 | * [func (this *IntentRequest) GetQuery() string](#IntentRequest.GetQuery) 29 | * [func (this *IntentRequest) IsDialogStateCompleted() bool](#IntentRequest.IsDialogStateCompleted) 30 | 31 | 32 | #### Package files 33 | [dialog.go](/src/github.com/dueros/bot-sdk-go/bot/model/dialog.go) [intent.go](/src/github.com/dueros/bot-sdk-go/bot/model/intent.go) [request.go](/src/github.com/dueros/bot-sdk-go/bot/model/request.go) [response.go](/src/github.com/dueros/bot-sdk-go/bot/model/response.go) [session.go](/src/github.com/dueros/bot-sdk-go/bot/model/session.go) [ssml_builder.go](/src/github.com/dueros/bot-sdk-go/bot/model/ssml_builder.go) 34 | 35 | 36 | 37 | 38 | 39 | 40 | ## type [Dialog](/src/target/dialog.go?s=68:204#L7) 41 | ``` go 42 | type Dialog struct { 43 | Intents []*Intent 44 | DialogState string 45 | // contains filtered or unexported fields 46 | } 47 | ``` 48 | 49 | 50 | 51 | 52 | 53 | 54 | ### func [NewDialog](/src/target/dialog.go?s=206:260#L14) 55 | ``` go 56 | func NewDialog(request data.IntentRequestBody) *Dialog 57 | ``` 58 | 59 | 60 | 61 | 62 | ### func (\*Dialog) [ConfirmIntent](/src/target/dialog.go?s=2601:2644#L122) 63 | ``` go 64 | func (this *Dialog) ConfirmIntent() *Dialog 65 | ``` 66 | 对意图进行确认 67 | 68 | 69 | 70 | 71 | ### func (\*Dialog) [ConfirmSlot](/src/target/dialog.go?s=2278:2330#L107) 72 | ``` go 73 | func (this *Dialog) ConfirmSlot(name string) *Dialog 74 | ``` 75 | 对槽位进行confirm 76 | 77 | 78 | 79 | 80 | ### func (\*Dialog) [Delegate](/src/target/dialog.go?s=2069:2107#L98) 81 | ``` go 82 | func (this *Dialog) Delegate() *Dialog 83 | ``` 84 | 托管对话. 对话由DuerOS代为处理 85 | 86 | 87 | 88 | 89 | ### func (\*Dialog) [ElicitSlot](/src/target/dialog.go?s=2810:2861#L131) 90 | ``` go 91 | func (this *Dialog) ElicitSlot(name string) *Dialog 92 | ``` 93 | 询问槽位 94 | 95 | 96 | 97 | 98 | ### func (\*Dialog) [GetDirective](/src/target/dialog.go?s=3107:3163#L145) 99 | ``` go 100 | func (this *Dialog) GetDirective() *data.DialogDirective 101 | ``` 102 | 103 | 104 | 105 | ### func (\*Dialog) [GetIntentConfirmationStatus](/src/target/dialog.go?s=1829:1897#L87) 106 | ``` go 107 | func (this *Dialog) GetIntentConfirmationStatus(index ...int) string 108 | ``` 109 | 获取意图的确认状态 110 | 111 | 112 | 113 | 114 | ### func (\*Dialog) [GetIntentName](/src/target/dialog.go?s=992:1042#L53) 115 | ``` go 116 | func (this *Dialog) GetIntentName() (string, bool) 117 | ``` 118 | 获取当前意图的名字 119 | 120 | 121 | 122 | 123 | ### func (\*Dialog) [GetQuery](/src/target/dialog.go?s=812:857#L45) 124 | ``` go 125 | func (this *Dialog) GetQuery() (string, bool) 126 | ``` 127 | 获取用户请求的原始query 128 | 129 | 130 | 131 | 132 | ### func (\*Dialog) [GetSlotConfirmationStatus](/src/target/dialog.go?s=1591:1670#L76) 133 | ``` go 134 | func (this *Dialog) GetSlotConfirmationStatus(name string, index ...int) string 135 | ``` 136 | 获取槽位的确认状态,默认取第一组槽位 137 | 138 | 139 | 140 | 141 | ### func (\*Dialog) [GetSlotValue](/src/target/dialog.go?s=1194:1260#L62) 142 | ``` go 143 | func (this *Dialog) GetSlotValue(name string, index ...int) string 144 | ``` 145 | 获取槽位的值,默认取第一组槽位 146 | 147 | 148 | 149 | 150 | ## type [IntentRequest](/src/target/request.go?s=1255:1336#L37) 151 | ``` go 152 | type IntentRequest struct { 153 | Data data.IntentRequest 154 | Dialog *Dialog 155 | Request 156 | } 157 | ``` 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | ### func (\*IntentRequest) [GetIntentName](/src/target/request.go?s=2140:2197#L85) 168 | ``` go 169 | func (this *IntentRequest) GetIntentName() (string, bool) 170 | ``` 171 | 获取意图名 172 | 173 | 174 | 175 | 176 | ### func (\*IntentRequest) [GetQuery](/src/target/request.go?s=2403:2447#L95) 177 | ``` go 178 | func (this *IntentRequest) GetQuery() string 179 | ``` 180 | 获取用户请求query 181 | 182 | 183 | 184 | 185 | ### func (\*IntentRequest) [IsDialogStateCompleted](/src/target/request.go?s=2267:2323#L90) 186 | ``` go 187 | func (this *IntentRequest) IsDialogStateCompleted() bool 188 | ``` 189 | 槽位填充是否完成 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | - - - 199 | Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md) 200 | -------------------------------------------------------------------------------- /doc/model/intent.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # model 4 | `import "github.com/dueros/bot-sdk-go/bot/model"` 5 | 6 | * [Overview](#pkg-overview) 7 | * [Index](#pkg-index) 8 | 9 | ## Overview 10 | 11 | 12 | 13 | ## Index 14 | * [type Intent](#Intent) 15 | * [func NewIntent(intent data.Intent) *Intent](#NewIntent) 16 | * [func (this *Intent) GetData() data.Intent](#Intent.GetData) 17 | * [func (this *Intent) GetSlot(name string) *data.Slot](#Intent.GetSlot) 18 | * [func (this *Intent) GetSlotStatus(name string) string](#Intent.GetSlotStatus) 19 | * [func (this *Intent) GetSlotValue(name string) string](#Intent.GetSlotValue) 20 | * [func (this *Intent) SetSlotValue(name string, value string) bool](#Intent.SetSlotValue) 21 | 22 | 23 | #### Package files 24 | [dialog.go](/src/github.com/dueros/bot-sdk-go/bot/model/dialog.go) [intent.go](/src/github.com/dueros/bot-sdk-go/bot/model/intent.go) [request.go](/src/github.com/dueros/bot-sdk-go/bot/model/request.go) [response.go](/src/github.com/dueros/bot-sdk-go/bot/model/response.go) [session.go](/src/github.com/dueros/bot-sdk-go/bot/model/session.go) [ssml_builder.go](/src/github.com/dueros/bot-sdk-go/bot/model/ssml_builder.go) 25 | 26 | 27 | 28 | 29 | 30 | 31 | ## type [Intent](/src/target/intent.go?s=68:176#L7) 32 | ``` go 33 | type Intent struct { 34 | Name string 35 | ConfirmationStatus string 36 | // contains filtered or unexported fields 37 | } 38 | ``` 39 | 40 | 41 | 42 | 43 | 44 | 45 | ### func [NewIntent](/src/target/intent.go?s=178:220#L13) 46 | ``` go 47 | func NewIntent(intent data.Intent) *Intent 48 | ``` 49 | 50 | 51 | 52 | 53 | ### func (\*Intent) [GetData](/src/target/intent.go?s=1096:1137#L62) 54 | ``` go 55 | func (this *Intent) GetData() data.Intent 56 | ``` 57 | 58 | 59 | 60 | ### func (\*Intent) [GetSlot](/src/target/intent.go?s=364:415#L23) 61 | ``` go 62 | func (this *Intent) GetSlot(name string) *data.Slot 63 | ``` 64 | 根据槽位名获取槽位 65 | 66 | 67 | 68 | 69 | ### func (\*Intent) [GetSlotStatus](/src/target/intent.go?s=722:775#L41) 70 | ``` go 71 | func (this *Intent) GetSlotStatus(name string) string 72 | ``` 73 | 根据槽位名获取槽位对应的状态 74 | 75 | 76 | 77 | 78 | ### func (\*Intent) [GetSlotValue](/src/target/intent.go?s=538:590#L32) 79 | ``` go 80 | func (this *Intent) GetSlotValue(name string) string 81 | ``` 82 | 根据槽位名获取槽位对应的值 83 | 84 | 85 | 86 | 87 | ### func (\*Intent) [SetSlotValue](/src/target/intent.go?s=897:961#L51) 88 | ``` go 89 | func (this *Intent) SetSlotValue(name string, value string) bool 90 | ``` 91 | 设置槽位的值 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | - - - 101 | Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md) 102 | -------------------------------------------------------------------------------- /doc/model/request.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # model 4 | `import "github.com/dueros/bot-sdk-go/bot/model"` 5 | 6 | * [Overview](#pkg-overview) 7 | * [Index](#pkg-index) 8 | 9 | ## Overview 10 | 11 | 12 | 13 | ## Index 14 | * [type Request](#Request) 15 | * [func (this *Request) GetAccessToken() string](#Request.GetAccessToken) 16 | * [func (this *Request) GetAudioPlayerContext() data.AudioPlayerContext](#Request.GetAudioPlayerContext) 17 | * [func (this *Request) GetBotId() string](#Request.GetBotId) 18 | * [func (this *Request) GetDeviceId() string](#Request.GetDeviceId) 19 | * [func (this *Request) GetRequestId() string](#Request.GetRequestId) 20 | * [func (this *Request) GetSupportedInterfaces() map[string]interface{}](#Request.GetSupportedInterfaces) 21 | * [func (this *Request) GetTimestamp() int](#Request.GetTimestamp) 22 | * [func (this *Request) GetUserId() string](#Request.GetUserId) 23 | * [func (this *Request) GetVideoPlayerContext() data.VideoPlayerContext](#Request.GetVideoPlayerContext) 24 | * [func (this *Request) IsSupportAudio() bool](#Request.IsSupportAudio) 25 | * [func (this *Request) IsSupportDisplay() bool](#Request.IsSupportDisplay) 26 | * [func (this *Request) IsSupportVideo() bool](#Request.IsSupportVideo) 27 | * [func (this *Request) VerifyBotID(myBotID string) bool](#Request.VerifyBotID) 28 | * [func (this *Request) VerifyTimestamp() bool](#Request.VerifyTimestamp) 29 | 30 | 31 | #### Package files 32 | [dialog.go](/src/github.com/dueros/bot-sdk-go/bot/model/dialog.go) [intent.go](/src/github.com/dueros/bot-sdk-go/bot/model/intent.go) [request.go](/src/github.com/dueros/bot-sdk-go/bot/model/request.go) [response.go](/src/github.com/dueros/bot-sdk-go/bot/model/response.go) [session.go](/src/github.com/dueros/bot-sdk-go/bot/model/session.go) [ssml_builder.go](/src/github.com/dueros/bot-sdk-go/bot/model/ssml_builder.go) 33 | 34 | 35 | 36 | 37 | 38 | 39 | ## type [Request](/src/target/request.go?s=1190:1253#L32) 40 | ``` go 41 | type Request struct { 42 | Type string 43 | Common data.RequestPart 44 | } 45 | ``` 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | ### func (\*Request) [GetAccessToken](/src/target/request.go?s=3041:3085#L121) 56 | ``` go 57 | func (this *Request) GetAccessToken() string 58 | ``` 59 | 获取access token 60 | 61 | 62 | 63 | 64 | ### func (\*Request) [GetAudioPlayerContext](/src/target/request.go?s=2760:2828#L111) 65 | ``` go 66 | func (this *Request) GetAudioPlayerContext() data.AudioPlayerContext 67 | ``` 68 | 获取音频播放上下文 69 | 70 | 71 | 72 | 73 | ### func (\*Request) [GetBotId](/src/target/request.go?s=3440:3478#L140) 74 | ``` go 75 | func (this *Request) GetBotId() string 76 | ``` 77 | 获取技能id 78 | 79 | 80 | 81 | 82 | ### func (\*Request) [GetDeviceId](/src/target/request.go?s=2631:2672#L106) 83 | ``` go 84 | func (this *Request) GetDeviceId() string 85 | ``` 86 | 获取设备id 87 | 88 | 89 | 90 | 91 | ### func (\*Request) [GetRequestId](/src/target/request.go?s=3336:3378#L135) 92 | ``` go 93 | func (this *Request) GetRequestId() string 94 | ``` 95 | 获取请求id 96 | 97 | 98 | 99 | 100 | ### func (\*Request) [GetSupportedInterfaces](/src/target/request.go?s=3753:3821#L155) 101 | ``` go 102 | func (this *Request) GetSupportedInterfaces() map[string]interface{} 103 | ``` 104 | 获取设备支持的接口类型 105 | 106 | 107 | 108 | 109 | ### func (\*Request) [GetTimestamp](/src/target/request.go?s=3171:3210#L126) 110 | ``` go 111 | func (this *Request) GetTimestamp() int 112 | ``` 113 | 获取请求的时间戳 114 | 115 | 116 | 117 | 118 | ### func (\*Request) [GetUserId](/src/target/request.go?s=2521:2560#L101) 119 | ``` go 120 | func (this *Request) GetUserId() string 121 | ``` 122 | 获取用户id 123 | 124 | 125 | 126 | 127 | ### func (\*Request) [GetVideoPlayerContext](/src/target/request.go?s=2905:2973#L116) 128 | ``` go 129 | func (this *Request) GetVideoPlayerContext() data.VideoPlayerContext 130 | ``` 131 | 获取视频播放上下文 132 | 133 | 134 | 135 | 136 | ### func (\*Request) [IsSupportAudio](/src/target/request.go?s=4244:4286#L175) 137 | ``` go 138 | func (this *Request) IsSupportAudio() bool 139 | ``` 140 | 检查是否支持音频播放 141 | 142 | 143 | 144 | 145 | ### func (\*Request) [IsSupportDisplay](/src/target/request.go?s=4117:4161#L170) 146 | ``` go 147 | func (this *Request) IsSupportDisplay() bool 148 | ``` 149 | 检查是否支持展现 150 | 151 | 152 | 153 | 154 | ### func (\*Request) [IsSupportVideo](/src/target/request.go?s=4373:4415#L180) 155 | ``` go 156 | func (this *Request) IsSupportVideo() bool 157 | ``` 158 | 检查是否支持视频播放 159 | 160 | 161 | 162 | 163 | ### func (\*Request) [VerifyBotID](/src/target/request.go?s=4495:4548#L185) 164 | ``` go 165 | func (this *Request) VerifyBotID(myBotID string) bool 166 | ``` 167 | 验证技能id合法性 168 | 169 | 170 | 171 | 172 | ### func (\*Request) [VerifyTimestamp](/src/target/request.go?s=3579:3622#L145) 173 | ``` go 174 | func (this *Request) VerifyTimestamp() bool 175 | ``` 176 | 验证请求时间戳合法性 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | - - - 186 | Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md) 187 | 188 | 189 | # model 190 | `import "github.com/dueros/bot-sdk-go/bot/model"` 191 | 192 | * [Overview](#pkg-overview) 193 | * [Index](#pkg-index) 194 | 195 | ## Overview 196 | 197 | 198 | 199 | ## Index 200 | * [type LaunchRequest](#LaunchRequest) 201 | 202 | 203 | #### Package files 204 | [dialog.go](/src/github.com/dueros/bot-sdk-go/bot/model/dialog.go) [intent.go](/src/github.com/dueros/bot-sdk-go/bot/model/intent.go) [request.go](/src/github.com/dueros/bot-sdk-go/bot/model/request.go) [response.go](/src/github.com/dueros/bot-sdk-go/bot/model/response.go) [session.go](/src/github.com/dueros/bot-sdk-go/bot/model/session.go) [ssml_builder.go](/src/github.com/dueros/bot-sdk-go/bot/model/ssml_builder.go) 205 | 206 | 207 | 208 | 209 | 210 | 211 | ## type [LaunchRequest](/src/target/request.go?s=1338:1401#L43) 212 | ``` go 213 | type LaunchRequest struct { 214 | Data data.LaunchRequest 215 | Request 216 | } 217 | ``` 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | - - - 232 | Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md) 233 | 234 | 235 | # model 236 | `import "github.com/dueros/bot-sdk-go/bot/model"` 237 | 238 | * [Overview](#pkg-overview) 239 | * [Index](#pkg-index) 240 | 241 | ## Overview 242 | 243 | 244 | 245 | ## Index 246 | * [type IntentRequest](#IntentRequest) 247 | * [func (this *IntentRequest) GetIntentName() (string, bool)](#IntentRequest.GetIntentName) 248 | * [func (this *IntentRequest) GetQuery() string](#IntentRequest.GetQuery) 249 | * [func (this *IntentRequest) IsDialogStateCompleted() bool](#IntentRequest.IsDialogStateCompleted) 250 | 251 | 252 | #### Package files 253 | [dialog.go](/src/github.com/dueros/bot-sdk-go/bot/model/dialog.go) [intent.go](/src/github.com/dueros/bot-sdk-go/bot/model/intent.go) [request.go](/src/github.com/dueros/bot-sdk-go/bot/model/request.go) [response.go](/src/github.com/dueros/bot-sdk-go/bot/model/response.go) [session.go](/src/github.com/dueros/bot-sdk-go/bot/model/session.go) [ssml_builder.go](/src/github.com/dueros/bot-sdk-go/bot/model/ssml_builder.go) 254 | 255 | 256 | 257 | 258 | 259 | 260 | ## type [IntentRequest](/src/target/request.go?s=1255:1336#L37) 261 | ``` go 262 | type IntentRequest struct { 263 | Data data.IntentRequest 264 | Dialog *Dialog 265 | Request 266 | } 267 | ``` 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | ### func (\*IntentRequest) [GetIntentName](/src/target/request.go?s=2140:2197#L85) 278 | ``` go 279 | func (this *IntentRequest) GetIntentName() (string, bool) 280 | ``` 281 | 获取意图名 282 | 283 | 284 | 285 | 286 | ### func (\*IntentRequest) [GetQuery](/src/target/request.go?s=2403:2447#L95) 287 | ``` go 288 | func (this *IntentRequest) GetQuery() string 289 | ``` 290 | 获取用户请求query 291 | 292 | 293 | 294 | 295 | ### func (\*IntentRequest) [IsDialogStateCompleted](/src/target/request.go?s=2267:2323#L90) 296 | ``` go 297 | func (this *IntentRequest) IsDialogStateCompleted() bool 298 | ``` 299 | 槽位填充是否完成 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | - - - 309 | Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md) 310 | 311 | 312 | # model 313 | `import "github.com/dueros/bot-sdk-go/bot/model"` 314 | 315 | * [Overview](#pkg-overview) 316 | * [Index](#pkg-index) 317 | 318 | ## Overview 319 | 320 | 321 | 322 | ## Index 323 | * [type SessionEndedRequest](#SessionEndedRequest) 324 | 325 | 326 | #### Package files 327 | [dialog.go](/src/github.com/dueros/bot-sdk-go/bot/model/dialog.go) [intent.go](/src/github.com/dueros/bot-sdk-go/bot/model/intent.go) [request.go](/src/github.com/dueros/bot-sdk-go/bot/model/request.go) [response.go](/src/github.com/dueros/bot-sdk-go/bot/model/response.go) [session.go](/src/github.com/dueros/bot-sdk-go/bot/model/session.go) [ssml_builder.go](/src/github.com/dueros/bot-sdk-go/bot/model/ssml_builder.go) 328 | 329 | 330 | 331 | 332 | 333 | 334 | ## type [SessionEndedRequest](/src/target/request.go?s=1403:1478#L48) 335 | ``` go 336 | type SessionEndedRequest struct { 337 | Data data.SessionEndedRequest 338 | Request 339 | } 340 | ``` 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | - - - 355 | Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md) 356 | 357 | 358 | # model 359 | `import "github.com/dueros/bot-sdk-go/bot/model"` 360 | 361 | * [Overview](#pkg-overview) 362 | * [Index](#pkg-index) 363 | 364 | ## Overview 365 | 366 | 367 | 368 | ## Index 369 | * [type EventRequest](#EventRequest) 370 | * [func (this *EventRequest) GetName() string](#EventRequest.GetName) 371 | * [func (this *EventRequest) GetUrl() string](#EventRequest.GetUrl) 372 | 373 | 374 | #### Package files 375 | [dialog.go](/src/github.com/dueros/bot-sdk-go/bot/model/dialog.go) [intent.go](/src/github.com/dueros/bot-sdk-go/bot/model/intent.go) [request.go](/src/github.com/dueros/bot-sdk-go/bot/model/request.go) [response.go](/src/github.com/dueros/bot-sdk-go/bot/model/response.go) [session.go](/src/github.com/dueros/bot-sdk-go/bot/model/session.go) [ssml_builder.go](/src/github.com/dueros/bot-sdk-go/bot/model/ssml_builder.go) 376 | 377 | 378 | 379 | 380 | 381 | 382 | ## type [EventRequest](/src/target/request.go?s=1480:1541#L53) 383 | ``` go 384 | type EventRequest struct { 385 | Data data.EventRequest 386 | Request 387 | } 388 | ``` 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | ### func (\*EventRequest) [GetName](/src/target/request.go?s=1800:1842#L72) 399 | ``` go 400 | func (this *EventRequest) GetName() string 401 | ``` 402 | 403 | 404 | 405 | ### func (\*EventRequest) [GetUrl](/src/target/request.go?s=1723:1764#L68) 406 | ``` go 407 | func (this *EventRequest) GetUrl() string 408 | ``` 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | - - - 417 | Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md) 418 | -------------------------------------------------------------------------------- /doc/model/response.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # model 4 | `import "github.com/dueros/bot-sdk-go/bot/model"` 5 | 6 | * [Overview](#pkg-overview) 7 | * [Index](#pkg-index) 8 | 9 | ## Overview 10 | 11 | 12 | 13 | ## Index 14 | * [type Response](#Response) 15 | * [func NewResponse(session *Session, request interface{}) *Response](#NewResponse) 16 | * [func (this *Response) Ask(speech string) *Response](#Response.Ask) 17 | * [func (this *Response) AskSlot(speech string, slot string) *Response](#Response.AskSlot) 18 | * [func (this *Response) Build() string](#Response.Build) 19 | * [func (this *Response) CloseMicrophone() *Response](#Response.CloseMicrophone) 20 | * [func (this *Response) Command(directive interface{}) *Response](#Response.Command) 21 | * [func (this *Response) DisplayCard(card interface{}) *Response](#Response.DisplayCard) 22 | * [func (this *Response) GetData() map[string]interface{}](#Response.GetData) 23 | * [func (this *Response) HoldOn() *Response](#Response.HoldOn) 24 | * [func (this *Response) Reprompt(speech string) *Response](#Response.Reprompt) 25 | * [func (this *Response) Tell(speech string) *Response](#Response.Tell) 26 | 27 | 28 | #### Package files 29 | [dialog.go](/src/github.com/dueros/bot-sdk-go/bot/model/dialog.go) [intent.go](/src/github.com/dueros/bot-sdk-go/bot/model/intent.go) [request.go](/src/github.com/dueros/bot-sdk-go/bot/model/request.go) [response.go](/src/github.com/dueros/bot-sdk-go/bot/model/response.go) [session.go](/src/github.com/dueros/bot-sdk-go/bot/model/session.go) [ssml_builder.go](/src/github.com/dueros/bot-sdk-go/bot/model/ssml_builder.go) 30 | 31 | 32 | 33 | 34 | 35 | 36 | ## type [Response](/src/target/response.go?s=127:222#L10) 37 | ``` go 38 | type Response struct { 39 | // contains filtered or unexported fields 40 | } 41 | ``` 42 | 43 | 44 | 45 | 46 | 47 | 48 | ### func [NewResponse](/src/target/response.go?s=224:289#L16) 49 | ``` go 50 | func NewResponse(session *Session, request interface{}) *Response 51 | ``` 52 | 53 | 54 | 55 | 56 | ### func (\*Response) [Ask](/src/target/response.go?s=642:692#L30) 57 | ``` go 58 | func (this *Response) Ask(speech string) *Response 59 | ``` 60 | * 61 | 62 | 63 | * 询问用户时,返回的speech. 64 | * 此时设备的麦克风会进入收音状态,比如设备灯光亮起 65 | * TIP: 一般技能要完成一项任务,还缺少一些信息,主动发起对用户的询问的时候使用 66 | 67 | 68 | 69 | 70 | ### func (\*Response) [AskSlot](/src/target/response.go?s=745:812#L36) 71 | ``` go 72 | func (this *Response) AskSlot(speech string, slot string) *Response 73 | ``` 74 | 75 | 76 | 77 | ### func (\*Response) [Build](/src/target/response.go?s=2427:2463#L111) 78 | ``` go 79 | func (this *Response) Build() string 80 | ``` 81 | 82 | 83 | 84 | ### func (\*Response) [CloseMicrophone](/src/target/response.go?s=2325:2374#L106) 85 | ``` go 86 | func (this *Response) CloseMicrophone() *Response 87 | ``` 88 | * 89 | 90 | 91 | * 保持会话. 92 | * 关闭麦克风 93 | 94 | 95 | 96 | 97 | ### func (\*Response) [Command](/src/target/response.go?s=1774:1836#L79) 98 | ``` go 99 | func (this *Response) Command(directive interface{}) *Response 100 | ``` 101 | * 102 | 103 | 104 | * 返回指令. 比如,返回音频播放指令,使设备开始播放音频 105 | * TIP: 可以同时返回多个指令,设备按返回顺序执行这些指令,指令协议参考TODO 106 | 107 | 108 | 109 | 110 | ### func (\*Response) [DisplayCard](/src/target/response.go?s=1472:1533#L69) 111 | ``` go 112 | func (this *Response) DisplayCard(card interface{}) *Response 113 | ``` 114 | * 115 | 116 | 117 | * 返回卡片. 118 | * 针对有屏幕的设备,比如: 电视、show,可以呈现更多丰富的信息给用户 119 | * 卡片协议参考:TODO 120 | 121 | 122 | 123 | 124 | ### func (\*Response) [GetData](/src/target/response.go?s=2994:3048#L137) 125 | ``` go 126 | func (this *Response) GetData() map[string]interface{} 127 | ``` 128 | 129 | 130 | 131 | ### func (\*Response) [HoldOn](/src/target/response.go?s=2183:2223#L97) 132 | ``` go 133 | func (this *Response) HoldOn() *Response 134 | ``` 135 | * 136 | 137 | 138 | * 保持会话. 139 | * 此时设备的麦克风会自动开启监听用户说话 140 | 141 | 142 | 143 | 144 | ### func (\*Response) [Reprompt](/src/target/response.go?s=1150:1205#L57) 145 | ``` go 146 | func (this *Response) Reprompt(speech string) *Response 147 | ``` 148 | * 149 | 150 | 151 | * 回复用户,返回的speech 152 | 153 | 154 | 155 | 156 | ### func (\*Response) [Tell](/src/target/response.go?s=983:1034#L49) 157 | ``` go 158 | func (this *Response) Tell(speech string) *Response 159 | ``` 160 | * 161 | 162 | 163 | * 回复用户,返回的speech 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | - - - 173 | Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md) 174 | -------------------------------------------------------------------------------- /doc/model/session.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # model 4 | `import "github.com/dueros/bot-sdk-go/bot/model"` 5 | 6 | * [Overview](#pkg-overview) 7 | * [Index](#pkg-index) 8 | 9 | ## Overview 10 | 11 | 12 | 13 | ## Index 14 | * [type Session](#Session) 15 | * [func NewSession(data data.Session) *Session](#NewSession) 16 | * [func (this *Session) GetAttribute(key string) string](#Session.GetAttribute) 17 | * [func (this *Session) GetData() data.Session](#Session.GetData) 18 | * [func (this *Session) GetId() string](#Session.GetId) 19 | * [func (this *Session) IsNew() bool](#Session.IsNew) 20 | * [func (this *Session) SetAttribute(key, value string)](#Session.SetAttribute) 21 | 22 | 23 | #### Package files 24 | [dialog.go](/src/github.com/dueros/bot-sdk-go/bot/model/dialog.go) [intent.go](/src/github.com/dueros/bot-sdk-go/bot/model/intent.go) [request.go](/src/github.com/dueros/bot-sdk-go/bot/model/request.go) [response.go](/src/github.com/dueros/bot-sdk-go/bot/model/response.go) [session.go](/src/github.com/dueros/bot-sdk-go/bot/model/session.go) [ssml_builder.go](/src/github.com/dueros/bot-sdk-go/bot/model/ssml_builder.go) 25 | 26 | 27 | 28 | 29 | 30 | 31 | ## type [Session](/src/target/session.go?s=68:110#L7) 32 | ``` go 33 | type Session struct { 34 | // contains filtered or unexported fields 35 | } 36 | ``` 37 | 38 | 39 | 40 | 41 | 42 | 43 | ### func [NewSession](/src/target/session.go?s=112:155#L11) 44 | ``` go 45 | func NewSession(data data.Session) *Session 46 | ``` 47 | 48 | 49 | 50 | 51 | ### func (\*Session) [GetAttribute](/src/target/session.go?s=493:545#L32) 52 | ``` go 53 | func (this *Session) GetAttribute(key string) string 54 | ``` 55 | 获取session中对应字段的值 56 | 57 | 58 | 59 | 60 | ### func (\*Session) [GetData](/src/target/session.go?s=789:832#L49) 61 | ``` go 62 | func (this *Session) GetData() data.Session 63 | ``` 64 | 65 | 66 | 67 | ### func (\*Session) [GetId](/src/target/session.go?s=386:421#L27) 68 | ``` go 69 | func (this *Session) GetId() string 70 | ``` 71 | 获取session id 72 | 73 | 74 | 75 | 76 | ### func (\*Session) [IsNew](/src/target/session.go?s=305:338#L22) 77 | ``` go 78 | func (this *Session) IsNew() bool 79 | ``` 80 | 当前session是否是新的 81 | 82 | 83 | 84 | 85 | ### func (\*Session) [SetAttribute](/src/target/session.go?s=667:719#L41) 86 | ``` go 87 | func (this *Session) SetAttribute(key, value string) 88 | ``` 89 | 设置session中对应字段的值 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | - - - 99 | Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md) 100 | -------------------------------------------------------------------------------- /doc/model/ssml-text-builder.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # model 4 | `import "github.com/dueros/bot-sdk-go/bot/model"` 5 | 6 | * [Overview](#pkg-overview) 7 | * [Index](#pkg-index) 8 | 9 | ## Overview 10 | 11 | 12 | 13 | ## Index 14 | * [type SSMLTextBuilder](#SSMLTextBuilder) 15 | * [func NewSSMLTextBuilder() *SSMLTextBuilder](#NewSSMLTextBuilder) 16 | * [func (this *SSMLTextBuilder) AppendAudio(src string) *SSMLTextBuilder](#SSMLTextBuilder.AppendAudio) 17 | * [func (this *SSMLTextBuilder) AppendBackground(text string, src string, repeat bool) *SSMLTextBuilder](#SSMLTextBuilder.AppendBackground) 18 | * [func (this *SSMLTextBuilder) AppendPlainSpeech(text string) *SSMLTextBuilder](#SSMLTextBuilder.AppendPlainSpeech) 19 | * [func (this *SSMLTextBuilder) AppendSilence(time int) *SSMLTextBuilder](#SSMLTextBuilder.AppendSilence) 20 | * [func (this *SSMLTextBuilder) AppendSubstitution(text, alias string) *SSMLTextBuilder](#SSMLTextBuilder.AppendSubstitution) 21 | * [func (this *SSMLTextBuilder) ApplyBackground(src string, repeat bool) *SSMLTextBuilder](#SSMLTextBuilder.ApplyBackground) 22 | * [func (this *SSMLTextBuilder) Build() string](#SSMLTextBuilder.Build) 23 | 24 | 25 | #### Package files 26 | [dialog.go](/src/github.com/dueros/bot-sdk-go/bot/model/dialog.go) [intent.go](/src/github.com/dueros/bot-sdk-go/bot/model/intent.go) [request.go](/src/github.com/dueros/bot-sdk-go/bot/model/request.go) [response.go](/src/github.com/dueros/bot-sdk-go/bot/model/response.go) [session.go](/src/github.com/dueros/bot-sdk-go/bot/model/session.go) [ssml_builder.go](/src/github.com/dueros/bot-sdk-go/bot/model/ssml_builder.go) 27 | 28 | 29 | 30 | 31 | 32 | 33 | ## type [SSMLTextBuilder](/src/target/ssml_builder.go?s=239:292#L15) 34 | ``` go 35 | type SSMLTextBuilder struct { 36 | // contains filtered or unexported fields 37 | } 38 | ``` 39 | 40 | 41 | 42 | 43 | 44 | 45 | ### func [NewSSMLTextBuilder](/src/target/ssml_builder.go?s=294:336#L19) 46 | ``` go 47 | func NewSSMLTextBuilder() *SSMLTextBuilder 48 | ``` 49 | 50 | 51 | 52 | 53 | ### func (\*SSMLTextBuilder) [AppendAudio](/src/target/ssml_builder.go?s=522:591#L30) 54 | ``` go 55 | func (this *SSMLTextBuilder) AppendAudio(src string) *SSMLTextBuilder 56 | ``` 57 | 58 | 59 | 60 | ### func (\*SSMLTextBuilder) [AppendBackground](/src/target/ssml_builder.go?s=2062:2162#L93) 61 | ``` go 62 | func (this *SSMLTextBuilder) AppendBackground(text string, src string, repeat bool) *SSMLTextBuilder 63 | ``` 64 | 65 | 66 | 67 | ### func (\*SSMLTextBuilder) [AppendPlainSpeech](/src/target/ssml_builder.go?s=394:470#L23) 68 | ``` go 69 | func (this *SSMLTextBuilder) AppendPlainSpeech(text string) *SSMLTextBuilder 70 | ``` 71 | 72 | 73 | 74 | ### func (\*SSMLTextBuilder) [AppendSilence](/src/target/ssml_builder.go?s=1707:1776#L79) 75 | ``` go 76 | func (this *SSMLTextBuilder) AppendSilence(time int) *SSMLTextBuilder 77 | ``` 78 | 79 | 80 | 81 | ### func (\*SSMLTextBuilder) [AppendSubstitution](/src/target/ssml_builder.go?s=1876:1960#L86) 82 | ``` go 83 | func (this *SSMLTextBuilder) AppendSubstitution(text, alias string) *SSMLTextBuilder 84 | ``` 85 | 86 | 87 | 88 | ### func (\*SSMLTextBuilder) [ApplyBackground](/src/target/ssml_builder.go?s=2355:2441#L103) 89 | ``` go 90 | func (this *SSMLTextBuilder) ApplyBackground(src string, repeat bool) *SSMLTextBuilder 91 | ``` 92 | 93 | 94 | 95 | ### func (\*SSMLTextBuilder) [Build](/src/target/ssml_builder.go?s=2705:2748#L116) 96 | ``` go 97 | func (this *SSMLTextBuilder) Build() string 98 | ``` 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | - - - 107 | Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md) 108 | -------------------------------------------------------------------------------- /example/audio_play/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | dueros "github.com/dueros/bot-sdk-go/bot" 5 | "github.com/dueros/bot-sdk-go/bot/card" 6 | "github.com/dueros/bot-sdk-go/bot/directive/audio_player" 7 | "github.com/dueros/bot-sdk-go/bot/model" 8 | ) 9 | 10 | func main() { 11 | 12 | bot := dueros.NewBot() // 创建bot 只创建一次 13 | bot.AddDefaultEventListener(defaultRequest) // 添加默认事件的监听 14 | bot.AddIntentHandler("start_play", startPlay) // 添加开始播放的意图 15 | bot.OnLaunchRequest(launchRequest) // 添加启动意图 16 | 17 | application := dueros.Application{AppId: "9f8f898b-2e91-a7ca-b25d-4aa9071f0470", Handler: bot.Handler} // 添加web容器 18 | application.Start(":8080") // 启动服务器 19 | } 20 | 21 | func launchRequest(bot *dueros.Bot, request *model.LaunchRequest) { 22 | txtCard := card.NewTextCard("欢迎使用,请说开始测试") 23 | bot.Response.Tell("欢迎使用,请说开始测试") 24 | bot.Response.DisplayCard(txtCard) 25 | } 26 | 27 | func startPlay(bot *dueros.Bot, request *model.IntentRequest) { 28 | mp3 := audio_player.NewPlayDirective("http://baobaozhidao.bj.bcebos.com/beilehu%2F%E9%9D%92%E8%9B%99%E4%B9%90%E9%98%9F-%E5%B0%8F%E8%B7%B3%E8%9B%99.mp3") 29 | info := audio_player.NewPlayerInfo() 30 | info.SetTitle("小跳蛙") 31 | info.SetTitleSubtext1("xiaotiaowa") 32 | mp3.SetPlayerInfo(info) 33 | bot.Response.Command(mp3) 34 | } 35 | 36 | func defaultRequest(bot *dueros.Bot, request interface{}) { 37 | bot.Response.HoldOn() 38 | bot.Response.CloseMicrophone() 39 | } 40 | -------------------------------------------------------------------------------- /example/flight/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "fmt" 7 | "io/ioutil" 8 | "log" 9 | "net/http" 10 | "os" 11 | "strconv" 12 | 13 | dueros "github.com/dueros/bot-sdk-go/bot" 14 | "github.com/dueros/bot-sdk-go/bot/directive/display" 15 | "github.com/dueros/bot-sdk-go/bot/directive/display/template" 16 | "github.com/dueros/bot-sdk-go/bot/model" 17 | ) 18 | 19 | var CODE_INIT = false 20 | var CODE = make(map[string]City) 21 | 22 | type City struct { 23 | Code string 24 | Name string 25 | } 26 | 27 | type CityList struct { 28 | Cities []City 29 | DataVer int32 30 | } 31 | 32 | type Result struct { 33 | FlightNo string 34 | Airname string 35 | DDate string 36 | Price int 37 | Departure string 38 | Destination string 39 | } 40 | 41 | type CitySlot struct { 42 | City string 43 | } 44 | 45 | func main() { 46 | 47 | bot := dueros.NewBot() // 创建bot 只创建一次 48 | bot.OnLaunchRequest(launchRequest) // 添加启动意图 49 | bot.AddIntentHandler("flightSearch", flightSearch) // 添加查询意图处理 50 | 51 | application := dueros.Application{AppId: "14a6ee9e-3367-f4e3-6698-d8df54c8a104", Handler: bot.Handler} // 添加web容器 52 | application.Start(":8880") 53 | } 54 | 55 | func launchRequest(this *dueros.Bot, request *model.LaunchRequest) { 56 | this.Response.HoldOn().Tell("欢迎使用机票查询服务,告诉我出发时间、离开城市、到达城市就可以查询最低的机票价格,比如:明天北京到上海的机票") 57 | } 58 | 59 | func flightSearch(this *dueros.Bot, request *model.IntentRequest) { 60 | if !request.IsDialogStateCompleted() && !request.IsSupportDisplay() { 61 | request.Dialog.Delegate() 62 | return 63 | } 64 | 65 | date := request.Dialog.GetSlotValue("date") 66 | departure := request.Dialog.GetSlotValue("departure") 67 | destination := request.Dialog.GetSlotValue("destination") 68 | 69 | if request.IsSupportDisplay() { 70 | if date == "" { 71 | text := "请问什么时间出发呢?" 72 | display := getResult(text, "机票助手") 73 | this.Response.AskSlot(text, "date").Reprompt(text).Command(display) 74 | return 75 | } else if departure == "" { 76 | text := "请问你的出发城市是哪里?" 77 | display := getResult(text, "机票助手") 78 | this.Response.AskSlot(text, "departure").Reprompt(text).Command(display) 79 | return 80 | } else if destination == "" { 81 | text := "请问你的目的城市是哪里?" 82 | display := getResult(text, "机票助手") 83 | this.Response.AskSlot(text, "destination").Reprompt(text).Command(display) 84 | return 85 | } 86 | } 87 | 88 | departureCity := getCity(departure) 89 | destinationCity := getCity(destination) 90 | 91 | departureCode := getCityCode(departureCity) 92 | destinationCode := getCityCode(destinationCity) 93 | 94 | result := getFlight(date, departureCode, destinationCode) 95 | 96 | if result != nil { 97 | result.Departure = departureCity 98 | result.Destination = destinationCity 99 | 100 | text := "价格" + strconv.Itoa(result.Price) 101 | this.Response.Tell(text) 102 | if request.IsSupportDisplay() { 103 | display := getResult(text, "机票助手") 104 | this.Response.Command(display) 105 | } 106 | return 107 | } 108 | 109 | this.Response.Tell("查询失败") 110 | return 111 | } 112 | 113 | func getCity(jsonStr string) string { 114 | city := CitySlot{} 115 | if err := json.Unmarshal([]byte(jsonStr), &city); err != nil { 116 | log.Fatal("city slot parse error") 117 | return "" 118 | } 119 | 120 | return city.City 121 | } 122 | 123 | func getFlight(date, departure, destination string) *Result { 124 | url := "http://sec-m.ctrip.com/restapi/soa2/13516/lowPriceCalendar" 125 | req := fmt.Sprintf(`{"head":{},"stype":1,"dcty":"%s","acty":"%s","start":"","end":"%s","flag":1}`, departure, destination, date) 126 | log.Println(req) 127 | 128 | client := &http.Client{} 129 | request, _ := http.NewRequest("POST", url, bytes.NewBuffer([]byte(req))) 130 | request.Header.Set("Content-type", "application/json") 131 | response, _ := client.Do(request) 132 | defer response.Body.Close() 133 | if response.StatusCode == 200 { 134 | body, _ := ioutil.ReadAll(response.Body) 135 | log.Println(string(body)) 136 | 137 | d := struct { 138 | Prices []Result 139 | }{} 140 | 141 | if err := json.Unmarshal(body, &d); err != nil { 142 | log.Fatal("flight result parse error") 143 | return nil 144 | } 145 | 146 | for _, item := range d.Prices { 147 | if item.DDate == date { 148 | return &item 149 | } 150 | } 151 | } 152 | return nil 153 | } 154 | 155 | func getCityCode(city string) string { 156 | if !CODE_INIT { 157 | f, err := os.Open("city.json") 158 | defer f.Close() 159 | 160 | if err != nil { 161 | return "" 162 | log.Fatal("city.json file ready error") 163 | } 164 | 165 | d := CityList{} 166 | jsonBlob, _ := ioutil.ReadAll(f) 167 | if err := json.Unmarshal(jsonBlob, &d); err != nil { 168 | log.Fatal("json parse error") 169 | return "" 170 | } 171 | 172 | for _, cityItem := range d.Cities { 173 | CODE[cityItem.Name] = cityItem 174 | } 175 | CODE_INIT = true 176 | } 177 | 178 | return CODE[city].Code 179 | } 180 | 181 | func getResult(text string, title string) *display.RenderTemplate { 182 | template := template.NewBodyTemplate1() 183 | template.SetTitle(title) 184 | template.SetPlainContent(text) 185 | template.SetBackgroundImageUrl("http://img.taopic.com/uploads/allimg/120801/214828-120P10Z43585.jpg") 186 | 187 | return display.NewRenderTemplate(template) 188 | } 189 | -------------------------------------------------------------------------------- /example/tax/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | dueros "github.com/dueros/bot-sdk-go/bot" 5 | //"github.com/dueros/bot-sdk-go/bot/card" 6 | //"github.com/dueros/bot-sdk-go/bot/directive/audio_player" 7 | "github.com/dueros/bot-sdk-go/bot/directive/display" 8 | "github.com/dueros/bot-sdk-go/bot/directive/display/template" 9 | //"github.com/dueros/bot-sdk-go/bot/directive/video_player" 10 | "github.com/dueros/bot-sdk-go/bot/model" 11 | ) 12 | 13 | func main() { 14 | 15 | bot := dueros.CreateBot() // 创建bot 只创建一次 16 | bot.AddDefaultEventListener(defaultRequest) // 添加默认事件的监听 17 | bot.AddIntentHandler("test.inquiry888", func(this *dueros.Bot, request *model.IntentRequest) { 18 | this.Session.SetAttribute("key1", "test") 19 | template := template.NewBodyTemplate1() 20 | template.SetTitle("hah") 21 | template.SetPlainContent("欢迎查询") 22 | template.SetBackgroundImageUrl("http://www.baidu.com") 23 | directive := display.NewRenderTemplate(template) 24 | //c := card.NewTextCard("欢迎查询") 25 | 26 | //audio := audio_player.NewPlayDirective("http://www.wg") 27 | //playInfo := audio_player.NewPlayerInfo() 28 | //playInfo.SetTitle(request.GetUserId()) 29 | //audio.SetPlayerInfo(playInfo) 30 | 31 | //video := video_player.NewPlayDirective("http://wwgwgw") 32 | //video.SetReportIntervalInMs(20000) 33 | 34 | //request.Dialog.ConfirmIntent() 35 | this.Response.AskSlot("工资多少呢?", "salary").Command(directive) 36 | 37 | //ssmlBuilder := model.NewSSMLTextBuilder() 38 | //ssmlBuilder.AppendPlainSpeech("欢迎").AppendAudio("http://www.gasg.mp3").ApplyBackground("http://www.ga", true) 39 | 40 | //this.Response.Ask("欢迎查询").Command(directive) 41 | //this.Response.Ask("欢迎查询").Command(directive).Command(audio).Command(video) 42 | //this.Response.Ask(ssmlBuilder.Build()).Command(directive).Command(audio).Command(video) 43 | }) // 添加开始播放的意图 44 | bot.OnLaunchRequest(func(this *dueros.Bot, request *model.LaunchRequest) { 45 | this.Response.Tell("欢迎使用查个税") 46 | }) // 添加启动意图 47 | 48 | application := dueros.Application{AppId: "17a64831-b273-8af5-f995-9a805e45cffe", Handler: bot.Handler} // 添加web容器 49 | application.Start(":8888") 50 | } 51 | --------------------------------------------------------------------------------