Skip to content

Instantly share code, notes, and snippets.

@fayazara
Last active March 26, 2023 08:32
Show Gist options
  • Save fayazara/e5e05e027fb9c33a249796d3cc1e20fe to your computer and use it in GitHub Desktop.
Save fayazara/e5e05e027fb9c33a249796d3cc1e20fe to your computer and use it in GitHub Desktop.
A cf worker to sumamrize emails even before they hit your inbox. (DOES NOT WORK as there's no way to edit the email content)
const { default: PostalMime } = require("postal-mime");
const AI_MODEL = "gpt-3.5-turbo";
const OPEN_AI_API_KEY = "YOUR_API_KEY_HERE";
const streamToArrayBuffer = async (stream, streamSize) => {
const result = new Uint8Array(streamSize);
let bytesRead = 0;
const reader = stream.getReader();
while (bytesRead < streamSize) {
const { done, value } = await reader.read();
if (done) {
break;
}
result.set(value, bytesRead);
bytesRead += value.length;
}
return result;
};
const generateSystemMessage = () => {
return {
role: "system",
content: `You are an AI summarizer. Summarize the email below. You will tell us what the email is about and write a small summary. Response format - { "type": "Event Invitation", "summary": Email invitation from John Doe to attend his daughters birthday party on June 1st}`,
};
};
function generateUserMessage(subject, message) {
return {
role: "user",
content: `Email subject: ${subject} \n Email body: ${message}`,
};
}
const isKeyInvalid = ({ error }) => {
return (
error?.type === "invalid_request_error" && error?.code === "invalid_api_key"
);
};
const getSummaryfromOpenAi = async (subject, message) => {
const messages = [
generateSystemMessage(),
generateUserMessage(subject, message),
];
const response = await fetch("https://api.openai.com/v1/chat/completions", {
method: "POST",
body: JSON.stringify({
model: AI_MODEL,
messages,
}),
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${OPEN_AI_API_KEY}`,
},
});
const completion = await response.json();
if (isKeyInvalid(completion)) {
console.error("Invalid OpenAI API key");
} else {
const { choices } = completion;
const { type, summary } = choices[0].message.content;
const summaryString = `Email type: ${type} \n Email summary: ${summary}`;
return summaryString;
}
};
const email = async (message) => {
try {
const rawEmail = await streamToArrayBuffer(message.raw, message.rawSize);
const parser = new PostalMime();
const parsedEmail = await parser.parse(rawEmail);
const summaryData = await getSummaryfromOpenAi(parsedEmail.text);
const emailWithSummary = generateEmailWithSummary(parsedEmail, summaryData);
const headers = new Headers();
headers.set("Content-Type", "message/rfc822");
await message.forward(message.to, { body: emailWithSummary, headers });
console.log("Email with summary sent");
} catch (error) {
console.error(`Error processing email: ${error}`);
} finally {
console.log("Email processed");
}
};
export default {
email,
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment