Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support react-native #42

Closed
vitalets opened this issue Nov 23, 2019 · 10 comments
Closed

Support react-native #42

vitalets opened this issue Nov 23, 2019 · 10 comments

Comments

@vitalets
Copy link
Owner

Currently library works only in Node.js, because it replies on packages like fs, configstore etc. It does not work in React Native out of box but technically it is possible.

It would be great to to add build for react native where usage of fs and configstore are replaced with RN asyncStorage api.

Related issues:

@JeongJun-Lee
Copy link

And it'll be also good if there is for Angular.

@Samranvirk44
Copy link

have you resolve issue Unable to resolve module 'querystring'?

@AlenToma
Copy link

AlenToma commented Feb 20, 2021

Hi, I have been trying to convert this library for react-native without using got or querystring. so far i have been doing well but now im getting somehow different json response from

json = JSON.parse(json.slice(length.length, parseInt(length, 10) + length.length));

this is the translator method please have a look you may find something i dont.

import translatorLanguage from './translatorLanguage';

export default async (
    text: string,
    opts?: { from?: string | boolean; to?: string | boolean; tld?: string }
) => {
    try {
        opts = opts || {};
        var e = undefined as { message: string; code: number } | undefined;
        var languages = new translatorLanguage();
        [opts.from, opts.to].forEach(function (lang) {
            if (lang && !languages.isSupported(lang)) {
                e = {
                    message: "The language '" + lang + "' is not supported",
                    code: 400,
                };
            }
        });
        if (e) {
           return e;
        }
        const extract = (key: string, res: string) => {
            var re = new RegExp(`"${key}":".*?"`);
            var result = re.exec(res);
            if (result !== null) {
                return result[0].replace(`"${key}":"`, '').slice(0, -1);
            }
            return '';
        };

        const objToQueryString = (obj: any) => {
            const keyValuePairs = [];
            for (const key in obj) {
                keyValuePairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]));
            }
            return keyValuePairs.join('&');
        }

        opts.from = opts.from || 'auto';
        opts.to = opts.to || 'en';
        opts.tld = opts.tld || 'com';

        opts.from = languages.getCode(opts.from.toString());
        opts.to = languages.getCode(opts.to.toString());

        var url = 'https://translate.google.' + opts.tld;
        var response = await fetch(url);
        var text = await response.text();

        var data = {
            rpcids: 'MkEWBc',
            'f.sid': extract('FdrFJe', text),
            bl: extract('cfb2h', text),
            hl: 'en-US',
            'soc-app': 1,
            'soc-platform': 1,
            'soc-device': 1,
            _reqid: Math.floor(1000 + Math.random() * 9000),
            rt: 'c',
        };
       
        url = url + '/_/TranslateWebserverUi/data/batchexecute?' + objToQueryString(data);
        let headers = new Headers({
            'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
        });
        var body = 'f.req=' + encodeURIComponent(JSON.stringify([[['MkEWBc', JSON.stringify([[text, opts.from, opts.to, true], [null]]), null, 'generic']]])) + '&';
        var res = await fetch(url, {
            method: "POST",
            headers: headers,
            body: body
        });
        if (res) {
            var ttx= await res.text();
            console.log(ttx)
            var json = (ttx).slice(6);
            var length = '';
         
            var result = {
                text: '',
                pronunciation: '',
                from: {
                    language: {
                        didYouMean: false,
                        iso: ''
                    },
                    text: {
                        autoCorrected: false,
                        value: '',
                        didYouMean: false
                    }
                },
                raw: ''
            };

            try {
                length = /^\d+/.exec(json)[0];
             
                json = JSON.parse(json.slice(length.length, parseInt(length, 10) + length.length));
                console.log(json)
                json = JSON.parse(json[0][2]);
                
                result.raw = json;
            } catch (e) {
                return result;
            }

            if (json[1][0][0][5] === undefined) {
                // translation not found, could be a hyperlink?
                result.text = json[1][0][0][0];
            } else {
                json[1][0][0][5].forEach(function (obj) {
                    if (obj[0]) {
                        result.text += obj[0];
                    }
                });
            }
            result.pronunciation = json[1][0][0][1];

            // From language
            if (json[0] && json[0][1] && json[0][1][1]) {
                result.from.language.didYouMean = true;
                result.from.language.iso = json[0][1][1][0];
            } else if (json[1][3] === 'auto') {
                result.from.language.iso = json[2];
            } else {
                result.from.language.iso = json[1][3];
            }

            // Did you mean & autocorrect
            if (json[0] && json[0][1] && json[0][1][0]) {
                var str = json[0][1][0][0][1];

                str = str.replace(/<b>(<i>)?/g, '[');
                str = str.replace(/(<\/i>)?<\/b>/g, ']');

                result.from.text.value = str;

                if (json[0][1][0][2] === 1) {
                    result.from.text.autoCorrected = true;
                } else {
                    result.from.text.didYouMean = true;
                }
            }

            return result;
        }      
    } catch (error) {
        console.log(error);
    }
    return undefined;
};


@AlenToma
Copy link

never mind I found the issue

@cook2c9
Copy link

cook2c9 commented Mar 11, 2021

never mind I found the issue

What was your solution?

@AlenToma
Copy link

Well I hade made small mistake, and overwrote property text . Anyway here the full working react-native code

import translatorLanguage from './translatorLanguage';

export default async (
    text: string,
    opts?: { from?: string | boolean; to?: string | boolean; tld?: string }
) => {
    try {
        var result = {
            text: '',
            pronunciation: '',
            from: {
                language: {
                    didYouMean: false,
                    iso: ''
                },
                text: {
                    autoCorrected: false,
                    value: '',
                    didYouMean: false
                }
            },
            raw: ''
        };


        opts = opts || {};
        var e = undefined as { message: string; code: number } | undefined;
        var languages = new translatorLanguage();
        [opts.from, opts.to].forEach(function (lang) {
            if (lang && !languages.isSupported(lang)) {
                e = {
                    message: "The language '" + lang + "' is not supported",
                    code: 400,
                };
            }
        });
        if (e) {
            return undefined;
        }
        const extract = (key: string, res: string) => {
            var re = new RegExp(`"${key}":".*?"`);
            var result = re.exec(res);
            if (result !== null) {
                return result[0].replace(`"${key}":"`, '').slice(0, -1);
            }
            return '';
        };

        const objToQueryString = (obj: any) => {
            const keyValuePairs = [];
            for (const key in obj) {
                keyValuePairs.push(key + '=' + obj[key]);
            }
            return keyValuePairs.join('&');
        }

        opts.from = opts.from || 'auto';
        opts.to = opts.to || 'en';
        opts.tld = opts.tld || 'com';

        opts.from = languages.getCode(opts.from.toString());
        opts.to = languages.getCode(opts.to.toString());

        var url = 'https://translate.google.' + opts.tld;
        var response = await fetch(url);
        var txt = await response.text();

        var data = {
            rpcids: 'MkEWBc',
            'f.sid': extract('FdrFJe', txt),
            bl: extract('cfb2h', txt),
            hl: 'en-US',
            'soc-app': 1,
            'soc-platform': 1,
            'soc-device': 1,
            _reqid: Math.floor(1000 + Math.random() * 9000),
            rt: 'c',
        };
      
        url = url + '/_/TranslateWebserverUi/data/batchexecute?' + objToQueryString(data);
        var body = 'f.req=' + encodeURIComponent(JSON.stringify([[['MkEWBc', JSON.stringify([[text, opts.from, opts.to, true], [null]]), null, 'generic']]])) + '&';
        var res = await fetch(url, {
            method: "POST",
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
              },
            body: body
        });
        if (res) {
            var ttx = await res.text();
            var json = (ttx).slice(6);
            var length = '';

      

            try {
                length = /^\d+/.exec(json)[0];

                json = JSON.parse(json.slice(length.length, parseInt(length, 10) + length.length));

                json = JSON.parse(json[0][2]);

                result.raw = json;
            } catch (e) {
                return result;
            }
            if (json[1][0][0][5] === undefined) {
                // translation not found, could be a hyperlink?
                result.text = json[1][0][0][0];
            } else {
                json[1][0][0][5].forEach(function (obj) {
                    if (obj[0]) {
                        result.text += obj[0];
                    }
                });
            }
            result.pronunciation = json[1][0][0][1];

            // From language
            if (json[0] && json[0][1] && json[0][1][1]) {
                result.from.language.didYouMean = true;
                result.from.language.iso = json[0][1][1][0];
            } else if (json[1][3] === 'auto') {
                result.from.language.iso = json[2];
            } else {
                result.from.language.iso = json[1][3];
            }

            // Did you mean & autocorrect
            if (json[0] && json[0][1] && json[0][1][0]) {
                var str = json[0][1][0][0][1];

                str = str.replace(/<b>(<i>)?/g, '[');
                str = str.replace(/(<\/i>)?<\/b>/g, ']');

                result.from.text.value = str;

                if (json[0][1][0][2] === 1) {
                    result.from.text.autoCorrected = true;
                } else {
                    result.from.text.didYouMean = true;
                }
            }

            return result;
        }
    } catch (error) {
        console.log(error);
    }
    return undefined;
};


translatorLanguage.tsx

import * as IOSLang from '../../languages/ISOLANG.json'
export default class translatorLanguage {

  lang: any = Object.assign({}, IOSLang);

  getCode(desiredLang: string) {
    if (!desiredLang) {
      return false;
    }
    var lng = this.lang;

    if (lng[desiredLang]) {
      return desiredLang;
    }
    ;
    var keys = Object.keys(lng).filter(function (key) {
      return key.toLowerCase() === desiredLang.toLowerCase();
    });

    return keys[0] || false;
  }

  isSupported(desiredLang: string | boolean) {
    return Boolean(this.getCode(desiredLang.toString()));
  }

  static GetLanguages = () => {
    var item = new translatorLanguage().lang;
    return Object.keys(item).map(function (x) { return { label: item[x].name, value: x } }).filter(x => x.label && x.value).sort((a, b) => {
      return a.label - b.label
    });
  }

  constructor() {

  }
}



@RayRama
Copy link

RayRama commented Oct 17, 2021

Well I hade made small mistake, and overwrote property text . Anyway here the full working react-native code

import translatorLanguage from './translatorLanguage';

export default async (
    text: string,
    opts?: { from?: string | boolean; to?: string | boolean; tld?: string }
) => {
    try {
        var result = {
            text: '',
            pronunciation: '',
            from: {
                language: {
                    didYouMean: false,
                    iso: ''
                },
                text: {
                    autoCorrected: false,
                    value: '',
                    didYouMean: false
                }
            },
            raw: ''
        };


        opts = opts || {};
        var e = undefined as { message: string; code: number } | undefined;
        var languages = new translatorLanguage();
        [opts.from, opts.to].forEach(function (lang) {
            if (lang && !languages.isSupported(lang)) {
                e = {
                    message: "The language '" + lang + "' is not supported",
                    code: 400,
                };
            }
        });
        if (e) {
            return undefined;
        }
        const extract = (key: string, res: string) => {
            var re = new RegExp(`"${key}":".*?"`);
            var result = re.exec(res);
            if (result !== null) {
                return result[0].replace(`"${key}":"`, '').slice(0, -1);
            }
            return '';
        };

        const objToQueryString = (obj: any) => {
            const keyValuePairs = [];
            for (const key in obj) {
                keyValuePairs.push(key + '=' + obj[key]);
            }
            return keyValuePairs.join('&');
        }

        opts.from = opts.from || 'auto';
        opts.to = opts.to || 'en';
        opts.tld = opts.tld || 'com';

        opts.from = languages.getCode(opts.from.toString());
        opts.to = languages.getCode(opts.to.toString());

        var url = 'https://translate.google.' + opts.tld;
        var response = await fetch(url);
        var txt = await response.text();

        var data = {
            rpcids: 'MkEWBc',
            'f.sid': extract('FdrFJe', txt),
            bl: extract('cfb2h', txt),
            hl: 'en-US',
            'soc-app': 1,
            'soc-platform': 1,
            'soc-device': 1,
            _reqid: Math.floor(1000 + Math.random() * 9000),
            rt: 'c',
        };
      
        url = url + '/_/TranslateWebserverUi/data/batchexecute?' + objToQueryString(data);
        var body = 'f.req=' + encodeURIComponent(JSON.stringify([[['MkEWBc', JSON.stringify([[text, opts.from, opts.to, true], [null]]), null, 'generic']]])) + '&';
        var res = await fetch(url, {
            method: "POST",
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
              },
            body: body
        });
        if (res) {
            var ttx = await res.text();
            var json = (ttx).slice(6);
            var length = '';

      

            try {
                length = /^\d+/.exec(json)[0];

                json = JSON.parse(json.slice(length.length, parseInt(length, 10) + length.length));

                json = JSON.parse(json[0][2]);

                result.raw = json;
            } catch (e) {
                return result;
            }
            if (json[1][0][0][5] === undefined) {
                // translation not found, could be a hyperlink?
                result.text = json[1][0][0][0];
            } else {
                json[1][0][0][5].forEach(function (obj) {
                    if (obj[0]) {
                        result.text += obj[0];
                    }
                });
            }
            result.pronunciation = json[1][0][0][1];

            // From language
            if (json[0] && json[0][1] && json[0][1][1]) {
                result.from.language.didYouMean = true;
                result.from.language.iso = json[0][1][1][0];
            } else if (json[1][3] === 'auto') {
                result.from.language.iso = json[2];
            } else {
                result.from.language.iso = json[1][3];
            }

            // Did you mean & autocorrect
            if (json[0] && json[0][1] && json[0][1][0]) {
                var str = json[0][1][0][0][1];

                str = str.replace(/<b>(<i>)?/g, '[');
                str = str.replace(/(<\/i>)?<\/b>/g, ']');

                result.from.text.value = str;

                if (json[0][1][0][2] === 1) {
                    result.from.text.autoCorrected = true;
                } else {
                    result.from.text.didYouMean = true;
                }
            }

            return result;
        }
    } catch (error) {
        console.log(error);
    }
    return undefined;
};

translatorLanguage.tsx

import * as IOSLang from '../../languages/ISOLANG.json'
export default class translatorLanguage {

  lang: any = Object.assign({}, IOSLang);

  getCode(desiredLang: string) {
    if (!desiredLang) {
      return false;
    }
    var lng = this.lang;

    if (lng[desiredLang]) {
      return desiredLang;
    }
    ;
    var keys = Object.keys(lng).filter(function (key) {
      return key.toLowerCase() === desiredLang.toLowerCase();
    });

    return keys[0] || false;
  }

  isSupported(desiredLang: string | boolean) {
    return Boolean(this.getCode(desiredLang.toString()));
  }

  static GetLanguages = () => {
    var item = new translatorLanguage().lang;
    return Object.keys(item).map(function (x) { return { label: item[x].name, value: x } }).filter(x => x.label && x.value).sort((a, b) => {
      return a.label - b.label
    });
  }

  constructor() {

  }
}

Save in where this file and how to calling the function?

@AidanWelch
Copy link

I was able to implement it with webpack using 'node-stdlib-browser' and 'setimmediate' I imagine it could be fairly easily implemented in a similar way for react.

@AidanWelch
Copy link

Okay, I made an axios port that doesn't require either of those here: https://github.com/AidanWelch/google-translate-api

@vitalets
Copy link
Owner Author

I've added React-native support in new beta release v9.
Please check it out and feel free to reopen if needed.
In my tests with [email protected] everything works fine 🥳

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants