134 lines
4.6 KiB
JavaScript
134 lines
4.6 KiB
JavaScript
import striptags from "striptags";
|
|
import { PrismaClient } from "../generated/prisma/client.js";
|
|
const prisma = new PrismaClient();
|
|
const getNotifications = async () => {
|
|
try {
|
|
const request = await fetch(`${process.env.PLEROMA_INSTANCE_URL}/api/v1/notifications?types[]=mention`, {
|
|
method: "GET",
|
|
headers: {
|
|
Authorization: `Bearer ${process.env.INSTANCE_BEARER_TOKEN}`,
|
|
},
|
|
});
|
|
const notifications = await request.json();
|
|
return notifications;
|
|
}
|
|
catch (error) {
|
|
throw new Error(error.message);
|
|
}
|
|
};
|
|
const notifications = await getNotifications();
|
|
const storeUserData = async (notification) => {
|
|
try {
|
|
const user = await prisma.user.upsert({
|
|
where: { userFqn: notification.status.account.fqn },
|
|
update: {
|
|
lastRespondedTo: new Date(Date.now()),
|
|
},
|
|
create: {
|
|
userFqn: notification.status.account.fqn,
|
|
lastRespondedTo: new Date(Date.now()),
|
|
},
|
|
});
|
|
}
|
|
catch (error) {
|
|
throw new Error(error.message);
|
|
}
|
|
};
|
|
const alreadyRespondedTo = async (notification) => {
|
|
try {
|
|
const duplicate = await prisma.response.findFirst({
|
|
where: { pleromaNotificationId: notification.status.id },
|
|
});
|
|
if (duplicate) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
catch (error) {
|
|
throw new Error(error.message);
|
|
}
|
|
};
|
|
const storePromptData = async (notification, ollamaResponseBody) => {
|
|
try {
|
|
await prisma.response.create({
|
|
data: {
|
|
response: ollamaResponseBody.response,
|
|
request: striptags(notification.status.content),
|
|
to: notification.account.fqn,
|
|
pleromaNotificationId: notification.status.id,
|
|
createdAt: new Date(Date.now()),
|
|
},
|
|
});
|
|
}
|
|
catch (error) {
|
|
throw new Error(error.message);
|
|
}
|
|
};
|
|
const generateOllamaRequest = async (notification) => {
|
|
try {
|
|
if (striptags(notification.status.content).includes("!prompt") &&
|
|
!notification.status.account.bot) {
|
|
if (process.env.ONLY_LOCAL_REPLIES === "true" &&
|
|
!notification.status.account.fqn.includes(`@${process.env.PLEROMA_INSTANCE_DOMAIN}`)) {
|
|
return;
|
|
}
|
|
if (await alreadyRespondedTo(notification)) {
|
|
// console.log(
|
|
// `Already responded to notification ID ${notification.status.id}. Canceling.`
|
|
// );
|
|
return;
|
|
}
|
|
await storeUserData(notification);
|
|
const ollamaRequestBody = {
|
|
model: process.env.OLLAMA_MODEL,
|
|
system: process.env.OLLAMA_SYSTEM_PROMPT,
|
|
prompt: striptags(notification.status.content),
|
|
stream: false,
|
|
};
|
|
const response = await fetch(`${process.env.OLLAMA_URL}/api/generate`, {
|
|
method: "POST",
|
|
body: JSON.stringify(ollamaRequestBody),
|
|
});
|
|
const ollamaResponse = await response.json();
|
|
await storePromptData(notification, ollamaResponse);
|
|
console.log(`${notification.status.account.fqn} asked:\n${notification.status.content}\nResponse:\n${ollamaResponse.response}`);
|
|
postReplyToStatus(notification, ollamaResponse);
|
|
}
|
|
}
|
|
catch (error) {
|
|
throw new Error(error.message);
|
|
}
|
|
};
|
|
const postReplyToStatus = async (notification, ollamaResponseBody) => {
|
|
try {
|
|
const mentions = notification.status.mentions?.map((mention) => {
|
|
return mention.acct;
|
|
});
|
|
let statusBody = {
|
|
content_type: "text/markdown",
|
|
status: ollamaResponseBody.response,
|
|
in_reply_to_id: notification.status.id,
|
|
to: mentions,
|
|
};
|
|
const response = await fetch(`${process.env.PLEROMA_INSTANCE_URL}/api/v1/statuses`, {
|
|
method: "POST",
|
|
headers: {
|
|
Authorization: `Bearer ${process.env.INSTANCE_BEARER_TOKEN}`,
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify(statusBody),
|
|
});
|
|
if (!response.ok) {
|
|
throw new Error(`New status request failed: ${response.statusText}`);
|
|
}
|
|
}
|
|
catch (error) {
|
|
throw new Error(error.message);
|
|
}
|
|
};
|
|
if (notifications) {
|
|
await Promise.all(notifications.map((notification) => {
|
|
generateOllamaRequest(notification);
|
|
}));
|
|
}
|