-33
automod/engine/context.go
-33
automod/engine/context.go
···
91
91
Event toolsozone.ModerationDefs_ModEventView_Event
92
92
}
93
93
94
-
// Originally intended for push notifications, but can also work for any inter-account notification.
95
-
type NotificationContext struct {
96
-
AccountContext
97
-
98
-
Recipient AccountMeta
99
-
Notification NotificationMeta
100
-
}
101
-
102
-
// Additional notification metadata, with fields aligning with the `app.bsky.notification.listNotifications` Lexicon schemas
103
-
type NotificationMeta struct {
104
-
// Expected values are 'like', 'repost', 'follow', 'mention', 'reply', and 'quote'; arbitrary values may be added in the future.
105
-
Reason string
106
-
// The content (atproto record) which was the cause of this notification. Could be a post with a mention, or a like, follow, or repost record.
107
-
Subject syntax.ATURI
108
-
}
109
-
110
94
// Checks that op has expected fields, based on the action type
111
95
func (op *RecordOp) Validate() error {
112
96
switch op.Action {
···
198
182
}
199
183
}
200
184
201
-
func NewNotificationContext(ctx context.Context, eng *Engine, sender, recipient AccountMeta, reason string, subject syntax.ATURI) NotificationContext {
202
-
ac := NewAccountContext(ctx, eng, sender)
203
-
ac.BaseContext.Logger = ac.BaseContext.Logger.With("recipient", recipient.Identity.DID, "reason", reason, "subject", subject.String())
204
-
return NotificationContext{
205
-
AccountContext: ac,
206
-
Recipient: recipient,
207
-
Notification: NotificationMeta{
208
-
Reason: reason,
209
-
Subject: subject,
210
-
},
211
-
}
212
-
}
213
-
214
185
// fetch relationship metadata between this account and another account
215
186
func (c *AccountContext) GetAccountRelationship(other syntax.DID) AccountRelationship {
216
187
rel, err := c.engine.GetAccountRelationship(c.Ctx, c.Account.Identity.DID, other)
···
322
293
func (c *RecordContext) TakedownBlob(cid string) {
323
294
c.effects.TakedownBlob(cid)
324
295
}
325
-
326
-
func (c *NotificationContext) Reject() {
327
-
c.effects.Reject()
328
-
}
-71
automod/engine/engine.go
-71
automod/engine/engine.go
···
296
296
return nil
297
297
}
298
298
299
-
// returns a boolean indicating "block the event"
300
-
// NOTE: this code is unused and should be removed
301
-
func (eng *Engine) ProcessNotificationEvent(ctx context.Context, senderDID, recipientDID syntax.DID, reason string, subject syntax.ATURI) (bool, error) {
302
-
eventProcessCount.WithLabelValues("notif").Inc()
303
-
start := time.Now()
304
-
defer func() {
305
-
duration := time.Since(start)
306
-
eventProcessDuration.WithLabelValues("notif").Observe(duration.Seconds())
307
-
}()
308
-
309
-
// similar to an HTTP server, we want to recover any panics from rule execution
310
-
defer func() {
311
-
if r := recover(); r != nil {
312
-
eng.Logger.Error("automod event execution exception", "err", r, "sender", senderDID, "recipient", recipientDID)
313
-
}
314
-
}()
315
-
var cancel context.CancelFunc
316
-
ctx, cancel = context.WithTimeout(ctx, time.Second*5)
317
-
defer cancel()
318
-
319
-
senderIdent, err := eng.Directory.LookupDID(ctx, senderDID)
320
-
if err != nil {
321
-
eventErrorCount.WithLabelValues("notif").Inc()
322
-
return false, fmt.Errorf("resolving identity: %w", err)
323
-
}
324
-
if senderIdent == nil {
325
-
eventErrorCount.WithLabelValues("notif").Inc()
326
-
return false, fmt.Errorf("identity not found for sender DID: %s", senderDID.String())
327
-
}
328
-
329
-
recipientIdent, err := eng.Directory.LookupDID(ctx, recipientDID)
330
-
if err != nil {
331
-
eventErrorCount.WithLabelValues("notif").Inc()
332
-
return false, fmt.Errorf("resolving identity: %w", err)
333
-
}
334
-
if recipientIdent == nil {
335
-
eventErrorCount.WithLabelValues("notif").Inc()
336
-
return false, fmt.Errorf("identity not found for sender DID: %s", recipientDID.String())
337
-
}
338
-
339
-
senderMeta, err := eng.GetAccountMeta(ctx, senderIdent)
340
-
if err != nil {
341
-
eventErrorCount.WithLabelValues("notif").Inc()
342
-
return false, fmt.Errorf("failed to fetch account metadata: %w", err)
343
-
}
344
-
recipientMeta, err := eng.GetAccountMeta(ctx, recipientIdent)
345
-
if err != nil {
346
-
eventErrorCount.WithLabelValues("notif").Inc()
347
-
return false, fmt.Errorf("failed to fetch account metadata: %w", err)
348
-
}
349
-
350
-
nc := NewNotificationContext(ctx, eng, *senderMeta, *recipientMeta, reason, subject)
351
-
if err := eng.Rules.CallNotificationRules(&nc); err != nil {
352
-
eventErrorCount.WithLabelValues("notif").Inc()
353
-
return false, fmt.Errorf("rule execution failed: %w", err)
354
-
}
355
-
eng.CanonicalLogLineNotification(&nc)
356
-
return nc.effects.RejectEvent, nil
357
-
}
358
-
359
299
// Purge metadata caches for a specific account.
360
300
func (e *Engine) PurgeAccountCaches(ctx context.Context, did syntax.DID) error {
361
301
e.Logger.Debug("purging account caches", "did", did.String())
···
391
331
"recordReports", len(c.effects.RecordReports),
392
332
)
393
333
}
394
-
395
-
func (e *Engine) CanonicalLogLineNotification(c *NotificationContext) {
396
-
c.Logger.Info("canonical-event-line",
397
-
"accountLabels", c.effects.AccountLabels,
398
-
"accountFlags", c.effects.AccountFlags,
399
-
"accountTags", c.effects.AccountTags,
400
-
"accountTakedown", c.effects.AccountTakedown,
401
-
"accountReports", len(c.effects.AccountReports),
402
-
"reject", c.effects.RejectEvent,
403
-
)
404
-
}
-11
automod/engine/ruleset.go
-11
automod/engine/ruleset.go
···
18
18
IdentityRules []IdentityRuleFunc
19
19
AccountRules []AccountRuleFunc
20
20
BlobRules []BlobRuleFunc
21
-
NotificationRules []NotificationRuleFunc
22
21
OzoneEventRules []OzoneEventRuleFunc
23
22
}
24
23
···
96
95
err := f(c)
97
96
if err != nil {
98
97
c.Logger.Error("account rule execution failed", "err", err)
99
-
}
100
-
}
101
-
return nil
102
-
}
103
-
104
-
func (r *RuleSet) CallNotificationRules(c *NotificationContext) error {
105
-
for _, f := range r.NotificationRules {
106
-
err := f(c)
107
-
if err != nil {
108
-
c.Logger.Error("notification rule execution failed", "err", err)
109
98
}
110
99
}
111
100
return nil
-1
automod/engine/ruletypes.go
-1
automod/engine/ruletypes.go
···
11
11
type PostRuleFunc = func(c *RecordContext, post *appbsky.FeedPost) error
12
12
type ProfileRuleFunc = func(c *RecordContext, profile *appbsky.ActorProfile) error
13
13
type BlobRuleFunc = func(c *RecordContext, blob lexutil.LexBlob, data []byte) error
14
-
type NotificationRuleFunc = func(c *NotificationContext) error
15
14
type OzoneEventRuleFunc = func(c *OzoneEventContext) error
-2
automod/pkg.go
-2
automod/pkg.go
···
18
18
type AccountContext = engine.AccountContext
19
19
type RecordContext = engine.RecordContext
20
20
type OzoneEventContext = engine.OzoneEventContext
21
-
type NotificationContext = engine.NotificationContext
22
21
type RecordOp = engine.RecordOp
23
22
24
23
type IdentityRuleFunc = engine.IdentityRuleFunc
···
26
25
type PostRuleFunc = engine.PostRuleFunc
27
26
type ProfileRuleFunc = engine.ProfileRuleFunc
28
27
type BlobRuleFunc = engine.BlobRuleFunc
29
-
type NotificationRuleFunc = engine.NotificationRuleFunc
30
28
type OzoneEventRuleFunc = engine.OzoneEventRuleFunc
31
29
32
30
var (