无服务器实现openai接口反向代理和额度查询

使用Cloudflare代理openai接口,并实现简单查询额度。

安装步骤

  • 将代码部署到Cloudflare的worker平台(其他支持worker的平台也可)
  • 替换自己代码中的api.openai.com为你自己的worker域名,例如 your.worker.domain

Worker 代码

/**
 * @auther Rehiy
 * @url https://www.rehiy.com/post/500
 * @description woker service for cloudflare
 */

async function openai_get(api, key) {
    const opts = {
        method: 'GET',
        headers: {
            Authorization: 'Bearer ' + key,
        },
    };
    const url = 'https://api.openai.com/v1/' + api;
    return fetch(url, opts).then(r => r.json());
}

async function openai_usage(key) {
    const today = new Date();
    const formatDate = function (timestamp) {
        const date = new Date(timestamp * 1000);
        return [date.getFullYear(), date.getMonth() + 1, date.getDate()].join('-');
    };

    const subscription = await openai_get('dashboard/billing/subscription', key);

    const start_date = subscription.hard_limit_usd > 20
        ? [today.getFullYear(), today.getMonth() + 1, '1'].join('-') : formatDate(today / 1000 - 90 * 86400);
    const end_date = formatDate(today / 1000 + 86400);

    const usage = await openai_get(`dashboard/billing/usage?start_date=${start_date}&end_date=${end_date}`, key);

    return {
        access_until: formatDate(subscription.access_until),
        hard_limit_usd: subscription.hard_limit_usd.toFixed(5),
        total_usage: (usage.total_usage / 100).toFixed(5),
        left_quota: (subscription.hard_limit_usd - usage.total_usage / 100).toFixed(5),
        start_date: start_date,
        end_date: end_date,
    };
}

async function openai_proxy(request) {
    const url = new URL(request.url);
    const auth = request.headers.get('Authorization');
    const backend = request.url.replace(url.host, 'api.openai.com');
    const payload = {
        method: request.method,
        headers: { Authorization: auth },
    };

    if (request.body) {
        payload.body = await request.text();
        payload.headers['Content-Type'] = 'application/json';
    }

    return fetch(backend, payload);
}

export default {
    async fetch(request) {
        if (request.method === 'OPTIONS') {
            const corsHeaders = {
                'Access-Control-Allow-Origin': '*',
                'Access-Control-Allow-Methods': 'OPTIONS',
                'Access-Control-Allow-Headers': '*',
            };
            return new Response(null, { headers: corsHeaders });
        }

        const url = new URL(request.url);

        if (url.pathname.startsWith('/v1/')) {
            return openai_proxy(request);
        }

        if (url.pathname.startsWith('/usage/')) {
            const [, key] = url.pathname.split('/usage/');
            return new Response(JSON.stringify(openai_usage(key)));
        }

        return new Response('Not Found', { status: 404 });
    }
}
  • ai
  • cloudflare
  • worker
  • chatgpt

6 评论

鹰瑶 回复

很久前码的一小段代码,偶然翻出来了。带注释分享一下,仅供大家研究学习,切勿用于其他用途

小东 回复

很久没更新这个系列的文章了,想来按照之前教程部署的集群也都到了该升级的时候,今天我们来探讨下如何升级k3s集群

荒年 回复

在和上可以通过删除“设置账户邮件和账户”里的登录账号来达到目的。但是在上尝试了各种删除的办法都是没用

梦屿 回复

MariaDB 安装时,默认会创建一个特权用户。如果忘记超级管理员可以使用这个账号登录后修改密码或者主机

蛋黄 回复

使用Cloudflare部署Ai聊天前端界面,无需置备服务器,只要一个可以接入cloudflare的域名即可

king 回复

前言 不得不吐槽下,将一个现有域名添加到Cloudflare时,系统自动导入的几百个不那么正确的解析记录,让人抓狂

回复题主

您的电子邮件地址将不会被公布。必填字段已标记 *