-
-
Notifications
You must be signed in to change notification settings - Fork 0
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
Showing
28 changed files
with
23,389 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
name: Deploy Website to GitHub Pages | ||
|
||
on: | ||
push: | ||
branches: [main] | ||
|
||
jobs: | ||
deploy: | ||
name: Deploy to GitHub Pages | ||
runs-on: ubuntu-latest | ||
defaults: | ||
run: | ||
working-directory: website | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- uses: actions/setup-node@v2 | ||
with: | ||
node-version: 16.x | ||
cache: npm | ||
|
||
- name: Build website | ||
run: | | ||
npm ci | ||
npm run build | ||
# Popular action to deploy to GitHub Pages: | ||
# Docs: https://github.com/peaceiris/actions-gh-pages#%EF%B8%8F-docusaurus | ||
- name: Deploy to GitHub Pages | ||
uses: peaceiris/actions-gh-pages@v3 | ||
with: | ||
github_token: ${{ secrets.GITHUB_TOKEN }} | ||
# Build output to publish to the `gh-pages` branch: | ||
publish_dir: ./build | ||
# Assign commit authorship to the official GH-Actions bot for deploys to `gh-pages` branch: | ||
# https://github.com/actions/checkout/issues/13#issuecomment-724415212 | ||
# The GH actions bot is used by default if you didn't specify the two fields. | ||
# You can swap them out with your own user credentials. | ||
user_name: github-actions[bot] | ||
user_email: 41898282+github-actions[bot]@users.noreply.github.com |
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,20 @@ | ||
# Dependencies | ||
/node_modules | ||
|
||
# Production | ||
/build | ||
|
||
# Generated files | ||
.docusaurus | ||
.cache-loader | ||
|
||
# Misc | ||
.DS_Store | ||
.env.local | ||
.env.development.local | ||
.env.test.local | ||
.env.production.local | ||
|
||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* |
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,41 @@ | ||
# Website | ||
|
||
This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator. | ||
|
||
### Installation | ||
|
||
``` | ||
$ yarn | ||
``` | ||
|
||
### Local Development | ||
|
||
``` | ||
$ yarn start | ||
``` | ||
|
||
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. | ||
|
||
### Build | ||
|
||
``` | ||
$ yarn build | ||
``` | ||
|
||
This command generates static content into the `build` directory and can be served using any static contents hosting service. | ||
|
||
### Deployment | ||
|
||
Using SSH: | ||
|
||
``` | ||
$ USE_SSH=true yarn deploy | ||
``` | ||
|
||
Not using SSH: | ||
|
||
``` | ||
$ GIT_USER=<Your GitHub username> yarn deploy | ||
``` | ||
|
||
If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. |
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,3 @@ | ||
module.exports = { | ||
presets: [require.resolve('@docusaurus/core/lib/babel/preset')], | ||
}; |
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,5 @@ | ||
{ | ||
"label": "API Versions", | ||
"position": 2 | ||
} | ||
|
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,152 @@ | ||
--- | ||
id: gRPC | ||
title: gRPC (reccomended) | ||
sidebar_position: 0 | ||
--- | ||
|
||
v3 of the Export API introduces a gRPC API. One of the major upsides of using the gRPC protocol is a stream of progress updates and finally streaming the file back to the client. | ||
|
||
The `@fyko/export-api` package includes a typed JavaScript client and will be referenced in this part of the documentation. | ||
|
||
## Protobuf Definition | ||
|
||
:::tip Server Reflection | ||
The gRPC service has [server reflection](https://github.com/grpc/grpc/blob/master/doc/server-reflection.md), allowing you to test the API in Postman. | ||
::: | ||
|
||
```protobuf | ||
service Exporter { | ||
rpc CreateExport (CreateExportRequest) returns (stream CreateExportResponse); | ||
} | ||
enum ExportFormat { | ||
PlainText = 0; | ||
HtmlDark = 1; | ||
HtmlLight = 2; | ||
CSV = 3; | ||
JSON = 4; | ||
} | ||
message CreateExportRequest { | ||
string token = 1; | ||
string channel_id = 2; | ||
ExportFormat export_format = 3; | ||
string date_format = 4; | ||
string after = 5; | ||
string before = 6; | ||
} | ||
message CreateExportResponse { | ||
oneof ResponseType { | ||
double progress = 1; | ||
ExportComplete data = 2; | ||
} | ||
} | ||
message ExportComplete { | ||
int32 message_count = 1; | ||
bytes data = 2; | ||
} | ||
``` | ||
|
||
## `Exporter/CreateExport` | ||
|
||
> `rpc CreateExport (CreateExportRequest) returns (stream CreateExportResponse);` | ||
### Export Formats Enum | ||
|
||
| **Type** | **ID** | **Description** | **File Extension** | | ||
| --------- | ------ | --------------------------------------- | ------------------ | | ||
| PlainText | 0 | Export to a plaintext file | txt | | ||
| HtmlDark | 1 | Export to an HTML file in dark mode | html | | ||
| HtmlLight | 2 | Export to an HTML file in light mode | html | | ||
| CSV | 3 | Export to a comma separated values file | csv | | ||
| JSON | 4 | Export to a JSON file | json | | ||
|
||
### CreateExportRequest | ||
|
||
| **Field** | **Type** | **Description** | | ||
| ------------- | ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| token | string | The bot token for performing requests | | ||
| channel_id | string | The id of the channel to export | | ||
| export_format | ?[ExportFormat](#export-formats-enum) | The format to export the channel as, defaults to `PlainText` | | ||
| date_format | ?string | The [date format](https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings) for dates in exported files, defaults to `dd-MMM-yy hh:mm tt` | | ||
| after | ?string | Only include messages sent after this date | | ||
| before | ?string | Only include messages sent before this date | | ||
|
||
### CreateExportResponse | ||
|
||
| **Field** | **Type** | **Description** | | ||
| --------- | ---------------------------------- | ------------------------------------------------- | | ||
| progress | int64 | A decimal representing the progress of the export | | ||
| data | ?[ExportComplete](#exportcomplete) | The file data once `progress` equals `1` | | ||
|
||
### ExportComplete | ||
|
||
| **Field** | **Type** | **Description** | | ||
| ------------- | -------- | -------------------------------- | | ||
| message_count | int | The number of messages exported | | ||
| data | byte[] | The exported file in 32kb chunks | | ||
|
||
### Example | ||
|
||
```ts | ||
import { credentials } from "@grpc/grpc-js"; | ||
import { ExporterClient } from "@fyko/export-api/client"; | ||
import { | ||
CreateExportRequest, | ||
CreateExportResponse, | ||
ExportFormat, | ||
} from "@fyko/export-api/types"; | ||
import { writeFile } from "fs/promises"; | ||
|
||
// creates a new gRPC client | ||
const client = new ExporterClient( | ||
`localhost:${process.env.PORT}`, | ||
credentials.createInsecure() | ||
); | ||
|
||
void (async () => { | ||
// new CreateExport Request | ||
const request = new CreateExportRequest(); | ||
// set required options | ||
request.setChannelId(process.env.DISCORD_CHANNEL!); | ||
request.setToken(process.env.DISCORD_TOKEN!); | ||
// set optional options | ||
request.setExportFormat(ExportFormat.HTMLDARK); | ||
|
||
// | ||
return new Promise(async (res, rej) => { | ||
// "POST" the request | ||
const stream = client.createExport(request); | ||
|
||
const chunks: (string | Uint8Array)[] = []; | ||
let progress = 0; | ||
stream.on("data", (response: CreateExportResponse) => { | ||
// if `response.progress` is present | ||
const p = response.getProgress(); | ||
if (p && p > progress) { | ||
progress = p; | ||
console.log((p * 100).toFixed() + "%"); | ||
} | ||
|
||
// if finally sending the file itself, push to chunk array | ||
const data = response.getData(); | ||
const inner = data?.getData(); | ||
if (inner) { | ||
console.log(`Inner exists!`); | ||
chunks.push(inner); | ||
} | ||
}); | ||
|
||
// once the server closes the stream, | ||
// we can finally write the file | ||
stream.on("end", async () => { | ||
await writeFile("./foo.html", chunks); | ||
return res(void 0); | ||
}); | ||
|
||
stream.on("error", rej); | ||
}); | ||
})(); | ||
``` |
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,67 @@ | ||
--- | ||
id: v1 | ||
title: v1 | ||
sidebar_position: 0 | ||
--- | ||
|
||
:::danger API Deprecated | ||
This API version is deprecated, it's advised you use either [v2](v2.md) or [gRPC](gRPC.md). | ||
::: | ||
|
||
## `POST` `/v1/export` | ||
__JSON Body__ | ||
|
||
| **Field** | **Type** | **Description** | | ||
|-----------|----------|---------------------------------------| | ||
| token | string | The bot token for performing requests | | ||
| channelId | string | The id of the channel to export | | ||
|
||
__Response Codes__ | ||
|
||
| **Status** | **Description** | | ||
|------------|----------------------------------------------| | ||
| 200 | Success - exported channel sent as text/html | | ||
| 401 | Unauthorized - bad Discord bot token | | ||
| 409 | Conflict - unknown channel | | ||
|
||
### Examples | ||
#### Typescript: | ||
```ts | ||
import fetch from 'node-fetch'; | ||
|
||
async function exportChannel(channelId: string, token: string): Promise<Buffer> { | ||
const response = await fetch('http://exportapi:80/v1/export', { | ||
method: 'POST', | ||
body: JSON.stringify({ channelId, token }), | ||
headers: { | ||
'Content-Type': 'application/json' | ||
} | ||
}); | ||
if (response.ok) { | ||
return response.buffer(); | ||
} | ||
throw Error('Channel export failed!'); | ||
} | ||
``` | ||
#### Rust | ||
```rust | ||
// reqwest = { version = "0.10", features = ["json"] } | ||
use reqwest::Client; | ||
use std::collections::HashMap; | ||
use std::io::copy; | ||
use std::fs::File; | ||
|
||
async fn export_channel(channelId: &str, token: &str) -> Result<File, reqwest::Error> { | ||
let client = Client::new(); | ||
let mut map = HashMap::new(); | ||
map.insert("channelId", "channel id"); | ||
map.insert("token", "discord token"); | ||
|
||
let file = client.post("http://exportapi:80/v1/export").json(&map).await?.text().await?; | ||
|
||
let dest = File::create("myexport.html")?; | ||
copy(&mut file.as_bytes(), &mut dest)?; | ||
|
||
Ok(dest) | ||
} | ||
``` |
Oops, something went wrong.