mirror of
https://github.com/chatmail/core.git
synced 2026-04-01 21:12:13 +03:00
Compare commits
13 Commits
822a99ea9c
...
simon/impr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ba45134ea | ||
|
|
5d512a726d | ||
|
|
bfa8da092c | ||
|
|
72eef59f25 | ||
|
|
5f3dbe0037 | ||
|
|
a74edb2f86 | ||
|
|
963335e660 | ||
|
|
b1ace43b28 | ||
|
|
1ac520439b | ||
|
|
c4d849a502 | ||
|
|
78bac6021f | ||
|
|
4602b661d9 | ||
|
|
c65ce1b673 |
@@ -16,6 +16,7 @@ We also include a JavaScript and TypeScript client for the JSON-RPC API. The sou
|
||||
The package includes a JavaScript/TypeScript client which is partially auto-generated through the JSON-RPC library used by this crate ([yerpc](https://github.com/chatmail/yerpc)). Find the source in the [`typescript`](typescript) folder.
|
||||
|
||||
To use it locally, first install the dependencies and compile the TypeScript code to JavaScript:
|
||||
|
||||
```sh
|
||||
cd typescript
|
||||
npm install
|
||||
@@ -24,11 +25,28 @@ npm run build
|
||||
|
||||
The JavaScript client is [published on NPM](https://www.npmjs.com/package/@deltachat/jsonrpc-client).
|
||||
|
||||
###### Usage
|
||||
|
||||
```typescript
|
||||
import { startDeltaChat } from "@deltachat/stdio-rpc-server";
|
||||
import { C } from "@deltachat/jsonrpc-client";
|
||||
|
||||
const dc = await startDeltaChat("deltachat-data");
|
||||
console.log(await dc.rpc.getSystemInfo());
|
||||
const accounts = await dc.rpc.getAllAccounts();
|
||||
console.log("accounts", accounts);
|
||||
dc.close();
|
||||
```
|
||||
|
||||
##### Generate TypeScript/JavaScript documentation
|
||||
|
||||
A script is included to build autogenerated documentation, which includes all RPC methods:
|
||||
|
||||
```sh
|
||||
cd typescript
|
||||
npm run docs
|
||||
```
|
||||
|
||||
Then open the [`typescript/docs`](typescript/docs) folder in a web browser.
|
||||
|
||||
## Development
|
||||
|
||||
206
deltachat-jsonrpc/typescript/Readme.md
Normal file
206
deltachat-jsonrpc/typescript/Readme.md
Normal file
@@ -0,0 +1,206 @@
|
||||
# @deltachat/jsonrpc-client
|
||||
|
||||
This package is a client for the jsonrpc server.
|
||||
|
||||
> If you are looking for the functions in the documentation, they are under [`RawClient`](https://js.jsonrpc.delta.chat/classes/RawClient.html).
|
||||
|
||||
### Important Terms
|
||||
|
||||
- [chat mail core (formerly delta chat core)](https://github.com/deltachat/deltachat-core-rust/) is heart of all Delta Chat clients. Handels all the heavy lifting (email, encryption, ...) and provides an easy api for bots and clients (`getChatlist`, `getChat`, `getContact`, ...).
|
||||
- [jsonrpc](https://www.jsonrpc.org/specification) is a JSON based protocol
|
||||
for applications to speak to each other by [remote procedure calls](https://en.wikipedia.org/wiki/Remote_procedure_call) (short RPC),
|
||||
which basically means that the client can call methods on the server by sending a JSON messages.
|
||||
- [`deltachat-rpc-server`](https://github.com/deltachat/deltachat-core-rust/tree/main/deltachat-rpc-server) provides the jsonrpc api over stdio (stdin/stdout)
|
||||
- [`@deltachat/stdio-rpc-server`](https://www.npmjs.com/package/@deltachat/stdio-rpc-server) is an easy way to install `deltachat-rpc-server` from npm and use it from nodejs.
|
||||
|
||||
#### Transport
|
||||
|
||||
You need to connect this client to an instance of chatmail-core via a transport.
|
||||
|
||||
For this you can use the `StdioTransport`, which you can use by importing `StdioDeltaChat`.
|
||||
|
||||
You can also make your own transport, for example deltachat desktop uses a custom transport that sends the json messages over electron ipc.
|
||||
Just implement your transport based on the `Transport` interface - look at how the [stdio transport is implemented](https://github.com/deltachat/deltachat-core-rust/blob/7121675d226e69fd85d0194d4b9c4442e4dd8299/deltachat-jsonrpc/typescript/src/client.ts#L113) for an example, it's not hard.
|
||||
|
||||
The other transports that exist (but note that those are not standalone, they list here only serves as reference on how to implement those.):
|
||||
|
||||
- Electron IPC (from Delta Chat Desktop)
|
||||
- [transport](https://github.com/deltachat/deltachat-desktop/blob/0a4fdb2065c7b14fa097769181afd05e3f552f54/packages/target-electron/runtime-electron/runtime.ts#L49-L123), [request handling](https://github.com/deltachat/deltachat-desktop/blob/0a4fdb2065c7b14fa097769181afd05e3f552f54/packages/target-electron/src/deltachat/controller.ts#L199-L201), [responses](https://github.com/deltachat/deltachat-desktop/blob/0a4fdb2065c7b14fa097769181afd05e3f552f54/packages/target-electron/src/deltachat/controller.ts#L93-L113)
|
||||
- Tauri IPC (from DC Desktop Tauri edition)
|
||||
- [transport](https://github.com/deltachat/deltachat-desktop/blob/0a4fdb2065c7b14fa097769181afd05e3f552f54/packages/target-tauri/runtime-tauri/runtime.ts#L86-L118), backend: [request handling](https://github.com/deltachat/deltachat-desktop/blob/0a4fdb2065c7b14fa097769181afd05e3f552f54/packages/target-tauri/src-tauri/src/lib.rs#L85-L94), [responses](https://github.com/deltachat/deltachat-desktop/blob/0a4fdb2065c7b14fa097769181afd05e3f552f54/packages/target-tauri/src-tauri/src/state/deltachat.rs#L43-L95)
|
||||
- Authenticated Websocket (from DC Desktop Browser edition)
|
||||
- [transport](https://github.com/deltachat/deltachat-desktop/blob/0a4fdb2065c7b14fa097769181afd05e3f552f54/packages/target-browser/runtime-browser/runtime.ts#L37-L80), backend: [authentication](https://github.com/deltachat/deltachat-desktop/blob/0a4fdb2065c7b14fa097769181afd05e3f552f54/packages/target-browser/src/index.ts#L258-L275), [web socket server](https://github.com/deltachat/deltachat-desktop/blob/0a4fdb2065c7b14fa097769181afd05e3f552f54/packages/target-browser/src/deltachat-rpc.ts#L93) (this also contains some unrelated code, it's easier than it looks at first glance)
|
||||
|
||||
## Usage
|
||||
|
||||
> The **minimum** nodejs version for `@deltachat/stdio-rpc-server` is `16`
|
||||
|
||||
```
|
||||
npm i @deltachat/stdio-rpc-server @deltachat/jsonrpc-client
|
||||
```
|
||||
|
||||
```js
|
||||
import { startDeltaChat } from "@deltachat/stdio-rpc-server";
|
||||
// Import constants you might need later
|
||||
import { C } from "@deltachat/jsonrpc-client";
|
||||
|
||||
async function main() {
|
||||
const dc = await startDeltaChat("deltachat-data");
|
||||
console.log(await dc.rpc.getSystemInfo());
|
||||
dc.close();
|
||||
}
|
||||
main();
|
||||
```
|
||||
|
||||
For a more complete example refer to <https://github.com/deltachat-bot/echo/tree/master/nodejs_stdio_jsonrpc>.
|
||||
|
||||
### Listening for events
|
||||
|
||||
```ts
|
||||
dc.on("Info", (accountId, { msg }) =>
|
||||
console.info(accountId, "[core:info]", msg),
|
||||
);
|
||||
// Or get an event emitter for only one account
|
||||
const emitter = dc.getContextEvents(accountId);
|
||||
emitter.on("IncomingMsg", async ({ chatId, msgId }) => {
|
||||
const message = await dc.rpc.getMessage(accountId, msgId);
|
||||
console.log("got message in chat " + chatId + " : ", message.text);
|
||||
});
|
||||
```
|
||||
|
||||
### Getting Started
|
||||
|
||||
This section describes how to handle the Delta Chat core library over the jsonrpc bindings.
|
||||
For general information about Delta Chat itself,
|
||||
see <https://delta.chat> and <https://github.com/deltachat>.
|
||||
|
||||
Let's start.
|
||||
|
||||
First of all, you have to start the deltachat-rpc-server process.
|
||||
|
||||
```js
|
||||
import { startDeltaChat } from "@deltachat/stdio-rpc-server";
|
||||
const dc = await startDeltaChat("deltachat-data");
|
||||
```
|
||||
|
||||
Then we have to create an Account (also called Context or profile) that is bound to a database.
|
||||
The database is a normal SQLite file with a "blob directory" beside it.
|
||||
But these details are handled by deltachat's account manager.
|
||||
So you just have to tell the account manager to create a new account:
|
||||
|
||||
```js
|
||||
const accountId = await dc.rpc.addAccount();
|
||||
```
|
||||
|
||||
After that, register event listeners so you can see what core is doing:
|
||||
Intenally `@deltachat/jsonrpc-client` implments a loop that waits for new events and then emits them to javascript land.
|
||||
|
||||
```js
|
||||
dc.on("Info", (accountId, { msg }) =>
|
||||
console.info(accountId, "[core:info]", msg),
|
||||
);
|
||||
```
|
||||
|
||||
Now you can **configure the account:**
|
||||
|
||||
```js
|
||||
// use some real test credentials here
|
||||
await dc.rpc.setConfig(accountId, "addr", "alice@example.org");
|
||||
await dc.rpc.setConfig(accountId, "mail_pw", "***");
|
||||
// you can also set multiple config options in one call
|
||||
await dc.rpc.batchSetConfig(accountId, {
|
||||
addr: "alice@example.org",
|
||||
mail_pw: "***",
|
||||
});
|
||||
|
||||
// after setting the credentials attempt to login
|
||||
await dc.rpc.configure(accountId);
|
||||
```
|
||||
|
||||
`configure()` returns a promise that is rejected on error (with await is is thrown).
|
||||
The configuration itself may take a while. You can monitor it's progress like this:
|
||||
|
||||
```js
|
||||
dc.on("ConfigureProgress", (accountId, { progress, comment }) => {
|
||||
console.log(accountId, "ConfigureProgress", progress, comment);
|
||||
});
|
||||
// make sure to register this event handler before calling `dc.rpc.configure()`
|
||||
```
|
||||
|
||||
The configuration result is saved in the database.
|
||||
On subsequent starts it is not needed to call `dc.rpc.configure(accountId)`
|
||||
(you can check this using `dc.rpc.isConfigured(accountId)`).
|
||||
|
||||
On a successfully configuration delta chat core automatically connects to the server, however subsequent starts you **need to do that manually** by calling `dc.rpc.startIo(accountId)` or `dc.rpc.startIoForAllAccounts()`.
|
||||
|
||||
```js
|
||||
if (!(await dc.rpc.isConfigured(accountId))) {
|
||||
// use some real test credentials here
|
||||
await dc.rpc.batchSetConfig(accountId, {
|
||||
addr: "alice@example.org",
|
||||
mail_pw: "***",
|
||||
});
|
||||
await dc.rpc.configure(accountId);
|
||||
} else {
|
||||
await dc.rpc.startIo(accountId);
|
||||
}
|
||||
```
|
||||
|
||||
Now you can **send the first message:**
|
||||
|
||||
```js
|
||||
const contactId = await dc.rpc.createContact(
|
||||
accountId,
|
||||
"bob@example.org",
|
||||
null /* optional name */,
|
||||
);
|
||||
const chatId = await dc.rpc.createChatByContactId(accountId, contactId);
|
||||
|
||||
await dc.rpc.miscSendTextMessage(
|
||||
accountId,
|
||||
chatId,
|
||||
"Hi, here is my first message!",
|
||||
);
|
||||
```
|
||||
|
||||
`dc.rpc.miscSendTextMessage()` returns immediately;
|
||||
the sending itself is done in the background.
|
||||
If you check the testing address (bob),
|
||||
you should receive a normal e-mail.
|
||||
Answer this e-mail in any e-mail program with "Got it!",
|
||||
and the IO you started above will **receive the message**.
|
||||
|
||||
You can then **list all messages** of a chat as follows:
|
||||
|
||||
```js
|
||||
let i = 0;
|
||||
for (const msgId of await exp.rpc.getMessageIds(120, 12, false, false)) {
|
||||
i++;
|
||||
console.log(`Message: ${i}`, (await dc.rpc.getMessage(120, msgId)).text);
|
||||
}
|
||||
```
|
||||
|
||||
This will output the following two lines:
|
||||
|
||||
```
|
||||
Message 1: Hi, here is my first message!
|
||||
Message 2: Got it!
|
||||
```
|
||||
|
||||
<!-- TODO: ### Clean shutdown? - seems to be more advanced to call async functions on exit, also is this needed in this usecase? -->
|
||||
|
||||
## Further information
|
||||
|
||||
- `@deltachat/stdio-rpc-server`
|
||||
- [package on npm](https://www.npmjs.com/package/@deltachat/stdio-rpc-server)
|
||||
- [source code on github](https://github.com/deltachat/deltachat-core-rust/tree/main/deltachat-rpc-server/npm-package)
|
||||
- [use `@deltachat/stdio-rpc-server` on an usuported platform](https://github.com/deltachat/deltachat-core-rust/tree/main/deltachat-rpc-server/npm-package#how-to-use-on-an-unsupported-platform)
|
||||
- The issue-tracker for the core library is here: <https://github.com/deltachat/deltachat-core-rust/issues>
|
||||
|
||||
If you need further assistance,
|
||||
please do not hesitate to contact us
|
||||
through the channels shown at https://delta.chat/en/contribute
|
||||
|
||||
Please keep in mind, that your derived work
|
||||
must respect the Mozilla Public License 2.0 of deltachat-rpc-server
|
||||
and the respective licenses of the libraries deltachat-rpc-server links with.
|
||||
@@ -5,14 +5,14 @@ import { RawClient } from "../generated/client.js";
|
||||
import { BaseTransport, Request } from "yerpc";
|
||||
import { TinyEmitter } from "@deltachat/tiny-emitter";
|
||||
|
||||
type Events = { ALL: (accountId: number, event: EventType) => void } & {
|
||||
export type Events = { ALL: (accountId: number, event: EventType) => void } & {
|
||||
[Property in EventType["kind"]]: (
|
||||
accountId: number,
|
||||
event: Extract<EventType, { kind: Property }>,
|
||||
) => void;
|
||||
};
|
||||
|
||||
type ContextEvents = { ALL: (event: EventType) => void } & {
|
||||
export type ContextEvents = { ALL: (event: EventType) => void } & {
|
||||
[Property in EventType["kind"]]: (
|
||||
event: Extract<EventType, { kind: Property }>,
|
||||
) => void;
|
||||
|
||||
@@ -5,6 +5,8 @@ it does not use NAPI bindings but instead uses stdio executables
|
||||
to let you talk to core over jsonrpc over stdio.
|
||||
This simplifies cross-compilation and even reduces binary size (no CFFI layer and no NAPI layer).
|
||||
|
||||
📚 Docs: <https://js.jsonrpc.delta.chat/>
|
||||
|
||||
## Usage
|
||||
|
||||
> The **minimum** nodejs version for this package is `16`
|
||||
@@ -18,20 +20,47 @@ import { startDeltaChat } from "@deltachat/stdio-rpc-server";
|
||||
import { C } from "@deltachat/jsonrpc-client";
|
||||
|
||||
async function main() {
|
||||
const dc = await startDeltaChat("deltachat-data");
|
||||
console.log(await dc.rpc.getSystemInfo());
|
||||
dc.close()
|
||||
const dc = await startDeltaChat("deltachat-data");
|
||||
console.log(await dc.rpc.getSystemInfo());
|
||||
dc.close();
|
||||
}
|
||||
main()
|
||||
main();
|
||||
```
|
||||
|
||||
For a more complete example refer to https://github.com/deltachat-bot/echo/pull/69/files (TODO change link when pr is merged).
|
||||
For a more complete example refer to <https://github.com/deltachat-bot/echo/tree/master/nodejs_stdio_jsonrpc>.
|
||||
|
||||
## How to use on an unsupported platform
|
||||
|
||||
<!-- todo instructions, will uses an env var for pointing to `deltachat-rpc-server` binary -->
|
||||
You need to have rust installed to compile deltachat core for your platform and cpu architecture.
|
||||
<https://rustup.rs/> is the recommended way to install rust.
|
||||
Also your system probably needs more than 4GB RAM to compile core, alternatively your could try to build the debug build, which might take less RAM to build.
|
||||
|
||||
<!-- todo copy parts from https://github.com/deltachat/deltachat-desktop/blob/7045c6f549e4b9d5caa0709d5bd314bbd9fd53db/docs/UPDATE_CORE.md -->
|
||||
1. clone the core repo, right next to your project folder: `git clone git@github.com:deltachat/deltachat-core-rust.git`
|
||||
2. go into your core checkout and run `git pull` and `git checkout <version>` to point it to the correct version (needs to be the same version the `@deltachat/jsonrpc-client` package has)
|
||||
3. run `cargo build --release --package deltachat-rpc-server --bin deltachat-rpc-server`
|
||||
|
||||
Then you have 2 options:
|
||||
|
||||
### point to deltachat-rpc-server via direct path:
|
||||
|
||||
```sh
|
||||
# start your app with the DELTA_CHAT_RPC_SERVER env var
|
||||
DELTA_CHAT_RPC_SERVER="../deltachat-core-rust/target/release/deltachat-rpc-server" node myapp.js
|
||||
```
|
||||
|
||||
### install deltachat-rpc-server in your $PATH:
|
||||
|
||||
```sh
|
||||
# use this to install to ~/.cargo/bin
|
||||
cargo install --release --package deltachat-rpc-server --bin deltachat-rpc-server
|
||||
# or manually move deltachat-core-rust/target/release/deltachat-rpc-server
|
||||
# to a location that is included in your $PATH Environment variable.
|
||||
```
|
||||
|
||||
And make sure to enable the `takeVersionFromPATH` option:
|
||||
```js
|
||||
startDeltaChat("data-dir", { takeVersionFromPATH: true });
|
||||
```
|
||||
|
||||
## How does it work when you install it
|
||||
|
||||
@@ -46,7 +75,7 @@ references:
|
||||
When you import this package it searches for the rpc server in the following locations and order:
|
||||
|
||||
1. `DELTA_CHAT_RPC_SERVER` environment variable
|
||||
2. use the PATH when `{takeVersionFromPATH: true}` is supplied in the options.
|
||||
2. use the PATH when `{takeVersionFromPATH: true}` is supplied in the options.
|
||||
3. prebuilds in npm packages
|
||||
|
||||
so by default it uses the prebuilds.
|
||||
|
||||
Reference in New Issue
Block a user