JavaScript基于ChatGPT API实现划词翻译浏览器脚本

作者:狂奔滴小马 时间:2024-04-22 12:52:27 

前言

最近 GitHub 上有个基于 ChatGPT API 的浏览器脚本,openai-translator, 短时间内 star 冲到了 9.7k, 功能上除了支持翻译外,还支持润色和总结功能,除了浏览器插件外,还使用了 tauri 打包了一个桌面客户端,那抛开 tauri 是使用 rust 部分,那浏览器部分实现还是比较简单的,今天我们就来手动实现一下。

openAI 提供的接口

比如我们可以复制以下代码,在浏览器控制台中发起请求,就可以完成翻译

//这是示例
const OPENAI_API_KEY = "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";

const prompt = `Translate this into Chinese:
       hello world`;
const res = await fetch("https://api.openai.com/v1/completions", {
 method: "POST",
 headers: {
   "Content-Type": "application/json",
   authorization: `Bearer ${OPENAI_API_KEY}`,
 },
 body: JSON.stringify({
   model: "text-davinci-003",
   prompt,
   max_tokens: 1000,
   temperature: 0,
 }),
});
const response = await res.json();

const result = response.choices[0].text;

上述代码中 OPONAI_API_KEY 需要替换成你自己的。

实现划词翻译

划词翻译是一种常见的网页功能,用户选择一个单词或一段文本时,自动弹出一个小窗口,显示该单词或文本的翻译。

1.首先,在 HTML 页面中添加一个空的 DIV 元素和一个触发翻译的按钮

let keyword;
const translation = document.createElement("div");
translation.id ="translation";
const icon = document.createElement("img");
icon.style.width ="30px";
icon.style.height = "30px";
icon.src ="http://example.com/icon.png";
translation.appendChild(icon)

2.为页面添加一个鼠标抬起事件 * ,当用户选择一段文本时,设置搜索关键词。

document.addEventListener("mouseup", (event) => {
 const selection = window.getSelection().toString().trim();
 if (selection) {
   keyword=selection;
 }
});

3.鼠标点击执行翻译逻辑。可以使用 AJAX 请求从后台获取翻译结果并将其显示在 DIV 元素中。

function translate(){
 if(keyword){
   // 执行翻译逻辑
 }
}
icon.addEventListener("mouseover", translate);

4.在 CSS 样式表中为 DIV 元素添加样式,使其浮动在页面上显示。

#translation {
 position: fixed;
 top: 10px;
 right: 10px;
 max-width: 300px;
 padding: 5px;
 background-color: #f7f7f7;
 border: 1px solid #ccc;
 box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.1);
 z-index: 9999;
}

以上这些步骤就能实现划词翻译的基本功能,一起来看下效果。

JavaScript基于ChatGPT API实现划词翻译浏览器脚本

react + antd 实现

上面的代码只是实现了一个最简单的版本,样式也不够美观,因此我们可以使用 webpack + react + antd 来实现一个现代化的插件, 这里我使用一个之前创建的模版tampermonkey-starter。

使用 antd 的 Popover 组件来显示,使用 react 重构下js代码,我们就可以实现如下效果。

JavaScript基于ChatGPT API实现划词翻译浏览器脚本

点击翻译按钮,就会通过接口请求,将翻译结果显示在下方。但是翻译结果需要等 api 完全返回,才会显示出来,这样会等待较慢,我们可以使用 Stream,OpenAI 的接口支持流渲染吗,这样结果就会一个字一个字蹦出来。

import { createParser } from "eventsource-parser";

const translate = async (text: string) => {
   const resp = await fetch("https://api.openai.com/v1/completions", {
     method: "POST",
     headers: {
       "Content-Type": "application/json",
       authorization:
         `Bearer ${OPENAI_API_KEY}`,
     },
     body: JSON.stringify({
       model: "text-davinci-003",
       prompt: `Translate this into Chinese:
         ${text}`,
       max_tokens: 1000,
       temperature: 0,
       frequency_penalty: 0,
       stream: true,
     }),
   });
   if (resp.status !== 200) {
     const res = await resp.json();
     setLoading(false);
     console.error(res);
     return;
   }
   const parser = createParser((event) => {
     if (event.type === "event") {
       const data = event.data;
       if (data === "[DONE]") {
         setLoading(false);
       }
       try {
         let json = JSON.parse(event.data);
         setResult((prev) => {
           return prev + json.choices[0].text;
         });
       } catch (error) {
         console.log(error);
       }
     }
   });
   const data = resp.body;
   if (!data) {
     console.log("Error: No data received from API");
     return;
   }
   const reader = resp.body.getReader();
   try {
     while (true) {
       const { done, value } = await reader.read();
       if (done) {
         setLoading(false);
         break;
       }
       const str = new TextDecoder().decode(value);
       parser.feed(str);
     }
   } finally {
     reader.releaseLock();
   }
 };

在上面代码中,我们使用 fetch API 发送了一个 HTTP 请求,并在响应中获取了一个可读流。我们可以使用 getReader 方法获取一个读取器对象,并使用它来处理流数据,使用了 eventsource-parser这个包来解析服务器推送(Server-sent events)的数据。

这样响应的内容就会根据Server-sent events(服务器发送的事件)逐个显示了。

JavaScript基于ChatGPT API实现划词翻译浏览器脚本

文本转语音

一般翻译插件都有语音播放的功能,我们可以利用 可以使用Web Speech API。此API提供了两个语音合成接口:SpeechSynthesisSpeechSynthesisUtterance

function speak(text) {
 if ('speechSynthesis' in window) {
   const utterance = new SpeechSynthesisUtterance(text);
   utterance.voice = speechSynthesis.getVoices()[0];
   utterance.pitch = 1;
   utterance.rate = 1;
   speechSynthesis.speak(utterance);
 }
}

然后直接调用这个函数,传入需要朗读的文本,就可以实现语音播放

speak('Hello, world!');

小结

本文介绍了如何实现划词翻译的基本功能,包括使用 OpenAI 提供的接口进行翻译、在 HTML 页面中添加触发翻译的按钮和鼠标抬起事件监听事件、使用 AJAX 请求从接口获取翻译结果并将其显示在 DIV 元素中等。同时还介绍了如何使用 webpack + react + antd 实现一个现代化的插件,并利用 Web Speech API 实现语音播放功能。

来源:https://juejin.cn/post/7215517443728130106

标签:JavaScript,ChatGPT,API,翻译
0
投稿

猜你喜欢

  • 对Python强大的可变参数传递机制详解

    2021-06-23 02:54:09
  • SQL SERVER 数据库备份代码实例

    2024-01-22 02:25:00
  • python实现大文本文件分割成多个小文件

    2022-02-18 12:36:06
  • Python实现程序的单一实例用法分析

    2023-01-08 11:38:14
  • python xlwt如何设置单元格的自定义背景颜色

    2022-07-25 10:41:05
  • 解析SQL Server中数据库快照的工作原理

    2009-02-19 17:04:00
  • 如何测试字符串的长度?

    2009-11-11 20:02:00
  • MySQLMerge存储引擎

    2024-01-14 07:39:25
  • asp如何读取文本文件的内容?

    2009-11-18 20:55:00
  • python多进程间通信代码实例

    2023-10-06 20:22:17
  • MySql数据库之alter表的SQL语句集合

    2024-01-21 05:31:24
  • python 爬取古诗文存入mysql数据库的方法

    2024-01-28 13:35:26
  • 详解Python用户登录接口的方法

    2021-10-09 23:26:48
  • Python获取Windows或Linux主机名称通用函数分享

    2023-11-29 06:09:25
  • 在Python文件中指定Python解释器的方法

    2023-06-24 13:22:50
  • 面试官常问之说说js中var、let、const的区别

    2024-05-09 15:06:58
  • JavaScript基本数据类型及值类型和引用类型

    2024-05-10 13:59:39
  • Python得到弹幕并保存到Excel中怎么设置

    2021-04-04 16:42:22
  • Js 随机数产生6位数字

    2024-05-02 17:31:03
  • sql server数据库最大Id冲突问题解决方法之一

    2012-01-05 19:28:42
  • asp之家 网络编程 m.aspxhome.com