forked from soundhound/houndify-sdk-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexample.go
168 lines (149 loc) · 4.94 KB
/
example.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
package main
import (
"bufio"
"bytes"
"crypto/rand"
"flag"
"fmt"
"io/ioutil"
"log"
"os"
"strings"
houndify "github.com/soundhound/houndify-sdk-go/houndify"
)
const (
// This is not the clientId. This is the app user, so many will likely exist per clientId.
// This value can be any string.
// See https://www.houndify.com/docs/ for more details.
userID = "exampleUser"
envClientIDKey = "HOUNDIFY_CLIENT_ID"
envClientKeyKey = "HOUNDIFY_CLIENT_KEY"
cliClientIDKey = "id"
cliClientKeyKey = "key"
)
func main() {
clientIDFlag := flag.String(cliClientIDKey, "", "Client ID")
clientKeyFlag := flag.String(cliClientKeyKey, "", "Client Key")
voiceFlag := flag.String("voice", "", "Audio file to use for voice query")
textFlag := flag.String("text", "", "Message to use for text query")
stdinFlag := flag.Bool("stdin", false, "Text query via stdin messages")
verboseFlag := flag.Bool("v", false, "Verbose mode, which prints raw server data")
flag.Parse()
// Make log not print out time info
log.SetFlags(0)
clientID := derefOrFetchFromEnv(clientIDFlag, envClientIDKey)
clientKey := derefOrFetchFromEnv(clientKeyFlag, envClientKeyKey)
var errsList []string
if clientID == "" {
msg := fmt.Sprintf("must set the client ID in environment variable: %q or via commmandline flag: -%s", envClientIDKey, cliClientIDKey)
errsList = append(errsList, msg)
}
if clientKey == "" {
msg := fmt.Sprintf("must set the client key in environment variable: %q or via commandline flag: -%s", envClientKeyKey, cliClientKeyKey)
errsList = append(errsList, msg)
}
if len(errsList) > 0 {
log.Fatalf("%s", strings.Join(errsList, "\n"))
}
// create a new client
client := houndify.Client{
ClientID: clientID,
ClientKey: clientKey,
Verbose: *verboseFlag,
}
client.EnableConversationState()
switch {
default:
log.Fatalf("must choose either voice, text or stdin")
case *voiceFlag != "":
// voice query
audioFilePath := *voiceFlag
fileContents, err := ioutil.ReadFile(audioFilePath)
if err != nil {
log.Fatalf("failed to read contents of file %q, err: %v", audioFilePath, err)
}
req := houndify.VoiceRequest{
AudioStream: bytes.NewReader(fileContents),
UserID: userID,
RequestID: createRequestID(),
RequestInfoFields: make(map[string]interface{}),
}
// listen for partial transcript responses
partialTranscripts := make(chan houndify.PartialTranscript)
go func() {
for partial := range partialTranscripts {
if partial.Message != "" { // ignore the "" partial transcripts, not really useful
fmt.Println(partial.Message)
}
}
}()
serverResponse, err := client.VoiceSearch(req, partialTranscripts)
if err != nil {
log.Fatalf("failed to make voice request: %v\n%s\n", err, serverResponse)
}
writtenResponse, err := houndify.ParseWrittenResponse(serverResponse)
if err != nil {
log.Fatalf("failed to decode hound response\n%s\n", serverResponse)
}
fmt.Println(writtenResponse)
case *textFlag != "":
// text query
req := houndify.TextRequest{
Query: *textFlag,
UserID: userID,
RequestID: createRequestID(),
RequestInfoFields: make(map[string]interface{}),
}
serverResponse, err := client.TextSearch(req)
if err != nil {
log.Fatalf("failed to make text request: %v\n%s\n", err, serverResponse)
}
writtenResponse, err := houndify.ParseWrittenResponse(serverResponse)
if err != nil {
log.Fatalf("failed to decode hound response\n%s\n", serverResponse)
}
fmt.Println(writtenResponse)
case *stdinFlag:
// text queries in succession, demonstrating conversation state
scanner := bufio.NewScanner(os.Stdin)
fmt.Println("Enter a text query: ")
for scanner.Scan() {
req := houndify.TextRequest{
Query: scanner.Text(),
UserID: userID,
RequestID: createRequestID(),
RequestInfoFields: make(map[string]interface{}),
}
serverResponse, err := client.TextSearch(req)
if err != nil {
fmt.Printf("failed to make text request: %v\n%s\nEnter another text query:", err, serverResponse)
continue
}
writtenResponse, err := houndify.ParseWrittenResponse(serverResponse)
if err != nil {
log.Fatalf("failed to decode hound response\n%s\n", serverResponse)
}
fmt.Print(writtenResponse, "\n\n")
fmt.Println("Enter another text query:")
}
}
}
// Creates a pseudo unique/random request ID.
//
// SDK users should do something similar so each request to the Hound server
// is signed differently to prevent replay attacks.
func createRequestID() string {
n := 10
b := make([]byte, n)
rand.Read(b)
return fmt.Sprintf("%X", b)
}
// derefOrFetchFromEnv tries to dereference and retrieve a non-empty
// string stored in the string pointer, otherwise it falls back
// to retrieving the value stored in the environment keyed by envKey.
func derefOrFetchFromEnv(strPtr *string, envKey string) string {
if strPtr != nil && *strPtr != "" {
return *strPtr
}
return os.Getenv(envKey)
}