Node.js:命令行翻译工具

108 阅读2分钟

实现的效果展示

在命令行中输入想要翻译的词语,即可实现翻译功能,中英文互翻

需要安装的依赖

yarn global add typescript  //用来编译ts文件成js文件 

yarn global add ts-node-dev  //安装需要在开发时运行ts文件

yarn add --dev @types/node  // 命令行库

yarn add md5  // md5 加密库

yarn add --dev @types/md5  // md5 支持ts的依赖

注册、查看、使用百度翻译

注册成功以后,打开管理控制台,可以查自己的ID和秘钥

打开【文档与支持】--→【开发者文档】--→【通用翻译】--→查看接入方式,签名生成方式等资料

得出结论:完整的请求的参数是md5(q+from+to+appid+salt+sign)

创建文件

image.png

cli.ts

#!/usr/bin/env node
import * as commander from "commander";
import { translate } from "./main";
const program = new commander.Command();

program
  .version("0.0.1")
  .name("fy")
  .usage("<English>")
  .arguments("<English>")
  .action(function (english) {
    translate(english);
  });
program.parse(process.argv);

main.js

  • 使用querystring构造query查询参数

  • 使用https.request发起https请求

注意:querystring已经被弃用了,可以进入querystring.d.ts,删除框中的代码

import * as https from "https";
import md5 from "md5";
import * as querystring from "querystring";
import { appId, appSecret } from "./private";

type ErrorMap = {
  [k: string]: string;
};

const errorMap: ErrorMap = {
  "52001": "请求超时",
  "52002": "系统错误",
  "52003": "未授权用户",
  "54000": "必填参数为空",
  "54001": "签名错误",
  "54003": "访问频率受限",
  "54004": "账户余额不足",
  "54005": "长query请求频繁",
  "58000": "客户端IP非法",
  "58001": "译文语言方向不支持",
  "58002": "服务当前已关闭",
  "90107": "认证未通过或未生效",
};

export const translate = (word: string) => {
  const salt = Math.random();
  const sign = md5(appId + word + salt + appSecret);
  let from, to;
  if (/[a-zA-Z]/.test(word[0])) {
    from = "en";
    to = "zh";
  } else {
    from = "zh";
    to = "en";
  }

  const query: string = querystring.stringify({
    q: word,
    from,
    to,
    appid: appId,
    salt,
    sign,
  });

  const options = {
    hostname: "api.fanyi.baidu.com",
    port: 443,
    path: "/api/trans/vip/translate?" + query,
    method: "GET",
  };

  const request = https.request(options, (response) => {
    let chunks: Buffer[] = [];
    response.on("data", (chunk) => {
      chunks.push(chunk);
    });
    response.on("end", () => {
      const string = Buffer.concat(chunks).toString();

      type BaiduResult = {
        error_code?: string;
        error_msg?: string;
        from: string;
        to: string;
        trans_result: {
          src: string;
          dst: string;
        }[];
      };
      const object: BaiduResult = JSON.parse(string);
      if (object.error_code) {
        console.error(errorMap[object.error_code] || object.error_msg);
        process.exit(2);
      } else {
        object.trans_result.map((obj) => {
          console.log(obj.dst);
        });
        process.exit(0);
      }
    });
  });

  request.on("error", (e) => {
    console.error(e);
  });
  request.end();
};

private.ts

如果需要公开发布代码,一定要在.gitignore中加入该文件,不然ID和秘钥就会被公开使用

export const appId = "**************";  //ID
export const appSecret = "************";  //秘钥