Hooks prefixed by `action:api` now give access the original express req and res.
Checkout guide.md for possible usage.
res.status(HttpStatusCode.NO_CONTENT_204).end()
for (const comment of comments) {
- await removeComment(comment)
+ await removeComment(comment, req, res)
}
}
await Emailer.Instance.addPasswordCreateEmailJob(userToCreate.username, user.email, url)
}
- Hooks.runAction('action:api.user.created', { body, user, account, videoChannel })
+ Hooks.runAction('action:api.user.created', { body, user, account, videoChannel, req, res })
return res.json({
user: {
Notifier.Instance.notifyOnNewUserRegistration(user)
- Hooks.runAction('action:api.user.registered', { body, user, account, videoChannel })
+ Hooks.runAction('action:api.user.registered', { body, user, account, videoChannel, req, res })
return res.type('json').status(HttpStatusCode.NO_CONTENT_204).end()
}
await changeUserBlock(res, user, false)
- Hooks.runAction('action:api.user.unblocked', { user })
+ Hooks.runAction('action:api.user.unblocked', { user, req, res })
return res.status(HttpStatusCode.NO_CONTENT_204).end()
}
await changeUserBlock(res, user, true, reason)
- Hooks.runAction('action:api.user.blocked', { user })
+ Hooks.runAction('action:api.user.blocked', { user, req, res })
return res.status(HttpStatusCode.NO_CONTENT_204).end()
}
await user.destroy({ transaction: t })
})
- Hooks.runAction('action:api.user.deleted', { user })
+ Hooks.runAction('action:api.user.deleted', { user, req, res })
return res.status(HttpStatusCode.NO_CONTENT_204).end()
}
auditLogger.update(getAuditIdFromRes(res), new UserAuditView(user.toFormattedJSON()), oldUserAuditView)
- Hooks.runAction('action:api.user.updated', { user })
+ Hooks.runAction('action:api.user.updated', { user, req, res })
// Don't need to send this update to followers, these attributes are not federated
res.set('Cache-Control', 'no-store')
res.set('Pragma', 'no-cache')
- Hooks.runAction('action:api.user.oauth2-got-token', { username: token.user.username, ip: req.ip })
+ Hooks.runAction('action:api.user.oauth2-got-token', { username: token.user.username, ip: req.ip, req, res })
return res.json({
token_type: 'Bearer',
logger.info('Video added in playlist %s at position %d.', videoPlaylist.uuid, playlistElement.position)
- Hooks.runAction('action:api.video-playlist-element.created', { playlistElement })
+ Hooks.runAction('action:api.video-playlist-element.created', { playlistElement, req, res })
return res.json({
videoPlaylistElement: {
Notifier.Instance.notifyOnNewComment(comment)
auditLogger.create(getAuditIdFromRes(res), new CommentAuditView(comment.toFormattedJSON()))
- Hooks.runAction('action:api.video-thread.created', { comment })
+ Hooks.runAction('action:api.video-thread.created', { comment, req, res })
return res.json({ comment: comment.toFormattedJSON() })
}
Notifier.Instance.notifyOnNewComment(comment)
auditLogger.create(getAuditIdFromRes(res), new CommentAuditView(comment.toFormattedJSON()))
- Hooks.runAction('action:api.video-comment-reply.created', { comment })
+ Hooks.runAction('action:api.video-comment-reply.created', { comment, req, res })
return res.json({ comment: comment.toFormattedJSON() })
}
async function removeVideoComment (req: express.Request, res: express.Response) {
const videoCommentInstance = res.locals.videoCommentFull
- await removeComment(videoCommentInstance)
+ await removeComment(videoCommentInstance, req, res)
auditLogger.delete(getAuditIdFromRes(res), new CommentAuditView(videoCommentInstance.toFormattedJSON()))
const serverActor = await getServerActor()
await sendView(serverActor, video, undefined)
- Hooks.runAction('action:api.video.viewed', { video: video, ip })
+ Hooks.runAction('action:api.video.viewed', { video: video, ip, req, res })
}
return res.status(HttpStatusCode.NO_CONTENT_204).end()
return res.json(getFormattedObjects(resultList.data, resultList.total, guessAdditionalAttributesFromQuery(query)))
}
-async function removeVideo (_req: express.Request, res: express.Response) {
+async function removeVideo (req: express.Request, res: express.Response) {
const videoInstance = res.locals.videoAll
await sequelizeTypescript.transaction(async t => {
auditLogger.delete(getAuditIdFromRes(res), new VideoAuditView(videoInstance.toFormattedDetailsJSON()))
logger.info('Video with name %s and uuid %s deleted.', videoInstance.name, videoInstance.uuid)
- Hooks.runAction('action:api.video.deleted', { video: videoInstance })
+ Hooks.runAction('action:api.video.deleted', { video: videoInstance, req, res })
return res.type('json')
.status(HttpStatusCode.NO_CONTENT_204)
return { videoCreated }
})
- Hooks.runAction('action:api.live-video.created', { video: videoCreated })
+ Hooks.runAction('action:api.live-video.created', { video: videoCreated, req, res })
return res.json({
video: {
Notifier.Instance.notifyOnNewVideoIfNeeded(videoInstanceUpdated)
}
- Hooks.runAction('action:api.video.updated', { video: videoInstanceUpdated, body: req.body })
+ Hooks.runAction('action:api.video.updated', { video: videoInstanceUpdated, body: req.body, req, res })
} catch (err) {
// Force fields we want to update
// If the transaction is retried, sequelize will think the object has not changed
const videoInfo: VideoCreate = req.body
const files = req.files
- const response = await addVideo({ res, videoPhysicalFile, videoInfo, files })
+ const response = await addVideo({ req, res, videoPhysicalFile, videoInfo, files })
return res.json(response)
}
const videoInfo = videoPhysicalFile.metadata
const files = { previewfile: videoInfo.previewfile }
- const response = await addVideo({ res, videoPhysicalFile, videoInfo, files })
+ const response = await addVideo({ req, res, videoPhysicalFile, videoInfo, files })
await Redis.Instance.setUploadSession(req.query.upload_id, response)
return res.json(response)
}
async function addVideo (options: {
+ req: express.Request
res: express.Response
videoPhysicalFile: express.VideoUploadFile
videoInfo: VideoCreate
files: express.UploadFiles
}) {
- const { res, videoPhysicalFile, videoInfo, files } = options
+ const { req, res, videoPhysicalFile, videoInfo, files } = options
const videoChannel = res.locals.videoChannel
const user = res.locals.oauth.token.User
})
.catch(err => logger.error('Cannot add optimize/merge audio job for %s.', videoCreated.uuid, { err, ...lTags(videoCreated.uuid) }))
- Hooks.runAction('action:api.video.uploaded', { video: videoCreated })
+ Hooks.runAction('action:api.video.uploaded', { video: videoCreated, req, res })
return {
video: {
import { cloneDeep } from 'lodash'
import * as Sequelize from 'sequelize'
+import express from 'express'
import { logger } from '@server/helpers/logger'
import { sequelizeTypescript } from '@server/initializers/database'
import { ResultList } from '../../shared/models'
import { getLocalVideoCommentActivityPubUrl } from './activitypub/url'
import { Hooks } from './plugins/hooks'
-async function removeComment (videoCommentInstance: MCommentOwnerVideo) {
+async function removeComment (videoCommentInstance: MCommentOwnerVideo, req: express.Request, res: express.Response) {
const videoCommentInstanceBefore = cloneDeep(videoCommentInstance)
await sequelizeTypescript.transaction(async t => {
logger.info('Video comment %d deleted.', videoCommentInstance.id)
- Hooks.runAction('action:api.video-comment.deleted', { comment: videoCommentInstanceBefore })
+ Hooks.runAction('action:api.video-comment.deleted', { comment: videoCommentInstanceBefore, req, res })
}
async function createVideoComment (obj: {
// Fired when the application has been loaded and is listening HTTP requests
'action:application.listening': true,
+ // API actions hooks give access to the original express `req` and `res` parameters
+
// Fired when a local video is updated
'action:api.video.updated': true,
// Fired when a local video is deleted
}
```
+Hooks prefixed by `action:api` also give access the original **express** [Request](http://expressjs.com/en/api.html#req) and [Response](http://expressjs.com/en/api.html#res):
+
+```js
+async function register ({
+ registerHook,
+ peertubeHelpers: { logger }
+}) {
+ registerHook({
+ target: 'action:api.video.updated',
+ handler: ({ req, res }) => logger.debug('original request parameters', { params: req.params })
+ })
+}
+```
+
On client side, these hooks are registered by the `clientScripts` files defined in `package.json`.
All client scripts have scopes so PeerTube client only loads scripts it needs: