import { Transaction } from 'sequelize'
+import { getServerActor } from '@server/models/application/application'
+import { ContextType } from '@shared/models/activitypub/context'
import { Activity, ActivityAudience } from '../../../../shared/models/activitypub'
+import { afterCommitIfTransaction } from '../../../helpers/database-utils'
import { logger } from '../../../helpers/logger'
-import { ActorModel } from '../../../models/activitypub/actor'
-import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
+import { ActorModel } from '../../../models/actor/actor'
+import { ActorFollowModel } from '../../../models/actor/actor-follow'
+import { MActor, MActorId, MActorLight, MActorWithInboxes, MVideoAccountLight, MVideoId, MVideoImmutable } from '../../../types/models'
import { JobQueue } from '../../job-queue'
import { getActorsInvolvedInVideo, getAudienceFromFollowersOf, getRemoteVideoAudience } from '../audience'
-import { getServerActor } from '../../../helpers/utils'
-import { afterCommitIfTransaction } from '../../../helpers/database-utils'
-import { MActorFollowerException, MActor, MActorId, MActorLight, MVideo, MVideoAccountLight } from '../../../typings/models'
async function sendVideoRelatedActivity (activityBuilder: (audience: ActivityAudience) => Activity, options: {
- byActor: MActorLight,
- video: MVideoAccountLight,
+ byActor: MActorLight
+ video: MVideoImmutable | MVideoAccountLight
transaction?: Transaction
+ contextType?: ContextType
}) {
- const { byActor, video, transaction } = options
+ const { byActor, video, transaction, contextType } = options
const actorsInvolvedInVideo = await getActorsInvolvedInVideo(video, transaction)
// Send to origin
if (video.isOwned() === false) {
- const audience = getRemoteVideoAudience(video, actorsInvolvedInVideo)
+ const accountActor = (video as MVideoAccountLight).VideoChannel?.Account?.Actor || await ActorModel.loadAccountActorByVideoId(video.id)
+
+ const audience = getRemoteVideoAudience(accountActor, actorsInvolvedInVideo)
const activity = activityBuilder(audience)
return afterCommitIfTransaction(transaction, () => {
- return unicastTo(activity, byActor, video.VideoChannel.Account.Actor.sharedInboxUrl)
+ return unicastTo(activity, byActor, accountActor.getSharedInbox(), contextType)
})
}
const actorsException = [ byActor ]
- return broadcastToFollowers(activity, byActor, actorsInvolvedInVideo, transaction, actorsException)
+ return broadcastToFollowers(activity, byActor, actorsInvolvedInVideo, transaction, actorsException, contextType)
}
async function forwardVideoRelatedActivity (
activity: Activity,
t: Transaction,
- followersException: MActorFollowerException[] = [],
- video: MVideo
+ followersException: MActorWithInboxes[],
+ video: MVideoId
) {
// Mastodon does not add our announces in audience, so we forward to them manually
const additionalActors = await getActorsInvolvedInVideo(video, t)
async function forwardActivity (
activity: Activity,
t: Transaction,
- followersException: MActorFollowerException[] = [],
+ followersException: MActorWithInboxes[] = [],
additionalFollowerUrls: string[] = []
) {
logger.info('Forwarding activity %s.', activity.id)
byActor: MActorId,
toFollowersOf: MActorId[],
t: Transaction,
- actorsException: MActorFollowerException[] = []
+ actorsException: MActorWithInboxes[] = [],
+ contextType?: ContextType
) {
const uris = await computeFollowerUris(toFollowersOf, actorsException, t)
- return afterCommitIfTransaction(t, () => broadcastTo(uris, data, byActor))
+ return afterCommitIfTransaction(t, () => broadcastTo(uris, data, byActor, contextType))
}
async function broadcastToActors (
byActor: MActorId,
toActors: MActor[],
t?: Transaction,
- actorsException: MActorFollowerException[] = []
+ actorsException: MActorWithInboxes[] = [],
+ contextType?: ContextType
) {
const uris = await computeUris(toActors, actorsException)
- return afterCommitIfTransaction(t, () => broadcastTo(uris, data, byActor))
+ return afterCommitIfTransaction(t, () => broadcastTo(uris, data, byActor, contextType))
}
-function broadcastTo (uris: string[], data: any, byActor: MActorId) {
+function broadcastTo (uris: string[], data: any, byActor: MActorId, contextType?: ContextType) {
if (uris.length === 0) return undefined
logger.debug('Creating broadcast job.', { uris })
const payload = {
uris,
signatureActorId: byActor.id,
- body: data
+ body: data,
+ contextType
}
return JobQueue.Instance.createJob({ type: 'activitypub-http-broadcast', payload })
}
-function unicastTo (data: any, byActor: MActorId, toActorUrl: string) {
+function unicastTo (data: any, byActor: MActorId, toActorUrl: string, contextType?: ContextType) {
logger.debug('Creating unicast job.', { uri: toActorUrl })
const payload = {
uri: toActorUrl,
signatureActorId: byActor.id,
- body: data
+ body: data,
+ contextType
}
JobQueue.Instance.createJob({ type: 'activitypub-http-unicast', payload })
// ---------------------------------------------------------------------------
-async function computeFollowerUris (toFollowersOf: MActorId[], actorsException: MActorFollowerException[], t: Transaction) {
+async function computeFollowerUris (toFollowersOf: MActorId[], actorsException: MActorWithInboxes[], t: Transaction) {
const toActorFollowerIds = toFollowersOf.map(a => a.id)
const result = await ActorFollowModel.listAcceptedFollowerSharedInboxUrls(toActorFollowerIds, t)
const sharedInboxesException = await buildSharedInboxesException(actorsException)
- return result.data.filter(sharedInbox => sharedInboxesException.indexOf(sharedInbox) === -1)
+ return result.data.filter(sharedInbox => sharedInboxesException.includes(sharedInbox) === false)
}
-async function computeUris (toActors: MActor[], actorsException: MActorFollowerException[] = []) {
+async function computeUris (toActors: MActor[], actorsException: MActorWithInboxes[] = []) {
const serverActor = await getServerActor()
const targetUrls = toActors
.filter(a => a.id !== serverActor.id) // Don't send to ourselves
- .map(a => a.sharedInboxUrl || a.inboxUrl)
+ .map(a => a.getSharedInbox())
const toActorSharedInboxesSet = new Set(targetUrls)
const sharedInboxesException = await buildSharedInboxesException(actorsException)
return Array.from(toActorSharedInboxesSet)
- .filter(sharedInbox => sharedInboxesException.indexOf(sharedInbox) === -1)
+ .filter(sharedInbox => sharedInboxesException.includes(sharedInbox) === false)
}
-async function buildSharedInboxesException (actorsException: MActorFollowerException[]) {
+async function buildSharedInboxesException (actorsException: MActorWithInboxes[]) {
const serverActor = await getServerActor()
return actorsException
- .map(f => f.sharedInboxUrl || f.inboxUrl)
+ .map(f => f.getSharedInbox())
.concat([ serverActor.sharedInboxUrl ])
}