Skip to content

Commit

Permalink
feat: close ChatGPTNextWeb#2 add check account balance
Browse files Browse the repository at this point in the history
  • Loading branch information
Yidadaa committed Mar 29, 2023
1 parent 45088a3 commit 447dec9
Show file tree
Hide file tree
Showing 14 changed files with 245 additions and 99 deletions.
41 changes: 37 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,24 +78,56 @@ This project will be continuously maintained. If you want to keep the code repos

You can star or watch this project or follow author to get release notifictions in time.

## 访问控制 Access Control
## 配置密码 Password

本项目提供有限的权限控制功能,请在环境变量页增加名为 `CODE` 的环境变量,值为用英文逗号分隔的自定义控制码
本项目提供有限的权限控制功能,请在 Vercel 项目控制面板的环境变量页增加名为 `CODE` 的环境变量,值为用英文逗号分隔的自定义密码

```
code1,code2,code3
```

增加或修改该环境变量后,请**重新部署**项目使改动生效。

This project provides limited access control. Please add an environment variable named `CODE` on the environment variables page. The value should be a custom control code separated by comma like this:
This project provides limited access control. Please add an environment variable named `CODE` on the vercel environment variables page. The value should be passwords separated by comma like this:

```
code1,code2,code3
```

After adding or modifying this environment variable, please redeploy the project for the changes to take effect.

## 环境变量 Environment Variables

### `OPENAI_API_KEY` (required)

OpanAI 密钥。

Your openai api key.

### `CODE` (optional)

访问密码,可选,可以使用逗号隔开多个密码。

Access passsword, separated by comma.

### `BASE_URL` (optional)

> Default: `api.openai.com`
OpenAI 接口代理 URL。

Override openai api request base url.

### `PROTOCOL` (optional)

> Default: `https`
> Values: `http` | `https`
OpenAI 接口协议。

Override openai api request protocol.

## 开发 Development

点击下方按钮,开始二次开发:
Expand All @@ -118,11 +150,11 @@ OPENAI_API_KEY=<your api key here>
2. 执行 `yarn install && yarn dev` 即可。

### 本地部署 Local Deployment

```shell
bash <(curl -s https://raw.githubusercontent.com/Yidadaa/ChatGPT-Next-Web/main/scripts/setup.sh)
```


### 容器部署 Docker Deployment

```shell
Expand Down Expand Up @@ -157,6 +189,7 @@ If you would like to contribute your API key, you can email it to the author and
[@hoochanlon](https://github.com/hoochanlon)

### 贡献者 Contributor

[Contributors](https://github.com/Yidadaa/ChatGPT-Next-Web/graphs/contributors)

## LICENSE
Expand Down
18 changes: 2 additions & 16 deletions app/api/chat-stream/route.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,12 @@
import { createParser } from "eventsource-parser";
import { NextRequest } from "next/server";
import { requestOpenai } from "../common";

async function createStream(req: NextRequest) {
const encoder = new TextEncoder();
const decoder = new TextDecoder();

let apiKey = process.env.OPENAI_API_KEY;

const userApiKey = req.headers.get("token");
if (userApiKey) {
apiKey = userApiKey;
console.log("[Stream] using user api key");
}

const res = await fetch("https://api.openai.com/v1/chat/completions", {
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${apiKey}`,
},
method: "POST",
body: req.body,
});
const res = await requestOpenai(req);

const stream = new ReadableStream({
async start(controller) {
Expand Down
1 change: 0 additions & 1 deletion app/api/chat/.gitignore

This file was deleted.

29 changes: 0 additions & 29 deletions app/api/chat/route.ts

This file was deleted.

22 changes: 22 additions & 0 deletions app/api/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { NextRequest } from "next/server";

const OPENAI_URL = "api.openai.com";
const DEFAULT_PROTOCOL = "https";
const PROTOCOL = process.env.PROTOCOL ?? DEFAULT_PROTOCOL;
const BASE_URL = process.env.BASE_URL ?? OPENAI_URL;

export async function requestOpenai(req: NextRequest) {
const apiKey = req.headers.get("token");
const openaiPath = req.headers.get("path");

console.log("[Proxy] ", openaiPath);

return fetch(`${PROTOCOL}://${BASE_URL}/${openaiPath}`, {
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${apiKey}`,
},
method: req.method,
body: req.body,
});
}
28 changes: 28 additions & 0 deletions app/api/openai/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { NextRequest, NextResponse } from "next/server";
import { requestOpenai } from "../common";

async function makeRequest(req: NextRequest) {
try {
const res = await requestOpenai(req);
return new Response(res.body);
} catch (e) {
console.error("[OpenAI] ", req.body, e);
return NextResponse.json(
{
error: true,
msg: JSON.stringify(e),
},
{
status: 500,
},
);
}
}

export async function POST(req: NextRequest) {
return makeRequest(req);
}

export async function GET(req: NextRequest) {
return makeRequest(req);
}
File renamed without changes.
72 changes: 58 additions & 14 deletions app/components/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { getCurrentCommitId } from "../utils";
import Link from "next/link";
import { UPDATE_URL } from "../constant";
import { SearchService, usePromptStore } from "../store/prompt";
import { requestUsage } from "../requests";

function SettingItem(props: {
title: string;
Expand Down Expand Up @@ -54,7 +55,7 @@ export function Settings(props: { closeSettings: () => void }) {
state.updateConfig,
state.resetConfig,
state.clearAllData,
]
],
);

const updateStore = useUpdateStore();
Expand All @@ -70,14 +71,34 @@ export function Settings(props: { closeSettings: () => void }) {
});
}

const [usage, setUsage] = useState<{
granted?: number;
used?: number;
}>();
const [loadingUsage, setLoadingUsage] = useState(false);
function checkUsage() {
setLoadingUsage(true);
requestUsage()
.then((res) =>
setUsage({
granted: res?.total_granted,
used: res?.total_used,
}),
)
.finally(() => {
setLoadingUsage(false);
});
}

useEffect(() => {
checkUpdate();
checkUsage();
}, []);

const accessStore = useAccessStore();
const enabledAccessControl = useMemo(
() => accessStore.enabledAccessControl(),
[]
[],
);

const promptStore = usePromptStore();
Expand Down Expand Up @@ -179,7 +200,7 @@ export function Settings(props: { closeSettings: () => void }) {
onChange={(e) => {
updateConfig(
(config) =>
(config.submitKey = e.target.value as any as SubmitKey)
(config.submitKey = e.target.value as any as SubmitKey),
);
}}
>
Expand All @@ -199,7 +220,7 @@ export function Settings(props: { closeSettings: () => void }) {
value={config.theme}
onChange={(e) => {
updateConfig(
(config) => (config.theme = e.target.value as any as Theme)
(config) => (config.theme = e.target.value as any as Theme),
);
}}
>
Expand Down Expand Up @@ -240,7 +261,7 @@ export function Settings(props: { closeSettings: () => void }) {
onChange={(e) =>
updateConfig(
(config) =>
(config.fontSize = Number.parseInt(e.currentTarget.value))
(config.fontSize = Number.parseInt(e.currentTarget.value)),
)
}
></input>
Expand All @@ -253,7 +274,7 @@ export function Settings(props: { closeSettings: () => void }) {
checked={config.tightBorder}
onChange={(e) =>
updateConfig(
(config) => (config.tightBorder = e.currentTarget.checked)
(config) => (config.tightBorder = e.currentTarget.checked),
)
}
></input>
Expand All @@ -271,7 +292,7 @@ export function Settings(props: { closeSettings: () => void }) {
onChange={(e) =>
updateConfig(
(config) =>
(config.disablePromptHint = e.currentTarget.checked)
(config.disablePromptHint = e.currentTarget.checked),
)
}
></input>
Expand All @@ -281,7 +302,7 @@ export function Settings(props: { closeSettings: () => void }) {
title={Locale.Settings.Prompt.List}
subTitle={Locale.Settings.Prompt.ListCount(
builtinCount,
customCount
customCount,
)}
>
<IconButton
Expand Down Expand Up @@ -324,6 +345,28 @@ export function Settings(props: { closeSettings: () => void }) {
></input>
</SettingItem>

<SettingItem
title={Locale.Settings.Usage.Title}
subTitle={
loadingUsage
? Locale.Settings.Usage.IsChecking
: Locale.Settings.Usage.SubTitle(
usage?.granted ?? "[?]",
usage?.used ?? "[?]",
)
}
>
{loadingUsage ? (
<div />
) : (
<IconButton
icon={<ResetIcon></ResetIcon>}
text={Locale.Settings.Usage.Check}
onClick={checkUsage}
/>
)}
</SettingItem>

<SettingItem
title={Locale.Settings.HistoryCount.Title}
subTitle={Locale.Settings.HistoryCount.SubTitle}
Expand All @@ -338,7 +381,7 @@ export function Settings(props: { closeSettings: () => void }) {
onChange={(e) =>
updateConfig(
(config) =>
(config.historyMessageCount = e.target.valueAsNumber)
(config.historyMessageCount = e.target.valueAsNumber),
)
}
></input>
Expand All @@ -357,7 +400,7 @@ export function Settings(props: { closeSettings: () => void }) {
updateConfig(
(config) =>
(config.compressMessageLengthThreshold =
e.currentTarget.valueAsNumber)
e.currentTarget.valueAsNumber),
)
}
></input>
Expand All @@ -370,7 +413,8 @@ export function Settings(props: { closeSettings: () => void }) {
value={config.modelConfig.model}
onChange={(e) => {
updateConfig(
(config) => (config.modelConfig.model = e.currentTarget.value)
(config) =>
(config.modelConfig.model = e.currentTarget.value),
);
}}
>
Expand All @@ -395,7 +439,7 @@ export function Settings(props: { closeSettings: () => void }) {
updateConfig(
(config) =>
(config.modelConfig.temperature =
e.currentTarget.valueAsNumber)
e.currentTarget.valueAsNumber),
);
}}
></input>
Expand All @@ -413,7 +457,7 @@ export function Settings(props: { closeSettings: () => void }) {
updateConfig(
(config) =>
(config.modelConfig.max_tokens =
e.currentTarget.valueAsNumber)
e.currentTarget.valueAsNumber),
)
}
></input>
Expand All @@ -432,7 +476,7 @@ export function Settings(props: { closeSettings: () => void }) {
updateConfig(
(config) =>
(config.modelConfig.presence_penalty =
e.currentTarget.valueAsNumber)
e.currentTarget.valueAsNumber),
);
}}
></input>
Expand Down
Loading

0 comments on commit 447dec9

Please sign in to comment.