import { getAPId } from '@server/lib/activitypub/activity' import { ActivityAnnounce } from '../../../../shared/models/activitypub' import { retryTransactionWrapper } from '../../../helpers/database-utils' import { logger } from '../../../helpers/logger' import { sequelizeTypescript } from '../../../initializers/database' import { VideoShareModel } from '../../../models/video/video-share' import { APProcessorOptions } from '../../../types/activitypub-processor.model' import { MActorSignature, MVideoAccountLightBlacklistAllFiles } from '../../../types/models' import { Notifier } from '../../notifier' import { forwardVideoRelatedActivity } from '../send/shared/send-utils' import { getOrCreateAPVideo } from '../videos' async function processAnnounceActivity (options: APProcessorOptions) { const { activity, byActor: actorAnnouncer } = options // Only notify if it is not from a fetcher job const notify = options.fromFetch !== true // Announces on accounts are not supported if (actorAnnouncer.type !== 'Application' && actorAnnouncer.type !== 'Group') return return retryTransactionWrapper(processVideoShare, actorAnnouncer, activity, notify) } // --------------------------------------------------------------------------- export { processAnnounceActivity } // --------------------------------------------------------------------------- async function processVideoShare (actorAnnouncer: MActorSignature, activity: ActivityAnnounce, notify: boolean) { const objectUri = getAPId(activity.object) let video: MVideoAccountLightBlacklistAllFiles let videoCreated: boolean try { const result = await getOrCreateAPVideo({ videoObject: objectUri }) video = result.video videoCreated = result.created } catch (err) { logger.debug('Cannot process share of %s. Maybe this is not a video object, so just skipping.', objectUri, { err }) return } await sequelizeTypescript.transaction(async t => { // Add share entry const share = { actorId: actorAnnouncer.id, videoId: video.id, url: activity.id } const [ , created ] = await VideoShareModel.findOrCreate({ where: { url: activity.id }, defaults: share, transaction: t }) if (video.isOwned() && created === true) { // Don't resend the activity to the sender const exceptions = [ actorAnnouncer ] await forwardVideoRelatedActivity(activity, t, exceptions, video) } return undefined }) if (videoCreated && notify) Notifier.Instance.notifyOnNewVideoIfNeeded(video) }