mirror of https://github.com/Chocobozzz/PeerTube
Add video AP hooks
parent
30f939c4b7
commit
c3441b0320
|
@ -1,6 +1,7 @@
|
||||||
|
|
||||||
import { logger, loggerTagsFactory, LoggerTagsFn } from '@server/helpers/logger'
|
import { logger, loggerTagsFactory, LoggerTagsFn } from '@server/helpers/logger'
|
||||||
import { sequelizeTypescript } from '@server/initializers/database'
|
import { sequelizeTypescript } from '@server/initializers/database'
|
||||||
|
import { Hooks } from '@server/lib/plugins/hooks'
|
||||||
import { autoBlacklistVideoIfNeeded } from '@server/lib/video-blacklist'
|
import { autoBlacklistVideoIfNeeded } from '@server/lib/video-blacklist'
|
||||||
import { VideoModel } from '@server/models/video/video'
|
import { VideoModel } from '@server/models/video/video'
|
||||||
import { MThumbnail, MVideoFullLight, MVideoThumbnail } from '@server/types/models'
|
import { MThumbnail, MVideoFullLight, MVideoThumbnail } from '@server/types/models'
|
||||||
|
@ -61,6 +62,8 @@ export class APVideoCreator extends APVideoAbstractBuilder {
|
||||||
|
|
||||||
logger.info('Remote video with uuid %s inserted.', this.videoObject.uuid, this.lTags())
|
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 }
|
return { autoBlacklisted, videoCreated }
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// FIXME: Use rollback hook when https://github.com/sequelize/sequelize/pull/13038 is released
|
// FIXME: Use rollback hook when https://github.com/sequelize/sequelize/pull/13038 is released
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { resetSequelizeInstance, runInReadCommittedTransaction } from '@server/h
|
||||||
import { logger, loggerTagsFactory, LoggerTagsFn } from '@server/helpers/logger'
|
import { logger, loggerTagsFactory, LoggerTagsFn } from '@server/helpers/logger'
|
||||||
import { Notifier } from '@server/lib/notifier'
|
import { Notifier } from '@server/lib/notifier'
|
||||||
import { PeerTubeSocket } from '@server/lib/peertube-socket'
|
import { PeerTubeSocket } from '@server/lib/peertube-socket'
|
||||||
|
import { Hooks } from '@server/lib/plugins/hooks'
|
||||||
import { autoBlacklistVideoIfNeeded } from '@server/lib/video-blacklist'
|
import { autoBlacklistVideoIfNeeded } from '@server/lib/video-blacklist'
|
||||||
import { VideoLiveModel } from '@server/models/video/video-live'
|
import { VideoLiveModel } from '@server/models/video/video-live'
|
||||||
import { MActor, MChannelAccountLight, MChannelId, MVideoAccountLightBlacklistAllFiles, MVideoFullLight } from '@server/types/models'
|
import { MActor, MChannelAccountLight, MChannelId, MVideoAccountLightBlacklistAllFiles, MVideoFullLight } from '@server/types/models'
|
||||||
|
@ -81,6 +82,8 @@ export class APVideoUpdater extends APVideoAbstractBuilder {
|
||||||
PeerTubeSocket.Instance.sendVideoLiveNewState(videoUpdated)
|
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())
|
logger.info('Remote video with uuid %s updated', this.videoObject.uuid, this.lTags())
|
||||||
|
|
||||||
return videoUpdated
|
return videoUpdated
|
||||||
|
|
|
@ -1,42 +1,53 @@
|
||||||
async function register ({ registerHook, registerSetting, settingsManager, storageManager, peertubeHelpers }) {
|
async function register ({ registerHook, registerSetting, settingsManager, storageManager, peertubeHelpers }) {
|
||||||
const actionHooks = [
|
{
|
||||||
'action:application.listening',
|
const actionHooks = [
|
||||||
'action:notifier.notification.created',
|
'action:application.listening',
|
||||||
|
'action:notifier.notification.created',
|
||||||
|
|
||||||
'action:api.video.updated',
|
'action:api.video.updated',
|
||||||
'action:api.video.deleted',
|
'action:api.video.deleted',
|
||||||
'action:api.video.uploaded',
|
'action:api.video.uploaded',
|
||||||
'action:api.video.viewed',
|
'action:api.video.viewed',
|
||||||
|
|
||||||
'action:api.video-channel.created',
|
'action:api.video-channel.created',
|
||||||
'action:api.video-channel.updated',
|
'action:api.video-channel.updated',
|
||||||
'action:api.video-channel.deleted',
|
'action:api.video-channel.deleted',
|
||||||
|
|
||||||
'action:api.live-video.created',
|
'action:api.live-video.created',
|
||||||
|
|
||||||
'action:api.video-thread.created',
|
'action:api.video-thread.created',
|
||||||
'action:api.video-comment-reply.created',
|
'action:api.video-comment-reply.created',
|
||||||
'action:api.video-comment.deleted',
|
'action:api.video-comment.deleted',
|
||||||
|
|
||||||
'action:api.video-caption.created',
|
'action:api.video-caption.created',
|
||||||
'action:api.video-caption.deleted',
|
'action:api.video-caption.deleted',
|
||||||
|
|
||||||
'action:api.user.blocked',
|
'action:api.user.blocked',
|
||||||
'action:api.user.unblocked',
|
'action:api.user.unblocked',
|
||||||
'action:api.user.registered',
|
'action:api.user.registered',
|
||||||
'action:api.user.created',
|
'action:api.user.created',
|
||||||
'action:api.user.deleted',
|
'action:api.user.deleted',
|
||||||
'action:api.user.updated',
|
'action:api.user.updated',
|
||||||
'action:api.user.oauth2-got-token',
|
'action:api.user.oauth2-got-token',
|
||||||
|
|
||||||
'action:api.video-playlist-element.created'
|
'action:api.video-playlist-element.created'
|
||||||
]
|
]
|
||||||
|
|
||||||
for (const h of actionHooks) {
|
for (const h of actionHooks) {
|
||||||
registerHook({
|
registerHook({
|
||||||
target: h,
|
target: h,
|
||||||
handler: () => peertubeHelpers.logger.debug('Run hook %s.', 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({
|
registerHook({
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { ServerHookName, VideoPlaylistPrivacy, VideoPrivacy } from '@shared/mode
|
||||||
import {
|
import {
|
||||||
cleanupTests,
|
cleanupTests,
|
||||||
createMultipleServers,
|
createMultipleServers,
|
||||||
|
doubleFollow,
|
||||||
killallServers,
|
killallServers,
|
||||||
PeerTubeServer,
|
PeerTubeServer,
|
||||||
PluginsCommand,
|
PluginsCommand,
|
||||||
|
@ -36,6 +37,8 @@ describe('Test plugin action hooks', function () {
|
||||||
enabled: true
|
enabled: true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
await doubleFollow(servers[0], servers[1])
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('Application hooks', function () {
|
describe('Application hooks', function () {
|
||||||
|
@ -231,6 +234,27 @@ describe('Test plugin action 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 () {
|
after(async function () {
|
||||||
await cleanupTests(servers)
|
await cleanupTests(servers)
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// {hookType}:{api?}.{location}.{subLocation?}.{actionType}.{target}
|
// {hookType}:{root}.{location}.{subLocation?}.{actionType}.{target}
|
||||||
|
|
||||||
export const serverFilterHookObject = {
|
export const serverFilterHookObject = {
|
||||||
// Filter params/result used to list videos for the REST API
|
// Filter params/result used to list videos for the REST API
|
||||||
|
@ -184,7 +184,11 @@ export const serverActionHookObject = {
|
||||||
'action:api.user.oauth2-got-token': true,
|
'action:api.user.oauth2-got-token': true,
|
||||||
|
|
||||||
// Fired when a video is added to a playlist
|
// 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
|
export type ServerActionHookName = keyof typeof serverActionHookObject
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
- [Add external auth methods](#add-external-auth-methods)
|
- [Add external auth methods](#add-external-auth-methods)
|
||||||
- [Add new transcoding profiles](#add-new-transcoding-profiles)
|
- [Add new transcoding profiles](#add-new-transcoding-profiles)
|
||||||
- [Server helpers](#server-helpers)
|
- [Server helpers](#server-helpers)
|
||||||
|
- [Federation](#federation)
|
||||||
- [Client API (themes & plugins)](#client-api-themes--plugins)
|
- [Client API (themes & plugins)](#client-api-themes--plugins)
|
||||||
- [Get plugin static and router routes](#get-plugin-static-and-router-routes)
|
- [Get plugin static and router routes](#get-plugin-static-and-router-routes)
|
||||||
- [Notifier](#notifier)
|
- [Notifier](#notifier)
|
||||||
|
@ -587,6 +588,49 @@ async function register ({
|
||||||
|
|
||||||
See the [plugin API reference](https://docs.joinpeertube.org/api/plugins) to see the complete helpers list.
|
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)
|
### Client API (themes & plugins)
|
||||||
|
|
||||||
#### Get plugin static and router routes
|
#### Get plugin static and router routes
|
||||||
|
|
Loading…
Reference in New Issue