mirror of
https://github.com/tinode/chat.git
synced 2025-03-15 09:58:43 +00:00
adding new features: form voting and avatar as a URL
This commit is contained in:
12
docs/API.md
12
docs/API.md
@ -1068,11 +1068,14 @@ The `{note.recv}` and `{note.read}` do alter persistent state on the server. The
|
||||
note: {
|
||||
topic: "grp1XUtEhjv6HND", // string, topic to notify, required
|
||||
what: "kp", // string, one of "kp" (key press), "read" (read notification),
|
||||
// "rcpt" (received notification), any other string will cause
|
||||
// message to be silently ignored, required
|
||||
// "rcpt" (received notification), "data" (form response or other structured data);
|
||||
// any other string will cause the message to be silently ignored, required.
|
||||
seq: 123, // integer, ID of the message being acknowledged, required for
|
||||
// rcpt & read
|
||||
unread: 10 // integer, client-reported total count of unread messages, optional.
|
||||
// 'rcpt' & 'read'.
|
||||
unread: 10, // integer, client-reported total count of unread messages, optional.
|
||||
data: { // object, required payload for 'data'.
|
||||
...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@ -1080,6 +1083,7 @@ The following actions are currently recognised:
|
||||
* kp: key press, i.e. a typing notification. The client should use it to indicate that the user is composing a new message.
|
||||
* recv: a `{data}` message is received by the client software but may not yet seen by user.
|
||||
* read: a `{data}` message is seen by the user. It implies `recv` as well.
|
||||
* data: a generic packet of structured data, usually a form response.
|
||||
|
||||
The `read` and `recv` notifications may optionally include `unread` value which is the total count of unread messages as determined by this client. The per-user `unread` count is maintained by the server: it's incremented when new `{data}` messages are sent to user and reset to the values reported by the `{note unread=...}` message. The `unread` value is never decremented by the server. The value is included in push notifications to be shown on a badge on iOS:
|
||||
<p align="center">
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Drafty: Rich Message Format
|
||||
|
||||
Drafty is a text format used by Tinode to style messages. The intent of Drafty is to be expressive just enough without opening too many possibilities for security issues. One may think of it as JSON-encapsulated [markdown](https://en.wikipedia.org/wiki/Markdown). Drafty is influenced by FB's [draft.js](https://draftjs.org/) specification. As of the time of this writing [Javascript](https://github.com/tinode/tinode-js/blob/master/src/drafty.js), [Java](https://github.com/tinode/tindroid/blob/master/tinodesdk/src/main/java/co/tinode/tinodesdk/model/Drafty.java) and [Swift](https://github.com/tinode/ios/blob/master/TinodeSDK/model/Drafty.swift) implementations exist. A [Go implementation](https://github.com/tinode/chat/blob/master/server/drafty/drafty.go) can convert Drafy to plain text.
|
||||
Drafty is a text format used by Tinode to style messages. The intent of Drafty is to be expressive just enough without opening too many possibilities for security issues. One may think of it as JSON-encapsulated [markdown](https://en.wikipedia.org/wiki/Markdown). Drafty is influenced by FB's [draft.js](https://draftjs.org/) specification. As of the time of this writing [Javascript](https://github.com/tinode/tinode-js/blob/master/src/drafty.js), [Java](https://github.com/tinode/tindroid/blob/master/tinodesdk/src/main/java/co/tinode/tinodesdk/model/Drafty.java) and [Swift](https://github.com/tinode/ios/blob/master/TinodeSDK/model/Drafty.swift) implementations exist. A [Go implementation](https://github.com/tinode/chat/blob/master/server/drafty/drafty.go) can convert Drafy to plain text and previews.
|
||||
|
||||
## Example
|
||||
|
||||
@ -216,12 +216,21 @@ Hashtag `data` contains a single `val` field with the hashtag value which the cl
|
||||
}
|
||||
```
|
||||
* `act`: type of action in response to button click:
|
||||
* `pub`: send a `{pub}` message to the current server.
|
||||
* `url`: issue an `HTTP GET` request to the URL from the `data.ref` field. A `name=val` and `uid=<current-user-ID>` query parameters are appended to the url.
|
||||
* `pub`: send a Drafty-formatted `{pub}` message to the current topic with the form data as an attachment:
|
||||
```js
|
||||
{ "tp":"EX", "data":{ "mime":"application/json", "val": { "seq": 3, "resp":{ "confirmation": "some-value" } } } }
|
||||
```
|
||||
* `url`: issue an `HTTP GET` request to the URL from the `data.ref` field. The following query parameters are appended to the URL: `<name>=<val>`, `uid=<current-user-ID>`, `topic=<topic name>`, `seq=<message sequence ID>`.
|
||||
* `note`: send a `{note}` message to the current topic with `what` set to `data`.
|
||||
```js
|
||||
{ "what": "data", "data": { "mime": "application/json", "val": { "seq": 3, "resp": { "confirmation": "some-value" } } }
|
||||
```
|
||||
* `name`: optional name of the button which is reported back to the server.
|
||||
* `val`: additional opaque data. If `name` is provided but `val` is not, `val` is assumed to be `1`.
|
||||
* `ref`: the actual URL for the `url` action.
|
||||
* `val`: additional opaque data.
|
||||
* `ref`: the URL for the `url` action.
|
||||
|
||||
The button in this example will send a HTTP GET to https://www.example.com/?confirmation=some-value&uid=usrFsk73jYRR
|
||||
If the `name` is provided but `val` is not, `val` is assumed to be `1`. If `name` is undefined then nether `name` nor `val` are sent.
|
||||
|
||||
The button in the example above will send an HTTP GET to https://www.example.com/?confirmation=some-value&uid=usrFsk73jYRR&topic=grpnG99YhENiQU&seq=3 assuming the current user ID is `usrFsk73jYRR`, the topic is `grpnG99YhENiQU`, and the sequence ID of message with the button is `3`.
|
||||
|
||||
_IMPORTANT Security Consideration_: the client should restrict URL scheme in the `url` field to `http` and `https` only.
|
||||
|
@ -41,7 +41,7 @@ const (
|
||||
defaultDSN = "root:@tcp(localhost:3306)/tinode?parseTime=true"
|
||||
defaultDatabase = "tinode"
|
||||
|
||||
adpVersion = 111
|
||||
adpVersion = 112
|
||||
|
||||
adapterName = "mysql"
|
||||
|
||||
@ -507,7 +507,7 @@ func (a *adapter) CreateDb(reset bool) error {
|
||||
}
|
||||
|
||||
// Records of uploaded files.
|
||||
// Don't add FOREIGN KEY on userid. It's not needed and it will break user deletion.
|
||||
// Don't change INDEX(userid) to FOREIGN KEY(userid). It will break user deletion.
|
||||
if _, err = tx.Exec(
|
||||
`CREATE TABLE fileuploads(
|
||||
id BIGINT NOT NULL,
|
||||
@ -517,8 +517,10 @@ func (a *adapter) CreateDb(reset bool) error {
|
||||
status INT NOT NULL,
|
||||
mimetype VARCHAR(255) NOT NULL,
|
||||
size BIGINT NOT NULL,
|
||||
purpose VARCHAR(4),
|
||||
location VARCHAR(2048) NOT NULL,
|
||||
PRIMARY KEY(id)
|
||||
PRIMARY KEY(id),
|
||||
INDEX fileuploads_userid(userid)
|
||||
)`); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -622,7 +624,7 @@ func (a *adapter) UpgradeDb() error {
|
||||
|
||||
if a.version == 109 {
|
||||
// Perform database upgrade from version 109 to version 110.
|
||||
if _, err := a.db.Exec(`UPDATE topics SET touchedat=updatedat WHERE touchedat IS NULL`); err != nil {
|
||||
if _, err := a.db.Exec("UPDATE topics SET touchedat=updatedat WHERE touchedat IS NULL"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -682,6 +684,20 @@ func (a *adapter) UpgradeDb() error {
|
||||
}
|
||||
}
|
||||
|
||||
if a.version == 111 {
|
||||
if _, err := a.db.Exec("ALTER TABLE fileuploads ADD INDEX fileuploads_userid(userid)"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := a.db.Exec("ALTER TABLE fileuploads ADD purpose VARCHAR(4) AFTER size"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := bumpVersion(a, 112); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if a.version != adpVersion {
|
||||
return errors.New("Failed to perform database upgrade to version " + strconv.Itoa(adpVersion) +
|
||||
". DB is still at " + strconv.Itoa(a.version))
|
||||
|
@ -190,14 +190,16 @@ CREATE TABLE credentials(
|
||||
CREATE TABLE fileuploads(
|
||||
id BIGINT NOT NULL,
|
||||
createdat DATETIME(3) NOT NULL,
|
||||
updatedat DATETIME(3) NOT NULL,
|
||||
updatedat DATETIME(3) NOT NULL,
|
||||
userid BIGINT NOT NULL,
|
||||
status INT NOT NULL,
|
||||
mimetype VARCHAR(255) NOT NULL,
|
||||
size BIGINT NOT NULL,
|
||||
purpose VARCHAR(4),
|
||||
location VARCHAR(2048) NOT NULL,
|
||||
|
||||
PRIMARY KEY(id)
|
||||
PRIMARY KEY(id),
|
||||
INDEX fileuploads_userid(userid)
|
||||
);
|
||||
|
||||
# Links between uploaded files and messages.
|
||||
|
Reference in New Issue
Block a user