-
Notifications
You must be signed in to change notification settings - Fork 137
/
applications.md
163 lines (130 loc) · 4.95 KB
/
applications.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
---
title: Applications model
summary: How applications work on the AT Protocol.
tldr:
- Apps sign into the user's PDS to access their account
- Apps can directly read and write repo records
- Most interactions occur through higher-level lexicons
---
# Applications model
Applications on the AT Protocol connect to the user's Personal Data Server (PDS) to access their account. Once a session is established, the app can use the [lexicons](./lexicon) implemented by the PDS to drive behaviors.
In this guide, we'll step through a couple of common patterns (with simple code examples) to help you develop an intuition about this. All APIs shown below are generated using Lexicon's code-generator CLI.
## Signing in
Sign-in and authentication is a simple session-oriented process. The [com.atproto.session lexicon](/lexicons/com-atproto-session) includes APIs for creating and managing these sessions.
```typescript
// create an API instance with my PDS
const api = AtpApi.service('my-pds.com')
// sign in using my username and password
const res = await api.com.atproto.session.create({}, {
username: 'alice.host.com',
password: 'hunter2'
})
// configure future calls to include the token in the Authorization header
api.setHeader('Authorization', `Bearer ${res.data.accessJwt}`)
```
## Repo CRUD
Every user has a public data repository. The application can do basic CRUD on records using the API.
```typescript
await api.com.atproto.repo.listRecords({
repo: 'alice.com',
type: 'app.bsky.post'
})
await api.com.atproto.repo.getRecord({
repo: 'alice.com',
type: 'app.bsky.post',
tid: '1'
})
await api.com.atproto.repo.createRecord({
repo: 'alice.com',
type: 'app.bsky.post'
}, {
text: 'Second post!',
createdAt: (new Date()).toISOString()
})
await api.com.atproto.repo.putRecord({
repo: 'alice.com',
type: 'app.bsky.post',
tid: '1'
}, {
text: 'Hello universe!',
createdAt: originalPost.data.createdAt
})
await api.com.atproto.repo.deleteRecord({
repo: 'alice.com',
type: 'app.bsky.post',
tid: '1'
})
```
You may notice that the repo above is identified by a domain name `alice.com`. Take a look at the [Identity guide](./identity) to learn more about that.
## Record types
If you're noticing the "type" field and wondering how that works, see the [Intro to Lexicon guide](./lexicon). Here is a short list of types that are currently used by the ATP software.
You'll notice "cids" in some of the schemas. A "cid" is a "Content ID," a sha256 hash of some referenced content. These are used to ensure integrity; for instance, a like includes the cid of the post being liked so that a future edit can be detected and noted in the UI.
### <a href="/lexicons/app-bsky-graph#follow">app.bsky.graph.follow</a>
A social follow. Example:
```typescript
{
$type: 'app.bsky.graph.follow',
subject: {
did: 'did:plc:bv6ggog3tya2z3vxsub7hnal',
declarationCid: 'bafyreid27zk7lbis4zw5fz4podbvbs4fc5ivwji3dmrwa6zggnj4bnd57u'
},
createdAt: '2022-10-10T00:39:08.609Z'
}
```
### <a href="/lexicons/app-bsky-feed#like">app.bsky.feed.like</a>
A like on a piece of content. Example:
```typescript
{
$type: 'app.bsky.feed.like',
subject: {
uri: 'at://did:plc:bv6ggog3tya2z3vxsub7hnal/app.bsky.post/1',
cid: 'bafyreif5lqnk3tgbhi5vgqd6wy5dtovfgndhwta6bwla4iqaohuf2yd764'
}
createdAt: '2022-10-10T00:39:08.609Z'
}
```
### <a href="/lexicons/app-bsky-feed#post">app.bsky.feed.post</a>
A microblog post. Example:
```typescript
{
$type: 'app.bsky.feed.post',
text: 'Hello, world!',
createdAt: '2022-10-10T00:39:08.609Z'
}
```
### <a href="/lexicons/app-bsky-actor#profile">app.bsky.actor.profile</a>
A user profile. Example:
```typescript
{
$type: 'app.bsky.actor.profile',
displayName: 'Alice',
description: 'A cool hacker'
}
```
### <a href="/lexicons/app-bsky-feed#repost">app.bsky.feed.repost</a>
A repost of an existing microblog post (similar to retweets). Example:
```typescript
{
$type: 'app.bsky.feed.repost',
subject: {
uri: 'at://did:plc:bv6ggog3tya2z3vxsub7hnal/app.bsky.post/1',
cid: 'bafyreif5lqnk3tgbhi5vgqd6wy5dtovfgndhwta6bwla4iqaohuf2yd764'
}
createdAt: '2022-10-10T00:39:08.609Z'
}
```
## Social APIs
While there's a lot that can be done by repo CRUD and other low-level com.atproto.* APIs, the app.bsky.* lexicon provides more powerful and easy-to-use APIs for social applications.
```typescript
await api.app.bsky.feed.getTimeline()
await api.app.bsky.feed.getAuthorFeed({author: 'alice.com'})
await api.app.bsky.feed.getPostThread({uri: 'at://alice.com/app.bsky.post/1'})
await api.app.bsky.feed.getLikes({uri: 'at://alice.com/app.bsky.post/1'})
await api.app.bsky.feed.getRepostedBy({uri: 'at://alice.com/app.bsky.post/1'})
await api.app.bsky.actor.getProfile({user: 'alice.com'})
await api.app.bsky.graph.getFollowers({user: 'alice.com'})
await api.app.bsky.graph.getFollows({user: 'alice.com'})
await api.app.bsky.notification.listNotifications()
await api.app.bsky.notification.getUnreadCount()
await api.app.bsky.notification.updateSeen()
```