-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a51e45b
commit 8ad70b2
Showing
8 changed files
with
157 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
name: Docs | ||
|
||
# Trigger this Action when new code is pushed to the main branch | ||
on: | ||
push: | ||
branches: | ||
- main | ||
|
||
# We need some permissions to publish to Github Pages | ||
permissions: | ||
contents: write | ||
pages: write | ||
id-token: write | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
steps: | ||
# Checkout the source code | ||
- uses: actions/checkout@v4 | ||
# Setup dotnet, please use a global.json to ensure the right SDK is used! | ||
- name: Setup .NET | ||
uses: actions/setup-dotnet@v3 | ||
# Restore the local tools | ||
- name: Restore tools | ||
run: dotnet tool restore | ||
# Build the code for the API documentation | ||
- name: Build code | ||
run: dotnet build -c Release Threads.Lib/Threads.Lib.fsproj | ||
# Generate the documentation files | ||
- name: Generate the documentation' | ||
run: dotnet fsdocs build --properties Configuration=Release | ||
# Upload the static files | ||
- name: Upload documentation | ||
uses: actions/upload-pages-artifact@v3 | ||
with: | ||
path: ./output | ||
|
||
# GitHub Actions recommends deploying in a separate job. | ||
deploy: | ||
runs-on: ubuntu-latest | ||
needs: build | ||
steps: | ||
- name: Deploy to GitHub Pages | ||
id: deployment | ||
uses: actions/deploy-pages@v4 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -482,3 +482,7 @@ $RECYCLE.BIN/ | |
|
||
# Vim temporary swap files | ||
*.swp | ||
|
||
output | ||
.fsdocs | ||
tmp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
# Threads.Lib | ||
|
||
This is a .NET library for the [Threads] API. | ||
|
||
## Installation | ||
|
||
WIP | ||
|
||
## Usage | ||
|
||
The library itself is a thin wrapper over the API, so you don't have to craft everything yourself. However we don't provide any authentication dances, so you have to [obtain the access token] required to interact with the API yourself. | ||
|
||
Once you have your access token ready to go you can obtain a client instance like this: | ||
|
||
```fsharp | ||
open Threads.Lib | ||
open Threads.Lib.Profile | ||
let threads = Threads.Create("access-token") | ||
async { | ||
let! (response: ProfileValue seq) = | ||
threads.Profile.FetchProfile( | ||
profileId = "me", | ||
profileFields = [ | ||
ProfileField.Id | ||
ProfileField.Username | ||
ProfileField.ThreadsBiography | ||
ProfileField.ThreadsProfilePictureUrl | ||
] | ||
) | ||
printfn $"%A{response}" | ||
} | ||
``` | ||
|
||
The Threads API is quite dynamic and you can choose which fields you want to obtain in the response, this is at odds with fsharp's type system which requires types to be statically known at compile time. To work around this we provide a `ProfileValue` type which is a discriminated union of all possible fields you can obtain from the API. This way you can pattern match on the response and extract the fields you need. | ||
|
||
An example would be: | ||
|
||
```fsharp | ||
// Define a type to represent the user profile | ||
// with all of the fields you're interested in | ||
type UserProfile = { | ||
id: string | ||
username: string | ||
bio: string | ||
} | ||
module UserProfile = | ||
let emptyProfile = { | ||
id = "" | ||
username = "" | ||
bio = "" | ||
} | ||
// In a module or static method, you can define a mapping function to convert | ||
// the ProfileValue seq to a your type instance | ||
let ofValues (values: ProfileValue seq) : UserProfile = | ||
let foldToProfile (current: UserProfile) (nextValue: ProfileValue) = | ||
match nextValue with | ||
| Id id -> { current with id = id } | ||
| Username username -> { current with username = username } | ||
| ThreadsBiography bio -> { current with bio = bio } | ||
| ThreadsProfilePictureUrl profilePicture -> current | ||
Seq.fold foldToProfile emptyProfile values | ||
// somewhere else in your code | ||
async { | ||
let! (response: ProfileValue seq) = | ||
threads.Profile.FetchProfile( | ||
profileId = "me", | ||
profileFields = [ | ||
ProfileField.Id | ||
ProfileField.Username | ||
ProfileField.ThreadsBiography | ||
] | ||
) | ||
let profile = UserProfile.ofValues response | ||
printfn $"%A{profile}" | ||
// { id = "1234"; username = "johndoe"; bio = "I'm a bio" } | ||
} | ||
``` | ||
|
||
While there are too few fields in the profile response. This will come more handy in other responses like the thread posts themselves. Overall the library is meant to be used like this and tries to be as flexible as possible without compromising the type safety of F# or at least that's what we're trying. | ||
|
||
[Threads]: https://developers.facebook.com/docs/threads | ||
[obtain the access token]: https://developers.facebook.com/docs/threads/get-started/get-access-tokens-and-permissions |