9fbaa8196a21c721670f2b48ea5956cc7e645f2e
[oweals/peertube.git] / server / lib / activitypub / send / send-create.ts
1 import { Transaction } from 'sequelize'
2 import { ActivityAudience, ActivityCreate } from '../../../../shared/models/activitypub'
3 import { getServerAccount } from '../../../helpers'
4 import { AccountModel } from '../../../models/account/account'
5 import { VideoModel } from '../../../models/video/video'
6 import { VideoAbuseModel } from '../../../models/video/video-abuse'
7 import { VideoChannelModel } from '../../../models/video/video-channel'
8 import { getVideoAbuseActivityPubUrl, getVideoDislikeActivityPubUrl, getVideoViewActivityPubUrl } from '../url'
9 import {
10   broadcastToFollowers,
11   getAccountsInvolvedInVideo,
12   getAudience,
13   getObjectFollowersAudience,
14   getOriginVideoAudience,
15   unicastTo
16 } from './misc'
17
18 async function sendCreateVideoChannel (videoChannel: VideoChannelModel, t: Transaction) {
19   const byAccount = videoChannel.Account
20
21   const videoChannelObject = videoChannel.toActivityPubObject()
22   const data = await createActivityData(videoChannel.url, byAccount, videoChannelObject, t)
23
24   return broadcastToFollowers(data, byAccount, [ byAccount ], t)
25 }
26
27 async function sendVideoAbuse (byAccount: AccountModel, videoAbuse: VideoAbuseModel, video: VideoModel, t: Transaction) {
28   const url = getVideoAbuseActivityPubUrl(videoAbuse)
29
30   const audience = { to: [ video.VideoChannel.Account.url ], cc: [] }
31   const data = await createActivityData(url, byAccount, videoAbuse.toActivityPubObject(), t, audience)
32
33   return unicastTo(data, byAccount, video.VideoChannel.Account.sharedInboxUrl, t)
34 }
35
36 async function sendCreateViewToOrigin (byAccount: AccountModel, video: VideoModel, t: Transaction) {
37   const url = getVideoViewActivityPubUrl(byAccount, video)
38   const viewActivity = createViewActivityData(byAccount, video)
39
40   const accountsInvolvedInVideo = await getAccountsInvolvedInVideo(video, t)
41   const audience = getOriginVideoAudience(video, accountsInvolvedInVideo)
42   const data = await createActivityData(url, byAccount, viewActivity, t, audience)
43
44   return unicastTo(data, byAccount, video.VideoChannel.Account.sharedInboxUrl, t)
45 }
46
47 async function sendCreateViewToVideoFollowers (byAccount: AccountModel, video: VideoModel, t: Transaction) {
48   const url = getVideoViewActivityPubUrl(byAccount, video)
49   const viewActivity = createViewActivityData(byAccount, video)
50
51   const accountsToForwardView = await getAccountsInvolvedInVideo(video, t)
52   const audience = getObjectFollowersAudience(accountsToForwardView)
53   const data = await createActivityData(url, byAccount, viewActivity, t, audience)
54
55   // Use the server account to send the view, because it could be an unregistered account
56   const serverAccount = await getServerAccount()
57   const followersException = [ byAccount ]
58   return broadcastToFollowers(data, serverAccount, accountsToForwardView, t, followersException)
59 }
60
61 async function sendCreateDislikeToOrigin (byAccount: AccountModel, video: VideoModel, t: Transaction) {
62   const url = getVideoDislikeActivityPubUrl(byAccount, video)
63   const dislikeActivity = createDislikeActivityData(byAccount, video)
64
65   const accountsInvolvedInVideo = await getAccountsInvolvedInVideo(video, t)
66   const audience = getOriginVideoAudience(video, accountsInvolvedInVideo)
67   const data = await createActivityData(url, byAccount, dislikeActivity, t, audience)
68
69   return unicastTo(data, byAccount, video.VideoChannel.Account.sharedInboxUrl, t)
70 }
71
72 async function sendCreateDislikeToVideoFollowers (byAccount: AccountModel, video: VideoModel, t: Transaction) {
73   const url = getVideoDislikeActivityPubUrl(byAccount, video)
74   const dislikeActivity = createDislikeActivityData(byAccount, video)
75
76   const accountsToForwardView = await getAccountsInvolvedInVideo(video, t)
77   const audience = getObjectFollowersAudience(accountsToForwardView)
78   const data = await createActivityData(url, byAccount, dislikeActivity, t, audience)
79
80   const followersException = [ byAccount ]
81   return broadcastToFollowers(data, byAccount, accountsToForwardView, t, followersException)
82 }
83
84 async function createActivityData (
85   url: string,
86   byAccount: AccountModel,
87   object: any,
88   t: Transaction,
89   audience?: ActivityAudience
90 ): Promise<ActivityCreate> {
91   if (!audience) {
92     audience = await getAudience(byAccount, t)
93   }
94
95   return {
96     type: 'Create',
97     id: url,
98     actor: byAccount.url,
99     to: audience.to,
100     cc: audience.cc,
101     object
102   }
103 }
104
105 function createDislikeActivityData (byAccount: AccountModel, video: VideoModel) {
106   return {
107     type: 'Dislike',
108     actor: byAccount.url,
109     object: video.url
110   }
111 }
112
113 // ---------------------------------------------------------------------------
114
115 export {
116   sendCreateVideoChannel,
117   sendVideoAbuse,
118   createActivityData,
119   sendCreateViewToOrigin,
120   sendCreateViewToVideoFollowers,
121   sendCreateDislikeToOrigin,
122   sendCreateDislikeToVideoFollowers,
123   createDislikeActivityData
124 }
125
126 // ---------------------------------------------------------------------------
127
128 function createViewActivityData (byAccount: AccountModel, video: VideoModel) {
129   return {
130     type: 'View',
131     actor: byAccount.url,
132     object: video.url
133   }
134 }