Skip to content

Commit a2e1d08

Browse files
committed
Add CreateReport and fix docs bug
There's a bug where the documentation ends up breaking. As in, the inline web link doesn't work. This commit fixes this.
1 parent 4233c9a commit a2e1d08

File tree

3 files changed

+141
-0
lines changed

3 files changed

+141
-0
lines changed
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
//
2+
// AtprotoModerationCreateReport.swift
3+
//
4+
//
5+
// Created by Christopher Jr Riley on 2024-02-25.
6+
//
7+
8+
import Foundation
9+
10+
/// The main data model definition for creating a report.
11+
///
12+
/// - Note: According to the AT Protocol specifications: "Submit a moderation report regarding an atproto account or record. Implemented by moderation services (with PDS proxying), and requires auth."
13+
///
14+
/// - SeeAlso: This is based on the [`com.atproto.moderation.createReport`][github] lexicon.
15+
///
16+
/// [github]: https://github.com/bluesky-social/atproto/blob/main/lexicons/com/atproto/moderation/createReport.json
17+
public struct ModerationCreateReport: Codable {
18+
/// The reason for the report.
19+
///
20+
/// - Note: According to the AT Protocol specifications: "Indicates the broad category of violation the report is for."
21+
public let reasonType: ModerationReasonType
22+
/// Any clarifying comments accompanying the report. Optional.
23+
///
24+
/// - Note: According to the AT Protocol specifications: "Additional context about the content and violation."
25+
public let reason: String?
26+
/// The subject reference.
27+
///
28+
/// - Important: The item associated with this property is undocumented in the AT Protocol specifications. The documentation here is based on:\
29+
/// \* **For items with some inferable context from property names or references**: its best interpretation, though not with full certainty.\
30+
/// \* **For items without enough context for even an educated guess**: a direct acknowledgment of their undocumented status.\
31+
/// Clarifications from Bluesky are needed in order to fully understand this item.
32+
public let subject: RepoReferencesUnion
33+
}
34+
35+
/// A data model definition for the output of creating a report.
36+
///
37+
/// - SeeAlso: This is based on the [`com.atproto.moderation.createReport`][github] lexicon.
38+
///
39+
/// [github]: https://github.com/bluesky-social/atproto/blob/main/lexicons/com/atproto/moderation/createReport.json
40+
public struct ModerationCreateReportOutput: Codable {
41+
/// The ID of the report.
42+
public let id: Int
43+
/// The reason for the report.
44+
public let reasonType: ModerationReasonType
45+
/// The reason for the report. Optional.
46+
public let reason: String?
47+
/// The subject reference.
48+
///
49+
/// - Important: The item associated with this property is undocumented in the AT Protocol specifications. The documentation here is based on:\
50+
/// \* **For items with some inferable context from property names or references**: its best interpretation, though not with full certainty.\
51+
/// \* **For items without enough context for even an educated guess**: a direct acknowledgment of their undocumented status.\
52+
/// Clarifications from Bluesky are needed in order to fully understand this item.
53+
public let subject: RepoReferencesUnion
54+
/// The decentralized identifier (DID) of the user who created the report.
55+
public let reportedBy: String
56+
/// The date and time the report was created.
57+
@DateFormatting public var createdAt: Date
58+
59+
public init(id: Int, reasonType: ModerationReasonType, reason: String?, subject: RepoReferencesUnion, reportedBy: String, createdAt: Date) {
60+
self.id = id
61+
self.reasonType = reasonType
62+
self.reason = reason
63+
self.subject = subject
64+
self.reportedBy = reportedBy
65+
self._createdAt = DateFormatting(wrappedValue: createdAt)
66+
}
67+
68+
public init(from decoder: Decoder) throws {
69+
let container = try decoder.container(keyedBy: CodingKeys.self)
70+
71+
self.id = try container.decode(Int.self, forKey: .id)
72+
self.reasonType = try container.decode(ModerationReasonType.self, forKey: .reasonType)
73+
self.reason = try container.decodeIfPresent(String.self, forKey: .reason)
74+
self.subject = try container.decode(RepoReferencesUnion.self, forKey: .subject)
75+
self.reportedBy = try container.decode(String.self, forKey: .reportedBy)
76+
self.createdAt = try container.decode(DateFormatting.self, forKey: .createdAt).wrappedValue
77+
}
78+
79+
public func encode(to encoder: Encoder) throws {
80+
var container = encoder.container(keyedBy: CodingKeys.self)
81+
82+
try container.encode(self.id, forKey: .id)
83+
try container.encode(self.reasonType, forKey: .reasonType)
84+
85+
// Truncate `reason` to 20,000 characters before encoding
86+
// `maxGraphemes`'s limit is 2,000, but `String.count` should respect that limit implictly
87+
try truncatedEncodeIfPresent(self.reason, withContainer: &container, forKey: .reason, upToLength: 20_000)
88+
try container.encode(self.subject, forKey: .subject)
89+
try container.encode(self.reportedBy, forKey: .reportedBy)
90+
try container.encode(self._createdAt, forKey: .createdAt)
91+
}
92+
93+
public enum CodingKeys: CodingKey {
94+
case id
95+
case reasonType
96+
case reason
97+
case subject
98+
case reportedBy
99+
case createdAt
100+
}
101+
}

Sources/ATProtoKit/Models/Lexicons/com.atproto/Moderation/AtprotoModerationDefs.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import Foundation
1515
/// \* **For items with some inferable context from property names or references**: its best interpretation, though not with full certainty.\
1616
/// \* **For items without enough context for even an educated guess**: a direct acknowledgment of their undocumented status.\
1717
/// Clarifications from Bluesky are needed in order to fully understand this item.
18+
///
1819
/// [github]: https://github.com/bluesky-social/atproto/blob/main/lexicons/com/atproto/moderation/defs.json
1920
public enum ModerationReasonType: String, Codable {
2021
/// Indicates spam as the reason.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//
2+
// CreateReport.swift
3+
//
4+
//
5+
// Created by Christopher Jr Riley on 2024-02-25.
6+
//
7+
8+
import Foundation
9+
10+
extension ATProtoKit {
11+
/// Creates a report to send to moderators.
12+
///
13+
/// - Parameters:
14+
/// - reasonType: The reason for the report.
15+
/// - reason: Any additional context accompanying the report. Optional.
16+
/// - subject: The responsible party being reported.
17+
/// - Returns: A `Result`, containing either ``ModerationCreateReportOutput`` if successful, or an `Error` if not.
18+
public func createReport(with reasonType: ModerationReasonType, withContextof reason: String?, subject: RepoReferencesUnion) async throws -> Result<ModerationCreateReportOutput, Error> {
19+
guard let sessionURL = session.pdsURL,
20+
let requestURL = URL(string: "\(sessionURL)/xrpc/com.atproto.moderation.createReport") else {
21+
return .failure(NSError(domain: "", code: -1, userInfo: [NSLocalizedDescriptionKey: "Invalid URL"]))
22+
}
23+
24+
let requestBody = ModerationCreateReport(
25+
reasonType: reasonType,
26+
reason: reason,
27+
subject: subject
28+
)
29+
30+
do {
31+
let request = APIClientService.createRequest(forRequest: requestURL, andMethod: .post, acceptValue: "application/json", contentTypeValue: "application/json", authorizationValue: "Bearer \(session.accessToken)")
32+
let response = try await APIClientService.sendRequest(request, withEncodingBody: requestBody, decodeTo: ModerationCreateReportOutput.self)
33+
34+
return .success(response)
35+
} catch {
36+
return .failure(error)
37+
}
38+
}
39+
}

0 commit comments

Comments
 (0)