kidlj / metword.extension

Browser extension for MetWord
https://metword.co
147 stars 14 forks source link

希望可以吧后端完善下,后端过于简陋 #12

Closed shiguangwl closed 1 year ago

shiguangwl commented 2 years ago

希望可以吧后端完善一下~比如单词显示界面优化,增加按日期分类,类似burning vocabulary

kidlj commented 2 years ago

👋,感谢建议,后端是指网站端吗?如果是的,我有时间想想怎么优化下。

shiguangwl commented 2 years ago

是的,网页视乎有点简陋,如果可以的话~获取翻译结果可以前端处理,用户自己配置百度翻译等第三方的翻译接口,目前请求服务器后端接口视乎有时候会没反应

yin1999 commented 2 years ago

提供一份我之前写的 service worker 直接调用 Google 翻译、阿里翻译 API 的模块,逻辑可能比较简陋:

/**
 * 
 * @param {String} SourceText 
 * @param {Object} token 
 * @param {String} SourceLanguage 
 * @returns 
 */
async function aliTranslate(SourceText, token, SourceLanguage = undefined) {
    if (!token || !token.ak || !token.sk) {
        return {
            status: 'access key or secret key has not set'
        }
    }
    // detect language
    if (!SourceLanguage) {
        const body = {
            SourceText
        }
        try {
            const res = await aliOpenAPIRequest('GetDetectLanguage', body, token.ak, token.sk)
            SourceLanguage = res.DetectedLanguage
        } catch (err) {
            return {
                status: err
            }
        }
    }
    const body = {
        FormatType: 'text',
        SourceLanguage,
        SourceText,
        TargetLanguage: 'zh',
    }
    try {
        const res = await aliOpenAPIRequest('TranslateGeneral', body, token.ak, token.sk)
        return {
            translatedText: res.Data.Translated,
            SourceLanguage,
            status: "ok"
        }
    } catch (err) {
        console.error(err)
        return {
            status: err.toString()
        }
    }
}

/**
 * 
 * @param {String} SourceText 
 * @param {Object} token 
 * @param {String} SourceLanguage 
 * @returns 
 */
async function googleTranslate(SourceText, token, SourceLanguage = undefined) {
    if (!token.key) {
        return {
            status: 'key has not set'
        }
    }
    const requestUrl = 'https://translation.googleapis.com/language/translate/v2'
    const body = {
        q: SourceText,
        target: "zh",
        format: "text"
    }
    if (SourceLanguage) {
        body.source = SourceLanguage
    }
    const headers = {
        "Content-Type": "application/json; charset=utf-8"
    }
    const url = new URL(requestUrl)

    url.searchParams.append("key", token.key)
    try {
        let res = await fetch(url, {
            method: "POST",
            body: JSON.stringify(body),
            headers
        })
        res = await res.json()
        return {
            translatedText: res.data.translations[0].translatedText,
            SourceLanguage: SourceLanguage || res.data.translations[0].detectedSourceLanguage,
            status: "ok"
        }
    } catch (err) {
        console.error(err)
        return {
            status: err.toString()
        }
    }
}

async function aliOpenAPIRequest(action, body, accessKey, secretKey) {
    const requestUrl = 'https://mt.aliyuncs.com/'
    body.AccessKeyId = accessKey
    body.Action = action
    body.Format = 'JSON'
    body.SignatureMethod = 'HMAC-SHA1'
    body.SignatureVersion = '1.0'
    body.Timestamp = new Date().toISOString()
    body.Version = '2018-10-12'
    const randomArray = crypto.getRandomValues(new Uint8Array(4))
    body.SignatureNonce = btoa(randomArray)
    const params = new URLSearchParams(body)
    params.sort()
    let encodedBody = params.toString()
    const stringToSign = 'POST&%2F&' + encodeURIComponent(encodedBody)
    const signature = await HmacSha1Digest(secretKey, stringToSign)
    encodedBody += "&Signature=" + encodeURIComponent(signature)
    const headers = {
        "Content-Type": "application/x-www-form-urlencoded"
    }
    const resp = await fetch(requestUrl, {
        method: "POST",
        body: encodedBody,
        headers
    })
    return await resp.json()
}

/**
 * 
 * @param {String} secretKey 
 * @param {String} stringToSign 
 * @returns 
 */
async function HmacSha1Digest(secretKey, stringToSign) {
    const enc = new TextEncoder()
    let key = await crypto.subtle.importKey('raw', enc.encode(secretKey + "&"), {
        name: 'HMAC',
        hash: 'SHA-1'
    }, false, ['sign'])
    let signature = await crypto.subtle.sign('HMAC', key, enc.encode(stringToSign))
    signature = String.fromCharCode(...new Uint8Array(signature))
    return btoa(signature)
}
kidlj commented 1 year ago

服务网站新增了单词本复习单词功能。感谢反馈。