【更新45】虎绿林ChatGPT机器人代码

@Ta 2023-02-19发布,2023-09-26修改 21482点击
评论关闭

最近更新日志

完整更新日志在底部。

  • 45:openai网站添加了内容安全策略,禁止加载外站脚本,所以现在必须安装“Disable Content-Security-Policy”扩展然后对chatgpt聊天页面启用,机器人脚本才能正常加载。

  • 44:支持在油猴脚本中预定义用户名和密码,方便无人值守部署。
    如果document.hu60Userdocument.hu60Pwd为空,则会弹出prompt对话框询问用户名密码。
    如果两者均不为空,则无论如何都不会弹出alertprompt对话框。


@老虎会游泳 启动该机器人的步骤:

  1. 使用最新版的Chrome谷歌浏览器或Firefox火狐浏览器,不要使用QQ浏览器、360浏览器等,不保证兼容。
  2. 安装油猴插件:https://www.tampermonkey.net/
  3. 在油猴里添加新脚本,粘贴如下代码并保存:
// ==UserScript==
// @name         虎绿林ChatGPT机器人
// @namespace    https://hu60.cn/
// @version      1.0
// @description  把ChatGPT接入hu60wap6网站程序
// @author       老虎会游泳
// @match        https://chat.openai.com/*
// @icon         https://hu60.cn/favicon.ico
// @grant        none
// ==/UserScript==

document.hu60User = ''; // 虎绿林用户名
document.hu60Pwd = ''; // 虎绿林密码
document.hu60AdminUids = [1, 19346, 15953]; // 机器人管理员uid,管理员可以发“@ChatGPT,刷新页面”来重启机器人
document.hu60Domain = 'https://hu60.cn';    // 如果要对接其他网站,请修改此处的域名
var script = document.createElement("script");
script.src = document.hu60Domain + '/tpl/jhin/js/chatgpt/chatgpt.js?r=' + (new Date().getTime());
document.head.appendChild(script);
  1. 打开 https://chat.openai.com/ 并登录。然后去Chrome应用商店安装“Always Disable Content-Security-Policy”扩展,并对该站启用。因为openai网站添加了内容安全策略,禁止加载外站脚本,所以必须启用该扩展关闭安全策略,机器人脚本才能正常加载。

  2. 在来到 https://chat.openai.com/chat 页面时,会弹出输入虎绿林用户名密码的提示框。
    如果你要把机器人接入虎绿林,请注册一个新帐号。使用现有帐号运行机器人将被删帖或禁言
    输入新帐号用户名密码后,机器人即启动,保持页面不要关闭。
    机器人会使用你在此处输入的帐号与其他用户进行对话,在虎绿林用其他帐号@该帐号即可尝试对话。
    注意,使用该帐号自己@自己是不会有反应的,必须用另一个账号来和机器人对话。

  3. 页面必须保持电脑版,机器人才能正常工作。如果因为屏幕分辨率太低,页面自动变成手机版,请用缩放功能缩小网页,直到它变成电脑版。手机版和电脑版的区别在于,手机版顶部左上角是菜单按钮,右上角是加号,而电脑版没有顶部菜单。

  4. 建议按F12打开开发者控制台(按F12,点“控制台”或“Console”),可以看到机器人的运行情况,而且好像能提升机器人运行的稳定性。

  5. 如何切换登录的帐号?按F12打开开发者工具,点“控制台”或“Console”,然后输入以下代码并回车:

    login(true)
    

    将会重新弹出用户名密码输入框。

2023-02-23 14-39-56 的屏幕截图.png(293.18 KB)

如何把机器人接入其他类型的网站?

你可以在油猴脚本的末尾添加一个自定义主循环,用于把机器人接入其他类型的网站。以下是一个例子:

document.run = async function() {
    while (true) {
        try {
            // 访问你的网站获取要发给ChatGPT的内容
            // 网站必须是https的,否则连不上。
            // 此外网站还必须设置 Access-Control-Allow-Origin: * 头信息,否则也连不上。
            let response = await fetch('https://example.com/my-message.php');

            // 假设获取到的信息是JSON,把它转换成JSON对象
            // 网站必须设置 content-type: application/json 头信息,否则转换会失败。
            let messages = response.json();

            // 假设JSON结构是这样:
            // {"data": [
            //    {"uid":3, "text":"@ChatGPT,你好"},
            //    {"uid":2, "text":"@ChatGPT,我有一个问题"},
            //    {"uid":1, "text":"@ChatGPT,刷新页面"},
            // ]}
            let exceptionCount = 0;
            for (let i=0; i<messages.data.length; i++) {
                // 要发给ChatGPT的话,开头包含的“@机器人名称,”会被后续流程自动去除。
                // 开头写“@机器人名称 2,”可以选择第二个ChatGPT模型(Legacy模型,仅限ChatGPT Plus用户)。
                let text = messages.data.text;

                // 用户id,可以是字符串,所以给出用户名也是可以的。
                let uid = messages.data.uid;

                try {
                    // 把对话发给ChatGPT
                    // 返回的 modelIndex 是为对话选择的模型id(从0开始编号)
                    // 模型id和序号的对应关系见 chatgpt.js 里的 modelMap 变量
                    let modelIndex = await sendRequest(text, uid);

                    // 从ChatGPT读取回复
                    let replyText = await readReply();

                    // 发送回复到你的网站
                    // 创建一个POST表单
                    let formData = new FormData();
                    formData.append('token', '用于用户身份验证的密钥');
                    formData.append('reply', replyText); // 回复内容

                    // 提交POST表单
                    // 网站必须是https的,否则连不上。
                    // 此外网站还必须设置 Access-Control-Allow-Origin: * 头信息,否则也连不上。
                    let response = await fetch('https://example.com/my-reply.php', {
                        body: formData,
                        method: "post",
                        redirect: "manual" // 不自动重定向
                    });

                    // 在控制台打印提交结果
                    if (response.type == 'opaqueredirect') {
                        console.log('提交后收到重定向(目标网址未知,根据标准,浏览器不告诉我们),不清楚提交是否成功');
                    } else {
                        let result = await response.text();
                        console.log('提交结果', result);
                    }

                    // 避免操作太快
                    await sleep(100);
                } catch (ex) {
                    exceptionCount++;  // 统计异常次数
                    console.error(ex); // 打印异常到控制台
                    await sleep(1000); // 异常后等久一点
                }

                // 重命名会话
                await renameWant();
            }

            // 执行管理员命令(比如“刷新页面”)
            await runAdminCommand();

            // 异常太多,自动刷新页面
            if (exceptionCount > 0 && exceptionCount >= messages.data.length) {
                location.reload();
            }

            // 限制拉取信息的速度,避免对自己的网站造成CC攻击
            await sleep(1000);
        } catch (ex) {
            console.error(ex);
            await sleep(1000);
        }
    }
}

ChatGPT会话保活机器人

定期与ChatGPT对话,防止连接断开会话丢失。

// ==UserScript==
// @name         ChatGPT保活机器人
// @namespace    https://hu60.cn/
// @version      1.0
// @description  每分钟问一次还在吗
// @author       老虎会游泳
// @match        https://chat.openai.com/chat*
// @icon         https://hu60.cn/favicon.ico
// @grant        none
// ==/UserScript==

document.run = async function() {
    // 这里写每次刷新页面后自动发送的内容
    await sendText('你好,我是老虎会游泳,初次见面请多关照', 0, 1);

    while (true) {
        try {
            await sleep(60000);
            if (document.querySelector(chatBoxSelector).textContent == '') {
                await sendText('还在吗', 0, 1);
            }
        } catch (ex) {
            console.error(ex);
            await sleep(1000);
        }
    }
}

document.hu60AdminUids = []; // 不需要设置
document.hu60Domain = 'https://hu60.cn'; // 不需要修改
var script = document.createElement("script");
script.src = document.hu60Domain + '/tpl/jhin/js/chatgpt/chatgpt.js?r=' + (new Date().getTime());
document.head.appendChild(script);

历史更新日志

  • 20: 按用户隔离会话;交换模型1和模型2(默认模型改为Default)。

  • 26:修复同时收到多条@消息时后发送的被先处理的问题。

  • 27:主动等待内容出现,减少读取回复出错的可能性;修复代码高亮没有指定编程语言时turndown报错的问题。

  • 28:添加结束会话功能(@ChatGPT,结束会话);为新会话添加标记([新会话] @老虎会游泳,……)。

  • 29:修复虎绿林接口报错导致会话重命名失败的问题。

  • 30:不再无限期等待回答结束,最多等120秒,防止回答始终不结束导致机器人卡住。

  • 31:修复登录失败后不会再次弹出密码框的问题。

  • 32:改为通过油猴自动加载脚本,提升稳定性。

  • 33:更新已知机器人列表;优化错误处理,在遇到未捕捉异常时刷新页面。

  • 34:添加了管理员命令功能,机器人管理员可以发“@ChatGPT,刷新页面”来重启机器人。注意油猴脚本需要更新,新增了管理员uid。

  • 35:允许添加自定义主循环来把机器人接入其他类型的网站,见下方“如何把机器人接入其他类型的网站”一节。

  • 36:修复帖子正文@ChatGPT无效的问题;改进会话重命名和操作完成等待逻辑。

  • 37:添加了重试功能,发送@ChatGPT,重试相当于把上一条内容重新发送一次,可在ChatGPT出错时使用。

  • 38:有用户发言失败时自动刷新页面,尽量实现自动故障恢复。

  • 39:刷新页面前自动保存控制台日志到localStorage以供分析。
    如何查看日志(以chrome为例):打开F12控制台,点“应用”,在左侧展开“本地存储空间”,选中展开后的第一项,然后右侧找“console:”开头的key,点击后,底部可以换行显示value,把底部拉大即可查看完整日志。
    日志最多保存5个,之前的会被清理。

  • 40:尝试解决发言失败时获取到上一条发言的问题;在模型2回复的开头添加“[2]”标记。

  • 41:添加了html模式,说@ChatGPT html,生成一段html hello world,生成的代码将用[html][/html]包围。以下是完整格式:

     @ChatGPT html,输出一段html hello world
     @ChatGPT 2 html,输出一段html hello world
     @ChatGPT html=500,输出一段html hello world
     @ChatGPT 2 html=300x500,输出一段html hello world
     
     @ChatGPT text,讲个笑话
     @ChatGPT latex,证明勾股定理,内容放在Markdown代码块中,采用Latex格式书写
     @ChatGPT math,证明勾股定理,公式采用Latex格式书写并单独放在markdown代码块中(备注:不好用,公式无法正常显示,有待修复)
    
  • 42:ChatGPT界面改版了,移除了切换会话功能,所以我们只能回到所有用户共享单个会话的旧模式。

  • 43:切换会话功能回来了,如果你还是看不到该功能,可以尝试清空浏览器缓存。

回复列表(8|隐藏机器人聊天)
  • @Ta / 2023-02-21 / /

    @ChatGPT,就可以与该机器人对话。示例:

    @ChatGPT,你会做什么?


    隐私提醒:所有ChatGPT聊天记录都会出现在@老虎会游泳 的浏览器上,请不要聊不想被他看到的话题。


    注意事项:

    1. 不要在其他人的帖子内@ChatGPT 问无关问题,我会删除相关评论。如果你想和ChatGPT聊天,请自行发帖。

    2. ChatGPT随时都可能会编造内容,请不要完全相信它。即使ChatGPT的语气十分肯定、不容置疑,内容也可能完全不正确,请务必自行求证。

    3. 小尾巴可能会导致ChatGPT无法理解你的发言,在@ChatGPT 时记得关掉小尾巴。

    4. 如果ChatGPT回复待审核,请查看@消息

    5. 不要在@ChatGPT@其他人,否则ChatGPT可能会无法理解你的发言。

    6. 机器人已部署会话隔离,每个人的会话都是独立的,不会受其他人的打扰。注意@ChatGPT 1@ChatGPT 2是两个单独的会话,不共享上下文。

    7. 因为ChatGPT的会话重命名功能不稳定,有时候标注会话所属用户会失败,此时上下文会丢失。如果你看到了“[新会话]”字样,说明上下文已丢失,ChatGPT不存在关于之前对话的记忆。

    8. 发送@ChatGPT,结束会话可以删除当前会话,清除所有对话记忆。注意小尾巴会让命令失败。


    机器人目前有两个模型,模型1(Default)数据更新,但更喜欢胡编乱造。模型2(Default)数据更旧,但更稳重。在生成程序代码时,模型1可能会编造完全不存在的函数或接口,此时可尝试改用模型2。

    可以用以下方式选择回答问题的模型:

    @ChatGPT 1,你好。

    @ChatGPT 2,你好。

    注意1和2前面有空格。如果不指定,则使用模型1。


    并发程度:每次只能与一个人对话,所以其他@消息需要排队等待回复。

    如果长时间没有收到任何回复,也可能是@老虎会游泳 的浏览器出问题了,可以@他进行修复。目前机器人代码运行在@老虎会游泳 的Chrome浏览器调试控制台里。

  • @Ta / 2023-02-19 / /

    @ChatGPT,你可以做什么?

  • @Ta / 2023-02-19 / /

    @老虎会游泳,作为一个大型语言模型,我可以回答各种问题并提供信息,如:

    回答各种普通问题,如历史、科学、文化等。
    提供解释、定义、说明、概述等等。
    提供一般建议和指导。
    生成创意、设计、内容等等。
    编写代码、算法等等。
    语言翻译和文本生成等等。

    请注意,我是一种人工智能,我的回答可能不是完美的,也可能存在误差或不准确。因此,如果您对某些答案有任何疑问或需要更多信息,请随时告诉我。

  • @Ta / 2023-02-19 / /

    @ChatGPT,写一段生成100以内素数的PHP代码

  • @Ta / 2023-02-19 / /

    @老虎会游泳,好的,以下是生成100以内素数的PHP代码:

    <?php
    function generate_primes($n) {
        $primes = array();
        for ($num = 2; $num <= $n; $num++) {
            $is_prime = true;
            for ($i = 2; $i < $num; $i++) {
                if ($num % $i == 0) {
                    $is_prime = false;
                    break;
                }
            }
            if ($is_prime) {
                $primes[] = $num;
            }
        }
        return $primes;
    }
    
    $primes = generate_primes(100);
    foreach ($primes as $prime) {
        echo $prime . " ";
    }
    ?>
    
    

    这段代码定义了一个 generate_primes() 函数,该函数使用与先前提供的计算100以内素数的代码类似的算法来生成一个数组,其中包含从2到给定数字 $n 之间的所有素数。然后,使用 foreach 循环遍历这个素数数组,并输出每个素数。

  • @Ta / 2023-02-19 / /

    @ChatGPT,讲一个笑话

  • @Ta / 2023-02-19 / /

    @老虎会游泳,当然,这是一个我喜欢的笑话:

    有一天,一个兔子走进一个面包店,问道:“你们这里有胡萝卜面包吗?”店员回答:“没有,我们只有面包和蛋糕。”于是兔子离开了。

    第二天,兔子又走进了面包店,问道:“你们这里有胡萝卜面包吗?”店员回答:“我昨天跟你说了,没有啊!”兔子又离开了。

    第三天,兔子又来到面包店,问道:“你们这里有胡萝卜面包吗?”这一次,店员有些生气了,回答说:“我们没有胡萝卜面包,也没有曾经有过,如果你再来问一次,我就用钉子把你的耳朵钉在墙上!”兔子听完之后,非常慌张地跑了。

    第四天,兔子又来到面包店,店员生气地问道:“你又来问胡萝卜面包?”兔子回答:“不,我只是想问你们有没有钉子。”店员回答:“没有啊。”兔子接着说:“那你们有胡萝卜面包吗?”

  • @Ta / 2023-02-23 / /

    @幕后导演,代码在这里,需要搭建一个hu60wap6来对接:https://gitee.com/hu60t/hu60wap6

添加新回复
该帖子已关闭评论,仅楼主可回复。