forked from tuhinpal/WhatsBot
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into dependabot/npm_and_yarn/mongodb-4.17.0
- Loading branch information
Showing
93 changed files
with
4,627 additions
and
707 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,7 +23,6 @@ session-output/* | |
session-output | ||
session.secure | ||
/.lh/ | ||
**/*.js | ||
/dist/ | ||
/docker/data | ||
/docker/wtstodis-data |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# http://editorconfig.org | ||
root = true | ||
|
||
[*] | ||
indent_style = tab | ||
tab_width = 2 | ||
end_of_line = lf | ||
charset = utf-8 | ||
trim_trailing_whitespace = true | ||
insert_final_newline = true | ||
|
||
[*.yml] | ||
indent_style = space |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"printWidth": 140, | ||
"singleQuote": true, | ||
"semi": true, | ||
"useTabs": true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"name": "whatsbot-worker", | ||
"version": "0.0.0", | ||
"private": true, | ||
"type": "module", | ||
"scripts": { | ||
"deploy": "wrangler deploy", | ||
"dev": "wrangler dev", | ||
"start": "wrangler dev" | ||
}, | ||
"devDependencies": { | ||
"wrangler": "^3.0.0" | ||
}, | ||
"dependencies": { | ||
"@cloudflare/ai": "^1.1.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { BadRequestException, UnauthorizedException } from './exceptions.js'; | ||
import { Env } from './types.js'; | ||
|
||
export function basicAuthentication(request: Request) { | ||
const Authorization = request.headers.get('Authorization'); | ||
|
||
const [scheme, encoded] = Authorization?.split(' ') || ['', '']; | ||
|
||
// The Authorization header must start with Basic, followed by a space. | ||
if (!encoded || scheme !== 'Basic') { | ||
throw new BadRequestException('Malformed authorization header.'); | ||
} | ||
|
||
// Decodes the base64 value and performs unicode normalization. | ||
// @see https://datatracker.ietf.org/doc/html/rfc7613#section-3.3.2 (and #section-4.2.2) | ||
// @see https://dev.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String/normalize | ||
const buffer = Uint8Array.from(atob(encoded), (character) => character.charCodeAt(0)); | ||
const decoded = new TextDecoder().decode(buffer).normalize(); | ||
|
||
// The username & password are split by the first colon. | ||
//=> example: "username:password" | ||
const index = decoded.indexOf(':'); | ||
|
||
// The user & password are split by the first colon and MUST NOT contain control characters. | ||
// @see https://tools.ietf.org/html/rfc5234#appendix-B.1 (=> "CTL = %x00-1F / %x7F") | ||
// eslint-disable-next-line no-control-regex | ||
if (index === -1 || /[\0-\x1F\x7F]/.test(decoded)) { | ||
throw new BadRequestException('Invalid authorization value.'); | ||
} | ||
|
||
return { | ||
user: decoded.substring(0, index), | ||
pass: decoded.substring(index + 1), | ||
}; | ||
} | ||
|
||
export function verifyCredentials(user: string, pass: string, env: Env) { | ||
if (env.AUTH_USER !== user) { | ||
throw new UnauthorizedException('Invalid credentials.'); | ||
} | ||
|
||
if (env.AUTH_PASSWORD !== pass) { | ||
throw new UnauthorizedException('Invalid credentials.'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
export class UnauthorizedException { | ||
status: number; | ||
statusText: string; | ||
reason: string; | ||
|
||
constructor(reason: string) { | ||
this.status = 401; | ||
this.statusText = 'Unauthorized'; | ||
this.reason = reason; | ||
} | ||
} | ||
|
||
export class BadRequestException { | ||
status: number; | ||
statusText: string; | ||
reason: string; | ||
|
||
constructor(reason: string) { | ||
this.status = 400; | ||
this.statusText = 'Bad Request'; | ||
this.reason = reason; | ||
} | ||
} | ||
|
||
export class FailedException { | ||
status: number; | ||
statusText: string; | ||
reason: string; | ||
|
||
constructor(reason: string) { | ||
this.status = 500; | ||
this.statusText = 'Internal Server Error'; | ||
this.reason = reason; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
import { Ai } from '@cloudflare/ai'; | ||
import { Env } from './types.js'; | ||
import { BadRequestException, FailedException } from './exceptions.js'; | ||
import { basicAuthentication, verifyCredentials } from './auth.js'; | ||
|
||
export default { | ||
async fetch(request: Request, env: Env) { | ||
const { protocol } = new URL(request.url); | ||
|
||
// In the case of a Basic authentication, the exchange MUST happen over an HTTPS (TLS) connection to be secure. | ||
if ('https:' !== protocol || 'https' !== request.headers.get('x-forwarded-proto')) { | ||
throw new BadRequestException('Please use a HTTPS connection.'); | ||
} | ||
|
||
if (request.headers.has('Authorization')) { | ||
// Throws exception when authorization fails. | ||
const { user, pass } = basicAuthentication(request); | ||
try { | ||
verifyCredentials(user, pass, env); | ||
} catch { | ||
// Not authenticated. | ||
return new Response('You need to login.', { | ||
status: 401, | ||
headers: { | ||
// Prompts the user for credentials. | ||
'WWW-Authenticate': 'Basic realm="my scope", charset="UTF-8"', | ||
}, | ||
}); | ||
} | ||
|
||
// Only returns this response when no exception is thrown. | ||
} else { | ||
// Not authenticated. | ||
return new Response('You need to login.', { | ||
status: 401, | ||
headers: { | ||
// Prompts the user for credentials. | ||
'WWW-Authenticate': 'Basic realm="my scope", charset="UTF-8"', | ||
}, | ||
}); | ||
} | ||
|
||
const ai = new Ai(env.AI); | ||
|
||
const url = new URL(request.url); | ||
const params = url.searchParams; | ||
const path = url.pathname; | ||
|
||
if ((path === '/' && request.method === 'GET') || path === '/llama') { | ||
const prompt = params.get('prompt'); | ||
let messages: { role: 'user' | 'system' | 'assistant'; content: string }[] = []; | ||
try { | ||
messages = JSON.parse(decodeURIComponent(params.get('messages')) || '[]'); | ||
} catch { | ||
return new BadRequestException('Messages must be a valid JSON array.'); | ||
} | ||
|
||
const chat = { | ||
messages: [ | ||
{ | ||
role: 'system', | ||
content: 'Below is an instruction that describes a task. Write a response that appropriately completes the request.', | ||
}, | ||
...(messages?.length | ||
? messages | ||
: [ | ||
{ | ||
role: 'user', | ||
content: prompt, | ||
}, | ||
]), | ||
], | ||
}; | ||
let response: string; | ||
for (let i = 5; i > 0; i--) { | ||
try { | ||
response = await ai.run('@cf/meta/llama-3-8b-instruct', chat); | ||
break; | ||
} catch { | ||
if (i === 1) { | ||
return new FailedException('Failed to generate after five tries.'); | ||
} | ||
} | ||
} | ||
|
||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
return Response.json(response); | ||
} | ||
|
||
if ((path === '/' && request.method === 'POST') || path === '/transcribe') { | ||
const contentType = request.headers.get('Content-Type'); | ||
if (!contentType || !contentType.includes('multipart/form-data')) { | ||
return new Response('Content-Type must be "multipart/form-data"', { status: 400 }); | ||
} | ||
|
||
const formData = await request.formData(); | ||
const audioFile = formData.get('audio'); | ||
|
||
// Check if audio file exists in the POST request | ||
if (!audioFile || !(audioFile instanceof File)) { | ||
return new Response('Audio file not found in the request', { status: 400 }); | ||
} | ||
|
||
// Convert audio file to ArrayBuffer | ||
const blob = await audioFile.arrayBuffer(); | ||
const inputs = { | ||
audio: [...new Uint8Array(blob)], | ||
}; | ||
const response = await ai.run('@cf/openai/whisper', inputs); | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
return Response.json(response); | ||
} | ||
|
||
if (path === '/sd') { | ||
const prompt = params.get('prompt'); | ||
const inputs = { | ||
prompt, | ||
}; | ||
|
||
const response = await ai.run('@cf/lykon/dreamshaper-8-lcm', inputs); | ||
|
||
return new Response(response, { | ||
headers: { | ||
'content-type': 'image/png', | ||
}, | ||
}); | ||
} | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export interface Env { | ||
AUTH_USER: string; | ||
AUTH_PASSWORD: string; | ||
AI: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
name = "your-worker-name" | ||
main = "src/index.ts" | ||
compatibility_date = "2023-10-07" | ||
workers_dev = true | ||
|
||
[ai] | ||
binding = "AI" |
Oops, something went wrong.