OwO-Network / DeepLX

Powerful Free DeepL API, No Token Required
https://ssa.sx/deeplx
MIT License
6.64k stars 532 forks source link

Deployed to the edge function, the request always reports a 525 error. #33

Closed ifyour closed 1 year ago

ifyour commented 1 year ago

Hello, after referring to your code implementation principle, I wrote a JS version which works fine when debugging locally. However, when I tried to deploy it to the edge function, it always reported a 525 error. May I ask why?

However, when I deployed your go version on the server, it worked normally and now I am seeking help.

// src/pages/api/translate.ts

import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";

interface RequestParams {
  text: string;
  source_lang: string;
  target_lang: string;
}

interface ResponseParams {
  id: number;
  code: number;
  data: string;
}

async function queryAPI(data: RequestParams): Promise<ResponseParams> {
  const res = await fetch("https://www2.deepl.com/jsonrpc", {
    headers: {
      "Content-Type": "application/json; charset=utf-8",
    },
    method: "POST",
    body: buildBodyString(data),
  });

  if (res.ok) {
    const result = (await res.json()) as {
      jsonrpc: string;
      id: number;
      result: {
        texts: {
          text: string;
        }[];
      };
    };
    return {
      id: result.id,
      code: 200,
      data: result?.result?.texts?.[0]?.text,
    };
  }
  return {
    id: 42,
    code: res.status,
    data:
      res.status === 429
        ? "Too many requests, please try again later."
        : "Unknown error.",
  };
}

function buildRequestParams(sourceLang: string, targetLang: string) {
  return {
    jsonrpc: "2.0",
    method: "LMT_handle_texts",
    id: Math.floor(Math.random() * 100000 + 100000) * 1000,
    params: {
      texts: [{ text: "", requestAlternatives: 3 }],
      timestamp: 0,
      splitting: "newlines",
      lang: {
        source_lang_user_selected: sourceLang,
        target_lang: targetLang,
      },
    },
  };
}

function getCountOfI(translateText: string) {
  return translateText.split("i").length - 1;
}

function getTimestamp(iCount: number) {
  let ts = new Date().getTime();
  if (iCount !== 0) {
    iCount = iCount + 1;
    return ts - (ts % iCount) + iCount;
  } else {
    return ts;
  }
}

function buildBodyString(data: RequestParams) {
  const post_data = buildRequestParams(
    data.source_lang || "AUTO",
    data.target_lang || "AUTO"
  );
  post_data.params.texts = [{ text: data.text, requestAlternatives: 3 }];
  post_data.params.timestamp = getTimestamp(getCountOfI(data.text));
  let post_str = JSON.stringify(post_data);
  if (
    [0, 3].includes((post_data["id"] + 5) % 29) ||
    (post_data["id"] + 3) % 13 === 0
  ) {
    post_str = post_str.replace('"method":"', '"method" : "');
  } else {
    post_str = post_str.replace('"method":"', '"method": "');
  }

  return post_str;
}

export const config = {
  runtime: "edge",
};

export default async function MyEdgeFunction(request: NextRequest) {
  const req = (await request.json()) as RequestParams;
  const res = await queryAPI(req);
  return NextResponse.json(res);
}
curl --location 'https://deeplx-edge-api.vercel.app/api/translate' \
--header 'Content-Type: application/json' \
--data '{
    "text": "你好呀,请问你来自哪里",
    "source_lang": "auto",
    "target_lang": "en"
}'
{"id":42,"code":525,"data":"Unknown error."}
curl --location '127.0.0.1:3000/api/translate' \
--header 'Content-Type: application/json' \
--data '{
    "text": "请给我一个冰淇淋",
    "source_lang": "zh",
    "target_lang": "en"
}'
{"id":115601000,"code":200,"data":"Please give me an ice cream"}
missuo commented 1 year ago

An SSL Handshake Failure or Error 525 means that the server and browser were unable to establish a secure connection. This can happen for a variety of reasons. However, it's also important to understand that SSL errors can happen on the client-side or the server-side.

My guess is that vercel's IP may be blocked by DeepL.

ShevonKuan commented 1 year ago

maybe your id and headers are not right.

const id = 1000*(Math.floor(Math.random() * 99999) + 8300000)+1;

headers: { 
             "Content-Type": "application/json; charset=utf-8", 
             "Accept": "*/*", 
             "x-app-os-name": "iOS", 
             "x-app-os-version": "16.3.0", 
             "Accept-Language": "en-US,en;q=0.9", 
             "Accept-Encoding": "gzip, deflate, br", 
             "x-app-device": "iPhone13,2", 
             "User-Agent": "DeepL-iOS/2.6.0 iOS 16.3.0 (iPhone13,2)", 
             "x-app-build": "353933", 
             "x-app-version": "2.6", 
             "Connection": "keep-alive", 
         },
missuo commented 1 year ago

The actual test, id and headers actually can not need to specify, I do so only to request more like the official client. @ShevonKuan

ShevonKuan commented 1 year ago

If not specify the headers it will return 525 or 429 error sometimes. And if the id is wrong, it always return 429 error. So I think it is necessary to add the headers.

missuo commented 1 year ago

If not specify the headers it will return 525 or 429 error sometimes. And if the id is wrong, it always return 429 error. So I think it is necessary to add the headers.

"Content-Type": "application/json; charset=utf-8"

Content-Type should be required. id can be a number of almost digits.

ifyour commented 1 year ago

maybe your id and headers are not right.

I tried changing the id and headers, but still got the same error. I gave up and used the Go version instead, directly requesting through IP, which works normally. Thank you for answering my question.