Standardize bridge send/receive params

This commit is contained in:
Darren Clarke 2024-07-18 11:08:01 +02:00
parent 69abe9bee1
commit c32c26088f
23 changed files with 7042 additions and 1276 deletions

View file

@ -18,12 +18,12 @@
"@emotion/react": "^11.11.4", "@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5", "@emotion/styled": "^11.11.5",
"@mui/icons-material": "^5", "@mui/icons-material": "^5",
"@mui/lab": "^5.0.0-alpha.170", "@mui/lab": "^5.0.0-alpha.172",
"@mui/material": "^5", "@mui/material": "^5",
"@mui/material-nextjs": "^5.15.11", "@mui/material-nextjs": "^5.16.4",
"@mui/x-data-grid-pro": "^7.8.0", "@mui/x-data-grid-pro": "^7.10.0",
"@mui/x-date-pickers-pro": "^7.8.0", "@mui/x-date-pickers-pro": "^7.10.0",
"@mui/x-license": "^7.8.0", "@mui/x-license": "^7.10.0",
"@link-stack/bridge-common": "*", "@link-stack/bridge-common": "*",
"@link-stack/bridge-ui": "*", "@link-stack/bridge-ui": "*",
"@link-stack/signal-api": "*", "@link-stack/signal-api": "*",
@ -32,8 +32,8 @@
"graphile-worker": "^0.16.6", "graphile-worker": "^0.16.6",
"kysely": "0.26.1", "kysely": "0.26.1",
"material-ui-popup-state": "^5.1.2", "material-ui-popup-state": "^5.1.2",
"mui-chips-input": "^2.1.4", "mui-chips-input": "^2.1.5",
"next": "14.2.4", "next": "14.2.5",
"next-auth": "^4.24.7", "next-auth": "^4.24.7",
"pg": "^8.12.0", "pg": "^8.12.0",
"react": "18.3.1", "react": "18.3.1",

View file

@ -95,10 +95,6 @@ export default class WhatsappService extends Service {
const botDirectory = this.getBotDirectory(botID); const botDirectory = this.getBotDirectory(botID);
const qrPath = `${botDirectory}/qr.txt`; const qrPath = `${botDirectory}/qr.txt`;
fs.writeFileSync(qrPath, qr, "utf8"); fs.writeFileSync(qrPath, qr, "utf8");
const verifiedFile = `${botDirectory}/verified`;
if (fs.existsSync(verifiedFile)) {
fs.rmSync(verifiedFile);
}
} else if (isNewLogin) { } else if (isNewLogin) {
console.log("got new login"); console.log("got new login");
const botDirectory = this.getBotDirectory(botID); const botDirectory = this.getBotDirectory(botID);
@ -110,7 +106,6 @@ export default class WhatsappService extends Service {
console.log("connection closed due to ", lastDisconnect?.error); console.log("connection closed due to ", lastDisconnect?.error);
const disconnectStatusCode = (lastDisconnect?.error as any)?.output const disconnectStatusCode = (lastDisconnect?.error as any)?.output
?.statusCode; ?.statusCode;
if (disconnectStatusCode === DisconnectReason.restartRequired) { if (disconnectStatusCode === DisconnectReason.restartRequired) {
console.log("reconnecting after got new login"); console.log("reconnecting after got new login");
await this.createConnection(botID, server, options); await this.createConnection(botID, server, options);
@ -181,26 +176,26 @@ export default class WhatsappService extends Service {
const messageContent = Object.values(message)[0]; const messageContent = Object.values(message)[0];
let messageType: MediaType; let messageType: MediaType;
let attachment: string; let attachment: string | null | undefined;
let filename: string | null | undefined; let filename: string | null | undefined;
let mimetype: string | null | undefined; let mimeType: string | null | undefined;
if (isMediaMessage) { if (isMediaMessage) {
if (audioMessage) { if (audioMessage) {
messageType = "audio"; messageType = "audio";
filename = id + "." + audioMessage.mimetype?.split("/").pop(); filename = id + "." + audioMessage.mimetype?.split("/").pop();
mimetype = audioMessage.mimetype; mimeType = audioMessage.mimetype;
} else if (documentMessage) { } else if (documentMessage) {
messageType = "document"; messageType = "document";
filename = documentMessage.fileName; filename = documentMessage.fileName;
mimetype = documentMessage.mimetype; mimeType = documentMessage.mimetype;
} else if (imageMessage) { } else if (imageMessage) {
messageType = "image"; messageType = "image";
filename = id + "." + imageMessage.mimetype?.split("/").pop(); filename = id + "." + imageMessage.mimetype?.split("/").pop();
mimetype = imageMessage.mimetype; mimeType = imageMessage.mimetype;
} else if (videoMessage) { } else if (videoMessage) {
messageType = "video"; messageType = "video";
filename = id + "." + videoMessage.mimetype?.split("/").pop(); filename = id + "." + videoMessage.mimetype?.split("/").pop();
mimetype = videoMessage.mimetype; mimeType = videoMessage.mimetype;
} }
const stream = await downloadContentFromMessage( const stream = await downloadContentFromMessage(
@ -217,17 +212,6 @@ export default class WhatsappService extends Service {
// @ts-ignore // @ts-ignore
if (messageContent || attachment) { if (messageContent || attachment) {
const receivedMessage = {
waMessageId: id,
waMessage: JSON.stringify(webMessageInfo),
waTimestamp: new Date((messageTimestamp as number) * 1000),
// @ts-ignore
attachment,
filename,
mimetype,
whatsappBotId: botID,
};
const message = const message =
webMessageInfo?.message?.conversation ?? webMessageInfo?.message?.conversation ??
webMessageInfo?.message?.extendedTextMessage?.text ?? webMessageInfo?.message?.extendedTextMessage?.text ??
@ -235,8 +219,14 @@ export default class WhatsappService extends Service {
webMessageInfo?.message?.videoMessage?.caption; webMessageInfo?.message?.videoMessage?.caption;
const payload = { const payload = {
to: botID,
from: webMessageInfo.key.remoteJid?.split("@")[0],
messageId: id,
sentAt: new Date((messageTimestamp as number) * 1000).toISOString(),
message, message,
sender: webMessageInfo.key.remoteJid?.split("@")[0], attachment,
filename,
mimeType,
}; };
await fetch( await fetch(

View file

@ -20,20 +20,20 @@
"jest": "^29.7.0", "jest": "^29.7.0",
"kysely": "^0.27.3", "kysely": "^0.27.3",
"pg": "^8.12.0", "pg": "^8.12.0",
"remeda": "^2.2.2", "remeda": "^2.6.0",
"twilio": "^5.2.2" "twilio": "^5.2.2"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "7.24.7", "@babel/core": "7.24.9",
"@babel/preset-env": "7.24.7", "@babel/preset-env": "7.24.8",
"@babel/preset-typescript": "7.24.7", "@babel/preset-typescript": "7.24.7",
"@types/fluent-ffmpeg": "^2.1.24", "@types/fluent-ffmpeg": "^2.1.24",
"dotenv-cli": "^7.4.2", "dotenv-cli": "^7.4.2",
"@link-stack/eslint-config": "*", "@link-stack/eslint-config": "*",
"prettier": "^3.3.2", "prettier": "^3.3.3",
"@link-stack/typescript-config": "*", "@link-stack/typescript-config": "*",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"typedoc": "^0.26.3", "typedoc": "^0.26.4",
"typescript": "^5.5.3" "typescript": "^5.5.3"
} }
} }

View file

@ -19,8 +19,11 @@ const receiveFacebookMessageTask = async ({
.executeTakeFirstOrThrow(); .executeTakeFirstOrThrow();
const backendId = row.id; const backendId = row.id;
const payload = { const payload = {
text: messaging.message.text, to: pageId,
recipient: messaging.sender.id, from: messaging.sender.id,
sent_at: new Date(messaging.timestamp).toISOString(),
message: messaging.message.text,
message_id: messaging.message.mid,
}; };
await worker.addJob("common/notify-webhooks", { backendId, payload }); await worker.addJob("common/notify-webhooks", { backendId, payload });

View file

@ -2,14 +2,14 @@ import { db } from "@link-stack/bridge-common";
interface SendFacebookMessageTaskOptions { interface SendFacebookMessageTaskOptions {
token: string; token: string;
recipient: string; to: string;
text: string; message: string;
} }
const sendFacebookMessageTask = async ( const sendFacebookMessageTask = async (
options: SendFacebookMessageTaskOptions, options: SendFacebookMessageTaskOptions,
): Promise<void> => { ): Promise<void> => {
const { token, text, recipient } = options; const { token, to, message } = options;
const { pageId, pageAccessToken } = await db const { pageId, pageAccessToken } = await db
.selectFrom("FacebookBot") .selectFrom("FacebookBot")
.selectAll() .selectAll()
@ -19,17 +19,23 @@ const sendFacebookMessageTask = async (
const endpoint = `https://graph.facebook.com/v19.0/${pageId}/messages`; const endpoint = `https://graph.facebook.com/v19.0/${pageId}/messages`;
const outgoingMessage = { const outgoingMessage = {
recipient: { id: recipient }, recipient: { id: to },
message: { text }, message: { text: message },
messaging_type: "RESPONSE", messaging_type: "RESPONSE",
access_token: pageAccessToken, access_token: pageAccessToken,
}; };
await fetch(endpoint, { try {
const response = await fetch(endpoint, {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
body: JSON.stringify(outgoingMessage), body: JSON.stringify(outgoingMessage),
}); });
console.log({ response });
} catch (error) {
console.error({ error });
throw error;
}
}; };
export default sendFacebookMessageTask; export default sendFacebookMessageTask;

View file

@ -17,16 +17,23 @@ const fetchSignalMessagesTask = async (): Promise<void> => {
for (const msg of messages) { for (const msg of messages) {
const { envelope } = msg as any; const { envelope } = msg as any;
const { source, sourceUuid, dataMessage } = envelope; const { source, sourceUuid, dataMessage } = envelope;
const messageID = sourceUuid; const messageId = sourceUuid;
const message = dataMessage?.message; const message = dataMessage?.message;
const timestamp = new Date(dataMessage?.timestamp); const timestamp = new Date(dataMessage?.timestamp);
const attachment = undefined;
const mimeType = undefined;
const filename = undefined;
if (source !== number && message) { if (source !== number && message) {
await worker.addJob("signal/receive-signal-message", { await worker.addJob("signal/receive-signal-message", {
token: id, token: id,
sender: source, to: number,
messageID, from: source,
messageId,
message, message,
timestamp: timestamp.toISOString(), sentAt: timestamp.toISOString(),
attachment,
filename,
mimeType,
}); });
} }
} }

View file

@ -2,20 +2,28 @@ import { db, getWorkerUtils } from "@link-stack/bridge-common";
interface ReceiveSignalMessageTaskOptions { interface ReceiveSignalMessageTaskOptions {
token: string; token: string;
sender: string; to: string;
from: string;
messageId: string;
sentAt: string;
message: string; message: string;
messageID: string; attachment?: string;
timestamp: string; filename?: string;
mimeType?: string;
} }
const receiveSignalMessageTask = async ({ const receiveSignalMessageTask = async ({
token, token,
sender, to,
from,
messageId,
sentAt,
message, message,
messageID, attachment,
timestamp, filename,
mimeType,
}: ReceiveSignalMessageTaskOptions): Promise<void> => { }: ReceiveSignalMessageTaskOptions): Promise<void> => {
console.log({ token, sender, message, messageID, timestamp }); console.log({ token, to, from });
const worker = await getWorkerUtils(); const worker = await getWorkerUtils();
const row = await db const row = await db
.selectFrom("SignalBot") .selectFrom("SignalBot")
@ -23,15 +31,16 @@ const receiveSignalMessageTask = async ({
.where("id", "=", token) .where("id", "=", token)
.executeTakeFirstOrThrow(); .executeTakeFirstOrThrow();
console.log(row);
console.log(message);
const backendId = row.id; const backendId = row.id;
const payload = { const payload = {
to: row.phoneNumber, to,
from: sender, from,
sent_at: timestamp, message_id: messageId,
sent_at: sentAt,
message, message,
message_id: messageID, attachment,
filename,
mime_type: mimeType,
}; };
await worker.addJob("common/notify-webhooks", { backendId, payload }); await worker.addJob("common/notify-webhooks", { backendId, payload });

View file

@ -4,15 +4,16 @@ const { Configuration, MessagesApi } = signalApi;
interface SendSignalMessageTaskOptions { interface SendSignalMessageTaskOptions {
token: string; token: string;
recipient: string; to: string;
message: any; message: any;
} }
const sendSignalMessageTask = async ({ const sendSignalMessageTask = async ({
message,
recipient,
token, token,
to,
message,
}: SendSignalMessageTaskOptions): Promise<void> => { }: SendSignalMessageTaskOptions): Promise<void> => {
console.log({ token, to });
const bot = await db const bot = await db
.selectFrom("SignalBot") .selectFrom("SignalBot")
.selectAll() .selectAll()
@ -24,15 +25,20 @@ const sendSignalMessageTask = async ({
basePath: process.env.BRIDGE_SIGNAL_URL, basePath: process.env.BRIDGE_SIGNAL_URL,
}); });
const messagesClient = new MessagesApi(config); const messagesClient = new MessagesApi(config);
try {
const response = await messagesClient.v2SendPost({ const response = await messagesClient.v2SendPost({
data: { data: {
number, number,
recipients: [recipient], recipients: [to],
message, message,
}, },
}); });
console.log({ response }); console.log({ response });
} catch (error) {
console.error({ error });
throw error;
}
}; };
export default sendSignalMessageTask; export default sendSignalMessageTask;

View file

@ -1,93 +0,0 @@
/* eslint-disable camelcase */
// import logger from "../logger";
// import { IncomingMessagev1 } from "@digiresilience/node-signald/build/main/generated";
import { withDb, AppDatabase } from "../../lib/db.js";
import workerUtils from "../../lib/utils.js";
type IncomingMessagev1 = any;
interface WebhookPayload {
to: string;
from: string;
message_id: string;
sent_at: string;
message: string;
attachment: string | null;
filename: string | null;
mime_type: string | null;
}
interface SignaldMessageTaskOptions {
message: IncomingMessagev1;
botId: string;
botPhoneNumber: string;
attachment: string;
filename: string;
mimetype: string;
}
const formatPayload = (opts: SignaldMessageTaskOptions): WebhookPayload => {
const { botId, botPhoneNumber, message, attachment, filename, mimetype } =
opts;
const { source, timestamp, data_message: dataMessage } = message;
const { number }: any = source;
const { body, attachments }: any = dataMessage;
return {
to: botPhoneNumber,
from: number,
message_id: `${botId}-${timestamp}`,
sent_at: `${timestamp}`,
message: body,
attachment,
filename,
mime_type: mimetype,
};
};
const notifyWebhooks = async (
db: AppDatabase,
messageInfo: SignaldMessageTaskOptions,
) => {
const {
botId,
message: { timestamp },
} = messageInfo;
const webhooks = await db.webhooks.findAllByBackendId("signal", botId);
if (webhooks && webhooks.length === 0) {
// logger.debug({ botId }, "no webhooks registered for signal bot");
return;
}
webhooks.forEach(({ id }: any) => {
const payload = formatPayload(messageInfo);
// logger.debug(
// { payload },
// "formatted signal bot payload for notify-webhook",
// );
workerUtils.addJob(
"notify-webhook",
{
payload,
webhookId: id,
},
{
// this de-deduplicates the job
jobKey: `webhook-${id}-message-${botId}-${timestamp}`,
},
);
});
};
const signaldMessageTask = async (
options: SignaldMessageTaskOptions,
): Promise<void> => {
console.log(options);
withDb(async (db: AppDatabase) => {
await notifyWebhooks(db, options);
});
};
export default signaldMessageTask;

View file

@ -2,130 +2,48 @@ import { db, getWorkerUtils } from "@link-stack/bridge-common";
interface ReceiveWhatsappMessageTaskOptions { interface ReceiveWhatsappMessageTaskOptions {
token: string; token: string;
sender: string; to: string;
from: string;
messageId: string;
sentAt: string;
message: string; message: string;
attachment?: string;
filename?: string;
mimeType?: string;
} }
const receiveWhatsappMessageTask = async ({ const receiveWhatsappMessageTask = async ({
token, token,
sender, to,
from,
messageId,
sentAt,
message, message,
attachment,
filename,
mimeType,
}: ReceiveWhatsappMessageTaskOptions): Promise<void> => { }: ReceiveWhatsappMessageTaskOptions): Promise<void> => {
console.log({ token, sender, message }); console.log({ token, to, from });
const worker = await getWorkerUtils(); const worker = await getWorkerUtils();
const row = await db const row = await db
.selectFrom("WhatsappBot") .selectFrom("WhatsappBot")
.selectAll() .selectAll()
.where("id", "=", token) .where("id", "=", token)
.executeTakeFirstOrThrow(); .executeTakeFirstOrThrow();
console.log(row);
const backendId = row.id; const backendId = row.id;
const payload = { const payload = {
to,
from,
message_id: messageId,
sent_at: sentAt,
message, message,
recipient: sender, attachment,
filename,
mime_type: mimeType,
}; };
await worker.addJob("common/notify-webhooks", { backendId, payload }); await worker.addJob("common/notify-webhooks", { backendId, payload });
}; };
export default receiveWhatsappMessageTask; export default receiveWhatsappMessageTask;
/* eslint-disable camelcase */
/*
import { withDb, AppDatabase } from "../../lib/db";
import workerUtils from "../../lib/utils";
interface WebhookPayload {
to: string;
from: string;
message_id: string;
sent_at: string;
message: string;
attachment: string;
filename: string;
mime_type: string;
}
interface WhatsappMessageTaskOptions {
waMessageId: string;
waMessage: string;
waTimestamp: string;
attachment: string;
filename: string;
mimetype: string;
botPhoneNumber: string;
whatsappBotId: string;
}
const formatPayload = (
messageInfo: WhatsappMessageTaskOptions,
): WebhookPayload => {
const {
waMessageId,
waMessage,
waTimestamp,
attachment,
filename,
mimetype,
botPhoneNumber,
} = messageInfo;
const parsedMessage = JSON.parse(waMessage);
const message =
parsedMessage.message?.conversation ??
parsedMessage.message?.extendedTextMessage?.text ??
parsedMessage.message?.imageMessage?.caption ??
parsedMessage.message?.videoMessage?.caption;
return {
to: botPhoneNumber,
from: parsedMessage.key.remoteJid,
message_id: waMessageId,
sent_at: waTimestamp,
message,
attachment,
filename,
mime_type: mimetype,
};
};
const notifyWebhooks = async (
db: AppDatabase,
messageInfo: WhatsappMessageTaskOptions,
) => {
const { waMessageId, whatsappBotId } = messageInfo;
const webhooks = await db.webhooks.findAllByBackendId(
"whatsapp",
whatsappBotId,
);
if (webhooks && webhooks.length === 0) return;
webhooks.forEach(({ id }) => {
const payload = formatPayload(messageInfo);
console.log({ payload });
workerUtils.addJob(
"notify-webhook",
{
payload,
webhookId: id,
},
{
// this de-deduplicates the job
jobKey: `webhook-${id}-message-${waMessageId}`,
},
);
});
};
const whatsappMessageTask = async (
options: WhatsappMessageTaskOptions,
): Promise<void> => {
console.log(options);
withDb(async (db: AppDatabase) => {
await notifyWebhooks(db, options);
});
};
export default whatsappMessageTask;
*/

View file

@ -2,13 +2,13 @@ import { db } from "@link-stack/bridge-common";
interface SendWhatsappMessageTaskOptions { interface SendWhatsappMessageTaskOptions {
token: string; token: string;
recipient: string; to: string;
message: any; message: any;
} }
const sendWhatsappMessageTask = async ({ const sendWhatsappMessageTask = async ({
message, message,
recipient, to,
token, token,
}: SendWhatsappMessageTaskOptions): Promise<void> => { }: SendWhatsappMessageTaskOptions): Promise<void> => {
const bot = await db const bot = await db
@ -18,15 +18,18 @@ const sendWhatsappMessageTask = async ({
.executeTakeFirstOrThrow(); .executeTakeFirstOrThrow();
const url = `${process.env.BRIDGE_WHATSAPP_URL}/api/bots/${bot.id}/send`; const url = `${process.env.BRIDGE_WHATSAPP_URL}/api/bots/${bot.id}/send`;
const params = { message, phoneNumber: recipient }; const params = { message, phoneNumber: to };
console.log({ params }); try {
const result = await fetch(url, { const result = await fetch(url, {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
body: JSON.stringify(params), body: JSON.stringify(params),
}); });
console.log({ result }); console.log({ result });
} catch (error) {
console.error({ error });
throw new Error("Failed to send message");
}
}; };
export default sendWhatsappMessageTask; export default sendWhatsappMessageTask;

View file

@ -18,17 +18,17 @@
"@emotion/server": "^11.11.0", "@emotion/server": "^11.11.0",
"@emotion/styled": "^11.11.5", "@emotion/styled": "^11.11.5",
"@mui/icons-material": "^5", "@mui/icons-material": "^5",
"@mui/lab": "^5.0.0-alpha.170", "@mui/lab": "^5.0.0-alpha.172",
"@mui/material": "^5", "@mui/material": "^5",
"@mui/x-data-grid-pro": "^7.8.0", "@mui/x-data-grid-pro": "^7.10.0",
"@mui/x-date-pickers-pro": "^7.8.0", "@mui/x-date-pickers-pro": "^7.10.0",
"@opensearch-project/opensearch": "^2.10.0", "@opensearch-project/opensearch": "^2.10.0",
"cryptr": "^6.3.0", "cryptr": "^6.3.0",
"date-fns": "^3.6.0", "date-fns": "^3.6.0",
"http-proxy-middleware": "^3.0.0", "http-proxy-middleware": "^3.0.0",
"@link-stack/leafcutter-ui": "*", "@link-stack/leafcutter-ui": "*",
"material-ui-popup-state": "^5.1.2", "material-ui-popup-state": "^5.1.2",
"next": "14.2.4", "next": "14.2.5",
"next-auth": "^4.24.7", "next-auth": "^4.24.7",
"next-http-proxy-middleware": "^1.2.6", "next-http-proxy-middleware": "^1.2.6",
"@link-stack/opensearch-common": "*", "@link-stack/opensearch-common": "*",
@ -46,18 +46,18 @@
"uuid": "^10.0.0" "uuid": "^10.0.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.24.7", "@babel/core": "^7.24.9",
"@types/node": "^20.14.9", "@types/node": "^20.14.11",
"@types/react": "18.3.3", "@types/react": "18.3.3",
"@types/uuid": "^10.0.0", "@types/uuid": "^10.0.0",
"babel-loader": "^9.1.3", "babel-loader": "^9.1.3",
"eslint": "^8.0.0", "eslint": "^8.0.0",
"eslint-config-next": "^14.2.4", "eslint-config-next": "^14.2.5",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.29.1", "eslint-plugin-import": "^2.29.1",
"eslint-plugin-jsx-a11y": "^6.9.0", "eslint-plugin-jsx-a11y": "^6.9.0",
"eslint-plugin-prettier": "^5.1.3", "eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-react": "^7.34.3", "eslint-plugin-react": "^7.34.4",
"typescript": "5.5.3" "typescript": "5.5.3"
} }
} }

View file

@ -17,10 +17,10 @@
"@emotion/server": "^11.11.0", "@emotion/server": "^11.11.0",
"@emotion/styled": "^11.11.5", "@emotion/styled": "^11.11.5",
"@mui/icons-material": "^5", "@mui/icons-material": "^5",
"@mui/lab": "^5.0.0-alpha.170", "@mui/lab": "^5.0.0-alpha.172",
"@mui/material": "^5", "@mui/material": "^5",
"@mui/x-data-grid-pro": "^7.8.0", "@mui/x-data-grid-pro": "^7.10.0",
"@mui/x-date-pickers-pro": "^7.8.0", "@mui/x-date-pickers-pro": "^7.10.0",
"@link-stack/bridge-common": "*", "@link-stack/bridge-common": "*",
"@link-stack/bridge-ui": "*", "@link-stack/bridge-ui": "*",
"date-fns": "^3.6.0", "date-fns": "^3.6.0",
@ -28,8 +28,8 @@
"graphql-request": "^7.1.0", "graphql-request": "^7.1.0",
"@link-stack/leafcutter-ui": "*", "@link-stack/leafcutter-ui": "*",
"material-ui-popup-state": "^5.1.2", "material-ui-popup-state": "^5.1.2",
"mui-chips-input": "^2.1.4", "mui-chips-input": "^2.1.5",
"next": "14.2.4", "next": "14.2.5",
"next-auth": "^4.24.7", "next-auth": "^4.24.7",
"@link-stack/opensearch-common": "*", "@link-stack/opensearch-common": "*",
"react": "18.3.1", "react": "18.3.1",
@ -44,18 +44,18 @@
"@link-stack/ui": "*" "@link-stack/ui": "*"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.24.7", "@babel/core": "^7.24.9",
"@types/node": "^20.14.9", "@types/node": "^20.14.11",
"@types/react": "18.3.3", "@types/react": "18.3.3",
"@types/uuid": "^10.0.0", "@types/uuid": "^10.0.0",
"babel-loader": "^9.1.3", "babel-loader": "^9.1.3",
"eslint": "^8.0.0", "eslint": "^8.0.0",
"eslint-config-next": "^14.2.4", "eslint-config-next": "^14.2.5",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.29.1", "eslint-plugin-import": "^2.29.1",
"eslint-plugin-jsx-a11y": "^6.9.0", "eslint-plugin-jsx-a11y": "^6.9.0",
"eslint-plugin-prettier": "^5.1.3", "eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-react": "^7.34.3", "eslint-plugin-react": "^7.34.4",
"typescript": "5.5.3" "typescript": "5.5.3"
} }
} }

View file

@ -14,7 +14,7 @@ x-zammad-vars: &common-zammad-variables
ELASTICSEARCH_HOST: ${OPENSEARCH_HOST} ELASTICSEARCH_HOST: ${OPENSEARCH_HOST}
ELASTICSEARCH_USER: ${OPENSEARCH_USER} ELASTICSEARCH_USER: ${OPENSEARCH_USER}
ELASTICSEARCH_PASS: ${OPENSEARCH_ADMIN_PASSWORD} ELASTICSEARCH_PASS: ${OPENSEARCH_ADMIN_PASSWORD}
ELASTICSEARCH_SSL_VERIFY: false # this doesn't set es_ssl_verify as expected, but ideally it would ELASTICSEARCH_SSL_VERIFY: "false" # this doesn't set es_ssl_verify as expected, but ideally it would
ELASTICSEARCH_SCHEMA: "https" ELASTICSEARCH_SCHEMA: "https"
services: services:

7803
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -15,10 +15,10 @@
"pg": "^8.12.0" "pg": "^8.12.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "7.24.7", "@babel/core": "7.24.9",
"@babel/preset-env": "7.24.7", "@babel/preset-env": "7.24.8",
"@babel/preset-typescript": "7.24.7", "@babel/preset-typescript": "7.24.7",
"prettier": "^3.3.2", "prettier": "^3.3.3",
"@link-stack/typescript-config": "*", "@link-stack/typescript-config": "*",
"tsx": "^4.16.2", "tsx": "^4.16.2",
"typescript": "^5.5.3" "typescript": "^5.5.3"

View file

@ -95,9 +95,7 @@ export class Service {
req: NextRequest, req: NextRequest,
{ params: { service, token } }: ServiceParams, { params: { service, token } }: ServiceParams,
): Promise<NextResponse> { ): Promise<NextResponse> {
console.log("INTO receiveMessage");
const json = await req.json(); const json = await req.json();
console.log({ json });
const worker = await getWorkerUtils(); const worker = await getWorkerUtils();
await worker.addJob(`${service}/receive-${service}-message`, { await worker.addJob(`${service}/receive-${service}-message`, {
token, token,

View file

@ -12,14 +12,14 @@
"@emotion/styled": "^11.11.5", "@emotion/styled": "^11.11.5",
"@link-stack/signal-api": "*", "@link-stack/signal-api": "*",
"@mui/icons-material": "^5", "@mui/icons-material": "^5",
"@mui/lab": "^5.0.0-alpha.170", "@mui/lab": "^5.0.0-alpha.172",
"@mui/material": "^5", "@mui/material": "^5",
"@mui/x-data-grid-pro": "^7.8.0", "@mui/x-data-grid-pro": "^7.10.0",
"@mui/x-date-pickers-pro": "^7.8.0", "@mui/x-date-pickers-pro": "^7.10.0",
"date-fns": "^3.6.0", "date-fns": "^3.6.0",
"kysely": "0.26.1", "kysely": "0.26.1",
"material-ui-popup-state": "^5.1.2", "material-ui-popup-state": "^5.1.2",
"next": "14.2.4", "next": "14.2.5",
"react": "18.3.1", "react": "18.3.1",
"react-cookie": "^7.1.4", "react-cookie": "^7.1.4",
"react-cookie-consent": "^9.0.0", "react-cookie-consent": "^9.0.0",
@ -32,19 +32,19 @@
"uuid": "^10.0.0" "uuid": "^10.0.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.24.7", "@babel/core": "^7.24.9",
"@types/node": "^20.14.9", "@types/node": "^20.14.11",
"@types/react": "18.3.3", "@types/react": "18.3.3",
"@types/react-dom": "^18.3.0", "@types/react-dom": "^18.3.0",
"@types/uuid": "^10.0.0", "@types/uuid": "^10.0.0",
"babel-loader": "^9.1.3", "babel-loader": "^9.1.3",
"eslint": "^8.0.0", "eslint": "^8.0.0",
"eslint-config-next": "^14.2.4", "eslint-config-next": "^14.2.5",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.29.1", "eslint-plugin-import": "^2.29.1",
"eslint-plugin-jsx-a11y": "^6.9.0", "eslint-plugin-jsx-a11y": "^6.9.0",
"eslint-plugin-prettier": "^5.1.3", "eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-react": "^7.34.3", "eslint-plugin-react": "^7.34.4",
"file-loader": "^6.2.0", "file-loader": "^6.2.0",
"typescript": "5.5.3" "typescript": "5.5.3"
} }

View file

@ -10,8 +10,8 @@
}, },
"dependencies": { "dependencies": {
"@rushstack/eslint-patch": "^1.10.3", "@rushstack/eslint-patch": "^1.10.3",
"@typescript-eslint/eslint-plugin": "^7.15.0", "@typescript-eslint/eslint-plugin": "^7.16.1",
"@typescript-eslint/parser": "^7.15.0", "@typescript-eslint/parser": "^7.16.1",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"eslint-config-xo-space": "^0.35.0", "eslint-config-xo-space": "^0.35.0",
"eslint-plugin-cypress": "^3.3.0", "eslint-plugin-cypress": "^3.3.0",
@ -20,7 +20,7 @@
"eslint-plugin-jest": "^28.6.0", "eslint-plugin-jest": "^28.6.0",
"eslint-plugin-promise": "^6.4.0", "eslint-plugin-promise": "^6.4.0",
"eslint-plugin-unicorn": "54.0.0", "eslint-plugin-unicorn": "54.0.0",
"@babel/eslint-parser": "7.24.7" "@babel/eslint-parser": "7.24.8"
}, },
"peerDependencies": { "peerDependencies": {
"typescript": "^4.9.5" "typescript": "^4.9.5"

View file

@ -80,7 +80,7 @@ export const QueryListSelector: FC<QueryListSelectorProps> = ({
disableColumnMenu disableColumnMenu
scrollbarSize={10} scrollbarSize={10}
onRowSelectionModelChange={(newSelectionModel) => { onRowSelectionModelChange={(newSelectionModel) => {
setSelectionModel(newSelectionModel); setSelectionModel(newSelectionModel as any);
updateQuery({ updateQuery({
[keyName]: { values: newSelectionModel }, [keyName]: { values: newSelectionModel },
}); });

View file

@ -10,14 +10,14 @@
"@emotion/server": "^11.11.0", "@emotion/server": "^11.11.0",
"@emotion/styled": "^11.11.5", "@emotion/styled": "^11.11.5",
"@mui/icons-material": "^5", "@mui/icons-material": "^5",
"@mui/lab": "^5.0.0-alpha.170", "@mui/lab": "^5.0.0-alpha.172",
"@mui/material": "^5", "@mui/material": "^5",
"@mui/x-data-grid-pro": "^7.8.0", "@mui/x-data-grid-pro": "^7.10.0",
"@mui/x-date-pickers-pro": "^7.8.0", "@mui/x-date-pickers-pro": "^7.10.0",
"@link-stack/opensearch-common": "*", "@link-stack/opensearch-common": "*",
"date-fns": "^3.6.0", "date-fns": "^3.6.0",
"material-ui-popup-state": "^5.1.2", "material-ui-popup-state": "^5.1.2",
"next": "14.2.4", "next": "14.2.5",
"react": "18.3.1", "react": "18.3.1",
"react-cookie": "^7.1.4", "react-cookie": "^7.1.4",
"react-cookie-consent": "^9.0.0", "react-cookie-consent": "^9.0.0",
@ -29,18 +29,18 @@
"uuid": "^10.0.0" "uuid": "^10.0.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.24.7", "@babel/core": "^7.24.9",
"@types/node": "^20.14.9", "@types/node": "^20.14.11",
"@types/react": "18.3.3", "@types/react": "18.3.3",
"@types/uuid": "^10.0.0", "@types/uuid": "^10.0.0",
"babel-loader": "^9.1.3", "babel-loader": "^9.1.3",
"eslint": "^8.0.0", "eslint": "^8.0.0",
"eslint-config-next": "^14.2.4", "eslint-config-next": "^14.2.5",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.29.1", "eslint-plugin-import": "^2.29.1",
"eslint-plugin-jsx-a11y": "^6.9.0", "eslint-plugin-jsx-a11y": "^6.9.0",
"eslint-plugin-prettier": "^5.1.3", "eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-react": "^7.34.3", "eslint-plugin-react": "^7.34.4",
"file-loader": "^6.2.0", "file-loader": "^6.2.0",
"typescript": "5.5.3" "typescript": "5.5.3"
} }

View file

@ -9,8 +9,8 @@
"uuid": "^10.0.0" "uuid": "^10.0.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.24.7", "@babel/core": "^7.24.9",
"@types/node": "^20.14.9", "@types/node": "^20.14.11",
"@types/react": "18.3.3", "@types/react": "18.3.3",
"@types/uuid": "^10.0.0", "@types/uuid": "^10.0.0",
"babel-loader": "^9.1.3", "babel-loader": "^9.1.3",

View file

@ -9,16 +9,16 @@
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@mui/icons-material": "^5", "@mui/icons-material": "^5",
"@mui/lab": "^5.0.0-alpha.170", "@mui/lab": "^5.0.0-alpha.172",
"@mui/material": "^5", "@mui/material": "^5",
"@mui/x-data-grid-pro": "^7.8.0", "@mui/x-data-grid-pro": "^7.10.0",
"@mui/x-date-pickers-pro": "^7.8.0", "@mui/x-date-pickers-pro": "^7.10.0",
"next": "14.2.4", "next": "14.2.5",
"react": "18.3.1", "react": "18.3.1",
"react-dom": "18.3.1" "react-dom": "18.3.1"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^20.14.9", "@types/node": "^20.14.11",
"@types/react": "18.3.3", "@types/react": "18.3.3",
"typescript": "^5.5.3" "typescript": "^5.5.3"
} }