├── .gitignore ├── README.md ├── netlify.toml ├── netlify └── functions │ └── proxy.ts ├── package-lock.json └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # palm-netlify-proxy 2 | 3 | Google PaLM API proxy on Netlify Edge 4 | 5 | 6 | ## Deploy 7 | 8 | ### Deploy With Netlify 9 | 10 | [![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/antergone/palm-netlify-proxy) 11 | 12 | 13 | ## Discussion 14 | 15 | Please Visit Simon's Blog. https://simonmy.com/posts/使用netlify反向代理google-palm-api.html 16 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [[headers]] 2 | for = "/*" 3 | [headers.values] 4 | Access-Control-Allow-Origin = "*" 5 | Access-Control-Allow-Headers = "*" 6 | Access-Control-Allow-Methods = "*" 7 | [[redirects]] 8 | from = "/*" 9 | to = "/.netlify/functions/proxy" 10 | status = 200 11 | force = true -------------------------------------------------------------------------------- /netlify/functions/proxy.ts: -------------------------------------------------------------------------------- 1 | import { Context } from "@netlify/edge-functions"; 2 | 3 | const pickHeaders = (headers: Headers, keys: (string | RegExp)[]): Headers => { 4 | const picked = new Headers(); 5 | for (const key of headers.keys()) { 6 | if (keys.some((k) => (typeof k === "string" ? k === key : k.test(key)))) { 7 | const value = headers.get(key); 8 | if (typeof value === "string") { 9 | picked.set(key, value); 10 | } 11 | } 12 | } 13 | return picked; 14 | }; 15 | 16 | const CORS_HEADERS: Record = { 17 | "access-control-allow-origin": "*", 18 | "access-control-allow-methods": "*", 19 | "access-control-allow-headers": "*", 20 | }; 21 | 22 | export default async (request: Request, context: Context) => { 23 | 24 | if (request.method === "OPTIONS") { 25 | return new Response(null, { 26 | headers: CORS_HEADERS, 27 | }); 28 | } 29 | 30 | const { pathname, searchParams } = new URL(request.url); 31 | if(pathname === "/") { 32 | let blank_html = ` 33 | 34 | 35 | 36 | 37 | Google PaLM API proxy on Netlify Edge 38 | 39 | 40 |

Google PaLM API proxy on Netlify Edge

41 |

Tips: This project uses a reverse proxy to solve problems such as location restrictions in Google APIs.

42 |

If you have any of the following requirements, you may need the support of this project.

43 |
    44 |
  1. When you see the error message "User location is not supported for the API use" when calling the Google PaLM API
  2. 45 |
  3. You want to customize the Google PaLM API
  4. 46 |
47 |

For technical discussions, please visit https://simonmy.com/posts/google-palm-api-proxy-on-netlify-edge.html

48 | 49 | 50 | ` 51 | return new Response(blank_html, { 52 | headers: { 53 | ...CORS_HEADERS, 54 | "content-type": "text/html" 55 | }, 56 | }); 57 | } 58 | 59 | const url = new URL(pathname, "https://generativelanguage.googleapis.com"); 60 | searchParams.delete("_path"); 61 | 62 | searchParams.forEach((value, key) => { 63 | url.searchParams.append(key, value); 64 | }); 65 | 66 | const headers = pickHeaders(request.headers, ["content-type", "authorization", "x-goog-api-client", "x-goog-api-key", "accept-encoding"]); 67 | 68 | const response = await fetch(url, { 69 | body: request.body, 70 | method: request.method, 71 | headers, 72 | }); 73 | 74 | const responseHeaders = { 75 | ...CORS_HEADERS, 76 | ...Object.fromEntries(response.headers), 77 | }; 78 | 79 | return new Response(response.body, { 80 | headers: responseHeaders, 81 | status: response.status 82 | }); 83 | }; -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "palm-netlify-proxy", 3 | "version": "1.0.1", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "palm-netlify-proxy", 9 | "version": "1.0.1", 10 | "devDependencies": { 11 | "@netlify/edge-functions": "2.11.1" 12 | } 13 | }, 14 | "node_modules/@netlify/edge-functions": { 15 | "version": "2.11.1", 16 | "resolved": "https://registry.npmjs.org/@netlify/edge-functions/-/edge-functions-2.11.1.tgz", 17 | "integrity": "sha512-pyQOTZ8a+ge5lZlE+H/UAHyuqQqtL5gE0pXrHT9mOykr3YQqnkB2hZMtx12odatZ87gHg4EA+UPyMZUbLfnXvw==", 18 | "dev": true, 19 | "license": "MIT" 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "palm-netlify-proxy", 3 | "version": "1.0.1", 4 | "scripts": {}, 5 | "dependencies": {}, 6 | "devDependencies": { 7 | "@netlify/edge-functions": "2.11.1" 8 | } 9 | } --------------------------------------------------------------------------------