///
// Hook for sending team invitation emails
onRecordAfterCreateRequest((e) => {
// Handle new team invitations for existing users
if (e.collection.name === "workspace_members") {
const record = e.record;
// Only send email for pending invitations
if (record.get("invitation_status") !== "pending") {
return;
}
try {
// Get the invited user's email and workspace owner
const user = $app.dao().findRecordById("users", record.get("user"));
const workspace = $app.dao().findRecordById("workspaces", record.get("workspace"));
const owner = workspace ? $app.dao().findRecordById("users", workspace.get("owner")) : null;
if (!user || !owner) {
console.log("Could not find user or owner");
return;
}
const inviterName = owner.get("name") || owner.get("username") || owner.get("email");
const token = record.get("invitation_token");
const appUrl = "https://ulo.ad"; // Change this to your domain
// Email content
const subject = `${inviterName} hat dich zu seinem Team eingeladen / invited you to their team - ulo.ad π₯`;
const html = `
π ulo.ad
π₯ Team-Einladung / Team Invitation
π©πͺ ${inviterName} hat dich eingeladen, Teil des Teams zu werden!
π¬π§ ${inviterName} has invited you to join their team!
Von / From: ${owner.get("email")}
An / To: ${user.get("email")}
β±οΈ Diese Einladung ist 7 Tage gΓΌltig / This invitation is valid for 7 days
`;
// Send email using PocketBase's mailer
const message = new MailerMessage({
from: {
address: $app.settings().meta.senderAddress,
name: $app.settings().meta.senderName,
},
to: [{address: user.get("email"), name: user.get("name") || user.get("username")}],
subject: subject,
html: html,
});
$app.newMailClient().send(message);
console.log(`Team invitation email sent to ${user.get("email")}`);
// Create in-app notification for the invited user
try {
const notification = new Record($app.dao().findCollectionByNameOrId("notifications"));
notification.set("user", user.id);
notification.set("type", "team_invite");
notification.set("title", "Neue Team-Einladung / New Team Invitation");
notification.set("message", `${inviterName} hat dich zu seinem Team eingeladen / invited you to their team`);
notification.set("data", {
invitation_id: record.id,
owner_id: owner.id,
owner_name: inviterName,
invitation_token: token
});
notification.set("read", false);
notification.set("action_url", `${appUrl}/team/accept-invite?token=${token}`);
$app.dao().saveRecord(notification);
console.log(`In-app notification created for user ${user.get("email")}`);
} catch (notifError) {
console.error("Failed to create in-app notification:", notifError);
}
} catch (error) {
console.error("Failed to send team invitation email:", error);
}
}
}, "workspace_members");
// Hook for sending invitations to new users (not registered yet)
onRecordAfterCreateRequest((e) => {
if (e.collection.name === "pending_invitations") {
const record = e.record;
try {
const owner = $app.dao().findRecordById("users", record.get("owner"));
if (!owner) {
console.log("Could not find invitation owner");
return;
}
const inviterName = owner.get("name") || owner.get("username") || owner.get("email");
const token = record.get("token");
const recipientEmail = record.get("email");
const appUrl = "https://ulo.ad"; // Change this to your domain
// Email content for new users
const subject = `${inviterName} hat dich zu ulo.ad eingeladen / invited you to ulo.ad - π`;
const html = `
π ulo.ad
π Willkommen bei ulo.ad / Welcome to ulo.ad
π©πͺ ${inviterName} hat dich eingeladen, Teil des Teams zu werden!
π¬π§ ${inviterName} has invited you to join their team!
π Neu bei ulo.ad? / New to ulo.ad?
π©πͺ Kein Problem! Erstelle einfach einen kostenlosen Account und die Einladung wird automatisch angenommen.
π¬π§ No problem! Simply create a free account and the invitation will be accepted automatically.
β±οΈ Diese Einladung ist 7 Tage gΓΌltig / This invitation is valid for 7 days
`;
// Send email
const message = new MailerMessage({
from: {
address: $app.settings().meta.senderAddress,
name: $app.settings().meta.senderName,
},
to: [{address: recipientEmail}],
subject: subject,
html: html,
});
$app.newMailClient().send(message);
console.log(`New user invitation email sent to ${recipientEmail}`);
} catch (error) {
console.error("Failed to send new user invitation email:", error);
}
}
}, "pending_invitations");
// Hook for sending acceptance notifications
onRecordAfterUpdateRequest((e) => {
if (e.collection.name === "workspace_members") {
const record = e.record;
const originalRecord = e.originalRecord;
// Check if invitation was just accepted
if (originalRecord.get("invitation_status") === "pending" &&
record.get("invitation_status") === "accepted") {
try {
const user = $app.dao().findRecordById("users", record.get("user"));
const workspace = $app.dao().findRecordById("workspaces", record.get("workspace"));
const owner = workspace ? $app.dao().findRecordById("users", workspace.get("owner")) : null;
if (!user || !owner) {
return;
}
const subject = `${user.get("email")} hat deine Einladung angenommen / accepted your invitation - ulo.ad β
`;
const html = `
π ulo.ad
Einladung angenommen / Invitation Accepted
π©πͺ ${user.get("email")} hat deine Team-Einladung angenommen!
π¬π§ ${user.get("email")} has accepted your team invitation!
`;
// Send notification to owner
const message = new MailerMessage({
from: {
address: $app.settings().meta.senderAddress,
name: $app.settings().meta.senderName,
},
to: [{address: owner.get("email"), name: owner.get("name") || owner.get("username")}],
subject: subject,
html: html,
});
$app.newMailClient().send(message);
console.log(`Acceptance notification sent to ${owner.get("email")}`);
// Create in-app notification for the owner
try {
const notification = new Record($app.dao().findCollectionByNameOrId("notifications"));
notification.set("user", owner.id);
notification.set("type", "team_accepted");
notification.set("title", "Team-Einladung angenommen / Team Invitation Accepted");
notification.set("message", `${user.get("email")} ist deinem Team beigetreten / has joined your team`);
notification.set("data", {
member_id: user.id,
member_email: user.get("email"),
member_name: user.get("name") || user.get("username") || user.get("email")
});
notification.set("read", false);
notification.set("action_url", "https://ulo.ad/settings/team");
$app.dao().saveRecord(notification);
console.log(`In-app notification created for owner ${owner.get("email")}`);
} catch (notifError) {
console.error("Failed to create owner notification:", notifError);
}
} catch (error) {
console.error("Failed to send acceptance notification:", error);
}
}
}
}, "workspace_members");