package main import ( "bytes" "encoding/json" "fmt" "io/ioutil" "log" "net/http" "strconv" "strings" "time" "github.com/hamcha/clessy/tg" ) type QRequest struct { SessionID string `json:"sessionId"` Query string `json:"query"` Language string `json:"lang"` } type QResponse struct { ID string `json:"id"` Timestamp time.Time `json:"timestamp"` Result struct { Source string `json:"source"` ResolvedQuery string `json:"resolvedQuery"` Action string `json:"action"` ActionIncomplete bool `json:"actionIncomplete"` Parameters struct { Name string `json:"name"` } `json:"parameters"` Contexts []struct { Name string `json:"name"` Parameters struct { Name string `json:"name"` } `json:"parameters"` Lifespan int `json:"lifespan"` } `json:"contexts"` Metadata struct { IntentID string `json:"intentId"` IntentName string `json:"intentName"` } `json:"metadata"` Fulfillment struct { Speech string `json:"speech"` } `json:"fulfillment"` } `json:"result"` Status struct { Code int `json:"code"` ErrorType string `json:"errorType"` } `json:"status"` } const talkBaseURL = "https://api.api.ai/v1" func inittalk() { if strings.HasPrefix(*talktoken, "@") { data, err := ioutil.ReadFile((*talktoken)[1:]) if err != nil { panic(err) } *talktoken = string(data) } if *talktoken == "" { panic(fmt.Errorf("API token for api.ai must be provided! (provide it or --disable talk)")) } } func talk(broker *tg.Broker, update tg.APIMessage) { // Must be a text message if update.Text == nil { return } text := *(update.Text) // Make sure it's aimed at Clessy if strings.Index(text, "@"+*botname) >= 0 { // @maudbot text = strings.Replace(text, "@"+*botname, "", 1) } else if idx := strings.Index(strings.ToLower(text), "clessy"); idx == 0 && len(text) > 7 { // Clessy, text = strings.TrimLeft(text[len("clessy"):], ":,") } else if text[0] != '/' && update.ReplyTo != nil && update.ReplyTo.User.Username == *botname { // Reply to Clessy (previous prompt?) which is not a command (such as unsplash), pass } else if update.Chat.Username != nil { // Private chat, pass } else { return } text = strings.TrimSpace(text) // Generate unique id for user id := strconv.FormatInt(update.User.UserID, 36) if len(id) > 36 { id = id[:36] } // Create POST body data, err := json.Marshal(QRequest{ SessionID: id, Query: text, Language: "it", }) if err != nil { log.Printf("[talk] Could not create JSON body: %s\n", err.Error()) broker.SendTextMessage(update.Chat, "ERRORE! @hamcha controlla la console!", &update.MessageID) return } // Build the request req, err := http.NewRequest("POST", talkBaseURL+"/query?v=20150910", bytes.NewReader(data)) if err != nil { log.Printf("[talk] Could not create POST request: %s\n", err.Error()) broker.SendTextMessage(update.Chat, "ERRORE! @hamcha controlla la console!", &update.MessageID) return } req.Header.Add("Authorization", "Bearer "+*talktoken) req.Header.Set("Content-Type", "application/json; charset=utf-8") client := &http.Client{} resp, err := client.Do(req) if err != nil { log.Printf("[talk] Request error: %s\n", err.Error()) broker.SendTextMessage(update.Chat, "ERRORE! @hamcha controlla la console!", &update.MessageID) return } defer resp.Body.Close() var record QResponse if err := json.NewDecoder(resp.Body).Decode(&record); err != nil { log.Printf("[talk] Could not decode JSON response: %s\n", err.Error()) broker.SendTextMessage(update.Chat, "ERRORE! @hamcha controlla la console!", &update.MessageID) return } if record.Status.ErrorType != "success" { body, _ := json.MarshalIndent(record, "", " ") log.Printf("[talk] Non-success status, full response body follows:\n%s\n", body) broker.SendTextMessage(update.Chat, "ERRORE! @hamcha controlla la console!", &update.MessageID) return } reply := record.Result.Fulfillment.Speech // Replace tokens if found if strings.Index(reply, "$") >= 0 { reply = strings.Replace(reply, "$name", update.User.FirstName, -1) } // Call command if needed if reply[0] == '#' { //TODO Find a better way? if strings.HasPrefix(reply, "#metafora") { message := "/metafora" update.Text = &message metafora(broker, update) } return } broker.SendTextMessage(update.Chat, reply, &update.MessageID) }