import { logger, loggerTagsFactory, LoggerTagsFn } from '@server/helpers/logger'
import { sequelizeTypescript } from '@server/initializers/database'
+import { Hooks } from '@server/lib/plugins/hooks'
import { autoBlacklistVideoIfNeeded } from '@server/lib/video-blacklist'
import { VideoModel } from '@server/models/video/video'
import { MThumbnail, MVideoFullLight, MVideoThumbnail } from '@server/types/models'
logger.info('Remote video with uuid %s inserted.', this.videoObject.uuid, this.lTags())
+ Hooks.runAction('action:activity-pub.remote-video.created', { video: videoCreated, videoAPObject: this.videoObject })
+
return { autoBlacklisted, videoCreated }
} catch (err) {
// FIXME: Use rollback hook when https://github.com/sequelize/sequelize/pull/13038 is released
import { logger, loggerTagsFactory, LoggerTagsFn } from '@server/helpers/logger'
import { Notifier } from '@server/lib/notifier'
import { PeerTubeSocket } from '@server/lib/peertube-socket'
+import { Hooks } from '@server/lib/plugins/hooks'
import { autoBlacklistVideoIfNeeded } from '@server/lib/video-blacklist'
import { VideoLiveModel } from '@server/models/video/video-live'
import { MActor, MChannelAccountLight, MChannelId, MVideoAccountLightBlacklistAllFiles, MVideoFullLight } from '@server/types/models'
PeerTubeSocket.Instance.sendVideoLiveNewState(videoUpdated)
}
+ Hooks.runAction('action:activity-pub.remote-video.updated', { video: videoUpdated, videoAPObject: this.videoObject })
+
logger.info('Remote video with uuid %s updated', this.videoObject.uuid, this.lTags())
return videoUpdated
async function register ({ registerHook, registerSetting, settingsManager, storageManager, peertubeHelpers }) {
- const actionHooks = [
- 'action:application.listening',
- 'action:notifier.notification.created',
+ {
+ const actionHooks = [
+ 'action:application.listening',
+ 'action:notifier.notification.created',
- 'action:api.video.updated',
- 'action:api.video.deleted',
- 'action:api.video.uploaded',
- 'action:api.video.viewed',
+ 'action:api.video.updated',
+ 'action:api.video.deleted',
+ 'action:api.video.uploaded',
+ 'action:api.video.viewed',
- 'action:api.video-channel.created',
- 'action:api.video-channel.updated',
- 'action:api.video-channel.deleted',
+ 'action:api.video-channel.created',
+ 'action:api.video-channel.updated',
+ 'action:api.video-channel.deleted',
- 'action:api.live-video.created',
+ 'action:api.live-video.created',
- 'action:api.video-thread.created',
- 'action:api.video-comment-reply.created',
- 'action:api.video-comment.deleted',
+ 'action:api.video-thread.created',
+ 'action:api.video-comment-reply.created',
+ 'action:api.video-comment.deleted',
- 'action:api.video-caption.created',
- 'action:api.video-caption.deleted',
+ 'action:api.video-caption.created',
+ 'action:api.video-caption.deleted',
- 'action:api.user.blocked',
- 'action:api.user.unblocked',
- 'action:api.user.registered',
- 'action:api.user.created',
- 'action:api.user.deleted',
- 'action:api.user.updated',
- 'action:api.user.oauth2-got-token',
+ 'action:api.user.blocked',
+ 'action:api.user.unblocked',
+ 'action:api.user.registered',
+ 'action:api.user.created',
+ 'action:api.user.deleted',
+ 'action:api.user.updated',
+ 'action:api.user.oauth2-got-token',
- 'action:api.video-playlist-element.created'
- ]
+ 'action:api.video-playlist-element.created'
+ ]
- for (const h of actionHooks) {
- registerHook({
- target: h,
- handler: () => peertubeHelpers.logger.debug('Run hook %s.', h)
- })
+ for (const h of actionHooks) {
+ registerHook({
+ target: h,
+ handler: () => peertubeHelpers.logger.debug('Run hook %s.', h)
+ })
+ }
+
+ for (const h of [ 'action:activity-pub.remote-video.created', 'action:activity-pub.remote-video.updated' ]) {
+ registerHook({
+ target: h,
+ handler: ({ video, videoAPObject }) => {
+ peertubeHelpers.logger.debug('Run hook %s - AP %s - video %s.', h, video.name, videoAPObject.name )
+ }
+ })
+ }
}
registerHook({
import {
cleanupTests,
createMultipleServers,
+ doubleFollow,
killallServers,
PeerTubeServer,
PluginsCommand,
enabled: true
}
})
+
+ await doubleFollow(servers[0], servers[1])
})
describe('Application hooks', function () {
})
})
+ describe('Activity Pub hooks', function () {
+ let videoUUID: string
+
+ it('Should run action:activity-pub.remote-video.created', async function () {
+ this.timeout(30000)
+
+ const { uuid } = await servers[1].videos.quickUpload({ name: 'remote video' })
+ videoUUID = uuid
+
+ await servers[0].servers.waitUntilLog('action:activity-pub.remote-video.created - AP remote video - video remote video')
+ })
+
+ it('Should run action:activity-pub.remote-video.updated', async function () {
+ this.timeout(30000)
+
+ await servers[1].videos.update({ id: videoUUID, attributes: { name: 'remote video updated' } })
+
+ await servers[0].servers.waitUntilLog('action:activity-pub.remote-video.updated - AP remote video - video remote video')
+ })
+ })
+
after(async function () {
await cleanupTests(servers)
})
-// {hookType}:{api?}.{location}.{subLocation?}.{actionType}.{target}
+// {hookType}:{root}.{location}.{subLocation?}.{actionType}.{target}
export const serverFilterHookObject = {
// Filter params/result used to list videos for the REST API
'action:api.user.oauth2-got-token': true,
// Fired when a video is added to a playlist
- 'action:api.video-playlist-element.created': true
+ 'action:api.video-playlist-element.created': true,
+
+ // Fired when a remote video has been created/updated
+ 'action:activity-pub.remote-video.created': true,
+ 'action:activity-pub.remote-video.updated': true
}
export type ServerActionHookName = keyof typeof serverActionHookObject
- [Add external auth methods](#add-external-auth-methods)
- [Add new transcoding profiles](#add-new-transcoding-profiles)
- [Server helpers](#server-helpers)
+ - [Federation](#federation)
- [Client API (themes & plugins)](#client-api-themes--plugins)
- [Get plugin static and router routes](#get-plugin-static-and-router-routes)
- [Notifier](#notifier)
See the [plugin API reference](https://docs.joinpeertube.org/api/plugins) to see the complete helpers list.
+#### Federation
+
+You can use some server hooks to federate plugin data to other PeerTube instances that may have installed your plugin.
+
+For example to federate additional video metadata:
+
+```js
+async function register ({ registerHook }) {
+
+ // Send plugin metadata to remote instances
+ // We also update the JSON LD context because we added a new field
+ {
+ registerHook({
+ target: 'filter:activity-pub.video.json-ld.build.result',
+ handler: async (jsonld, { video }) => {
+ return Object.assign(jsonld, { recordedAt: 'https://example.com/event' })
+ }
+ })
+
+ registerHook({
+ target: 'filter:activity-pub.activity.context.build.result',
+ handler: jsonld => {
+ return jsonld.concat([ { recordedAt: 'https://schema.org/recordedAt' } ])
+ }
+ })
+ }
+
+ // Save remote video metadata
+ {
+ for (const h of [ 'action:activity-pub.remote-video.created', 'action:activity-pub.remote-video.updated' ]) {
+ registerHook({
+ target: h,
+ handler: ({ video, videoAPObject }) => {
+ if (videoAPObject.recordedAt) {
+ // Save information about the video
+ }
+ }
+ })
+ }
+ }
+```
+
+
### Client API (themes & plugins)
#### Get plugin static and router routes