Skip to content

Instantly share code, notes, and snippets.

@HonmaMasaru
Last active May 8, 2023 20:41
Show Gist options
  • Save HonmaMasaru/08cb36f1a0a2e550a4588b4c089f4b7b to your computer and use it in GitHub Desktop.
Save HonmaMasaru/08cb36f1a0a2e550a4588b4c089f4b7b to your computer and use it in GitHub Desktop.
Blueskyに投稿する
import Foundation
import PlaygroundSupport
/// ID
/// - Note: DIDかハンドル
let identifier = "(ID)"
/// パスワード
/// - Note: https://staging.bsky.app/settings/app-passwords で取得する
let appPassword = "(パスワード)"
/// エンドポイント
let endPoint = "https://bsky.social/xrpc/"
/// セッション作成のID
let createSession = "com.atproto.server.createSession"
/// 投稿のID
let createRecord = "com.atproto.repo.createRecord"
/// 投稿を実行
do {
let session = try await createSession(identifier: identifier, password: appPassword)
print(session)
let record = try await createRecord(accessJwt: session.accessJwt, did: session.did, text: "Test", createdAt: Date())
print(record)
} catch {
print(error)
}
// MARK: -
/// セッション作成
func createSession(identifier: String, password: String) async throws -> CreateSessionResponse {
var req = URLRequest(url: URL(string: endPoint + createSession)!)
req.httpMethod = "POST"
req.addValue("application/json", forHTTPHeaderField: "Content-Type")
req.httpBody = try JSONEncoder().encode(CreateSessionRequest(identifier: identifier, password: password))
let (data, response) = try await URLSession.shared.data(for: req)
guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {
print(response)
throw URLError(.badServerResponse)
}
return try JSONDecoder().decode(CreateSessionResponse.self, from: data)
}
/// 投稿
func createRecord(accessJwt: String, did: String, text: String, createdAt: Date) async throws -> CreateRecordResponse {
var req = URLRequest(url: URL(string: endPoint + createRecord)!)
req.httpMethod = "POST"
req.addValue("application/json", forHTTPHeaderField: "Content-Type")
req.addValue("Bearer \(accessJwt)", forHTTPHeaderField: "Authorization")
req.httpBody = try JSONEncoder().encode(CreateRecordRequest(did: did, text: text, createdAt: createdAt))
let (data, response) = try await URLSession.shared.data(for: req)
guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {
print(response)
throw URLError(.badServerResponse)
}
return try JSONDecoder().decode(CreateRecordResponse.self, from: data)
}
// MARK: -
/// セッション作成リクエスト
struct CreateSessionRequest: Codable {
let identifier: String
let password: String
}
/// セッション作成レスポンス
struct CreateSessionResponse: Codable {
let accessJwt: String
let refreshJwt: String
let handle: String
let did: String
let email: String?
}
// MARK: -
/// 投稿リクエスト
struct CreateRecordRequest: Codable {
let repo: String
let collection: String
let record: Record
init(did: String, text: String, createdAt: Date) {
repo = did
collection = "app.bsky.feed.post"
let createdAt = ISO8601DateFormatter().string(from: createdAt)
record = .init(text: text, createdAt: createdAt)
}
}
/// レコード
struct Record: Codable {
let text: String
let createdAt: String
let type: String
init(text: String, createdAt: String) {
self.text = text
self.createdAt = createdAt
self.type = "app.bsky.feed.post"
}
private enum CodingKeys: String, CodingKey {
case text
case createdAt
case type = "$type"
}
}
/// 投稿レスポンス
struct CreateRecordResponse: Codable {
let uri: String
let cid: String
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment