Advertisement
Guest User

Untitled

a guest
Apr 25th, 2018
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 11.20 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4.     "bytes"
  5.     "database/sql"
  6.     "encoding/json"
  7.     "fmt"
  8.     "io/ioutil"
  9.     "log"
  10.     "net/http"
  11.     "os"
  12.     "path/filepath"
  13.     "strings"
  14.  
  15.     _ "github.com/go-sql-driver/mysql"
  16.     "github.com/gorilla/mux"
  17.     "github.com/ivahaev/amigo"
  18.     "github.com/tidwall/gjson"
  19. )
  20.  
  21. //Config настройки
  22. type Config struct {
  23.     Database struct {
  24.         User string `json:"user"`
  25.         Pass string `json:"pass"`
  26.         Host string `json:"host"`
  27.         Name string `json:"name"`
  28.     } `json:"database"`
  29.     Manager struct {
  30.         User string `json:"user"`
  31.         Pass string `json:"pass"`
  32.         Host string `json:"host"`
  33.     } `json:"manager"`
  34.     Bot struct {
  35.         Art  string `json:"bot"`
  36.         Auth string `json:"auth"`
  37.         Url  string `json:"url"`
  38.     } `json:"bot"`
  39. }
  40.  
  41. var (
  42.     db     *sql.DB
  43.     config Config
  44.     a      *amigo.Amigo
  45. )
  46.  
  47. func art(w http.ResponseWriter, r *http.Request) {
  48.  
  49.     if match := r.Header.Get("Authorization"); match != "" {
  50.         if strings.Contains(match, ""); match == "W7Vw}7Rj}_er]nSCvM" {
  51.  
  52.             body, err := ioutil.ReadAll(r.Body)
  53.             CheckErr(err, "Ошибка боди")
  54.             var cont, n string
  55.             //----распарс json из dialogflow
  56.             ra := gjson.GetBytes(body, "result.action")
  57.             action := ra.String()
  58.  
  59.             rs := gjson.GetBytes(body, "result.fulfillment.speech")
  60.             speech := rs.String()
  61.  
  62.             ss := gjson.GetBytes(body, "sessionId")
  63.             session := ss.String()
  64.  
  65.             r := gjson.GetBytes(body, "result.fulfillment.messages.1.payload.redirect")
  66.             redirect := r.String()
  67.  
  68.             //----распарс json из dialogflow
  69.  
  70.             log.Printf("Action %v\n", action)
  71.  
  72.             switch action {
  73.             case "get_data":
  74.                 {
  75.                     //log.Printf("Start%v\n",action)
  76.                     tel := phone(session)
  77.                     //tel := "79789998899"
  78.                     status, err, b := JSON(action, tel, "")
  79.                     log.Printf("Ошибка от JSON %v\n",err)
  80.  
  81.  
  82.                     if status != "ok" {
  83.                         speak("Назовите ваш номер договора состоящий из пяти цифр. говорите по одной цифре", w)
  84.                         long(session)
  85.  
  86.                     } else {
  87.                         u := gjson.GetBytes(b, "response.street")
  88.                         street := u.String()
  89.  
  90.                         h := gjson.GetBytes(b, "response.house")
  91.                         home := h.String()
  92.  
  93.                         k := gjson.GetBytes(b, "response.flat")
  94.                         flat := k.String()
  95.  
  96.                         c := gjson.GetBytes(b, "response.id")
  97.                         cont = c.String()
  98.  
  99.                         if flat != "" {
  100.                             speak(speech+` `+street+` дом `+home+`. квартира `+flat+`. Скажите, адрес вашего подключения правильный или нет?`, w)
  101.  
  102.                         } else {
  103.                             speak(speech+` `+street+` дом `+home+`. Скажите адрес вашего подключения правильный или нет?`, w)
  104.                         }
  105.                     }
  106.  
  107.                 }
  108.             case "contract":
  109.                 {
  110.                     //Распарсиваем номер договора и переводим из массива в строку
  111.                     r := gjson.GetBytes(body, `result.contexts.#[name="contract"].parameters.number1`)
  112.                     var stringList []string
  113.                     for _, name := range r.Array() {
  114.                         stringList = append(stringList,name.String())
  115.                     }
  116.                     n = strings.Join(stringList,"")
  117.                     log.Printf("Тип %T переменная %v",n,n)
  118.                     //--------------------------------------------------------------
  119.                     if len(n) != 5 {
  120.                         speak("Вы назвали не правильное количество цифр, повторите 5 цифр вашего договора", w)
  121.                         long(session)
  122.                     }else{
  123.                         speak(speech,w)
  124.                     }
  125.                 }
  126.             case "yes":{
  127.                 speak(speech,w)
  128.                 log.Printf("Тип %T переменная %v",n,n)
  129.                 cont = n
  130.             }
  131.                
  132.             case "activate":
  133.                 {
  134.                     tel := phone(session)
  135.                     status, err, _ := JSON(action, tel, cont)
  136.  
  137.                     log.Printf("Статус %v\n, Ошибка %v\n", status, err)
  138.                     //Три попытки подключения услуги
  139.                     if status != "ok" {
  140.                         for i := 1; i < 4; i++ {
  141.                             log.Printf("Попытка номер %v\n", i)
  142.                             status, _, _ := JSON(action, tel, cont)
  143.                             if status == "ok" {
  144.                                 speak(speech, w)
  145.                                 hangup(session)
  146.                                 break
  147.                             }
  148.                         }
  149.                         //Три попытки подключения услуги
  150.                         redir(session, redirect, "Подключение услуги в данный момент не возможно. Соединяю вас с оператором ", w)
  151.                     } else {
  152.                         speak(speech, w)
  153.                         hangup(session)
  154.                     }
  155.  
  156.                 }
  157.             case "no":
  158.                 {
  159.                     var count int
  160.  
  161.                     res, err := db.Exec(`Update ziax set fallback_attempts = fallback_attempts + 1 where id_chat = ?`, session)
  162.                     CheckErr(err, "Ошибка записи в базу(Update)")
  163.  
  164.                     affect, err := res.RowsAffected()
  165.                     CheckErr(err, "Ошибка RowsAffected")
  166.                     fmt.Printf("RowsAffected %v\n", affect)
  167.  
  168.                     err = db.QueryRow(`select fallback_attempts from ziax where id_chat=?`, session).Scan(&count)
  169.  
  170.                     switch {
  171.                     case err == sql.ErrNoRows:
  172.                         log.Printf("No channel with that ID.")
  173.                     case err != nil:
  174.                         log.Printf("Error of QueryRow for count %v\n", err)
  175.                     default:
  176.                         log.Printf("count is %v\n", count)
  177.                         log.Printf("count is %s\n", speech)
  178.                     }
  179.                     if count < 2 {
  180.                         speak(speech, w)
  181.                         long(session)
  182.  
  183.                     } else {
  184.                         redir(session, redirect, "Извините я не понимаю Вас. Соединяю с оператором", w)
  185.                     }
  186.                 }
  187.  
  188.  
  189.             case "hangup":
  190.                 {
  191.                     speak(speech, w)
  192.                     hangup(session)
  193.  
  194.                 }
  195.             case "redirect":
  196.                 {
  197.                     redir(session, redirect, speech, w)
  198.                 }
  199.  
  200.             case "input.unknown":
  201.                 {
  202.                     var count int
  203.  
  204.                     res, err := db.Exec(`Update ziax set fallback_attempts = fallback_attempts + 1 where id_chat = ?`, session)
  205.                     CheckErr(err, "Ошибка записи в базу(Update)")
  206.  
  207.                     affect, err := res.RowsAffected()
  208.                     CheckErr(err, "Ошибка RowsAffected")
  209.                     fmt.Printf("RowsAffected %v\n", affect)
  210.  
  211.                     err = db.QueryRow("select fallback_attempts from ziax where id_chat=?", session).Scan(&count)
  212.  
  213.                     switch {
  214.                     case err == sql.ErrNoRows:
  215.                         log.Printf("No channel with that ID.")
  216.                     case err != nil:
  217.                         log.Printf("Error of QueryRow for count %v\n", err)
  218.                     default:
  219.                         log.Printf("count is %v\n", count)
  220.                         log.Printf("count is %s\n", speech)
  221.                     }
  222.  
  223.                     if count < 2 {
  224.                         speak(speech, w)
  225.  
  226.                     } else {
  227.                         redir(session, redirect, "Извините я не понимаю Вас. Соединяю с оператором", w)
  228.                     }
  229.                 }
  230.             }
  231.         } else {
  232.             log.Printf("Не верный ключ")
  233.             w.WriteHeader(http.StatusUnauthorized)
  234.         }
  235.     }
  236. }
  237. func long(session string)  {
  238.     channel := channels(session)
  239.     _, err := a.Action(map[string]string{"Action": "Setvar", "Channel": channel, "Variable": "answer", "Value": "long"})
  240.     CheckErr(err, "Ошибка отправки данных в канала")
  241. }
  242. func speak(speech string, w http.ResponseWriter) {
  243.     w.WriteHeader(http.StatusOK)
  244.     fmt.Fprintf(w, `{"speech":"`+speech+`","data":"","source":"","contextOut":[]}`)
  245. }
  246.  
  247. func redir(session, redirect, speech string, w http.ResponseWriter) {
  248.     channel := channels(session)
  249.     speak(speech, w)
  250.     _, err := a.Action(map[string]string{"Action": "Setvar", "Channel": channel, "Variable": "redirect", "Value": redirect})
  251.     CheckErr(err, "Ошибка отправки данных в канал (redirect)")
  252. }
  253. func hangup(session string) {
  254.     channel := channels(session)
  255.     _, err := a.Action(map[string]string{"Action": "Setvar", "Channel": channel, "Variable": "hangup", "Value": "yes"})
  256.     CheckErr(err, "Ошибка отправки данных в канала")
  257. }
  258.  
  259. func channels(session string) (channel string) {
  260.  
  261.     err := db.QueryRow(`select channel from ziax where id_chat=?`, session).Scan(&channel)
  262.     switch {
  263.     case err == sql.ErrNoRows:
  264.         log.Printf("No channel with that ID.")
  265.     case err != nil:
  266.         log.Printf("%v\n", err)
  267.     default:
  268.         log.Printf("channels is %s\n", channel)
  269.     }
  270.     return channel
  271. }
  272.  
  273. func phone(ses string) (tel string) {
  274.     err := db.QueryRow(`select tel from ziax where id_chat=?`, ses).Scan(&tel)
  275.     switch {
  276.     case err == sql.ErrNoRows:
  277.         log.Printf("No tel with that ID.")
  278.     case err != nil:
  279.         log.Printf("%v\n", err)
  280.     default:
  281.         log.Printf("tel is %s\n", tel)
  282.     }
  283.     return tel
  284. }
  285.  
  286. // JSON для отправки eventbus
  287. func JSON(cmd, phone, contract string) (string, string, []byte) {
  288.  
  289.     vid := map[string]interface{}{
  290.         "auth": config.Bot.Auth,
  291.         "cmd":  cmd,
  292.         "params": map[string]string{
  293.             "phone":    phone,
  294.             "contract": contract,
  295.         },
  296.     }
  297.     log.Printf("VID %s\n", vid)
  298.     vidEvent, err := json.Marshal(vid)
  299.     if err != nil {
  300.         log.Printf("JSON не отправлен %v\n", err)
  301.         return "", "", nil
  302.     }
  303.     body := httpPOST(vidEvent)
  304.  
  305.     log.Printf("%s\n", vidEvent)
  306.  
  307.     st := gjson.GetBytes(body, "status")
  308.     no := gjson.GetBytes(body, "errno")
  309.  
  310.     return st.String(), no.String(), body
  311.  
  312. }
  313.  
  314. func httpPOST(data []byte) []byte {
  315.     req, err := http.NewRequest("POST", config.Bot.Url, bytes.NewBuffer(data))
  316.     req.Header.Set("Content-Type", "application/json")
  317.     if err != nil {
  318.         log.Printf("Ошибка Header%v\n", err)
  319.     }
  320.     client := &http.Client{}
  321.     res, err := client.Do(req)
  322.     if err != nil {
  323.         log.Printf("Ошибка Do%v\n", err)
  324.         return nil
  325.     }
  326.     defer func() {
  327.         if err = res.Body.Close(); err != nil {
  328.             log.Printf("defer error%v\n", err)
  329.         }
  330.     }()
  331.     //Забираем ответ
  332.     body, err := ioutil.ReadAll(res.Body)
  333.     if err != nil {
  334.         log.Printf("Error httpPost answer:%v\n", err)
  335.         return nil
  336.     }
  337.     return body
  338. }
  339.  
  340. //Conf Загружаем файл с настройками
  341. func Conf() {
  342.     configFile, err := ioutil.ReadFile("/var/www/html/ziaxlk/config/config.json")
  343.     if err != nil {
  344.         log.Printf("Конфиг не найден")
  345.         panic(err)
  346.     }
  347.     err = json.Unmarshal(configFile, &config)
  348.     CheckErr(err, "Ошибка JSON(9)")
  349.  
  350. }
  351. func CheckErr(err error, s string) {
  352.     if err != nil {
  353.         log.Printf(s+":%v\n", err)
  354.     }
  355. }
  356. func main() {
  357.  
  358.     Conf()
  359.     pwd, err := filepath.Abs(filepath.Dir(os.Args[0]))
  360.     if err != nil {
  361.         panic(err)
  362.     }
  363.     //Настройки записи логов
  364.     f, err := os.OpenFile(pwd+"/art.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0600)
  365.     CheckErr(err, "error opening file")
  366.     defer func() {
  367.         if err = f.Close(); err != nil {
  368.             log.Printf("defer error%v\n", err)
  369.         }
  370.     }()
  371.  
  372.     log.SetOutput(f)
  373.  
  374.     //Подключаемя к AMI
  375.     settings := &amigo.Settings{Username: config.Manager.User, Password: config.Manager.Pass, Host: config.Manager.Host}
  376.     a = amigo.New(settings)
  377.     a.Connect()
  378.     // Listen for connection events
  379.     a.On("connect", func(message string) {
  380.         log.Printf("Connected %v\n", message)
  381.     })
  382.     a.On("error", func(message string) {
  383.         println("Connection error: %v\n", message)
  384.     })
  385.     log.Printf("into!")
  386.     //Подключение к DB
  387.     db, err = sql.Open("mysql", config.Database.User+":"+config.Database.Pass+"@tcp("+config.Database.Host+")/"+config.Database.Name)
  388.     if err != nil {
  389.         log.Printf("Ошибка подключения к DB %v\n", err)
  390.         panic(err)
  391.     }
  392.     defer func() {
  393.         if err = db.Close(); err != nil {
  394.             panic(err)
  395.         }
  396.     }()
  397.  
  398.     r := mux.NewRouter()
  399.     r.HandleFunc("/", art)
  400.     err = http.ListenAndServe(":"+config.Bot.Art, r)
  401.     CheckErr(err, "Ошибка подключения к порту")
  402. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement