import { blob } from "https://esm.town/v/std/blob";
import { OpenAI } from "https://esm.town/v/std/openai";
import { Buffer } from "node:buffer";
import { createHmac, timingSafeEqual } from "node:crypto";
const selfURL = "https://cephalization-smsjournalertextrelay.web.val.run";
const systemRegistrationKey = Deno.env.get("smsjournalerregistrationkey");
const sharedSecret = Deno.env.get("smsjournalersecret");
const textbeltKey = Deno.env.get("textbeltkey");
interface Message {
sender: string;
content: string;
date: string;
phone?: string;
}
const makeBlobKey = (phone: string) => `conversation_${phone}`;
function validateTextbeltRequestSignature(
apiKey: string,
timestamp: string,
requestSignature: string,
requestPayload: string,
) {
const mySignature = createHmac("sha256", apiKey)
.update(
timestamp + requestPayload,
)
.digest("hex");
return timingSafeEqual(
Buffer.from(requestSignature),
Buffer.from(mySignature),
);
}
async function sendSMS(phone: string, message: string) {
const response = await fetch("https://textbelt.com/text", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
phone,
message,
key: textbeltKey,
replyWebhookUrl: selfURL,
}),
});
return response.json();
}
async function getConversationHistory(phone: string): Promise<Message[]> {
const key = makeBlobKey(phone);
const history = await blob.getJSON(key) as Message[] | null;
return history || [];
}
async function updateConversationHistory(phone: string, message: Message) {
const key = makeBlobKey(phone);
const history = await getConversationHistory(phone);
history.push(message);
await blob.setJSON(key, history);
}
async function generateAIResponse(history: Message[]): Promise<string> {
const openai = new OpenAI();
const messages: { role: "user" | "assistant" | "system"; content: string }[] = history.map(msg => ({
role: msg.sender === "User" ? "user" : "assistant",
content: msg.content,
}));
messages.unshift({
role: "system",
content:
"You are an AI assistant communicating via SMS. Keep your responses concise and under 160 characters. Your task is to help the user organize their daily work activities and provide brief, helpful responses.",
});
const completion = await openai.chat.completions.create({
messages,