golang騰訊AI機械翻訳呼び出しによる中英相互通訳サービスの実現


騰訊AIマシン翻訳インターフェースへの呼び出し
前回の文字認識コードをもとに、コード構造を改善しました。 , , , http( , https), 。 http://localhost:8203/trans/to/zh?text=hello ( ) OCR文字認識
package main

import (
	"bytes"
	"crypto/md5"
	"encoding/hex"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/unrolled/secure"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"sort"
	"strings"
	"time"
)

/*
        
        id   key      ,            
          json  ,       status            
 */

var (
	//         ,   
	appId  = "*"
	appKey = "*"
)

//     
type Param struct {
	key, value string
}

func SortParams(p []Param) {
	//   
	sort.Slice(p, func(i, j int) bool {
		if p[i].key < p[j].key {
			return true
		}
		return false
	})
}

func ParamsToString(p []Param) string {
	s := ""
	for _, v := range p {
		if v.value == "" {
			continue
		}
		// value      url   
		s += v.key + "=" + url.QueryEscape(v.value) + "&"
	}
	return s[:len(s)-1]
}

func PostToTansApi(text, target string) (s []byte, ok bool) {
	client := http.Client{}
	params := make([]Param, 0, 10)
	params = append(params, Param{"app_id", appId})
	params = append(params, Param{"source", "auto"})
	params = append(params, Param{"target", target})
	params = append(params, Param{"text", text})

	//      ,       32
	params = append(params, Param{"nonce_str", "asbfiuasbhjbcuicg"})
	params = append(params, Param{"time_stamp", fmt.Sprintf("%d", time.Now().Unix())})

	//         ,  body
	params = getSign(params)
	form := ParamsToString(params)
	body := bytes.NewBufferString(form)

	request, err := http.NewRequest("POST", "https://api.ai.qq.com/fcgi-bin/nlp/nlp_texttranslate", body)
	if err != nil {
		log.Println(err)
		return
	}

	//    !!!
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	response, err := client.Do(request)
	if err != nil {
		log.Println(err)
		return
	}

	defer response.Body.Close()
	s, err = ioutil.ReadAll(response.Body)
	if err != nil {
		log.Println(err)
		return
	}

	return s, true
}

func getSign(p []Param) []Param {
	s := strings.Builder{}

	SortParams(p)
	s.WriteString(ParamsToString(p))

	s.WriteString("&app_key=" + appKey)

	// MD5
	hash := md5.New()
	hash.Write([]byte(s.String()))
	encodeToString := strings.ToUpper(hex.EncodeToString(hash.Sum(nil)))

	p = append(p, Param{"sign", encodeToString})
	return p
}

func TansToZHHandle(c *gin.Context) {
	text, ok := c.GetQuery("text")
	if !ok || text == "" {
		c.JSON(http.StatusOK, map[string]string{"status": "no", "msg": "   "})
		return
	}

	s, ok := PostToTansApi(text, "zh")
	if !ok {
		c.JSON(http.StatusOK, map[string]string{"status": "no", "msg": "        ,          "})
		return
	}
	c.JSON(http.StatusOK, map[string]string{"status": "ok", "msg": string(s)})
}

func TansToENHandle(c *gin.Context) {
	text, ok := c.GetQuery("text")
	if !ok || text == "" {
		c.JSON(http.StatusOK, map[string]string{"status": "no", "msg": "   "})
		return
	}

	s, ok := PostToTansApi(text, "en")
	if !ok {
		c.JSON(http.StatusOK, map[string]string{"status": "no", "msg": "        ,          "})
		return
	}
	c.JSON(http.StatusOK, map[string]string{"status": "ok", "msg": string(s)})
}

func AllowControl(c *gin.Context) {
	c.Header("Access-Control-Allow-Origin", "*")
}

func TlsHandler(c *gin.Context) {
	secureMiddleware := secure.New(secure.Options{
		SSLRedirect: true,
		SSLHost:     ":8203",
	})
	err := secureMiddleware.Process(c.Writer, c.Request)

	if err != nil {
		log.Println(err)
		return
	}
}

func main() {
	gin.SetMode(gin.ReleaseMode)
	r := gin.Default()
	r.Use(TlsHandler)
	r.Use(AllowControl)
	{
		r.GET("trans/to/zh", TansToZHHandle)
		r.GET("trans/to/en", TansToENHandle)
	}

	err := r.RunTLS(":8203", "*.pem", "*.key")
	if err != nil {
		panic(err)
	}
}

/*
       
r.Use(TlsHandler())
 
err := r.RunTLS(":8203", "*.pem", "*.key")
 
err := r.Run(":8203")
*/

フロントエンドの例
  • ここでは、`を押してESCの下の
  • を表示/非表示にします。
  • は参考だけを提供しています。もし私のインスタンスがアクセスできないなら、代わりにローカルオープンのサービスに変えます。http://localhost:8203/*またはその他。
  • 必要であれば、スタイルのサイズは自分で修正します。
  • うん。ちょっと使いたいですね。
    
    <html lang="ch">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Documenttitle>
        <script src="https://cdn.jsdelivr.net/npm/vue">script>
        <script src="https://unpkg.com/axios/dist/axios.min.js">script>
        <style>
            #trans-container {
                top: 200px;
                left: 200px;
                margin: 0 auto;
                border-radius: 8px;
                box-shadow: 0 0 0 -20px rgba(0, 0, 0, .2), 0 24px 38px 3px rgba(0, 0, 0, .14), 0 9px 46px 8px rgba(0, 0, 0, .12);
                position: fixed;
                background: rgba(255, 255, 255, 0.95);
                width: 150px;
                max-height: 100px;
                overflow: auto;
                opacity: 40%;
                z-index: 999999999;
            }
    
            #trans-container div p,
            #trans-container div input {
                font-weight: 100;
                padding: 0;
                margin: 0;
            }
    
            #trans-container div input{
                border-width: 0;
            }
    
            #trans-container div input:focus{
                outline: none;
            }
    
            #trans-container::-webkit-scrollbar {
                display: none;
            }
    
            [v-cloak] {
                display: none
            }
        style>
    head>
    <body>
    <div id="trans-container" @mousedown="move" v-cloak v-show="show">
        <div style="text-align: center;">
            <input type="text" v-model="text" placeholder="" @keypress.enter="send"
                   style="width: 100%;text-align: center;">
        div>
        <div>
            <p v-text="ret">p>
        div>
    div>
    body>
    <script>
        let pattern = new RegExp("[\u4E00-\u9FA5]+");
    
        function getTrans(text) {
            if (pattern.test(text)) {
                if (window.top.transapp)
                    getEN(text)
            } else {
                if (window.top.transapp)
                    getZH(text)
            }
        }
    
        function getZH(text) {
            axios.get('https:ligaofeng.top:8203/trans/to/zh?text=' + text)
                .then(function (response) {
                    let data = response.data;
                    if (data["status"] == "ok") {
                        data = data.msg;
                        data = JSON.parse(data);
                        if (data.ret!=0){
                            console.log(data.msg)
                            window.top.transapp.ret = "    ";
                            return
                        }
                        window.top.transapp.ret = data.data.target_text;
                    } else {
                        console.log(data.msg)
                        window.top.transapp.ret = "    ";
                    }
                })
                .catch(function (error) {
                    console.log(error);
                    window.top.transapp.ret = "    ";
                });
        }
    
        function getEN(text) {
            axios.get('https:ligaofeng.top:8203/trans/to/en?text=' + text)
                .then(function (response) {
                    let data = response.data;
                    if (data["status"] == "ok") {
                        data = data.msg;
                        data = JSON.parse(data);
                        if (data.ret!=0){
                            console.log(data.msg)
                            window.top.transapp.ret = "    ";
                            return
                        }
                        window.top.transapp.ret = data.data.target_text;
                    } else {
                        console.log(data.msg)
                        window.top.transapp.ret = "    ";
                    }
                })
                .catch(function (error) {
                    console.log(error);
                    window.top.transapp.ret = "    ";
                });
        }
    
        window.top.addEventListener("keypress", function (ev) {
            switch (ev.key) {
                case "`":
                    if (!window.top.transapp)
                        window.top.transapp = new Vue({
                            el: "#trans-container",
                            data: {
                                text: "",
                                ret: "",
                                positionX: 0,
                                positionY: 0,
                                show: true
                            },
                            methods: {
                                send() {
                                    if (this.text) {
                                        this.ret = "   。。。"
                                        getTrans(this.text)
                                        this.text = ""
                                    }
                                },
                                move(e) {
                                    let odiv = document.getElementById("trans-container");
                                    let disX = e.clientX - odiv.offsetLeft;
                                    let disY = e.clientY - odiv.offsetTop;
                                    document.onmousemove = (e) => {
                                        let left = e.clientX - disX;
                                        let top = e.clientY - disY;
                                        this.positionX = top;
                                        this.positionY = left;
                                        odiv.style.left = left + 'px';
                                        odiv.style.top = top + 'px';
                                    };
                                    document.onmouseup = () => {
                                        document.onmousemove = null;
                                        document.onmouseup = null;
                                    };
                                },
                            }
                        })
                    else
                        window.top.transapp.show = !window.top.transapp.show
                    break
            }
        })
    script>
    html>