@@ -17,6 +17,7 @@ import (
17
17
"time"
18
18
19
19
"github.com/buger/jsonparser"
20
+ "github.com/getsentry/sentry-go"
20
21
"github.com/nyaruka/courier"
21
22
"github.com/nyaruka/courier/handlers"
22
23
"github.com/nyaruka/courier/handlers/meta/messenger"
@@ -86,6 +87,7 @@ func (h *handler) Initialize(s courier.Server) error {
86
87
h .SetServer (s )
87
88
s .AddHandlerRoute (h , http .MethodGet , "receive" , courier .ChannelLogTypeWebhookVerify , h .receiveVerify )
88
89
s .AddHandlerRoute (h , http .MethodPost , "receive" , courier .ChannelLogTypeMultiReceive , handlers .JSONPayload (h , h .receiveEvents ))
90
+ s .AddHandlerRoute (h , http .MethodPost , "delete" , courier .ChannelLogTypeEventReceive , handlers .JSONPayload (h , h .deleteEvents ))
89
91
return nil
90
92
}
91
93
@@ -131,7 +133,7 @@ func (h *handler) WriteRequestError(ctx context.Context, w http.ResponseWriter,
131
133
132
134
// GetChannel returns the channel
133
135
func (h * handler ) GetChannel (ctx context.Context , r * http.Request ) (courier.Channel , error ) {
134
- if r .Method == http .MethodGet {
136
+ if r .Method == http .MethodGet || r . URL . Path == "/c/fba/delete" {
135
137
return nil , nil
136
138
}
137
139
@@ -215,6 +217,52 @@ func (h *handler) resolveMediaURL(mediaID string, token string, clog *courier.Ch
215
217
return mediaURL , err
216
218
}
217
219
220
+ type DeletionRequestData struct {
221
+ Algorithm string `json:"algorithm"`
222
+ Expires int64 `json:"expires"`
223
+ IssuedAt int64 `json:"issued_at"`
224
+ UserID string `json:"user_id"`
225
+ }
226
+
227
+ type DeleteConfirmationData struct {
228
+ URL string `json:"url"`
229
+ ConfirmationCode string `json:"confirmation_code"`
230
+ }
231
+
232
+ // deleteEvents is our HTTP handler function for deleting data requests
233
+ func (h * handler ) deleteEvents (ctx context.Context , channel courier.Channel , w http.ResponseWriter , r * http.Request , payload * DeletionRequestData , clog * courier.ChannelLog ) ([]courier.Event , error ) {
234
+ err := h .validateSignature (r )
235
+ if err != nil {
236
+ return nil , handlers .WriteAndLogRequestError (ctx , h , channel , w , r , err )
237
+ }
238
+
239
+ urn , err := urns .New (urns .Facebook , payload .UserID )
240
+ if err != nil {
241
+ return nil , handlers .WriteAndLogRequestError (ctx , h , channel , w , r , errors .New ("invalid facebook id" ))
242
+ }
243
+ date := parseTimestamp (payload .IssuedAt )
244
+
245
+ events := make ([]courier.Event , 0 , 2 )
246
+ data := make ([]any , 0 , 2 )
247
+
248
+ payloadJson , _ := json .Marshal (payload )
249
+ sentry .CaptureMessage (fmt .Sprintf ("Data Deletion Request: %s" , payloadJson ))
250
+
251
+ event := h .Backend ().NewChannelEvent (channel , courier .EventDeletionRequest , urn , clog ).WithOccurredOn (date ).WithExtra (map [string ]string {"userID" : payload .UserID })
252
+
253
+ err = h .Backend ().WriteChannelEvent (ctx , event , clog )
254
+ if err != nil {
255
+ return nil , err
256
+ }
257
+
258
+ confirmationURL := fmt .Sprintf ("https://%s/channels/events/read/%s/" , h .Server ().Config ().Domain , event .UUID ())
259
+
260
+ events = append (events , event )
261
+ data = append (data , DeleteConfirmationData {URL : confirmationURL , ConfirmationCode : string (event .UUID ())})
262
+
263
+ return events , courier .WriteDataResponse (w , http .StatusOK , "Deletion Request Received" , data )
264
+ }
265
+
218
266
// receiveEvents is our HTTP handler function for incoming messages and status updates
219
267
func (h * handler ) receiveEvents (ctx context.Context , channel courier.Channel , w http.ResponseWriter , r * http.Request , payload * Notifications , clog * courier.ChannelLog ) ([]courier.Event , error ) {
220
268
err := h .validateSignature (r )
0 commit comments