98 lines
3.4 KiB
JavaScript
98 lines
3.4 KiB
JavaScript
import { genId } from "../misc/gen-id.js";
|
|
import { Bites, Users } from "../models/index.js";
|
|
import { renderActivity } from "../remote/activitypub/renderer/index.js";
|
|
import renderBite from "../remote/activitypub/renderer/bite.js";
|
|
import { deliverToUser } from "../remote/activitypub/deliver-manager.js";
|
|
import { createNotification } from "./create-notification.js";
|
|
import { tickBiteLocal, tickBiteOutgoing } from "../metrics.js";
|
|
import { getNote } from "../server/api/common/getters.js";
|
|
import { IdentifiableError } from "../misc/identifiable-error.js";
|
|
export async function createBite(sender, targetType, targetId, remoteUri = null, createdAt = null) {
|
|
const id = genId();
|
|
const insert = {
|
|
id,
|
|
createdAt: createdAt ?? new Date(),
|
|
userId: sender.id,
|
|
userHost: sender.host,
|
|
targetType,
|
|
replied: false,
|
|
uri: remoteUri
|
|
};
|
|
let targetUser;
|
|
switch(targetType){
|
|
case "user":
|
|
insert.targetUserId = targetId;
|
|
targetUser = await Users.findOneByOrFail({
|
|
id: targetId
|
|
});
|
|
break;
|
|
case "bite":
|
|
insert.targetBiteId = targetId;
|
|
const bite = await Bites.findOneOrFail({
|
|
where: {
|
|
id: targetId
|
|
},
|
|
relations: [
|
|
"user"
|
|
]
|
|
});
|
|
targetUser = bite.user;
|
|
break;
|
|
case "note":
|
|
insert.targetNoteId = targetId;
|
|
const note = await getNote(targetId, sender);
|
|
targetUser = await Users.findOneByOrFail({
|
|
id: note.userId
|
|
});
|
|
break;
|
|
}
|
|
if (targetUser.canBite === "nobody") throw new IdentifiableError("92ce0141-760d-4163-a7a2-73b349e3d133", "Bites disabled");
|
|
const relations = await Users.getRelation(sender.id, targetUser.id);
|
|
if (targetUser.canBite === "followers" && !relations.isFollowing) throw new IdentifiableError("35363f14-f489-45e2-81a9-558450710dfe", "Not following");
|
|
if (relations.isBlocked) throw new IdentifiableError("f82d8d34-beaf-42f3-9135-477d32288213", "Blocked");
|
|
await Bites.insert(insert);
|
|
const bite1 = await Bites.findOneOrFail({
|
|
where: {
|
|
id
|
|
},
|
|
relations: [
|
|
"targetUser",
|
|
"targetBite",
|
|
"targetNote"
|
|
]
|
|
});
|
|
let deliverTarget;
|
|
switch(targetType){
|
|
case "user":
|
|
deliverTarget = bite1.targetUser;
|
|
break;
|
|
case "bite":
|
|
await Bites.update({
|
|
id: bite1.targetBiteId
|
|
}, {
|
|
replied: true
|
|
});
|
|
deliverTarget = bite1.targetBite.user ?? await Users.findOneByOrFail({
|
|
id: bite1.targetBite.userId
|
|
});
|
|
break;
|
|
case "note":
|
|
deliverTarget = bite1.targetNote.user ?? await Users.findOneByOrFail({
|
|
id: bite1.targetNote.userId
|
|
});
|
|
break;
|
|
}
|
|
if (Users.isLocalUser(sender) && Users.isRemoteUser(deliverTarget)) {
|
|
await deliverToUser(sender, renderActivity(await renderBite(bite1)), deliverTarget);
|
|
tickBiteOutgoing();
|
|
}
|
|
if (Users.isLocalUser(deliverTarget)) {
|
|
await createNotification(deliverTarget.id, "bite", {
|
|
notifierId: sender.id,
|
|
biteId: bite1.id
|
|
});
|
|
if (Users.isLocalUser(sender)) tickBiteLocal();
|
|
}
|
|
return id;
|
|
}
|