├── api ├── .gitignore ├── gen_json.js ├── meta.md ├── bin │ └── build-docs ├── file.location.md ├── channel.leave.md ├── session_channel.leave.md ├── channel.kick.md ├── channel.invite.md ├── channel.kickout.md ├── message_pin.delete.md ├── message.delete.md ├── session_channel.kick.md ├── session_channel.kickout.md ├── session_channel.invite.md ├── team.info.md ├── reaction.delete.md ├── sticker.list.md ├── emoji.list.md ├── p2p.list.md ├── session_channel.list.md ├── p2p.create.md ├── p2p.info.md ├── channel.list.md ├── session_channel.archive.md ├── session_channel.info.md ├── user.me.md ├── package.json ├── channel.archive.md ├── channel.join.md ├── message_pin.list.md ├── channel.info.md ├── message_pin.create.md ├── channel.unarchive.md ├── user.list.md ├── session_channel.create.md ├── reaction.create.md ├── rtm.start.md ├── user.info.md ├── session_channel.convert_to_channel.md ├── channel.create.md ├── message.info.md ├── message.create.md ├── user.update_me.md ├── message.update_text.md ├── vchannel.info.md ├── message.forward.md ├── message.query.md ├── index.tmpl ├── README.md ├── gen_doc.js ├── yarn.lock └── swagger.yml ├── rtm ├── README.md ├── api_start.md ├── event_add_message_reaction.md ├── event.md ├── event_delete_message_reaction.md ├── api.md ├── event_update_message.md ├── event_update_channel_message.md ├── event_channel_message.md ├── event_message.md └── api_message.md ├── CONTRIBUTING.md ├── package.Dockerfile ├── release.Dockerfile ├── deploy ├── nginx.conf └── static │ └── swagger-ui.css ├── README.md └── Makefile /api/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /rtm/README.md: -------------------------------------------------------------------------------- 1 | # RTM 服务 2 | 3 | RTM 服务提供实时聊天功能,主要分为两部分: 4 | 5 | - [HTTP API](./api.md): 提供 HTTP API 接口 6 | - [实时 RTM 事件](./event.md): 通过 websocket 提供实时的双工通信 7 | -------------------------------------------------------------------------------- /rtm/api_start.md: -------------------------------------------------------------------------------- 1 | # API `POST /start` 2 | 3 | 该接口用作获取 RTM 模式的连接地址和用户信息。 4 | 5 | ## 请求参数 6 | 7 | ``` 8 | { 9 | "token": "rtm token" 10 | } 11 | ``` 12 | 13 | ## 响应 14 | 15 | ``` 16 | { 17 | "code": 0, 18 | "result": { 19 | // RTM token 对应用户结构 20 | "user": {}, 21 | // RTM 连接地址 5 分钟内有效 22 | "ws_host": "wss://rtm.bearychat.com/nimbus/ws:xxx" 23 | } 24 | } 25 | ``` 26 | -------------------------------------------------------------------------------- /api/gen_json.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const join = require('path').join 3 | const yaml = require('js-yaml') 4 | 5 | const apiSchemaPath = join(__dirname, 'swagger.yml') 6 | const apiSchema = yaml.safeLoad(fs.readFileSync(apiSchemaPath)) 7 | 8 | const file = join(__dirname, 'swagger.json') 9 | fs.writeFileSync(file, JSON.stringify(apiSchema, null, ' ')) 10 | console.log(`generated ${file}`) 11 | -------------------------------------------------------------------------------- /api/meta.md: -------------------------------------------------------------------------------- 1 | # meta 2 | 3 | 返回 BearyChat API 的状态。 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | GET {base_url}/meta 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | 16 | ## 响应 17 | 18 | ### 200 19 | 20 | ```javascript 21 | { 22 | "version": "1" 23 | } 24 | ``` 25 | ### 错误响应 26 | 27 | ```javascript 28 | { 29 | "code": // error code, 30 | "error": "unexpected error" 31 | } 32 | ``` 33 | 34 | 35 | -------------------------------------------------------------------------------- /api/bin/build-docs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const mustache = require('mustache') 4 | const getStdin = require('get-stdin') 5 | const fs = require('fs') 6 | const join = require('path').join 7 | 8 | const tmplPath = join(__dirname, '../index.tmpl') 9 | const tmpl = fs.readFileSync(tmplPath).toString() 10 | 11 | getStdin().then((yaml) => { 12 | const rendered = mustache.render(tmpl, {spec: yaml}) 13 | console.log(rendered) 14 | }) 15 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Bug 上报 2 | 3 | 可以使用 GitHub 的 [issue tracker][issue] 来上报发现的问题: 4 | 5 | [issue]: https://github.com/bearyinnovative/OpenAPI/issues/new 6 | 7 | ## 开发社区 8 | 9 | 可以加入 [BearyChat OpenAPI][openapi] 团队来提问 & 回答关于 OpenAPI 的问题。 10 | 11 | [openapi]: https://openapi.bearychat.com/apply 12 | 13 | ## 本地开发 14 | 15 | 1. fork repo 16 | 2. 进入对应修改的目录 17 | 3. 修改对应文件 18 | 4. npm run build 19 | 5. commit 20 | 6. 发起 pull request 21 | 7. **benefit!!!1** 22 | -------------------------------------------------------------------------------- /package.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:8.15.0-alpine 2 | 3 | ARG build_date 4 | ARG commit 5 | ARG version 6 | ARG workspace=/workspace 7 | 8 | ENV HOME=/workspace 9 | 10 | # Inite workspace 11 | VOLUME /workspace 12 | WORKDIR /workspace 13 | 14 | # Generate version 15 | RUN echo "$version" >> $workspace/version 16 | RUN echo "$commit" >> $workspace/commit 17 | RUN echo "$build_date" >> $workspace/build_date 18 | 19 | RUN apk add make 20 | 21 | CMD ["make", "release"] 22 | -------------------------------------------------------------------------------- /api/file.location.md: -------------------------------------------------------------------------------- 1 | # file.location 2 | 3 | 换取文件真实地址 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | GET {base_url}/file.location 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `file_key` | `string` | 是 | 文件 key | | 18 | 19 | ## 响应 20 | 21 | ### 302 22 | ### 404 23 | 24 | ```javascript 25 | { 26 | "code": 6, 27 | "error": "文件不存在" 28 | } 29 | ``` 30 | 31 | 32 | -------------------------------------------------------------------------------- /api/channel.leave.md: -------------------------------------------------------------------------------- 1 | # channel.leave 2 | 3 | 当前用户离开讨论组。 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | POST {base_url}/channel.leave 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `channel_id` | `string` | 是 | 讨论组 id | =bw52O | 18 | 19 | ## 响应 20 | 21 | ### 204 22 | ### 错误响应 23 | 24 | ```javascript 25 | { 26 | "code": // error code, 27 | "error": "unexpected error" 28 | } 29 | ``` 30 | 31 | 32 | -------------------------------------------------------------------------------- /api/session_channel.leave.md: -------------------------------------------------------------------------------- 1 | # session_channel.leave 2 | 3 | 离开临时讨论组。 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | POST {base_url}/session_channel.leave 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `session_channel_id` | `string` | 是 | 临时讨论组 id | =bw52O | 18 | 19 | ## 响应 20 | 21 | ### 204 22 | ### 错误响应 23 | 24 | ```javascript 25 | { 26 | "code": // error code, 27 | "error": "unexpected error" 28 | } 29 | ``` 30 | 31 | 32 | -------------------------------------------------------------------------------- /api/channel.kick.md: -------------------------------------------------------------------------------- 1 | # channel.kick 2 | 3 | 当前用户移除一个讨论组成员。 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | POST {base_url}/channel.kick 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `channel_id` | `string` | 是 | 讨论组 id | =bw52O | 18 | | `kick_uid` | `string` | 是 | 移除用户 id | =bw52O | 19 | 20 | ## 响应 21 | 22 | ### 204 23 | ### 错误响应 24 | 25 | ```javascript 26 | { 27 | "code": // error code, 28 | "error": "unexpected error" 29 | } 30 | ``` 31 | 32 | 33 | -------------------------------------------------------------------------------- /api/channel.invite.md: -------------------------------------------------------------------------------- 1 | # channel.invite 2 | 3 | 当前用户邀请一个团队成员加入讨论组。 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | POST {base_url}/channel.invite 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `channel_id` | `string` | 是 | 讨论组 id | =bw52O | 18 | | `invite_uid` | `string` | 是 | 邀请用户 id | =bw52O | 19 | 20 | ## 响应 21 | 22 | ### 204 23 | ### 错误响应 24 | 25 | ```javascript 26 | { 27 | "code": // error code, 28 | "error": "unexpected error" 29 | } 30 | ``` 31 | 32 | 33 | -------------------------------------------------------------------------------- /api/channel.kickout.md: -------------------------------------------------------------------------------- 1 | # channel.kickout 2 | 3 | 当前用户移除一个讨论组成员。 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | POST {base_url}/channel.kickout 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `channel_id` | `string` | 是 | 讨论组 id | =bw52O | 18 | | `kick_uid` | `string` | 是 | 移除用户 id | =bw52O | 19 | 20 | ## 响应 21 | 22 | ### 204 23 | ### 错误响应 24 | 25 | ```javascript 26 | { 27 | "code": // error code, 28 | "error": "unexpected error" 29 | } 30 | ``` 31 | 32 | 33 | -------------------------------------------------------------------------------- /api/message_pin.delete.md: -------------------------------------------------------------------------------- 1 | # message_pin.delete 2 | 3 | 删除置顶消息 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | POST {base_url}/message_pin.delete 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `vchannel_id` | `string` | 是 | 消息所在的频道 | =bw52O | 18 | | `pin_id` | `string` | 是 | 置顶消息的 id | =bw52O | 19 | 20 | ## 响应 21 | 22 | ### 200 23 | ### 错误响应 24 | 25 | ```javascript 26 | { 27 | "code": // error code, 28 | "error": "unexpected error" 29 | } 30 | ``` 31 | 32 | 33 | -------------------------------------------------------------------------------- /api/message.delete.md: -------------------------------------------------------------------------------- 1 | # message.delete 2 | 3 | 删除一条消息。 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | POST {base_url}/message.delete 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `vchannel_id` | `string` | 是 | 待查询 vchannel_id | =bw52O | 18 | | `message_key` | `string` | 是 | 删除的消息 key | 1487667236785.0077 | 19 | 20 | ## 响应 21 | 22 | ### 204 23 | ### 错误响应 24 | 25 | ```javascript 26 | { 27 | "code": // error code, 28 | "error": "unexpected error" 29 | } 30 | ``` 31 | 32 | 33 | -------------------------------------------------------------------------------- /api/session_channel.kick.md: -------------------------------------------------------------------------------- 1 | # session_channel.kick 2 | 3 | 移除一个临时讨论组成员。 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | POST {base_url}/session_channel.kick 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `session_channel_id` | `string` | 是 | 临时讨论组 id | =bw52O | 18 | | `kick_uid` | `string` | 是 | 移除用户 id | =bw52O | 19 | 20 | ## 响应 21 | 22 | ### 204 23 | ### 错误响应 24 | 25 | ```javascript 26 | { 27 | "code": // error code, 28 | "error": "unexpected error" 29 | } 30 | ``` 31 | 32 | 33 | -------------------------------------------------------------------------------- /api/session_channel.kickout.md: -------------------------------------------------------------------------------- 1 | # session_channel.kickout 2 | 3 | 移除一个临时讨论组成员。 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | POST {base_url}/session_channel.kickout 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `session_channel_id` | `string` | 是 | 临时讨论组 id | =bw52O | 18 | | `kick_uid` | `string` | 是 | 移除用户 id | =bw52O | 19 | 20 | ## 响应 21 | 22 | ### 204 23 | ### 错误响应 24 | 25 | ```javascript 26 | { 27 | "code": // error code, 28 | "error": "unexpected error" 29 | } 30 | ``` 31 | 32 | 33 | -------------------------------------------------------------------------------- /api/session_channel.invite.md: -------------------------------------------------------------------------------- 1 | # session_channel.invite 2 | 3 | 邀请一个团队成员加入临时讨论组。 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | POST {base_url}/session_channel.invite 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `session_channel_id` | `string` | 是 | 临时讨论组 id | =bw52O | 18 | | `invite_uid` | `string` | 是 | 邀请用户 id | =bw52O | 19 | 20 | ## 响应 21 | 22 | ### 204 23 | ### 错误响应 24 | 25 | ```javascript 26 | { 27 | "code": // error code, 28 | "error": "unexpected error" 29 | } 30 | ``` 31 | 32 | 33 | -------------------------------------------------------------------------------- /api/team.info.md: -------------------------------------------------------------------------------- 1 | # team.info 2 | 3 | 返回当前团队信息。 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | GET {base_url}/team.info 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | 16 | ## 响应 17 | 18 | ### 200 19 | 20 | ```javascript 21 | { 22 | "id": "=bw52O", 23 | "subdomain": "openapi", 24 | "name": "BearyChat OpenAPI", 25 | "email_domain": null, 26 | "logo_url": null, 27 | "description": "", 28 | "plan": "basic", 29 | "created": "2017-01-11T12:28:31.000+0000" 30 | } 31 | ``` 32 | ### 错误响应 33 | 34 | ```javascript 35 | { 36 | "code": // error code, 37 | "error": "unexpected error" 38 | } 39 | ``` 40 | 41 | 42 | -------------------------------------------------------------------------------- /rtm/event_add_message_reaction.md: -------------------------------------------------------------------------------- 1 | # `add_message_reaction` 事件 2 | 3 | ``` 4 | { 5 | "data": { 6 | "created": "2017-02-20T14:19:15.000+0800", 7 | "created_ts": 1487571555467, 8 | "id": "=bwYQU", 9 | "message_id": "=eCRZP", 10 | "message_key": "1487571355082.0141", 11 | "reaction": ":+1:", 12 | "team_id": "=bw52O", 13 | "uid": "=bwCkD", 14 | "updated": "2017-02-20T14:19:15.000+0800" 15 | }, 16 | "ts": 1487571555491, 17 | "type": "add_message_reaction" 18 | } 19 | ``` 20 | 21 | add_message_reaction 事件在添加消息回应的时候触发。其中 `data` 字段包含了 22 | 该消息回应的数据:`message_key` 为对应消息的 key, `reaction` 为用户点选的 23 | emoji 名称,`uid` 为点选的用户 id. 24 | -------------------------------------------------------------------------------- /rtm/event.md: -------------------------------------------------------------------------------- 1 | # 实时双工通信 2 | 3 | RTM 服务通过 `websocket` 协议实现实时双工通信。 4 | 5 | ## 打开 websocket 连接 6 | 7 | 调用方可以通过 [`start`][rtm_start] API 来获取一个 websocket 连接。 8 | 9 | [rtm_start]: ./api_start.md 10 | 11 | ## 实时事件 12 | 13 | 14 | 15 | - [`message`](./event_message.md) P2P 会话消息事件 16 | - [`channel_message`](./event_channel_message.md) 讨论组会话消息事件 17 | - [`update_message`](./event_update_message.md) P2P 会话消息更新事件 18 | - [`update_channel_message`](./event_update_channel_message.md) 讨论组会话消息更新事件 19 | - [`add_message_reaction`](./event_add_message_reaction.md) 添加消息回应事件 20 | - [`delete_message_reaction`](./event_delete_message_reaction.md) 删除消息回应事件 21 | -------------------------------------------------------------------------------- /rtm/event_delete_message_reaction.md: -------------------------------------------------------------------------------- 1 | # `delete_message_reaction` 事件 2 | 3 | ``` 4 | { 5 | "data": { 6 | "created": "2017-02-20T14:26:55.000+0800", 7 | "created_ts": 1487572015282, 8 | "id": "=bwYQZ", 9 | "message_id": "=eCRZP", 10 | "message_key": "1487571355082.0141", 11 | "reaction": ":+1:", 12 | "team_id": "=bw52O", 13 | "uid": "=bwCkD", 14 | "updated": "2017-02-20T14:26:55.000+0800" 15 | }, 16 | "ts": 1487572021131, 17 | "type": "delete_message_reaction" 18 | } 19 | ``` 20 | 21 | delete_message_reaction 事件在取消消息回应的时候触发。其中 `data` 字段包含了 22 | 被取消的消息回应的数据:`message_key` 为对应消息的 key, `reaction` 为用户取消的 23 | emoji 名称,`uid` 为取消的用户 id. 24 | -------------------------------------------------------------------------------- /api/reaction.delete.md: -------------------------------------------------------------------------------- 1 | # reaction.delete 2 | 3 | 删除消息 reaction 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | POST {base_url}/reaction.delete 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `vchannel_id` | `string` | 是 | 消息所在的频道 | =bw52O | 18 | | `key` | `string` | 是 | 想要删 sticker 的 message 的 key | 1540460114044.0100 | 19 | | `reaction` | `string` | 是 | 想要删除的 reaction 名 | :smile: | 20 | 21 | ## 响应 22 | 23 | ### 200 24 | ### 错误响应 25 | 26 | ```javascript 27 | { 28 | "code": // error code, 29 | "error": "unexpected error" 30 | } 31 | ``` 32 | 33 | 34 | -------------------------------------------------------------------------------- /api/sticker.list.md: -------------------------------------------------------------------------------- 1 | # sticker.list 2 | 3 | 返回当前用户的自定义 sticker 列表 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | GET {base_url}/sticker.list 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | 16 | ## 响应 17 | 18 | ### 200 19 | 20 | ```javascript 21 | [ 22 | { 23 | "pack": "黑白熊静态", 24 | "stickers": [ 25 | { 26 | "url": "https://dn-bearychat.qbox.me/sticker-gif-20.gif", 27 | "name": "累", 28 | "width": 240, 29 | "height": 240 30 | } 31 | ] 32 | } 33 | ] 34 | ``` 35 | ### 错误响应 36 | 37 | ```javascript 38 | { 39 | "code": // error code, 40 | "error": "unexpected error" 41 | } 42 | ``` 43 | 44 | 45 | -------------------------------------------------------------------------------- /api/emoji.list.md: -------------------------------------------------------------------------------- 1 | # emoji.list 2 | 3 | 返回团队内的自定义 emoji 列表 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | GET {base_url}/emoji.list 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | 16 | ## 响应 17 | 18 | ### 200 19 | 20 | ```javascript 21 | [ 22 | { 23 | "id": "=bw52O", 24 | "uid": "=bw52O", 25 | "team_id": "=bw52O", 26 | "name": "hello", 27 | "type": "emoji", 28 | "created": "2017-03-13T13:54:16.000+0000", 29 | "updated": "2017-03-13T13:54:16.000+0000", 30 | "url": "http://example.com/1.jpg" 31 | } 32 | ] 33 | ``` 34 | ### 错误响应 35 | 36 | ```javascript 37 | { 38 | "code": // error code, 39 | "error": "unexpected error" 40 | } 41 | ``` 42 | 43 | 44 | -------------------------------------------------------------------------------- /api/p2p.list.md: -------------------------------------------------------------------------------- 1 | # p2p.list 2 | 3 | 返回 P2P 聊天会话列表,获取某个 P2P 会话的完整信息,请使用 `p2p.info`. 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | GET {base_url}/p2p.list 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | 16 | ## 响应 17 | 18 | ### 200 19 | 20 | ```javascript 21 | [ 22 | { 23 | "id": "=bw52O", 24 | "team_id": "=bw52O", 25 | "vchannel_id": "=bw52O", 26 | "type": "p2p", 27 | "is_active": true, 28 | "is_member": true, 29 | "member_uids": [ 30 | "=bw52O", 31 | "=bw52P" 32 | ], 33 | "latest_ts": 1485238998284 34 | } 35 | ] 36 | ``` 37 | ### 错误响应 38 | 39 | ```javascript 40 | { 41 | "code": // error code, 42 | "error": "unexpected error" 43 | } 44 | ``` 45 | 46 | 47 | -------------------------------------------------------------------------------- /release.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx:1.15.7-alpine 2 | 3 | ARG build_date 4 | ARG commit 5 | ARG version 6 | 7 | # Predefined environment (NOTE should not override, for ENTRYPOINT usage) 8 | ENV WORKSPACE=/workspace 9 | ENV LOG_DIR=/workspace/log 10 | 11 | # Init workspace 12 | RUN mkdir -p $WORKSPACE 13 | WORKDIR $WORKSPACE 14 | 15 | # Init log directory 16 | RUN mkdir -p $LOG_DIR 17 | VOLUME $LOG_DIR 18 | 19 | # Generate version and build information 20 | RUN echo "$version" >> $WORKSPACE/version 21 | RUN echo "$commit" >> $WORKSPACE/commit 22 | RUN echo "$build_date" >> $WORKSPACE/build_date 23 | 24 | COPY api/generated/openapi.html /workspace/index.html 25 | COPY deploy/nginx.conf /etc/nginx/nginx.conf 26 | COPY deploy/static/* /workspace/ 27 | 28 | EXPOSE 80 29 | -------------------------------------------------------------------------------- /api/session_channel.list.md: -------------------------------------------------------------------------------- 1 | # session_channel.list 2 | 3 | 返回团队内已经加入的临时讨论组列表,获取某个临时讨论组的完整信息, 4 | 请使用 `session_channel.info`. 5 | 6 | ## 请求方式 7 | 8 | ``` 9 | GET {base_url}/session_channel.list 10 | ``` 11 | 12 | ## 请求参数 13 | 14 | **需要登录** 15 | 16 | 17 | ## 响应 18 | 19 | ### 200 20 | 21 | ```javascript 22 | [ 23 | { 24 | "latest_ts": "1489242467694", 25 | "name": "临时讨论组名称", 26 | "is_member": true, 27 | "is_active": true, 28 | "type": "session", 29 | "member_uids": [ 30 | "=bw52O" 31 | ], 32 | "vchannel_id": "=bw52O", 33 | "id": "=bw52O", 34 | "team_id": "=bw52O" 35 | } 36 | ] 37 | ``` 38 | ### 错误响应 39 | 40 | ```javascript 41 | { 42 | "code": // error code, 43 | "error": "unexpected error" 44 | } 45 | ``` 46 | 47 | 48 | -------------------------------------------------------------------------------- /api/p2p.create.md: -------------------------------------------------------------------------------- 1 | # p2p.create 2 | 3 | 创建一个 P2P 聊天会话。 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | POST {base_url}/p2p.create 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `user_id` | `string` | 是 | P2P 聊天另外一方的用户 id | =bw52O | 18 | 19 | ## 响应 20 | 21 | ### 201 22 | 23 | ```javascript 24 | { 25 | "id": "=bw52O", 26 | "team_id": "=bw52O", 27 | "vchannel_id": "=bw52O", 28 | "type": "p2p", 29 | "is_active": true, 30 | "is_member": true, 31 | "member_uids": [ 32 | "=bw52O", 33 | "=bw52P" 34 | ], 35 | "latest_ts": 1485238998284 36 | } 37 | ``` 38 | ### 错误响应 39 | 40 | ```javascript 41 | { 42 | "code": // error code, 43 | "error": "unexpected error" 44 | } 45 | ``` 46 | 47 | 48 | -------------------------------------------------------------------------------- /api/p2p.info.md: -------------------------------------------------------------------------------- 1 | # p2p.info 2 | 3 | 返回一个 P2P 聊天会话的完整信息。 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | GET {base_url}/p2p.info 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `p2p_channel_id` | `string` | 是 | P2P 聊天会话 id, 例如\"=bw52O\" | | 18 | 19 | ## 响应 20 | 21 | ### 200 22 | 23 | ```javascript 24 | { 25 | "id": "=bw52O", 26 | "team_id": "=bw52O", 27 | "vchannel_id": "=bw52O", 28 | "type": "p2p", 29 | "is_active": true, 30 | "is_member": true, 31 | "member_uids": [ 32 | "=bw52O", 33 | "=bw52P" 34 | ], 35 | "latest_ts": 1485238998284 36 | } 37 | ``` 38 | ### 错误响应 39 | 40 | ```javascript 41 | { 42 | "code": // error code, 43 | "error": "unexpected error" 44 | } 45 | ``` 46 | 47 | 48 | -------------------------------------------------------------------------------- /deploy/nginx.conf: -------------------------------------------------------------------------------- 1 | user nginx; 2 | worker_processes 1; 3 | 4 | error_log /workspace/log/error.log warn; 5 | pid /var/run/nginx.pid; 6 | 7 | events { 8 | worker_connections 1024; 9 | } 10 | 11 | http { 12 | include /etc/nginx/mime.types; 13 | default_type application/octet-stream; 14 | 15 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 16 | '$status $body_bytes_sent "$http_referer" ' 17 | '"$http_user_agent" "$http_x_forwarded_for"'; 18 | 19 | access_log /workspace/log/access.log main; 20 | 21 | sendfile on; 22 | 23 | keepalive_timeout 65; 24 | 25 | gzip on; 26 | 27 | server { 28 | server_name openapi.bearychat.help; 29 | root /workspace; 30 | index index.html; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /api/channel.list.md: -------------------------------------------------------------------------------- 1 | # channel.list 2 | 3 | 返回团队内的讨论组列表,获取某个讨论组的完整信息,请使用 `channel.info`. 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | GET {base_url}/channel.list 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | 16 | ## 响应 17 | 18 | ### 200 19 | 20 | ```javascript 21 | [ 22 | { 23 | "private": false, 24 | "general": true, 25 | "latest_ts": 1486367046281, 26 | "uid": "=bw52O", 27 | "name": "所有人", 28 | "is_member": false, 29 | "is_active": true, 30 | "type": "normal", 31 | "topic": null, 32 | "member_uids": [ 33 | "=bw52O" 34 | ], 35 | "vchannel_id": "=bw52O", 36 | "id": "=bw52O", 37 | "team_id": "=bw52O" 38 | } 39 | ] 40 | ``` 41 | ### 错误响应 42 | 43 | ```javascript 44 | { 45 | "code": // error code, 46 | "error": "unexpected error" 47 | } 48 | ``` 49 | 50 | 51 | -------------------------------------------------------------------------------- /rtm/api.md: -------------------------------------------------------------------------------- 1 | # HTTP API 2 | 3 | RTM 服务提供了一系列接口来进行对 RTM 服务的调用。 4 | 5 | ## API 概况 6 | 7 | RTM HTTP API 基地址为: 8 | 9 | ``` 10 | https://rtm.bearychat.com 11 | ``` 12 | 13 | 对于不同的 API 接口,只需要拼接对应的请求方法路径到基地址即可,如: 14 | 15 | ``` 16 | https://rtm.bearychat.com/start 17 | ``` 18 | 19 | ## 授权 20 | 21 | 如无特别说明,所有 RTM API 都需要授权后才能访问。目前支持授权方式有: 22 | 23 | - RTM token 授权 24 | 25 | ### RTM token 授权 26 | 27 | **RTM token 目前可以通过创建 hubot 机器人获得** 28 | 29 | 该授权模式下,请求方需要把 RTM token 值放到请求的 token 参数中,如: 30 | 31 | ``` 32 | POST https://rtm.bearychat.com/start?token=your_rtm_token 33 | ``` 34 | 35 | 或者 36 | 37 | ``` 38 | POST https://rtm.bearychat.com/start 39 | { 40 | "token": "your_rtm_token" 41 | } 42 | ``` 43 | 44 | ## API 接口 45 | 46 | 47 | 48 | - [`start`](./api_start.md) 获取 RTM 模式的连接地址和用户信息 49 | - [`message`](./api_message.md) 发送富文本消息 50 | -------------------------------------------------------------------------------- /api/session_channel.archive.md: -------------------------------------------------------------------------------- 1 | # session_channel.archive 2 | 3 | 归档一个临时讨论组。 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | POST {base_url}/session_channel.archive 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `session_channel_id` | `string` | 是 | 临时讨论组 id | =bw52O | 18 | 19 | ## 响应 20 | 21 | ### 200 22 | 23 | ```javascript 24 | { 25 | "latest_ts": "1489242467694", 26 | "name": "临时讨论组名称", 27 | "is_member": true, 28 | "is_active": false, 29 | "type": "session", 30 | "member_uids": [ 31 | "=bw52O" 32 | ], 33 | "vchannel_id": "=bw52O", 34 | "id": "=bw52O", 35 | "team_id": "=bw52O" 36 | } 37 | ``` 38 | ### 错误响应 39 | 40 | ```javascript 41 | { 42 | "code": // error code, 43 | "error": "unexpected error" 44 | } 45 | ``` 46 | 47 | 48 | -------------------------------------------------------------------------------- /api/session_channel.info.md: -------------------------------------------------------------------------------- 1 | # session_channel.info 2 | 3 | 返回一个临时讨论组的完整信息。 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | GET {base_url}/session_channel.info 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `session_channel_id` | `string` | 是 | 讨论组 id, 例如 \"=bw52O\" | | 18 | 19 | ## 响应 20 | 21 | ### 200 22 | 23 | ```javascript 24 | { 25 | "latest_ts": "1489242467694", 26 | "name": "临时讨论组名称", 27 | "is_member": true, 28 | "is_active": true, 29 | "type": "session", 30 | "member_uids": [ 31 | "=bw52O" 32 | ], 33 | "vchannel_id": "=bw52O", 34 | "id": "=bw52O", 35 | "team_id": "=bw52O" 36 | } 37 | ``` 38 | ### 错误响应 39 | 40 | ```javascript 41 | { 42 | "code": // error code, 43 | "error": "unexpected error" 44 | } 45 | ``` 46 | 47 | 48 | -------------------------------------------------------------------------------- /api/user.me.md: -------------------------------------------------------------------------------- 1 | # user.me 2 | 3 | 返回当前用户的信息。 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | GET {base_url}/user.me 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | 16 | ## 响应 17 | 18 | ### 200 19 | 20 | ```javascript 21 | { 22 | "inactive": false, 23 | "role": "normal", 24 | "email": "support@bearyinnovative.com", 25 | "name": "BearyBot", 26 | "type": "assistant", 27 | "created": "2017-01-11T12:28:31.000+0000", 28 | "id": "=bwMkR", 29 | "avatars": { 30 | "small": null, 31 | "medium": null, 32 | "large": null 33 | }, 34 | "team_id": "=bw52O", 35 | "full_name": "倍洽小助手", 36 | "mobile": null, 37 | "profile": { 38 | "bio": null, 39 | "position": null, 40 | "skype": null 41 | } 42 | } 43 | ``` 44 | ### 错误响应 45 | 46 | ```javascript 47 | { 48 | "code": // error code, 49 | "error": "unexpected error" 50 | } 51 | ``` 52 | 53 | 54 | -------------------------------------------------------------------------------- /api/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "api", 3 | "version": "1.0.0", 4 | "description": "BearyChat OpenAPI documentation", 5 | "main": "swagger.yml", 6 | "scripts": { 7 | "build": "npm run build:json && npm run build:doc && npm run build:readme", 8 | "build:json": "node gen_json.js", 9 | "build:doc": "node gen_doc.js", 10 | "build:readme": "markdown-toc -i README.md", 11 | "prepare": "mkdir -p generated", 12 | "build:api": "swagger-cli bundle swagger.yml | node bin/build-docs > generated/openapi.html", 13 | "build:swagger": "npm install --verbose && npm run prepare && npm run build:api" 14 | }, 15 | "private": true, 16 | "license": "UNLICENSED", 17 | "dependencies": { 18 | "async": "^2.1.5", 19 | "get-stdin": "^6.0.0", 20 | "js-yaml": "^3.8.2", 21 | "markdown-toc": "^1.1.0", 22 | "mustache": "^3.0.0", 23 | "swagger-cli": "^2.1.3" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /api/channel.archive.md: -------------------------------------------------------------------------------- 1 | # channel.archive 2 | 3 | 归档一个讨论组。 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | POST {base_url}/channel.archive 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `channel_id` | `string` | 是 | 讨论组 id | =bw52O | 18 | 19 | ## 响应 20 | 21 | ### 200 22 | 23 | ```javascript 24 | { 25 | "private": false, 26 | "general": true, 27 | "latest_ts": 1486367046281, 28 | "uid": "=bw52O", 29 | "name": "所有人", 30 | "is_member": false, 31 | "is_active": false, 32 | "type": "normal", 33 | "topic": null, 34 | "member_uids": [ 35 | "=bw52O" 36 | ], 37 | "vchannel_id": "=bw52O", 38 | "id": "=bw52O", 39 | "team_id": "=bw52O" 40 | } 41 | ``` 42 | ### 错误响应 43 | 44 | ```javascript 45 | { 46 | "code": // error code, 47 | "error": "unexpected error" 48 | } 49 | ``` 50 | 51 | 52 | -------------------------------------------------------------------------------- /api/channel.join.md: -------------------------------------------------------------------------------- 1 | # channel.join 2 | 3 | 当前用户加入指定讨论组。 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | POST {base_url}/channel.join 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `channel_id` | `string` | 是 | 讨论组 id | =bw52O | 18 | 19 | ## 响应 20 | 21 | ### 200 22 | 23 | ```javascript 24 | { 25 | "private": false, 26 | "general": false, 27 | "latest_ts": 1486367046281, 28 | "uid": "=bw52O", 29 | "name": "吃喝玩乐在深圳", 30 | "is_member": false, 31 | "is_active": true, 32 | "type": "normal", 33 | "topic": null, 34 | "member_uids": [ 35 | "=bw52O" 36 | ], 37 | "vchannel_id": "=bw52O", 38 | "id": "=bw52O", 39 | "team_id": "=bw52O" 40 | } 41 | ``` 42 | ### 错误响应 43 | 44 | ```javascript 45 | { 46 | "code": // error code, 47 | "error": "unexpected error" 48 | } 49 | ``` 50 | 51 | 52 | -------------------------------------------------------------------------------- /api/message_pin.list.md: -------------------------------------------------------------------------------- 1 | # message_pin.list 2 | 3 | 查询某个聊天会话的置顶消息列表 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | GET {base_url}/message_pin.list 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `vchannel_id` | `string` | 是 | 讨论组 id, 例如 \"=bw52O\" | | 18 | 19 | ## 响应 20 | 21 | ### 200 22 | 23 | ```javascript 24 | [ 25 | { 26 | "id": "=bw52T", 27 | "team_id": "=bw52U", 28 | "uid": "=bw52W", 29 | "vchannel_id": "=bw52O", 30 | "message_id": "=bw53a", 31 | "message_key": "1539079277448.0002", 32 | "created_at": "2018-10-10T09:48:55.000+0800", 33 | "updated_at": "2018-10-10T09:48:55.000+0800", 34 | "message": null 35 | } 36 | ] 37 | ``` 38 | ### 错误响应 39 | 40 | ```javascript 41 | { 42 | "code": // error code, 43 | "error": "unexpected error" 44 | } 45 | ``` 46 | 47 | 48 | -------------------------------------------------------------------------------- /api/channel.info.md: -------------------------------------------------------------------------------- 1 | # channel.info 2 | 3 | 返回指定讨论组的完整信息。 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | GET {base_url}/channel.info 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `channel_id` | `string` | 是 | 讨论组 id, 例如 \"=bw52O\" | | 18 | 19 | ## 响应 20 | 21 | ### 200 22 | 23 | ```javascript 24 | { 25 | "private": false, 26 | "general": true, 27 | "latest_ts": 1486367046281, 28 | "uid": "=bw52O", 29 | "name": "所有人", 30 | "is_member": false, 31 | "is_active": true, 32 | "type": "normal", 33 | "topic": null, 34 | "member_uids": [ 35 | "=bw52O" 36 | ], 37 | "vchannel_id": "=bw52O", 38 | "id": "=bw52O", 39 | "team_id": "=bw52O" 40 | } 41 | ``` 42 | ### 错误响应 43 | 44 | ```javascript 45 | { 46 | "code": // error code, 47 | "error": "unexpected error" 48 | } 49 | ``` 50 | 51 | 52 | -------------------------------------------------------------------------------- /api/message_pin.create.md: -------------------------------------------------------------------------------- 1 | # message_pin.create 2 | 3 | 置顶消息 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | POST {base_url}/message_pin.create 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `vchannel_id` | `string` | 是 | 消息所在的频道 | =bw52O | 18 | | `message_key` | `string` | 是 | 想要置顶的消息 key | 1487667236785.0077 | 19 | 20 | ## 响应 21 | 22 | ### 200 23 | 24 | ```javascript 25 | { 26 | "id": "=bw52T", 27 | "team_id": "=bw52U", 28 | "uid": "=bw52W", 29 | "vchannel_id": "=bw52O", 30 | "message_id": "=bw53a", 31 | "message_key": "1539079277448.0002", 32 | "created_at": "2018-10-10T09:48:55.000+0800", 33 | "updated_at": "2018-10-10T09:48:55.000+0800" 34 | } 35 | ``` 36 | ### 错误响应 37 | 38 | ```javascript 39 | { 40 | "code": // error code, 41 | "error": "unexpected error" 42 | } 43 | ``` 44 | 45 | 46 | -------------------------------------------------------------------------------- /api/channel.unarchive.md: -------------------------------------------------------------------------------- 1 | # channel.unarchive 2 | 3 | 恢复一个已被归档的讨论组。 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | POST {base_url}/channel.unarchive 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `channel_id` | `string` | 是 | 讨论组 id | =bw52O | 18 | 19 | ## 响应 20 | 21 | ### 200 22 | 23 | ```javascript 24 | { 25 | "private": false, 26 | "general": true, 27 | "latest_ts": 1486367046281, 28 | "uid": "=bw52O", 29 | "name": "所有人", 30 | "is_member": false, 31 | "is_active": true, 32 | "type": "normal", 33 | "topic": null, 34 | "member_uids": [ 35 | "=bw52O" 36 | ], 37 | "vchannel_id": "=bw52O", 38 | "id": "=bw52O", 39 | "team_id": "=bw52O" 40 | } 41 | ``` 42 | ### 错误响应 43 | 44 | ```javascript 45 | { 46 | "code": // error code, 47 | "error": "unexpected error" 48 | } 49 | ``` 50 | 51 | 52 | -------------------------------------------------------------------------------- /api/user.list.md: -------------------------------------------------------------------------------- 1 | # user.list 2 | 3 | 返回团队内的用户列表,获取某个用户的完整信息,请使用 `user.info`. 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | GET {base_url}/user.list 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | 16 | ## 响应 17 | 18 | ### 200 19 | 20 | ```javascript 21 | [ 22 | { 23 | "inactive": false, 24 | "role": "normal", 25 | "email": "support@bearyinnovative.com", 26 | "name": "BearyBot", 27 | "type": "assistant", 28 | "created": "2017-01-11T12:28:31.000+0000", 29 | "id": "=bwMkR", 30 | "avatars": { 31 | "small": null, 32 | "medium": null, 33 | "large": null 34 | }, 35 | "team_id": "=bw52O", 36 | "full_name": "倍洽小助手", 37 | "mobile": null, 38 | "profile": { 39 | "bio": null, 40 | "position": null, 41 | "skype": null 42 | } 43 | } 44 | ] 45 | ``` 46 | ### 错误响应 47 | 48 | ```javascript 49 | { 50 | "code": // error code, 51 | "error": "unexpected error" 52 | } 53 | ``` 54 | 55 | 56 | -------------------------------------------------------------------------------- /api/session_channel.create.md: -------------------------------------------------------------------------------- 1 | # session_channel.create 2 | 3 | 创建一个临时讨论组。 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | POST {base_url}/session_channel.create 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `name` | `string` | 否 | 讨论组名称,可以包含 2 到 20 个英文字符或 1 到 10 个中文字符。允许使用数字、下划线 (`_`)、中线 (`-`) 和点。 | 吃喝玩乐在深圳 | 18 | | `member_uids` | `array` | 是 | 临时讨论组成员 id 列表 | ["=bw52O", "=bw52P"] | 19 | 20 | ## 响应 21 | 22 | ### 201 23 | 24 | ```javascript 25 | { 26 | "latest_ts": "1489242467694", 27 | "name": "临时讨论组名称", 28 | "is_member": true, 29 | "is_active": true, 30 | "type": "session", 31 | "member_uids": [ 32 | "=bw52O" 33 | ], 34 | "vchannel_id": "=bw52O", 35 | "id": "=bw52O", 36 | "team_id": "=bw52O" 37 | } 38 | ``` 39 | ### 错误响应 40 | 41 | ```javascript 42 | { 43 | "code": // error code, 44 | "error": "unexpected error" 45 | } 46 | ``` 47 | 48 | 49 | -------------------------------------------------------------------------------- /rtm/event_update_message.md: -------------------------------------------------------------------------------- 1 | # `update_message` 事件 2 | 3 | ``` 4 | { 5 | "data": { 6 | "created": "2017-02-20T14:09:23.000+0800", 7 | "created_ts": 1487570962679, 8 | "deleted": true, 9 | "edited": false, 10 | "id": "=eCRQ7", 11 | "is_channel": false, 12 | "key": "1487570962679.0147", 13 | "reactions": [], 14 | "refer_key": null, 15 | "robot_id": null, 16 | "subtype": "info", 17 | "team_id": "=bw52O", 18 | "text": "\u8be5\u6d88\u606f\u5df2\u88ab\u5220\u9664", 19 | "text_i18n": { 20 | "en": "This message has been deleted.", 21 | "zh-CN": "\u8be5\u6d88\u606f\u5df2\u88ab\u5220\u9664" 22 | }, 23 | "thread_key": null, 24 | "uid": "=bwCkD", 25 | "updated": "2017-02-20T14:32:53.000+0800", 26 | "vchannel_id": "=515SFkkX" 27 | }, 28 | "ts": 1487572373149, 29 | "type": "update_message" 30 | } 31 | ``` 32 | 33 | update_message 事件在修改、删除 P2P 消息的时候触发。其中 `data` 字段包含了修改 34 | 消息的数据:`deleted` 表示该消息是否已被删除,`edited` 表示该消息是否 35 | 已被修改过。其他值为修改后的消息内容。 36 | -------------------------------------------------------------------------------- /api/reaction.create.md: -------------------------------------------------------------------------------- 1 | # reaction.create 2 | 3 | 创建消息 Reaction 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | POST {base_url}/reaction.create 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `vchannel_id` | `string` | 是 | 消息所在的频道 | =bw52O | 18 | | `key` | `string` | 是 | 想要加 sticker 的 message 的 key | 1540460114044.0100 | 19 | | `reaction` | `string` | 是 | 想要添加的 reaction 名 | :smile: | 20 | 21 | ## 响应 22 | 23 | ### 200 24 | 25 | ```javascript 26 | { 27 | "id": "=bw52Q", 28 | "team_id": "=bw52R", 29 | "uid": "=bw52S", 30 | "message_id": "=bw52Q", 31 | "message_key": "1540460114044.0100", 32 | "reaction": ":smile:" 33 | "created_ts": 1540461431018, 34 | "created": "2018-10-25T09:57:11.000+0000", 35 | "updated": "2018-10-25T09:57:11.000+0000" 36 | } 37 | ``` 38 | ### 错误响应 39 | 40 | ```javascript 41 | { 42 | "code": // error code, 43 | "error": "unexpected error" 44 | } 45 | ``` 46 | 47 | 48 | -------------------------------------------------------------------------------- /api/rtm.start.md: -------------------------------------------------------------------------------- 1 | # rtm.start 2 | 3 | 打开 RTM 连接会话 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | POST {base_url}/rtm.start 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | 16 | ## 响应 17 | 18 | ### 200 19 | 20 | ```javascript 21 | { 22 | "ws_host": "wss://rtm.bearychat.com/nimbus/ws:xxx", 23 | "user": { 24 | "inactive": false, 25 | "role": "normal", 26 | "email": "support@bearyinnovative.com", 27 | "name": "BearyBot", 28 | "type": "assistant", 29 | "created": "2017-01-11T12:28:31.000+0000", 30 | "id": "=bwMkR", 31 | "avatars": { 32 | "small": null, 33 | "medium": null, 34 | "large": null 35 | }, 36 | "team_id": "=bw52O", 37 | "full_name": "倍洽小助手", 38 | "mobile": null, 39 | "profile": { 40 | "bio": null, 41 | "position": null, 42 | "skype": null 43 | } 44 | } 45 | } 46 | ``` 47 | ### 错误响应 48 | 49 | ```javascript 50 | { 51 | "code": // error code, 52 | "error": "unexpected error" 53 | } 54 | ``` 55 | 56 | 57 | -------------------------------------------------------------------------------- /rtm/event_update_channel_message.md: -------------------------------------------------------------------------------- 1 | # `update_channel_message` 事件 2 | 3 | ``` 4 | { 5 | "data": { 6 | "created": "2017-02-20T14:15:55.000+0800", 7 | "created_ts": 1487571355082, 8 | "deleted": true, 9 | "edited": false, 10 | "id": "=eCRZP", 11 | "is_channel": true, 12 | "key": "1487571355082.0141", 13 | "reactions": [], 14 | "refer_key": null, 15 | "robot_id": null, 16 | "subtype": "info", 17 | "team_id": "=bw52O", 18 | "text": "\u8be5\u6d88\u606f\u5df2\u88ab\u5220\u9664", 19 | "text_i18n": { 20 | "en": "This message has been deleted.", 21 | "zh-CN": "\u8be5\u6d88\u606f\u5df2\u88ab\u5220\u9664" 22 | }, 23 | "thread_key": null, 24 | "uid": "=bwCkD", 25 | "updated": "2017-02-20T14:28:34.000+0800", 26 | "vchannel_id": "=bwDfQ" 27 | }, 28 | "ts": 1487572113560, 29 | "type": "update_channel_message" 30 | } 31 | ``` 32 | 33 | update_channel_message 事件在修改、删除讨论组消息的时候触发。其中 `data` 字段 34 | 包含了修改消息的数据:`deleted` 表示该消息是否已被删除,`edited` 表示该消息是否 35 | 已被修改过。其他值为修改后的消息内容。 36 | -------------------------------------------------------------------------------- /api/user.info.md: -------------------------------------------------------------------------------- 1 | # user.info 2 | 3 | 返回团队内指定用户完整信息。 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | GET {base_url}/user.info 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `user_id` | `string` | 是 | 指定用户 id,如 \"=bw52O\" | | 18 | 19 | ## 响应 20 | 21 | ### 200 22 | 23 | ```javascript 24 | { 25 | "inactive": false, 26 | "role": "normal", 27 | "email": "support@bearyinnovative.com", 28 | "name": "BearyBot", 29 | "type": "assistant", 30 | "created": "2017-01-11T12:28:31.000+0000", 31 | "id": "=bwMkR", 32 | "avatars": { 33 | "small": null, 34 | "medium": null, 35 | "large": null 36 | }, 37 | "team_id": "=bw52O", 38 | "full_name": "倍洽小助手", 39 | "mobile": null, 40 | "profile": { 41 | "bio": null, 42 | "position": null, 43 | "skype": null 44 | } 45 | } 46 | ``` 47 | ### 错误响应 48 | 49 | ```javascript 50 | { 51 | "code": // error code, 52 | "error": "unexpected error" 53 | } 54 | ``` 55 | 56 | 57 | -------------------------------------------------------------------------------- /api/session_channel.convert_to_channel.md: -------------------------------------------------------------------------------- 1 | # session_channel.convert_to_channel 2 | 3 | 将临时讨论组转换为讨论组。 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | POST {base_url}/session_channel.convert_to_channel 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `session_channel_id` | `string` | 是 | 临时讨论组 id | =bw52O | 18 | | `name` | `string` | 是 | 讨论组名称,可以包含 2 到 20 个英文字符或 1 到 10 个中文字符。允许使用数字、下划线 (`_`)、中线 (`-`) 和点。 | 吃喝玩乐在深圳 | 19 | | `private` | `boolean` | 否 | 讨论组是否为私密? | | 20 | 21 | ## 响应 22 | 23 | ### 201 24 | 25 | ```javascript 26 | { 27 | "latest_ts": "1489242467694", 28 | "name": "临时讨论组名称", 29 | "is_member": true, 30 | "is_active": false, 31 | "type": "session", 32 | "member_uids": [ 33 | "=bw52O" 34 | ], 35 | "vchannel_id": "=bw52O", 36 | "id": "=bw52O", 37 | "team_id": "=bw52O" 38 | } 39 | ``` 40 | ### 错误响应 41 | 42 | ```javascript 43 | { 44 | "code": // error code, 45 | "error": "unexpected error" 46 | } 47 | ``` 48 | 49 | 50 | -------------------------------------------------------------------------------- /api/channel.create.md: -------------------------------------------------------------------------------- 1 | # channel.create 2 | 3 | 创建一个讨论组 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | POST {base_url}/channel.create 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `name` | `string` | 是 | 讨论组名称,可以包含 2 到 20 个英文字符或 1 到 10 个中文字符。允许使用数字、下划线 (`_`)、中线 (`-`) 和点。 | 吃喝玩乐在深圳 | 18 | | `topic` | `string` | 否 | 讨论组话题 | 今天吃什么 | 19 | | `private` | `boolean` | 否 | 讨论组是否为私密? | | 20 | 21 | ## 响应 22 | 23 | ### 201 24 | 25 | ```javascript 26 | { 27 | "private": false, 28 | "general": true, 29 | "latest_ts": 1486367046281, 30 | "uid": "=bw52O", 31 | "name": "所有人", 32 | "is_member": false, 33 | "is_active": true, 34 | "type": "normal", 35 | "topic": null, 36 | "member_uids": [ 37 | "=bw52O" 38 | ], 39 | "vchannel_id": "=bw52O", 40 | "id": "=bw52O", 41 | "team_id": "=bw52O" 42 | } 43 | ``` 44 | ### 错误响应 45 | 46 | ```javascript 47 | { 48 | "code": // error code, 49 | "error": "unexpected error" 50 | } 51 | ``` 52 | 53 | 54 | -------------------------------------------------------------------------------- /api/message.info.md: -------------------------------------------------------------------------------- 1 | # message.info 2 | 3 | 返回一条消息的信息。 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | GET {base_url}/message.info 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `vchannel_id` | `string` | 是 | 指定的目标聊天会话 id,例如 \"=bw52O\" | | 18 | | `message_key` | `string` | 是 | 获取消息的 key,例如 \"1487667236785.0077\" | | 19 | 20 | ## 响应 21 | 22 | ### 200 23 | 24 | ```javascript 25 | { 26 | "key": "1485236262366.0193", 27 | "updated": "2017-01-24T13:37:42.000+0000", 28 | "is_channel": false, 29 | "uid": "=bw52O", 30 | "fallback": null, 31 | "attachments": [], 32 | "created": "2017-01-24T13:37:42.000+0000", 33 | "vchannel_id": "=bw52O", 34 | "refer_key": null, 35 | "robot_id": null, 36 | "created_ts": 1485236262366, 37 | "team_id": "=bw52O", 38 | "subtype": "normal", 39 | "text": "hello" 40 | } 41 | ``` 42 | ### 错误响应 43 | 44 | ```javascript 45 | { 46 | "code": // error code, 47 | "error": "unexpected error" 48 | } 49 | ``` 50 | 51 | 52 | -------------------------------------------------------------------------------- /api/message.create.md: -------------------------------------------------------------------------------- 1 | # message.create 2 | 3 | 发送一条消息到指定聊天会话。 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | POST {base_url}/message.create 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `vchannel_id` | `string` | 是 | 指定的目标聊天会话 id | =bw52O | 18 | | `text` | `string` | 是 | 消息内容 | 中午吃啥啊? | 19 | | `attachments` | `array` | 否 | 消息附件 | 中午吃啥啊? | 20 | 21 | ## 响应 22 | 23 | ### 201 24 | 25 | ```javascript 26 | { 27 | "key": "1485236262366.0193", 28 | "updated": "2017-01-24T13:37:42.000+0000", 29 | "is_channel": false, 30 | "uid": "=bw52O", 31 | "fallback": null, 32 | "attachments": [], 33 | "created": "2017-01-24T13:37:42.000+0000", 34 | "vchannel_id": "=bw52O", 35 | "refer_key": null, 36 | "robot_id": null, 37 | "created_ts": 1485236262366, 38 | "team_id": "=bw52O", 39 | "subtype": "normal", 40 | "text": "hello" 41 | } 42 | ``` 43 | ### 错误响应 44 | 45 | ```javascript 46 | { 47 | "code": // error code, 48 | "error": "unexpected error" 49 | } 50 | ``` 51 | 52 | 53 | -------------------------------------------------------------------------------- /rtm/event_channel_message.md: -------------------------------------------------------------------------------- 1 | # `channel_message` 事件 2 | 3 | ## 被动接收 4 | 5 | ``` 6 | { 7 | "created_ts": 1487571355082, 8 | "image": "", 9 | "key": "1487571355082.0141", 10 | "refer_key": null, 11 | "subtype": "normal", 12 | "text": "test", 13 | "ts": 1487571355082, 14 | "type": "channel_message", 15 | "uid": "=bwCkD", 16 | "vchannel_id": "=bwDfQ" 17 | } 18 | ``` 19 | 20 | channel_message 时间在讨论组会话中收到新消息的时候触发。 21 | 其中 `uid` 为消息发送者 id, `vchannel_id` 为对应会话 id, `key` 为消息 key. 22 | 23 | ## 主动发送 24 | 25 | ``` 26 | { 27 | "vchannel_id": "=bwDfQ", 28 | "text": "test", 29 | "type": "channel_message", 30 | "channel_id": "=bwDfQ", 31 | "refer_key": null, 32 | "call_id": 1 33 | } 34 | ``` 35 | 36 | ### 字段说明 37 | 38 | | 字段 | 类型 | 说明 | 39 | |:----:|:----:|------| 40 | | `vchannel_id` | `string` | 讨论组会话 id,**必填** | 41 | | `text` | `string` | 消息内容,**必填** | 42 | | `type` | `MessageType` | 消息类型,讨论组消息值为 `channel_message`, **必填** | 43 | | `channel_id` | `string` | 接收讨论组 id, **必填** | 44 | | `refer_key` | `Optional` | 引用消息 id, 没有引用消息时值为 `null`, **必填** | 45 | | `call_id` | `int` | 事件序列 id **必填** | 46 | -------------------------------------------------------------------------------- /rtm/event_message.md: -------------------------------------------------------------------------------- 1 | # `message` 事件 2 | 3 | ## 被动接收 4 | 5 | ``` 6 | { 7 | "created_ts": 1487570962851, 8 | "image": "", 9 | "key": "1487570962851.0148", 10 | "refer_key": null, 11 | "subtype": "normal", 12 | "text": "test", 13 | "to_uid": "=bwCkD", 14 | "ts": 1487570962851, 15 | "type": "message", 16 | "uid": "=bwFrB", 17 | "vchannel_id": "=515SFkkX" 18 | } 19 | ``` 20 | 21 | message 事件在 P2P 会话中收到新消息的时候触发。其中 `uid` 为消息发送者 id, 22 | `to_uid` 为消息接收者 id, `vchannel_id` 为对应会话 id, `key` 为消息 key. 23 | 24 | 25 | ## 主动发送 26 | 27 | ``` 28 | { 29 | "vchannel_id": "=515SFkkX", 30 | "text": "test", 31 | "type": "message", 32 | "to_uid": "=bwCkD", 33 | "refer_key": null, 34 | "call_id": 1 35 | } 36 | ``` 37 | 38 | ### 字段说明 39 | 40 | | 字段 | 类型 | 说明 | 41 | |:----:|:----:|------| 42 | | `vchannel_id` | `string` | P2P 会话 id,**必填** | 43 | | `text` | `string` | 消息内容,**必填** | 44 | | `type` | `MessageType` | 消息类型,P2P 消息值为 `message`, **必填** | 45 | | `to_uid` | `string` | 接收用户 id, **必填** | 46 | | `refer_key` | `Optional` | 引用消息 id, 没有引用消息时值为 `null`, **必填** | 47 | | `call_id` | `int` | 事件序列 id **必填** | 48 | -------------------------------------------------------------------------------- /api/user.update_me.md: -------------------------------------------------------------------------------- 1 | # user.update_me 2 | 3 | 更新当前用户信息。 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | PATCH {base_url}/user.update_me 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `name` | `string` | 否 | 用户名 (@name) | beary_bot | 18 | | `full_name` | `string` | 否 | 用户全名 | bearybot | 19 | 20 | ## 响应 21 | 22 | ### 200 23 | 24 | ```javascript 25 | { 26 | "inactive": false, 27 | "role": "normal", 28 | "email": "support@bearyinnovative.com", 29 | "name": "BearyBot", 30 | "type": "assistant", 31 | "created": "2017-01-11T12:28:31.000+0000", 32 | "id": "=bwMkR", 33 | "avatars": { 34 | "small": null, 35 | "medium": null, 36 | "large": null 37 | }, 38 | "team_id": "=bw52O", 39 | "full_name": "倍洽小助手", 40 | "mobile": null, 41 | "profile": { 42 | "bio": null, 43 | "position": null, 44 | "skype": null 45 | } 46 | } 47 | ``` 48 | ### 错误响应 49 | 50 | ```javascript 51 | { 52 | "code": // error code, 53 | "error": "unexpected error" 54 | } 55 | ``` 56 | 57 | 58 | -------------------------------------------------------------------------------- /api/message.update_text.md: -------------------------------------------------------------------------------- 1 | # message.update_text 2 | 3 | 更新一条消息的内容。 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | PATCH {base_url}/message.update_text 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `vchannel_id` | `string` | 是 | 待查询 vchannel_id | =bw52O | 18 | | `message_key` | `string` | 是 | 更新的消息 key | 1487667236785.0077 | 19 | | `text` | `string` | 是 | 更新的消息内容 | 中午吃啥啊? | 20 | 21 | ## 响应 22 | 23 | ### 200 24 | 25 | ```javascript 26 | { 27 | "key": "1485236262366.0193", 28 | "updated": "2017-01-24T13:37:42.000+0000", 29 | "is_channel": false, 30 | "uid": "=bw52O", 31 | "fallback": null, 32 | "attachments": [], 33 | "created": "2017-01-24T13:37:42.000+0000", 34 | "vchannel_id": "=bw52O", 35 | "refer_key": null, 36 | "robot_id": null, 37 | "created_ts": 1485236262366, 38 | "team_id": "=bw52O", 39 | "subtype": "normal", 40 | "text": "hello" 41 | } 42 | ``` 43 | ### 错误响应 44 | 45 | ```javascript 46 | { 47 | "code": // error code, 48 | "error": "unexpected error" 49 | } 50 | ``` 51 | 52 | 53 | -------------------------------------------------------------------------------- /rtm/api_message.md: -------------------------------------------------------------------------------- 1 | # API `POST /message` 2 | 3 | 该接口用作发送富文本消息 4 | 5 | ## 请求参数 6 | 7 | ``` 8 | { 9 | "token": "rtm token" 10 | "vchannel": "=bw52O", 11 | "text": "test", 12 | "markdown": true, 13 | "attachments": [] 14 | } 15 | ``` 16 | 17 | | 字段 | 类型 | 说明 | 18 | |:----:|:----:|------| 19 | | `vchannel` | `string` | 目标会话 id, **必填** | 20 | | `text` | `string` | 消息正文,**必填** | 21 | | `markdown` | `Optional` | 消息正文是否使用 markdown 格式?默认为 true | 22 | | `attachments` | `Array` | 消息 attachment 结构,必填 | 23 | 24 | ### `MessageAttachment` 25 | 26 | ``` 27 | { 28 | "title": "test_title", 29 | "text": "test_text", 30 | "images": [{ 31 | "url": "http://example.com/1.jpg" 32 | }], 33 | "color": "#cb3f20" 34 | } 35 | ``` 36 | 37 | | 字段 | 类型 | 说明 | 38 | |:----:|:----:|------| 39 | | `title` | `Optional` | attachment 标题,`title` / `text` 至少包含一个 | 40 | | `text` | `Optional` | attachment 内容,`title` / `text` 至少包含一个 | 41 | | `images` | `Array` | attachment 图片数组,可选 | 42 | | `color` | `Optional` | attachment 颜色,可选 | 43 | 44 | ## 响应 45 | 46 | ``` 47 | { 48 | "code": 0, 49 | "result": null 50 | } 51 | ``` 52 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OpenAPI 2 | 3 | [Join OpenAPI group](https://openapi.bearychat.com/apply) 4 | ![doc: 1.0](https://img.shields.io/badge/doc-1.0-green.svg) 5 | 6 | [OpenAPI Online Document](http://openapi.bearychat.help) 7 | 8 | BearyChat 开放 API 文档 9 | 10 | 11 | 12 | - [API 文档](#api-%E6%96%87%E6%A1%A3) 13 | - [SDK 列表](#sdk-%E5%88%97%E8%A1%A8) 14 | - [基于 OpenAPI 的开发库](#%E5%9F%BA%E4%BA%8E-openapi-%E7%9A%84%E5%BC%80%E5%8F%91%E5%BA%93) 15 | - [反馈 & 贡献](#%E5%8F%8D%E9%A6%88--%E8%B4%A1%E7%8C%AE) 16 | - [License](#license) 17 | 18 | 19 | 20 | ## API 文档 21 | 22 | - [开放 API OpenAPI](./api) 23 | - [实时聊天 RTM](./rtm) 24 | 25 | ## SDK 列表 26 | 27 | - [bearychat.js][] 28 | - [bearychat.py][] 29 | - [bearychat-go][] 30 | - [bearychat.php][] 31 | 32 | [bearychat.js]: https://github.com/bearyinnovative/bearychat.js 33 | [bearychat.py]: https://github.com/bearyinnovative/bearychat.py 34 | [bearychat-go]: https://github.com/bearyinnovative/bearychat-go 35 | [bearychat.php]: https://github.com/hachi-zzq/bearychat-open-api 36 | 37 | ## 基于 OpenAPI 的开发库 38 | 39 | - [hubot-bearychat][] 40 | 41 | [hubot-bearychat]: https://github.com/bearyinnovative/hubot-bearychat 42 | 43 | 44 | ## 反馈 & 贡献 45 | 46 | 请参考 [CONTRIBUTING.md](./CONTRIBUTING.md) 47 | 48 | 49 | ## License 50 | 51 | © BearyInnovative 52 | -------------------------------------------------------------------------------- /api/vchannel.info.md: -------------------------------------------------------------------------------- 1 | # vchannel.info 2 | 3 | 返回指定聊天会话的完整信息。 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | GET {base_url}/vchannel.info 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `vchannel_id` | `string` | 是 | 聊天会话 id | | 18 | 19 | ## 响应 20 | 21 | ### 200 22 | 23 | ```javascript 24 | // Channel 25 | { 26 | "private": false, 27 | "general": true, 28 | "latest_ts": 1486367046281, 29 | "uid": "=bw52O", 30 | "name": "所有人", 31 | "is_member": false, 32 | "is_active": true, 33 | "type": "normal", 34 | "topic": null, 35 | "member_uids": [ 36 | "=bw52O" 37 | ], 38 | "vchannel_id": "=bw52O", 39 | "id": "=bw52O", 40 | "team_id": "=bw52O" 41 | } 42 | 43 | // SessionChannel 44 | { 45 | "latest_ts": "1489242467694", 46 | "name": "临时讨论组名称", 47 | "is_member": true, 48 | "is_active": true, 49 | "type": "session", 50 | "member_uids": [ 51 | "=bw52O" 52 | ], 53 | "vchannel_id": "=bw52O", 54 | "id": "=bw52O", 55 | "team_id": "=bw52O" 56 | } 57 | 58 | // P2PChannel 59 | { 60 | "id": "=bw52O", 61 | "team_id": "=bw52O", 62 | "vchannel_id": "=bw52O", 63 | "type": "p2p", 64 | "is_active": true, 65 | "is_member": true, 66 | "member_uids": [ 67 | "=bw52O", 68 | "=bw52P" 69 | ], 70 | "latest_ts": 1485238998284 71 | } 72 | ``` 73 | 74 | 75 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | build_date = `date +%Y%m%d%H%M` 2 | commit = `git rev-parse HEAD` 3 | version = `git rev-parse --short HEAD` 4 | package-image = hub.didiyun.com/bearyinnovative/openapi-help-package:$(version) 5 | release-image = hub.didiyun.com/bearyinnovative/openapi-help:$(version) 6 | 7 | # Common commands 8 | 9 | ## 编译及构建 10 | .PHONY: release 11 | release: 12 | cd api; \ 13 | npm install \ 14 | && node gen_doc.js \ 15 | && node gen_json.js \ 16 | && npm run build:api 17 | 18 | ## 清理当前工作目录 19 | .PHONY: clean 20 | clean: 21 | git clean -fdx 22 | 23 | # Commands used to generate docker image 24 | 25 | ## 构建 package 镜像 26 | .PHONY: build-package-image 27 | build-package-image: 28 | docker build . \ 29 | --no-cache \ 30 | --force-rm \ 31 | --build-arg build_date=$(build_date) \ 32 | --build-arg version=$(version) \ 33 | --build-arg commit=$(commit) \ 34 | -t $(package-image) \ 35 | -f package.Dockerfile 36 | 37 | ## 构建 release 镜像 38 | .PHONY: build-release-image 39 | build-release-image: 40 | docker build . \ 41 | --no-cache \ 42 | --force-rm \ 43 | --build-arg build_date=$(build_date) \ 44 | --build-arg version=$(version) \ 45 | --build-arg commit=$(commit) \ 46 | -t $(release-image) \ 47 | -f release.Dockerfile 48 | 49 | # Commands used to run with clean docker container 50 | 51 | ## 使用 package 镜像构建项目 52 | .PHONY: package 53 | package: 54 | docker run -u`id -u`:`id -g` \ 55 | --rm \ 56 | -v $(CURDIR):/workspace $(package-image) 57 | -------------------------------------------------------------------------------- /api/message.forward.md: -------------------------------------------------------------------------------- 1 | # message.forward 2 | 3 | 转发消息 4 | 5 | ## 请求方式 6 | 7 | ``` 8 | POST {base_url}/message.forward 9 | ``` 10 | 11 | ## 请求参数 12 | 13 | **需要登录** 14 | 15 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 16 | |:--------:|:--------:|:--------------:|------|------| 17 | | `vchannel_id` | `string` | 是 | 转发的消息所在的位置 id | =bw52O | 18 | | `key` | `string` | 是 | 更新的消息 key | 1487667236785.0077 | 19 | | `to_vchannel_id` | `string` | 是 | 转发目的会话 id | =bw52O | 20 | 21 | ## 响应 22 | 23 | ### 200 24 | 25 | ```javascript 26 | { 27 | "repost": { 28 | "uid": "=bw52T", 29 | "vchannel_id": "=bw52O", 30 | "robot_id": null, 31 | "created_ts": 1539056624039, 32 | "message_key": "1539056624039.0143", 33 | "id": "=bw52Q", 34 | "team_id": "=bw52U", 35 | "subtype": "normal", 36 | "text": "当测不测,反受其乱" 37 | }, 38 | "key": "1539079267590.0001", 39 | "updated": "2018-10-09T10:01:08.000+0000", 40 | "is_channel": true, 41 | "uid": "=bw52W", 42 | "thread_key": null, 43 | "created": "2018-10-09T10:01:08.000+0000", 44 | "vchannel_id": "=bw52O", 45 | "refer_key": null, 46 | "robot_id": null, 47 | "edited": false, 48 | "created_ts": 1539079267590, 49 | "pin_id": null, 50 | "id": "=bw52Z", 51 | "team_id": "=bw52U", 52 | "text_i18n": { 53 | "zh-CN": "转发了消息", 54 | "en": "fowarded message" 55 | }, 56 | "reactions": [], 57 | "subtype": "forwarded", 58 | "text": "转发了消息" 59 | } 60 | ``` 61 | ### 错误响应 62 | 63 | ```javascript 64 | { 65 | "code": // error code, 66 | "error": "unexpected error" 67 | } 68 | ``` 69 | 70 | 71 | -------------------------------------------------------------------------------- /api/message.query.md: -------------------------------------------------------------------------------- 1 | # message.query 2 | 3 | 查询指定 vchannel 下的消息列表。支持以下几种查询算法: 4 | 5 | ### `latest` 6 | 7 | 查询 vchannel 下最新的消息,支持参数: 8 | 9 | - `limit`: 查询数量限制,最大值为 100, 默认 20 10 | 11 | ### `since` 12 | 13 | 从指定位置开始拉取若干条消息,支持参数: 14 | 15 | - `key`: 开始位置的消息 key, 不可以和 `ts` 同时使用 16 | - `ts`: 开始位置的消息 ts, 不可以和 `ts` 同时使用 17 | - `forward`: 向前(时间发生方向)获取条数 18 | - `backward`: 向后(时间发生方向)获取条数 19 | 20 | **注意**: 21 | 22 | 1. 使用 `key` 查询时,查询区间不包括 key 对应的消息 23 | 2. 使用 `ts` 查询时,查询区间包括 ts 对应的消息 24 | 3. `forward` / `backward` 参数可以同时使用 25 | 4. `forward` / `backward` 参数最大值为 100, 26 | 5. `forward` / `backward` 均未指定时,默认使用 `forward=100` 27 | 28 | ### `window` 29 | 30 | 拉取一定时间窗口内的消息,支持参数: 31 | 32 | - `from_key` / `to_key`: 窗口区间的消息 key 33 | - `from_ts` / `to_ts`: 窗口区间的消息 ts 34 | - `forward`: 从 from 方向往 to 方向取的消息数 35 | - `backward`: 从 to 方向往 from 方向取的消息数 36 | 37 | **注意**: 38 | 39 | 1. `{from,to}_key` 和 `{from,to}_ts` 不可以混用 40 | 2. 使用 `{from,to}_key` 查询时,查询区间不包括 key 对应的消息 41 | 3. 使用 `{from,to}_ts` 查询时,查询区间包括 ts 对应的消息 42 | 4. `forward` 和 `backward` 参数只能选其中一个 43 | 5. `forward` / `backward` 均未指定时,默认使用 `forward=100` 44 | 6. 如果查询区间开始值比结束值大,返回空结果 45 | 46 | ## 请求方式 47 | 48 | ``` 49 | POST {base_url}/message.query 50 | ``` 51 | 52 | ## 请求参数 53 | 54 | **需要登录** 55 | 56 | | 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 | 57 | |:--------:|:--------:|:--------------:|------|------| 58 | | `vchannel_id` | `string` | 是 | 待查询 vchannel_id | =bw52O | 59 | | `query` | `string` | 是 | | | 60 | 61 | ```javascript 62 | // latest 63 | { 64 | "vchannel_id": "=bw52O", 65 | "query": { 66 | "latest": { 67 | "limit": 10 68 | } 69 | } 70 | } 71 | // since 72 | { 73 | "vchannel_id": "=bw52O", 74 | "query": { 75 | "since": { 76 | "ts": 1485236262366 77 | } 78 | } 79 | } 80 | // window 81 | { 82 | "vchannel_id": "=bw52O", 83 | "query": { 84 | "window": { 85 | "from_ts": 1485236262366, 86 | "to_ts": 1485236362366, 87 | "forward": 100 88 | } 89 | } 90 | } 91 | ``` 92 | 93 | ## 响应 94 | 95 | ### 200 96 | 97 | ```javascript 98 | { 99 | "messages": [ 100 | { 101 | "key": "1485236262366.0193", 102 | "updated": "2017-01-24T13:37:42.000+0000", 103 | "is_channel": false, 104 | "uid": "=bw52O", 105 | "fallback": null, 106 | "attachments": [], 107 | "created": "2017-01-24T13:37:42.000+0000", 108 | "vchannel_id": "=bw52O", 109 | "refer_key": null, 110 | "robot_id": null, 111 | "created_ts": 1485236262366, 112 | "team_id": "=bw52O", 113 | "subtype": "normal", 114 | "text": "hello" 115 | } 116 | ] 117 | } 118 | ``` 119 | ### 错误响应 120 | 121 | ```javascript 122 | { 123 | "code": // error code, 124 | "error": "unexpected error" 125 | } 126 | ``` 127 | 128 | 129 | -------------------------------------------------------------------------------- /api/index.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Swagger UI 7 | 8 | 9 | 10 | 11 | 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 | 73 | 74 | 75 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /api/README.md: -------------------------------------------------------------------------------- 1 | # 开放 API 服务 2 | 3 | 4 | 5 | - [概况](#%E6%A6%82%E5%86%B5) 6 | - [授权](#%E6%8E%88%E6%9D%83) 7 | * [RTM token 授权](#rtm-token-%E6%8E%88%E6%9D%83) 8 | - [请求 Rate Limit](#%E8%AF%B7%E6%B1%82-rate-limit) 9 | - [请求 & 响应风格](#%E8%AF%B7%E6%B1%82--%E5%93%8D%E5%BA%94%E9%A3%8E%E6%A0%BC) 10 | 11 | 12 | 13 | ## 概况 14 | 15 | 开放 API (OpenAPI) 服务提供基于 HTTP 协议的 API 接口。 16 | 17 | 本文档描述的 API 版本为:`1`, 目前开放 API 的基地址 (base_url) 为: 18 | 19 | ``` 20 | https://api.bearychat.com/v1 21 | ``` 22 | 23 | 包括以下几个模块: 24 | 25 | - [meta](./meta.md) 26 | - team: 团队相关 27 | * [GET /team.info](./team.info.md) 28 | - user: 用户相关 29 | * [GET /user.info](./user.info.md) 30 | * [GET /user.me](./user.me.md) 31 | * [GET /user.list](./user.list.md) 32 | - vchannel: 聊天会话相关 33 | * [GET /vchannel.info](./vchannel.info.md) 34 | - channel: 讨论组相关 35 | * [GET /channel.info](./channel.info.md) 36 | * [GET /channel.list](./channel.list.md) 37 | * [POST /channel.create](./channel.create.md) 38 | * [POST /channel.archive](./channel.archive.md) 39 | * [POST /channel.unarchive](./channel.unarchive.md) 40 | * [POST /channel.leave](./channel.leave.md) 41 | * [POST /channel.join](./channel.join.md) 42 | * [POST /channel.invite](./channel.invite.md) 43 | * [POST /channel.kick](./channel.kick.md) 44 | - session_channel: 临时讨论组相关 45 | * [GET /session_channel.info](./session_channel.info.md) 46 | * [GET /session_channel.list](./session_channel.list.md) 47 | * [POST /session_channel.create](./session_channel.create.md) 48 | * [POST /session_channel.archive](./session_channel.archive.md) 49 | * [POST /session_channel.convert_to_channel](./session_channel.convert_to_channel.md) 50 | * [POST /session_channel.leave](./session_channel.leave.md) 51 | * [POST /session_channel.invite](./session_channel.invite.md) 52 | * [POST /session_channel.kick](./session_channel.kick.md) 53 | - p2p: P2P 会话相关 54 | * [GET /p2p.info](./p2p.info.md) 55 | * [GET /p2p.list](./p2p.list.md) 56 | * [POST /p2p.create](./p2p.create.md) 57 | - message: 消息相关 58 | * [POST /message.query](./message.query.md) 59 | * [GET /message.info](./message.info.md) 60 | * [POST /message.create](./message.create.md) 61 | * [POST /message.delete](./message.delete.md) 62 | * [POST /message.update_text](./message.update_text.md) 63 | - emoji: 团队自定义 emoji 相关 64 | * [POST /emoji.list](./emoji.list.md) 65 | - sticker: 团队 sticker 相关 66 | * [POST /sticker.list](./sticker.list.md) 67 | - rtm: RTM 相关 68 | * [POST /rtm.start](./rtm.start.md) 69 | 70 | 71 | 所有接口都按照 [OpenAPI 规格][openapi-spec] 进行记录,对应规格文件可以查看 72 | [swagger.yml](./swagger.yml) 73 | 74 | [openapi-spec]: http://swagger.io/specification/ 75 | 76 | ## 授权 77 | 78 | 如无特别说明,所有 API 接口都需要授权后才能访问。目前支持授权方式有: 79 | 80 | - RTM token 授权 81 | 82 | ### RTM token 授权 83 | 84 | **RTM token 目前可以通过创建 hubot 机器人获得** 85 | 86 | 该授权模式下,请求方需要把 RTM token 值放到请求的 token 参数中,如: 87 | 88 | ``` 89 | POST https://api.bearychat.com/v1/rtm.start?token=your_rtm_token 90 | ``` 91 | 92 | 或者 93 | 94 | ``` 95 | POST https://api.bearychat.com/v1/rtm.start 96 | { 97 | "token": "your_rtm_token" 98 | } 99 | ``` 100 | 101 | ## 请求 Rate Limit 102 | 103 | 开放 API 采用以下 rate limit 策略: 104 | 105 | - 未进行授权的请求,每小时可以请求 **60** 次 106 | - 已进行授权的请求,每小时可以请求 **1000** 次 107 | 108 | 109 | 对应 rate limit 参数会在响应中给出: 110 | 111 | ``` 112 | x-ratelimit-remaining: 56 113 | x-ratelimit-limit: 60 114 | x-ratelimit-reset: 1489388400 115 | ``` 116 | 117 | - `x-ratelimit-remaining`: ratelimit 剩余数量 118 | - `x-ratelimit-limit`: ratelimit 限制数量 119 | - `x-ratelimit-reset`: ratelimit 重置 unix 时间戳 120 | 121 | 超出 ratelimit 限制会返回如下错误: 122 | 123 | ```json 124 | { 125 | "code": 13, 126 | "error": "请求太频繁,超过限制了,请慢点" 127 | } 128 | ``` 129 | 130 | ## 请求 & 响应风格 131 | 132 | **请求** 133 | 134 | 如无特别说明,GET 请求参数需要放到 url query string 中: 135 | 136 | ``` 137 | GET https://api.bearychat.com/v1/meta?token=your_rtm_token 138 | ``` 139 | 140 | 非 GET 请求参数需要使用 JSON 格式将参数放到请求体中: 141 | 142 | ``` 143 | POST https://api.bearychat.com/v1/rtm.start 144 | Content-Type: application/json 145 | { 146 | "token": "your_rtm_token" 147 | } 148 | ``` 149 | 150 | **响应** 151 | 152 | 如无特别说明,开放 API 所有响应都将以 JSON 格式进行响应。 153 | -------------------------------------------------------------------------------- /api/gen_doc.js: -------------------------------------------------------------------------------- 1 | const async = require('async') 2 | const fs = require('fs') 3 | const join = require('path').join 4 | const yaml = require('js-yaml') 5 | 6 | const apiSchemaPath = join(__dirname, 'swagger.yml') 7 | const apiSchema = yaml.safeLoad(fs.readFileSync(apiSchemaPath)) 8 | 9 | function pathToDocName(path) { 10 | return `${path.replace(/^\//, '')}` 11 | } 12 | 13 | function pathToDocFileName(path) { 14 | return `${path.replace(/^\//, '')}.md` 15 | } 16 | 17 | function describeAPI(methodSchema) { 18 | return (methodSchema.decl.description || '').trim() 19 | } 20 | 21 | function describeRequestMethod(methodSchema) { 22 | return [ 23 | '```', 24 | `${methodSchema.method} {base_url}${methodSchema.path}`, 25 | '```' 26 | ].join('\n') 27 | } 28 | 29 | function describeRequestParameters(methodSchema) { 30 | let content = [] 31 | if (methodSchema.decl.authentication != false) { 32 | content = content.concat([ 33 | '**需要登录**', 34 | '', 35 | ]) 36 | } 37 | 38 | const parameters = methodSchema.decl.parameters || [] 39 | if (parameters.length > 0) { 40 | content = content.concat([ 41 | '| 参数名称 | 参数类型 | 参数是否必须? | 说明 | 样例 |', 42 | '|:--------:|:--------:|:--------------:|------|------|', 43 | ]) 44 | 45 | parameters.forEach((p) => { 46 | if (p.in == 'body') { 47 | // init required 48 | schema = p.schema 49 | required = schema.required || [] 50 | Object.keys(schema.properties).forEach((key) => { 51 | let type = '`string`' 52 | if (schema.properties[key].type) { 53 | type = `\`${schema.properties[key].type}\`` 54 | } 55 | const line = [ 56 | `\`${key}\``, 57 | type, 58 | (required.indexOf(key) != -1) ? '是' : '否', 59 | (schema.properties[key].description || '').replace('\n', ' ').trim(), 60 | (schema.properties[key].example || '').replace('\n', ' ').trim() 61 | ].join(' | ') 62 | content.push(`| ${line} |`) 63 | }) 64 | } else { 65 | let type = '`string`' 66 | if (p.type) { 67 | type = `\`${p.type}\`` 68 | } 69 | const line = [ 70 | `\`${p.name}\``, 71 | type, 72 | p.required ? '是' : '否', 73 | (p.description || '').replace('\n', ' ').trim(), 74 | (p.example || '').replace('\n', ' ').trim(), 75 | ].join(' | ') 76 | content.push(`| ${line} |`) 77 | } 78 | }) 79 | } 80 | 81 | if (methodSchema.decl.parameters_example) { 82 | content.push('') 83 | content.push('```javascript') 84 | content.push(methodSchema.decl.parameters_example.trim()) 85 | content.push('```') 86 | } 87 | 88 | return content.join('\n') 89 | } 90 | 91 | function describeResponse(methodSchema) { 92 | const responses = methodSchema.decl.responses 93 | let content = [] 94 | 95 | Object.keys(responses).forEach((statusCode) => { 96 | if (statusCode === 'default') return 97 | 98 | content.push(`### ${statusCode}`); 99 | 100 | const examples = responses[statusCode].examples; 101 | if (examples) { 102 | Object.values(examples).forEach((example) => { 103 | content.push(''); 104 | content.push('```javascript'); 105 | content.push(example.trim()); 106 | content.push('```'); 107 | }); 108 | } 109 | }) 110 | 111 | if (responses.default) { 112 | content = content.concat([ 113 | `### 错误响应`, 114 | '', 115 | '```javascript', 116 | '{', 117 | ' "code": // error code,', 118 | ' "error": "unexpected error"', 119 | '}', 120 | '```', 121 | ]) 122 | } 123 | 124 | return content.join('\n') 125 | } 126 | 127 | async.forEachOf(apiSchema.paths, (decl, path, callback) => { 128 | const methodSchema = { 129 | path, 130 | method: Object.keys(decl)[0].toUpperCase(), 131 | decl: Object.values(decl)[0], 132 | } 133 | 134 | const content = [ 135 | `# ${pathToDocName(path)}`, 136 | '', 137 | describeAPI(methodSchema), 138 | '', 139 | '## 请求方式', 140 | '', 141 | describeRequestMethod(methodSchema), 142 | '', 143 | '## 请求参数', 144 | '', 145 | describeRequestParameters(methodSchema), 146 | '', 147 | '## 响应', 148 | '', 149 | describeResponse(methodSchema), 150 | '', 151 | '' 152 | ].join('\n') 153 | 154 | const file = join(__dirname, pathToDocFileName(path)) 155 | fs.writeFileSync(file, content.trim() + '\n') 156 | console.log(`generated ${file}`) 157 | }) 158 | -------------------------------------------------------------------------------- /api/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | ansi-red@^0.1.1: 4 | version "0.1.1" 5 | resolved "https://registry.yarnpkg.com/ansi-red/-/ansi-red-0.1.1.tgz#8c638f9d1080800a353c9c28c8a81ca4705d946c" 6 | dependencies: 7 | ansi-wrap "0.1.0" 8 | 9 | ansi-wrap@0.1.0: 10 | version "0.1.0" 11 | resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" 12 | 13 | argparse@^1.0.7: 14 | version "1.0.9" 15 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" 16 | dependencies: 17 | sprintf-js "~1.0.2" 18 | 19 | argparse@~0.1.15: 20 | version "0.1.16" 21 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-0.1.16.tgz#cfd01e0fbba3d6caed049fbd758d40f65196f57c" 22 | dependencies: 23 | underscore "~1.7.0" 24 | underscore.string "~2.4.0" 25 | 26 | async@^2.1.5: 27 | version "2.1.5" 28 | resolved "https://registry.yarnpkg.com/async/-/async-2.1.5.tgz#e587c68580994ac67fc56ff86d3ac56bdbe810bc" 29 | dependencies: 30 | lodash "^4.14.0" 31 | 32 | autolinker@~0.15.0: 33 | version "0.15.3" 34 | resolved "https://registry.yarnpkg.com/autolinker/-/autolinker-0.15.3.tgz#342417d8f2f3461b14cf09088d5edf8791dc9832" 35 | 36 | buffer-shims@^1.0.0: 37 | version "1.0.0" 38 | resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" 39 | 40 | coffee-script@^1.12.4: 41 | version "1.12.4" 42 | resolved "https://registry.yarnpkg.com/coffee-script/-/coffee-script-1.12.4.tgz#fe1bced97fe1fb3927b998f2b45616e0658be1ff" 43 | 44 | concat-stream@^1.5.2: 45 | version "1.6.0" 46 | resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" 47 | dependencies: 48 | inherits "^2.0.3" 49 | readable-stream "^2.2.2" 50 | typedarray "^0.0.6" 51 | 52 | core-util-is@~1.0.0: 53 | version "1.0.2" 54 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 55 | 56 | diacritics-map@^0.1.0: 57 | version "0.1.0" 58 | resolved "https://registry.yarnpkg.com/diacritics-map/-/diacritics-map-0.1.0.tgz#6dfc0ff9d01000a2edf2865371cac316e94977af" 59 | 60 | esprima@^3.1.1: 61 | version "3.1.3" 62 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" 63 | 64 | expand-range@^1.8.1: 65 | version "1.8.2" 66 | resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" 67 | dependencies: 68 | fill-range "^2.1.0" 69 | 70 | extend-shallow@^2.0.1: 71 | version "2.0.1" 72 | resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" 73 | dependencies: 74 | is-extendable "^0.1.0" 75 | 76 | fill-range@^2.1.0: 77 | version "2.2.3" 78 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" 79 | dependencies: 80 | is-number "^2.1.0" 81 | isobject "^2.0.0" 82 | randomatic "^1.1.3" 83 | repeat-element "^1.1.2" 84 | repeat-string "^1.5.2" 85 | 86 | for-in@^1.0.2: 87 | version "1.0.2" 88 | resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" 89 | 90 | gray-matter@^2.1.0: 91 | version "2.1.1" 92 | resolved "https://registry.yarnpkg.com/gray-matter/-/gray-matter-2.1.1.tgz#3042d9adec2a1ded6a7707a9ed2380f8a17a430e" 93 | dependencies: 94 | ansi-red "^0.1.1" 95 | coffee-script "^1.12.4" 96 | extend-shallow "^2.0.1" 97 | js-yaml "^3.8.1" 98 | toml "^2.3.2" 99 | 100 | inherits@^2.0.3, inherits@~2.0.1: 101 | version "2.0.3" 102 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 103 | 104 | is-buffer@^1.0.2: 105 | version "1.1.5" 106 | resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc" 107 | 108 | is-extendable@^0.1.0, is-extendable@^0.1.1: 109 | version "0.1.1" 110 | resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" 111 | 112 | is-number@^2.0.2, is-number@^2.1.0: 113 | version "2.1.0" 114 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" 115 | dependencies: 116 | kind-of "^3.0.2" 117 | 118 | isarray@~1.0.0, isarray@1.0.0: 119 | version "1.0.0" 120 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 121 | 122 | isobject@^2.0.0, isobject@^2.1.0: 123 | version "2.1.0" 124 | resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" 125 | dependencies: 126 | isarray "1.0.0" 127 | 128 | js-yaml@^3.8.1, js-yaml@^3.8.2: 129 | version "3.8.2" 130 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.2.tgz#02d3e2c0f6beab20248d412c352203827d786721" 131 | dependencies: 132 | argparse "^1.0.7" 133 | esprima "^3.1.1" 134 | 135 | kind-of@^3.0.2: 136 | version "3.1.0" 137 | resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.1.0.tgz#475d698a5e49ff5e53d14e3e732429dc8bf4cf47" 138 | dependencies: 139 | is-buffer "^1.0.2" 140 | 141 | lazy-cache@^2.0.2: 142 | version "2.0.2" 143 | resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-2.0.2.tgz#b9190a4f913354694840859f8a8f7084d8822264" 144 | dependencies: 145 | set-getter "^0.1.0" 146 | 147 | list-item@^1.1.1: 148 | version "1.1.1" 149 | resolved "https://registry.yarnpkg.com/list-item/-/list-item-1.1.1.tgz#0c65d00e287cb663ccb3cb3849a77e89ec268a56" 150 | dependencies: 151 | expand-range "^1.8.1" 152 | extend-shallow "^2.0.1" 153 | is-number "^2.1.0" 154 | repeat-string "^1.5.2" 155 | 156 | lodash@^4.14.0: 157 | version "4.17.4" 158 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" 159 | 160 | markdown-link@^0.1.1: 161 | version "0.1.1" 162 | resolved "https://registry.yarnpkg.com/markdown-link/-/markdown-link-0.1.1.tgz#32c5c65199a6457316322d1e4229d13407c8c7cf" 163 | 164 | markdown-toc@^1.1.0: 165 | version "1.1.0" 166 | resolved "https://registry.yarnpkg.com/markdown-toc/-/markdown-toc-1.1.0.tgz#18e47237d89549e9447121e69e2ca853ca2d752a" 167 | dependencies: 168 | concat-stream "^1.5.2" 169 | diacritics-map "^0.1.0" 170 | gray-matter "^2.1.0" 171 | lazy-cache "^2.0.2" 172 | list-item "^1.1.1" 173 | markdown-link "^0.1.1" 174 | minimist "^1.2.0" 175 | mixin-deep "^1.1.3" 176 | object.pick "^1.2.0" 177 | remarkable "^1.7.1" 178 | repeat-string "^1.6.1" 179 | strip-color "^0.1.0" 180 | 181 | minimist@^1.2.0: 182 | version "1.2.0" 183 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" 184 | 185 | mixin-deep@^1.1.3: 186 | version "1.2.0" 187 | resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.2.0.tgz#d02b8c6f8b6d4b8f5982d3fd009c4919851c3fe2" 188 | dependencies: 189 | for-in "^1.0.2" 190 | is-extendable "^0.1.1" 191 | 192 | object.pick@^1.2.0: 193 | version "1.2.0" 194 | resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.2.0.tgz#b5392bee9782da6d9fb7d6afaf539779f1234c2b" 195 | dependencies: 196 | isobject "^2.1.0" 197 | 198 | process-nextick-args@~1.0.6: 199 | version "1.0.7" 200 | resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" 201 | 202 | randomatic@^1.1.3: 203 | version "1.1.6" 204 | resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.6.tgz#110dcabff397e9dcff7c0789ccc0a49adf1ec5bb" 205 | dependencies: 206 | is-number "^2.0.2" 207 | kind-of "^3.0.2" 208 | 209 | readable-stream@^2.2.2: 210 | version "2.2.3" 211 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.3.tgz#9cf49463985df016c8ae8813097a9293a9b33729" 212 | dependencies: 213 | buffer-shims "^1.0.0" 214 | core-util-is "~1.0.0" 215 | inherits "~2.0.1" 216 | isarray "~1.0.0" 217 | process-nextick-args "~1.0.6" 218 | string_decoder "~0.10.x" 219 | util-deprecate "~1.0.1" 220 | 221 | remarkable@^1.7.1: 222 | version "1.7.1" 223 | resolved "https://registry.yarnpkg.com/remarkable/-/remarkable-1.7.1.tgz#aaca4972100b66a642a63a1021ca4bac1be3bff6" 224 | dependencies: 225 | argparse "~0.1.15" 226 | autolinker "~0.15.0" 227 | 228 | repeat-element@^1.1.2: 229 | version "1.1.2" 230 | resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" 231 | 232 | repeat-string@^1.5.2, repeat-string@^1.6.1: 233 | version "1.6.1" 234 | resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" 235 | 236 | set-getter@^0.1.0: 237 | version "0.1.0" 238 | resolved "https://registry.yarnpkg.com/set-getter/-/set-getter-0.1.0.tgz#d769c182c9d5a51f409145f2fba82e5e86e80376" 239 | dependencies: 240 | to-object-path "^0.3.0" 241 | 242 | sprintf-js@~1.0.2: 243 | version "1.0.3" 244 | resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" 245 | 246 | string_decoder@~0.10.x: 247 | version "0.10.31" 248 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" 249 | 250 | strip-color@^0.1.0: 251 | version "0.1.0" 252 | resolved "https://registry.yarnpkg.com/strip-color/-/strip-color-0.1.0.tgz#106f65d3d3e6a2d9401cac0eb0ce8b8a702b4f7b" 253 | 254 | to-object-path@^0.3.0: 255 | version "0.3.0" 256 | resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" 257 | dependencies: 258 | kind-of "^3.0.2" 259 | 260 | toml@^2.3.2: 261 | version "2.3.2" 262 | resolved "https://registry.yarnpkg.com/toml/-/toml-2.3.2.tgz#5eded5ca42887924949fd06eb0e955656001e834" 263 | 264 | typedarray@^0.0.6: 265 | version "0.0.6" 266 | resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" 267 | 268 | underscore.string@~2.4.0: 269 | version "2.4.0" 270 | resolved "https://registry.yarnpkg.com/underscore.string/-/underscore.string-2.4.0.tgz#8cdd8fbac4e2d2ea1e7e2e8097c42f442280f85b" 271 | 272 | underscore@~1.7.0: 273 | version "1.7.0" 274 | resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.7.0.tgz#6bbaf0877500d36be34ecaa584e0db9fef035209" 275 | 276 | util-deprecate@~1.0.1: 277 | version "1.0.2" 278 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 279 | 280 | -------------------------------------------------------------------------------- /deploy/static/swagger-ui.css: -------------------------------------------------------------------------------- 1 | .swagger-ui{font-family:Open Sans,sans-serif;color:#3b4151}.swagger-ui .wrapper{width:100%;max-width:1460px;margin:0 auto;padding:0 20px}.swagger-ui .opblock-tag-section{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.swagger-ui .opblock-tag{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:10px 20px 10px 10px;cursor:pointer;-webkit-transition:all .2s;transition:all .2s;border-bottom:1px solid rgba(59,65,81,.3)}.swagger-ui .opblock-tag:hover{background:rgba(0,0,0,.02)}.swagger-ui .opblock-tag{font-size:24px;margin:0 0 5px;font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui .opblock-tag.no-desc span{-webkit-box-flex:1;-ms-flex:1;flex:1}.swagger-ui .opblock-tag svg{-webkit-transition:all .4s;transition:all .4s}.swagger-ui .opblock-tag small{font-size:14px;font-weight:400;-webkit-box-flex:1;-ms-flex:1;flex:1;padding:0 10px;font-family:Open Sans,sans-serif;color:#3b4151}.swagger-ui .parameter__type{font-size:12px;padding:5px 0;font-family:Source Code Pro,monospace;font-weight:600;color:#3b4151}.swagger-ui .view-line-link{position:relative;top:3px;width:20px;margin:0 5px;cursor:pointer;-webkit-transition:all .5s;transition:all .5s}.swagger-ui .opblock{margin:0 0 15px;border:1px solid #000;border-radius:4px;-webkit-box-shadow:0 0 3px rgba(0,0,0,.19);box-shadow:0 0 3px rgba(0,0,0,.19)}.swagger-ui .opblock .tab-header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-ms-flex:1;flex:1}.swagger-ui .opblock .tab-header .tab-item{padding:0 40px;cursor:pointer}.swagger-ui .opblock .tab-header .tab-item:first-of-type{padding:0 40px 0 0}.swagger-ui .opblock .tab-header .tab-item.active h4 span{position:relative}.swagger-ui .opblock .tab-header .tab-item.active h4 span:after{position:absolute;bottom:-15px;left:50%;width:120%;height:4px;content:"";-webkit-transform:translateX(-50%);transform:translateX(-50%);background:gray}.swagger-ui .opblock.is-open .opblock-summary{border-bottom:1px solid #000}.swagger-ui .opblock .opblock-section-header{padding:8px 20px;min-height:50px;background:hsla(0,0%,100%,.8);-webkit-box-shadow:0 1px 2px rgba(0,0,0,.1);box-shadow:0 1px 2px rgba(0,0,0,.1)}.swagger-ui .opblock .opblock-section-header,.swagger-ui .opblock .opblock-section-header label{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.swagger-ui .opblock .opblock-section-header label{font-size:12px;font-weight:700;margin:0;margin-left:auto;font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui .opblock .opblock-section-header label span{padding:0 10px 0 0}.swagger-ui .opblock .opblock-section-header h4{font-size:14px;-webkit-box-flex:1;-ms-flex:1;flex:1;margin:0;font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui .opblock .opblock-summary-method{font-size:14px;font-weight:700;min-width:80px;padding:6px 15px;text-align:center;border-radius:3px;background:#000;text-shadow:0 1px 0 rgba(0,0,0,.1);font-family:Titillium Web,sans-serif;color:#fff}.swagger-ui .opblock .opblock-summary-operation-id,.swagger-ui .opblock .opblock-summary-path,.swagger-ui .opblock .opblock-summary-path__deprecated{font-size:16px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:0;-ms-flex:0 3 auto;flex:0 3 auto;-webkit-box-align:center;-ms-flex-align:center;align-items:center;word-break:break-all;padding:0 10px;font-family:Source Code Pro,monospace;font-weight:600;color:#3b4151}@media (max-width:768px){.swagger-ui .opblock .opblock-summary-operation-id,.swagger-ui .opblock .opblock-summary-path,.swagger-ui .opblock .opblock-summary-path__deprecated{font-size:12px}}.swagger-ui .opblock .opblock-summary-operation-id .view-line-link,.swagger-ui .opblock .opblock-summary-path .view-line-link,.swagger-ui .opblock .opblock-summary-path__deprecated .view-line-link{position:relative;top:2px;width:0;margin:0;cursor:pointer;-webkit-transition:all .5s;transition:all .5s}.swagger-ui .opblock .opblock-summary-operation-id:hover .view-line-link,.swagger-ui .opblock .opblock-summary-path:hover .view-line-link,.swagger-ui .opblock .opblock-summary-path__deprecated:hover .view-line-link{width:18px;margin:0 5px}.swagger-ui .opblock .opblock-summary-path__deprecated{text-decoration:line-through}.swagger-ui .opblock .opblock-summary-operation-id{font-size:14px}.swagger-ui .opblock .opblock-summary-description{font-size:13px;-webkit-box-flex:1;-ms-flex:1;flex:1;font-family:Open Sans,sans-serif;color:#3b4151}.swagger-ui .opblock .opblock-summary{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:5px;cursor:pointer}.swagger-ui .opblock.opblock-post{border-color:#49cc90;background:rgba(73,204,144,.1)}.swagger-ui .opblock.opblock-post .opblock-summary-method{background:#49cc90}.swagger-ui .opblock.opblock-post .opblock-summary{border-color:#49cc90}.swagger-ui .opblock.opblock-post .tab-header .tab-item.active h4 span:after{background:#49cc90}.swagger-ui .opblock.opblock-put{border-color:#fca130;background:rgba(252,161,48,.1)}.swagger-ui .opblock.opblock-put .opblock-summary-method{background:#fca130}.swagger-ui .opblock.opblock-put .opblock-summary{border-color:#fca130}.swagger-ui .opblock.opblock-put .tab-header .tab-item.active h4 span:after{background:#fca130}.swagger-ui .opblock.opblock-delete{border-color:#f93e3e;background:rgba(249,62,62,.1)}.swagger-ui .opblock.opblock-delete .opblock-summary-method{background:#f93e3e}.swagger-ui .opblock.opblock-delete .opblock-summary{border-color:#f93e3e}.swagger-ui .opblock.opblock-delete .tab-header .tab-item.active h4 span:after{background:#f93e3e}.swagger-ui .opblock.opblock-get{border-color:#61affe;background:rgba(97,175,254,.1)}.swagger-ui .opblock.opblock-get .opblock-summary-method{background:#61affe}.swagger-ui .opblock.opblock-get .opblock-summary{border-color:#61affe}.swagger-ui .opblock.opblock-get .tab-header .tab-item.active h4 span:after{background:#61affe}.swagger-ui .opblock.opblock-patch{border-color:#50e3c2;background:rgba(80,227,194,.1)}.swagger-ui .opblock.opblock-patch .opblock-summary-method{background:#50e3c2}.swagger-ui .opblock.opblock-patch .opblock-summary{border-color:#50e3c2}.swagger-ui .opblock.opblock-patch .tab-header .tab-item.active h4 span:after{background:#50e3c2}.swagger-ui .opblock.opblock-head{border-color:#9012fe;background:rgba(144,18,254,.1)}.swagger-ui .opblock.opblock-head .opblock-summary-method{background:#9012fe}.swagger-ui .opblock.opblock-head .opblock-summary{border-color:#9012fe}.swagger-ui .opblock.opblock-head .tab-header .tab-item.active h4 span:after{background:#9012fe}.swagger-ui .opblock.opblock-options{border-color:#0d5aa7;background:rgba(13,90,167,.1)}.swagger-ui .opblock.opblock-options .opblock-summary-method{background:#0d5aa7}.swagger-ui .opblock.opblock-options .opblock-summary{border-color:#0d5aa7}.swagger-ui .opblock.opblock-options .tab-header .tab-item.active h4 span:after{background:#0d5aa7}.swagger-ui .opblock.opblock-deprecated{opacity:.6;border-color:#ebebeb;background:hsla(0,0%,92%,.1)}.swagger-ui .opblock.opblock-deprecated .opblock-summary-method{background:#ebebeb}.swagger-ui .opblock.opblock-deprecated .opblock-summary{border-color:#ebebeb}.swagger-ui .opblock.opblock-deprecated .tab-header .tab-item.active h4 span:after{background:#ebebeb}.swagger-ui .opblock .opblock-schemes{padding:8px 20px}.swagger-ui .opblock .opblock-schemes .schemes-title{padding:0 10px 0 0}.swagger-ui .filter .operation-filter-input{width:100%;margin:20px 0;padding:10px;border:2px solid #d8dde7}.swagger-ui .tab{display:-webkit-box;display:-ms-flexbox;display:flex;margin:20px 0 10px;padding:0;list-style:none}.swagger-ui .tab li{font-size:12px;min-width:100px;min-width:90px;padding:0;cursor:pointer;font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui .tab li:first-of-type{position:relative;padding-left:0}.swagger-ui .tab li:first-of-type:after{position:absolute;top:0;right:6px;width:1px;height:100%;content:"";background:rgba(0,0,0,.2)}.swagger-ui .tab li.active{font-weight:700}.swagger-ui .opblock-description-wrapper,.swagger-ui .opblock-external-docs-wrapper,.swagger-ui .opblock-title_normal{font-size:12px;margin:0 0 5px;padding:15px 20px;font-family:Open Sans,sans-serif;color:#3b4151}.swagger-ui .opblock-description-wrapper h4,.swagger-ui .opblock-external-docs-wrapper h4,.swagger-ui .opblock-title_normal h4{font-size:12px;margin:0 0 5px;font-family:Open Sans,sans-serif;color:#3b4151}.swagger-ui .opblock-description-wrapper p,.swagger-ui .opblock-external-docs-wrapper p,.swagger-ui .opblock-title_normal p{font-size:14px;margin:0;font-family:Open Sans,sans-serif;color:#3b4151}.swagger-ui .opblock-external-docs-wrapper h4{padding-left:0}.swagger-ui .execute-wrapper{padding:20px;text-align:right}.swagger-ui .execute-wrapper .btn{width:100%;padding:8px 40px}.swagger-ui .body-param-options{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.swagger-ui .body-param-options .body-param-edit{padding:10px 0}.swagger-ui .body-param-options label{padding:8px 0}.swagger-ui .body-param-options label select{margin:3px 0 0}.swagger-ui .responses-inner{padding:20px}.swagger-ui .responses-inner h4,.swagger-ui .responses-inner h5{font-size:12px;margin:10px 0 5px;font-family:Open Sans,sans-serif;color:#3b4151}.swagger-ui .response-col_status{font-size:14px;font-family:Open Sans,sans-serif;color:#3b4151}.swagger-ui .response-col_status .response-undocumented{font-size:11px;font-family:Source Code Pro,monospace;font-weight:600;color:#909090}.swagger-ui .response-col_links{padding-left:2em;max-width:40em;font-size:14px;font-family:Open Sans,sans-serif;color:#3b4151}.swagger-ui .response-col_links .response-undocumented{font-size:11px;font-family:Source Code Pro,monospace;font-weight:600;color:#909090}.swagger-ui .response-col_description__inner div.markdown,.swagger-ui .response-col_description__inner div.renderedMarkdown{font-size:12px;font-style:italic;display:block;margin:0;padding:10px;border-radius:4px;background:#41444e;font-family:Source Code Pro,monospace;font-weight:600;color:#fff}.swagger-ui .response-col_description__inner div.markdown p,.swagger-ui .response-col_description__inner div.renderedMarkdown p{margin:0;font-family:Source Code Pro,monospace;font-weight:600;color:#fff}.swagger-ui .response-col_description__inner div.markdown a,.swagger-ui .response-col_description__inner div.renderedMarkdown a{font-family:Source Code Pro,monospace;font-weight:600;color:#89bf04;text-decoration:underline}.swagger-ui .response-col_description__inner div.markdown a:hover,.swagger-ui .response-col_description__inner div.renderedMarkdown a:hover{color:#81b10c}.swagger-ui .response-col_description__inner div.markdown th,.swagger-ui .response-col_description__inner div.renderedMarkdown th{font-family:Source Code Pro,monospace;font-weight:600;color:#fff;border-bottom:1px solid #fff}.swagger-ui .opblock-body pre{font-size:12px;margin:0;padding:10px;white-space:pre-wrap;word-wrap:break-word;word-break:break-all;word-break:break-word;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto;border-radius:4px;background:#41444e;overflow-wrap:break-word;font-family:Source Code Pro,monospace;font-weight:600;color:#fff}.swagger-ui .opblock-body pre span{color:#fff!important}.swagger-ui .opblock-body pre .headerline{display:block}.swagger-ui .scheme-container{margin:0 0 20px;padding:30px 0;background:#fff;-webkit-box-shadow:0 1px 2px 0 rgba(0,0,0,.15);box-shadow:0 1px 2px 0 rgba(0,0,0,.15)}.swagger-ui .scheme-container .schemes{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.swagger-ui .scheme-container .schemes>label{font-size:12px;font-weight:700;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin:-20px 15px 0 0;font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui .scheme-container .schemes>label select{min-width:130px;text-transform:uppercase}.swagger-ui .server-container{margin:0 0 20px;padding:30px 0;background:#fff;-webkit-box-shadow:0 1px 2px 0 rgba(0,0,0,.15);box-shadow:0 1px 2px 0 rgba(0,0,0,.15)}.swagger-ui .server-container .computed-url{margin:2em 0}.swagger-ui .server-container .computed-url code{color:gray;display:inline-block;padding:4px;font-size:16px;margin:0 1em;font-style:italic}.swagger-ui .server-container .servers{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.swagger-ui .server-container .servers .servers-title{margin-right:1em}.swagger-ui .server-container .servers>label{font-size:12px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin:-20px 15px 0 0;font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui .server-container .servers>label select{min-width:130px}.swagger-ui .server-container .servers table tr{width:30em}.swagger-ui .server-container .servers table td{display:inline-block;max-width:15em;vertical-align:middle;padding-top:10px;padding-bottom:10px}.swagger-ui .server-container .servers table td:first-of-type{padding-right:2em}.swagger-ui .server-container .servers table td input{width:100%;height:100%}.swagger-ui .loading-container{padding:40px 0 60px}.swagger-ui .loading-container .loading{position:relative}.swagger-ui .loading-container .loading:after{font-size:10px;font-weight:700;position:absolute;top:50%;left:50%;content:"loading";-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);text-transform:uppercase;font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui .loading-container .loading:before{position:absolute;top:50%;left:50%;display:block;width:60px;height:60px;margin:-30px;content:"";-webkit-animation:rotation 1s infinite linear,opacity .5s;animation:rotation 1s infinite linear,opacity .5s;opacity:1;border:2px solid rgba(85,85,85,.1);border-top-color:rgba(0,0,0,.6);border-radius:100%;-webkit-backface-visibility:hidden;backface-visibility:hidden}@-webkit-keyframes rotation{to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes rotation{to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.swagger-ui .response-content-type{padding-top:1em}.swagger-ui .response-content-type.controls-accept-header select{border-color:green}.swagger-ui .response-content-type.controls-accept-header small{color:green;font-size:.7em}@-webkit-keyframes blinker{50%{opacity:0}}@keyframes blinker{50%{opacity:0}}.swagger-ui section h3{font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui a.nostyle{display:inline}.swagger-ui a.nostyle,.swagger-ui a.nostyle:visited{text-decoration:inherit;color:inherit;cursor:pointer}.swagger-ui .btn{font-size:14px;font-weight:700;padding:5px 23px;-webkit-transition:all .3s;transition:all .3s;border:2px solid gray;border-radius:4px;background:transparent;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.1);box-shadow:0 1px 2px rgba(0,0,0,.1);font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui .btn.btn-sm{font-size:12px;padding:4px 23px}.swagger-ui .btn[disabled]{cursor:not-allowed;opacity:.3}.swagger-ui .btn:hover{-webkit-box-shadow:0 0 5px rgba(0,0,0,.3);box-shadow:0 0 5px rgba(0,0,0,.3)}.swagger-ui .btn.cancel{border-color:#ff6060;background-color:transparent;font-family:Titillium Web,sans-serif;color:#ff6060}.swagger-ui .btn.authorize{line-height:1;display:inline;color:#49cc90;border-color:#49cc90;background-color:transparent}.swagger-ui .btn.authorize span{float:left;padding:4px 20px 0 0}.swagger-ui .btn.authorize svg{fill:#49cc90}.swagger-ui .btn.execute{-webkit-animation:swagger-ui-pulse 2s infinite;animation:swagger-ui-pulse 2s infinite;will-change:transform;background-color:transparent;color:#fff;border-color:#4990e2}@-webkit-keyframes swagger-ui-pulse{0%{color:#fff;background:#4990e2;-webkit-box-shadow:0 0 0 0 rgba(73,144,226,.8);box-shadow:0 0 0 0 rgba(73,144,226,.8)}70%{-webkit-box-shadow:0 0 0 5px rgba(73,144,226,0);box-shadow:0 0 0 5px rgba(73,144,226,0)}to{color:#fff;background:#4990e2;-webkit-box-shadow:0 0 0 0 rgba(73,144,226,0);box-shadow:0 0 0 0 rgba(73,144,226,0)}}@keyframes swagger-ui-pulse{0%{color:#fff;background:#4990e2;-webkit-box-shadow:0 0 0 0 rgba(73,144,226,.8);box-shadow:0 0 0 0 rgba(73,144,226,.8)}70%{-webkit-box-shadow:0 0 0 5px rgba(73,144,226,0);box-shadow:0 0 0 5px rgba(73,144,226,0)}to{color:#fff;background:#4990e2;-webkit-box-shadow:0 0 0 0 rgba(73,144,226,0);box-shadow:0 0 0 0 rgba(73,144,226,0)}}.swagger-ui .btn-group{display:-webkit-box;display:-ms-flexbox;display:flex;padding:30px}.swagger-ui .btn-group .btn{-webkit-box-flex:1;-ms-flex:1;flex:1}.swagger-ui .btn-group .btn:first-child{border-radius:4px 0 0 4px}.swagger-ui .btn-group .btn:last-child{border-radius:0 4px 4px 0}.swagger-ui .authorization__btn{padding:0 10px;border:none;background:none}.swagger-ui .authorization__btn.locked{opacity:1}.swagger-ui .authorization__btn.unlocked{opacity:.4}.swagger-ui .expand-methods,.swagger-ui .expand-operation{border:none;background:none}.swagger-ui .expand-methods svg,.swagger-ui .expand-operation svg{width:20px;height:20px}.swagger-ui .expand-methods{padding:0 10px}.swagger-ui .expand-methods:hover svg{fill:#404040}.swagger-ui .expand-methods svg{-webkit-transition:all .3s;transition:all .3s;fill:#707070}.swagger-ui button{cursor:pointer;outline:none}.swagger-ui button.invalid{-webkit-animation:shake .4s 1;animation:shake .4s 1;border-color:#f93e3e;background:#feebeb}.swagger-ui select{font-size:14px;font-weight:700;padding:5px 40px 5px 10px;border:2px solid #41444e;border-radius:4px;background:#f7f7f7 url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAyMCI+ICAgIDxwYXRoIGQ9Ik0xMy40MTggNy44NTljLjI3MS0uMjY4LjcwOS0uMjY4Ljk3OCAwIC4yNy4yNjguMjcyLjcwMSAwIC45NjlsLTMuOTA4IDMuODNjLS4yNy4yNjgtLjcwNy4yNjgtLjk3OSAwbC0zLjkwOC0zLjgzYy0uMjctLjI2Ny0uMjctLjcwMSAwLS45NjkuMjcxLS4yNjguNzA5LS4yNjguOTc4IDBMMTAgMTFsMy40MTgtMy4xNDF6Ii8+PC9zdmc+) right 10px center no-repeat;background-size:20px;-webkit-box-shadow:0 1px 2px 0 rgba(0,0,0,.25);box-shadow:0 1px 2px 0 rgba(0,0,0,.25);font-family:Titillium Web,sans-serif;color:#3b4151;-webkit-appearance:none;-moz-appearance:none;appearance:none}.swagger-ui select[multiple]{margin:5px 0;padding:5px;background:#f7f7f7}.swagger-ui select.invalid{-webkit-animation:shake .4s 1;animation:shake .4s 1;border-color:#f93e3e;background:#feebeb}.swagger-ui .opblock-body select{min-width:230px}@media (max-width:768px){.swagger-ui .opblock-body select{min-width:180px}}.swagger-ui label{font-size:12px;font-weight:700;margin:0 0 5px;font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui input[type=email],.swagger-ui input[type=file],.swagger-ui input[type=password],.swagger-ui input[type=search],.swagger-ui input[type=text]{min-width:100px;margin:5px 0;padding:8px 10px;border:1px solid #d9d9d9;border-radius:4px;background:#fff}@media (max-width:768px){.swagger-ui input[type=email],.swagger-ui input[type=file],.swagger-ui input[type=password],.swagger-ui input[type=search],.swagger-ui input[type=text]{max-width:175px}}.swagger-ui input[type=email].invalid,.swagger-ui input[type=file].invalid,.swagger-ui input[type=password].invalid,.swagger-ui input[type=search].invalid,.swagger-ui input[type=text].invalid{-webkit-animation:shake .4s 1;animation:shake .4s 1;border-color:#f93e3e;background:#feebeb}@-webkit-keyframes shake{10%,90%{-webkit-transform:translate3d(-1px,0,0);transform:translate3d(-1px,0,0)}20%,80%{-webkit-transform:translate3d(2px,0,0);transform:translate3d(2px,0,0)}30%,50%,70%{-webkit-transform:translate3d(-4px,0,0);transform:translate3d(-4px,0,0)}40%,60%{-webkit-transform:translate3d(4px,0,0);transform:translate3d(4px,0,0)}}@keyframes shake{10%,90%{-webkit-transform:translate3d(-1px,0,0);transform:translate3d(-1px,0,0)}20%,80%{-webkit-transform:translate3d(2px,0,0);transform:translate3d(2px,0,0)}30%,50%,70%{-webkit-transform:translate3d(-4px,0,0);transform:translate3d(-4px,0,0)}40%,60%{-webkit-transform:translate3d(4px,0,0);transform:translate3d(4px,0,0)}}.swagger-ui textarea{font-size:12px;width:100%;min-height:280px;padding:10px;border:none;border-radius:4px;outline:none;background:hsla(0,0%,100%,.8);font-family:Source Code Pro,monospace;font-weight:600;color:#3b4151}.swagger-ui textarea:focus{border:2px solid #61affe}.swagger-ui textarea.curl{font-size:12px;min-height:100px;margin:0;padding:10px;resize:none;border-radius:4px;background:#41444e;font-family:Source Code Pro,monospace;font-weight:600;color:#fff}.swagger-ui .checkbox{padding:5px 0 10px;-webkit-transition:opacity .5s;transition:opacity .5s;color:#303030}.swagger-ui .checkbox label{display:-webkit-box;display:-ms-flexbox;display:flex}.swagger-ui .checkbox p{font-weight:400!important;font-style:italic;margin:0!important;font-family:Source Code Pro,monospace;font-weight:600;color:#3b4151}.swagger-ui .checkbox input[type=checkbox]{display:none}.swagger-ui .checkbox input[type=checkbox]+label>.item{position:relative;top:3px;display:inline-block;width:16px;height:16px;margin:0 8px 0 0;padding:5px;cursor:pointer;border-radius:1px;background:#e8e8e8;-webkit-box-shadow:0 0 0 2px #e8e8e8;box-shadow:0 0 0 2px #e8e8e8;-webkit-box-flex:0;-ms-flex:none;flex:none}.swagger-ui .checkbox input[type=checkbox]+label>.item:active{-webkit-transform:scale(.9);transform:scale(.9)}.swagger-ui .checkbox input[type=checkbox]:checked+label>.item{background:#e8e8e8 url("data:image/svg+xml;charset=utf-8,%3Csvg width='10' height='8' viewBox='3 7 10 8' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%2341474E' fill-rule='evenodd' d='M6.333 15L3 11.667l1.333-1.334 2 2L11.667 7 13 8.333z'/%3E%3C/svg%3E") 50% no-repeat}.swagger-ui .dialog-ux{position:fixed;z-index:9999;top:0;right:0;bottom:0;left:0}.swagger-ui .dialog-ux .backdrop-ux{position:fixed;top:0;right:0;bottom:0;left:0;background:rgba(0,0,0,.8)}.swagger-ui .dialog-ux .modal-ux{position:absolute;z-index:9999;top:50%;left:50%;width:100%;min-width:300px;max-width:650px;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);border:1px solid #ebebeb;border-radius:4px;background:#fff;-webkit-box-shadow:0 10px 30px 0 rgba(0,0,0,.2);box-shadow:0 10px 30px 0 rgba(0,0,0,.2)}.swagger-ui .dialog-ux .modal-ux-content{overflow-y:auto;max-height:540px;padding:20px}.swagger-ui .dialog-ux .modal-ux-content p{font-size:12px;margin:0 0 5px;color:#41444e;font-family:Open Sans,sans-serif;color:#3b4151}.swagger-ui .dialog-ux .modal-ux-content h4{font-size:18px;font-weight:600;margin:15px 0 0;font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui .dialog-ux .modal-ux-header{display:-webkit-box;display:-ms-flexbox;display:flex;padding:12px 0;border-bottom:1px solid #ebebeb;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.swagger-ui .dialog-ux .modal-ux-header .close-modal{padding:0 10px;border:none;background:none;-webkit-appearance:none;-moz-appearance:none;appearance:none}.swagger-ui .dialog-ux .modal-ux-header h3{font-size:20px;font-weight:600;margin:0;padding:0 20px;-webkit-box-flex:1;-ms-flex:1;flex:1;font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui .model{font-size:12px;font-weight:300;font-family:Source Code Pro,monospace;font-weight:600;color:#3b4151}.swagger-ui .model .deprecated span,.swagger-ui .model .deprecated td{color:#a0a0a0!important}.swagger-ui .model .deprecated>td:first-of-type{text-decoration:line-through}.swagger-ui .model-toggle{font-size:10px;position:relative;top:6px;display:inline-block;margin:auto .3em;cursor:pointer;-webkit-transition:-webkit-transform .15s ease-in;transition:-webkit-transform .15s ease-in;transition:transform .15s ease-in;transition:transform .15s ease-in,-webkit-transform .15s ease-in;-webkit-transform:rotate(90deg);transform:rotate(90deg);-webkit-transform-origin:50% 50%;transform-origin:50% 50%}.swagger-ui .model-toggle.collapsed{-webkit-transform:rotate(0deg);transform:rotate(0deg)}.swagger-ui .model-toggle:after{display:block;width:20px;height:20px;content:"";background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath d='M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z'/%3E%3C/svg%3E") 50% no-repeat;background-size:100%}.swagger-ui .model-jump-to-path{position:relative;cursor:pointer}.swagger-ui .model-jump-to-path .view-line-link{position:absolute;top:-.4em;cursor:pointer}.swagger-ui .model-title{position:relative}.swagger-ui .model-title:hover .model-hint{visibility:visible}.swagger-ui .model-hint{position:absolute;top:-1.8em;visibility:hidden;padding:.1em .5em;white-space:nowrap;color:#ebebeb;border-radius:4px;background:rgba(0,0,0,.7)}.swagger-ui .model p{margin:0 0 1em}.swagger-ui section.models{margin:30px 0;border:1px solid rgba(59,65,81,.3);border-radius:4px}.swagger-ui section.models.is-open{padding:0 0 20px}.swagger-ui section.models.is-open h4{margin:0 0 5px;border-bottom:1px solid rgba(59,65,81,.3)}.swagger-ui section.models h4{font-size:16px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin:0;padding:10px 20px 10px 10px;cursor:pointer;-webkit-transition:all .2s;transition:all .2s;font-family:Titillium Web,sans-serif;color:#707070}.swagger-ui section.models h4 svg{-webkit-transition:all .4s;transition:all .4s}.swagger-ui section.models h4 span{-webkit-box-flex:1;-ms-flex:1;flex:1}.swagger-ui section.models h4:hover{background:rgba(0,0,0,.02)}.swagger-ui section.models h5{font-size:16px;margin:0 0 10px;font-family:Titillium Web,sans-serif;color:#707070}.swagger-ui section.models .model-jump-to-path{position:relative;top:5px}.swagger-ui section.models .model-container{margin:0 20px 15px;-webkit-transition:all .5s;transition:all .5s;border-radius:4px;background:rgba(0,0,0,.05)}.swagger-ui section.models .model-container:hover{background:rgba(0,0,0,.07)}.swagger-ui section.models .model-container:first-of-type{margin:20px}.swagger-ui section.models .model-container:last-of-type{margin:0 20px}.swagger-ui section.models .model-box{background:none}.swagger-ui .model-box{padding:10px;border-radius:4px;background:rgba(0,0,0,.1)}.swagger-ui .model-box .model-jump-to-path{position:relative;top:4px}.swagger-ui .model-box.deprecated{opacity:.5}.swagger-ui .model-title{font-size:16px;font-family:Titillium Web,sans-serif;color:#505050}.swagger-ui .model-deprecated-warning{font-size:16px;font-weight:600;margin-right:1em;font-family:Titillium Web,sans-serif;color:#f93e3e}.swagger-ui span>span.model .brace-close{padding:0 0 0 10px}.swagger-ui .prop-name{display:inline-block;margin-right:1em}.swagger-ui .prop-type{color:#55a}.swagger-ui .prop-enum{display:block}.swagger-ui .prop-format{color:#909090}.swagger-ui table{width:100%;padding:0 10px;border-collapse:collapse}.swagger-ui table.model tbody tr td{padding:0;vertical-align:top}.swagger-ui table.model tbody tr td:first-of-type{width:174px;padding:0 0 0 2em}.swagger-ui table.headers td{font-size:12px;font-weight:300;vertical-align:middle;font-family:Source Code Pro,monospace;font-weight:600;color:#3b4151}.swagger-ui table tbody tr td{padding:10px 0 0;vertical-align:top}.swagger-ui table tbody tr td:first-of-type{max-width:20%;min-width:6em;padding:10px 0}.swagger-ui table thead tr td,.swagger-ui table thead tr th{font-size:12px;font-weight:700;padding:12px 0;text-align:left;border-bottom:1px solid rgba(59,65,81,.2);font-family:Open Sans,sans-serif;color:#3b4151}.swagger-ui .parameters-col_description p{font-size:14px;margin:0;font-family:Open Sans,sans-serif;color:#3b4151}.swagger-ui .parameters-col_description input[type=text]{width:100%;max-width:340px}.swagger-ui .parameters-col_description select{border-width:1px}.swagger-ui .parameter__name{font-size:16px;font-weight:400;font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui .parameter__name.required{font-weight:700}.swagger-ui .parameter__name.required:after{font-size:10px;position:relative;top:-6px;padding:5px;content:"required";color:rgba(255,0,0,.6)}.swagger-ui .parameter__extension,.swagger-ui .parameter__in{font-size:12px;font-style:italic;font-family:Source Code Pro,monospace;font-weight:600;color:gray}.swagger-ui .parameter__deprecated{font-size:12px;font-style:italic;font-family:Source Code Pro,monospace;font-weight:600;color:red}.swagger-ui .table-container{padding:20px}.swagger-ui .topbar{height:75px;line-height:75px;-webkit-box-shadow:0 0 12px rgba(0,0,0,.1);box-shadow:0 0 12px rgba(0,0,0,.1)}.swagger-ui .topbar .topbar-wrapper,.swagger-ui .topbar a{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.swagger-ui .topbar a{font-size:1.5em;font-weight:700;-webkit-box-flex:1;-ms-flex:1;flex:1;text-decoration:none;font-family:Titillium Web,sans-serif;color:#909090}.swagger-ui .topbar a span{margin:0;padding:0 10px}.swagger-ui .topbar .download-url-wrapper{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:3;-ms-flex:3;flex:3;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.swagger-ui .topbar .download-url-wrapper input[type=text]{width:100%;margin:0;border:2px solid #547f00;border-radius:4px 0 0 4px;outline:none}.swagger-ui .topbar .download-url-wrapper .select-label{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:100%;max-width:600px;margin:0}.swagger-ui .topbar .download-url-wrapper .select-label span{font-size:16px;-webkit-box-flex:1;-ms-flex:1;flex:1;padding:0 10px 0 0;text-align:right}.swagger-ui .topbar .download-url-wrapper .select-label select{-webkit-box-flex:2;-ms-flex:2;flex:2;width:100%;border:2px solid #547f00;outline:none;-webkit-box-shadow:none;box-shadow:none}.swagger-ui .topbar .download-url-wrapper .download-url-button{font-size:16px;font-weight:700;padding:4px 30px;border:none;border-radius:0 4px 4px 0;background:#547f00;font-family:Titillium Web,sans-serif;color:#fff}.swagger-ui .info{margin:50px 0}.swagger-ui .info hgroup.main{margin:0 0 20px}.swagger-ui .info hgroup.main a{font-size:12px}.swagger-ui .info li,.swagger-ui .info p,.swagger-ui .info table{font-size:14px;font-family:Open Sans,sans-serif;color:#3b4151}.swagger-ui .info h1,.swagger-ui .info h2,.swagger-ui .info h3,.swagger-ui .info h4,.swagger-ui .info h5{font-family:Open Sans,sans-serif;color:#3b4151}.swagger-ui .info code{padding:3px 5px;border-radius:4px;background:rgba(0,0,0,.05);font-family:Source Code Pro,monospace;font-weight:600;color:#9012fe}.swagger-ui .info a{font-size:14px;-webkit-transition:all .4s;transition:all .4s;font-family:Open Sans,sans-serif;color:#4990e2}.swagger-ui .info a:hover{color:#1f69c0}.swagger-ui .info>div{margin:0 0 5px}.swagger-ui .info .base-url{font-size:12px;font-weight:300!important;margin:0;font-family:Source Code Pro,monospace;font-weight:600;color:#3b4151}.swagger-ui .info .title{font-size:36px;margin:0;font-family:Open Sans,sans-serif;color:#3b4151}.swagger-ui .info .title small{font-size:10px;position:relative;top:-5px;display:inline-block;margin:0 0 0 5px;padding:2px 4px;vertical-align:super;border-radius:57px;background:#7d8492}.swagger-ui .info .title small pre{margin:0;font-family:Titillium Web,sans-serif;color:#fff}.swagger-ui .auth-btn-wrapper{display:-webkit-box;display:-ms-flexbox;display:flex;padding:10px 0;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.swagger-ui .auth-btn-wrapper .btn-done{margin-right:1em}.swagger-ui .auth-wrapper{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-ms-flex:1;flex:1;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.swagger-ui .auth-wrapper .authorize{padding-right:20px}.swagger-ui .auth-container{margin:0 0 10px;padding:10px 20px;border-bottom:1px solid #ebebeb}.swagger-ui .auth-container:last-of-type{margin:0;padding:10px 20px;border:0}.swagger-ui .auth-container h4{margin:5px 0 15px!important}.swagger-ui .auth-container .wrapper{margin:0;padding:0}.swagger-ui .auth-container input[type=password],.swagger-ui .auth-container input[type=text]{min-width:230px}.swagger-ui .auth-container .errors{font-size:12px;padding:10px;border-radius:4px;font-family:Source Code Pro,monospace;font-weight:600;color:#3b4151}.swagger-ui .scopes h2{font-size:14px;font-family:Titillium Web,sans-serif;color:#3b4151}.swagger-ui .scope-def{padding:0 0 20px}.swagger-ui .errors-wrapper{margin:20px;padding:10px 20px;-webkit-animation:scaleUp .5s;animation:scaleUp .5s;border:2px solid #f93e3e;border-radius:4px;background:rgba(249,62,62,.1)}.swagger-ui .errors-wrapper .error-wrapper{margin:0 0 10px}.swagger-ui .errors-wrapper .errors h4{font-size:14px;margin:0;font-family:Source Code Pro,monospace;font-weight:600;color:#3b4151}.swagger-ui .errors-wrapper .errors small{color:#606060}.swagger-ui .errors-wrapper hgroup{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.swagger-ui .errors-wrapper hgroup h4{font-size:20px;margin:0;-webkit-box-flex:1;-ms-flex:1;flex:1;font-family:Titillium Web,sans-serif;color:#3b4151}@-webkit-keyframes scaleUp{0%{-webkit-transform:scale(.8);transform:scale(.8);opacity:0}to{-webkit-transform:scale(1);transform:scale(1);opacity:1}}@keyframes scaleUp{0%{-webkit-transform:scale(.8);transform:scale(.8);opacity:0}to{-webkit-transform:scale(1);transform:scale(1);opacity:1}}.swagger-ui .Resizer.vertical.disabled{display:none} 2 | /*# sourceMappingURL=swagger-ui.css.map*/ -------------------------------------------------------------------------------- /api/swagger.yml: -------------------------------------------------------------------------------- 1 | swagger: '2.0' 2 | info: 3 | version: 1.0.0 4 | title: beary-openapi 5 | description: BearyChat OpenAPI 列表 6 | host: api.bearychat.com 7 | basePath: /v1 8 | schemes: 9 | - https 10 | consumes: 11 | - application/json 12 | produces: 13 | - application/json 14 | securityDefinitions: 15 | TokenAuth: 16 | type: apiKey 17 | in: query 18 | name: token 19 | security: 20 | - TokenAuth: [] 21 | paths: 22 | /meta: 23 | get: 24 | tags: 25 | - meta 26 | description: | 27 | 返回 BearyChat API 的状态。 28 | responses: 29 | '200': 30 | description: meta response 31 | schema: 32 | $ref: '#/definitions/Meta' 33 | examples: 34 | API 状态: | 35 | { 36 | "version": "1" 37 | } 38 | default: 39 | description: unexpected error 40 | schema: 41 | $ref: '#/definitions/Error' 42 | /team.info: 43 | get: 44 | tags: 45 | - team 46 | description: | 47 | 返回当前团队信息。 48 | responses: 49 | '200': 50 | description: request success 51 | schema: 52 | $ref: '#/definitions/Team' 53 | examples: 54 | team response: | 55 | { 56 | "id": "=bw52O", 57 | "subdomain": "openapi", 58 | "name": "BearyChat OpenAPI", 59 | "email_domain": null, 60 | "logo_url": null, 61 | "description": "", 62 | "plan": "basic", 63 | "created": "2017-01-11T12:28:31.000+0000" 64 | } 65 | default: 66 | description: unexpected error 67 | schema: 68 | $ref: '#/definitions/Error' 69 | /user.info: 70 | get: 71 | tags: 72 | - user 73 | description: | 74 | 返回团队内指定用户完整信息。 75 | responses: 76 | '200': 77 | description: request success 78 | schema: 79 | $ref: '#/definitions/User' 80 | examples: 81 | user response: | 82 | { 83 | "inactive": false, 84 | "role": "normal", 85 | "email": "support@bearyinnovative.com", 86 | "name": "BearyBot", 87 | "type": "assistant", 88 | "created": "2017-01-11T12:28:31.000+0000", 89 | "id": "=bwMkR", 90 | "avatars": { 91 | "small": null, 92 | "medium": null, 93 | "large": null 94 | }, 95 | "team_id": "=bw52O", 96 | "full_name": "倍洽小助手", 97 | "mobile": null, 98 | "profile": { 99 | "bio": null, 100 | "position": null, 101 | "skype": null 102 | } 103 | } 104 | default: 105 | description: request fail 106 | schema: 107 | $ref: '#/definitions/Error' 108 | parameters: 109 | - name: user_id 110 | in: query 111 | description: 指定用户 id,如 \"=bw52O\" 112 | required: true 113 | type: string 114 | /file.location: 115 | get: 116 | tags: 117 | - file 118 | description: | 119 | 换取文件真实地址 120 | responses: 121 | '302': 122 | description: request success and 302 123 | '404': 124 | description: request no exist file 125 | examples: 126 | file not found: | 127 | { 128 | "code": 6, 129 | "error": "文件不存在" 130 | } 131 | parameters: 132 | - name: file_key 133 | type: string 134 | in: query 135 | description: 文件 key 136 | required: ture 137 | /user.list: 138 | get: 139 | tags: 140 | - user 141 | description: | 142 | 返回团队内的用户列表,获取某个用户的完整信息,请使用 `user.info`. 143 | responses: 144 | '200': 145 | description: request success 146 | schema: 147 | type: array 148 | items: 149 | $ref: '#/definitions/User' 150 | examples: 151 | users response: | 152 | [ 153 | { 154 | "inactive": false, 155 | "role": "normal", 156 | "email": "support@bearyinnovative.com", 157 | "name": "BearyBot", 158 | "type": "assistant", 159 | "created": "2017-01-11T12:28:31.000+0000", 160 | "id": "=bwMkR", 161 | "avatars": { 162 | "small": null, 163 | "medium": null, 164 | "large": null 165 | }, 166 | "team_id": "=bw52O", 167 | "full_name": "倍洽小助手", 168 | "mobile": null, 169 | "profile": { 170 | "bio": null, 171 | "position": null, 172 | "skype": null 173 | } 174 | } 175 | ] 176 | default: 177 | description: request fail 178 | schema: 179 | $ref: '#/definitions/Error' 180 | /user.me: 181 | get: 182 | tags: 183 | - user 184 | description: | 185 | 返回当前用户的信息。 186 | responses: 187 | '200': 188 | description: request success 189 | schema: 190 | $ref: '#/definitions/User' 191 | examples: 192 | user response: | 193 | { 194 | "inactive": false, 195 | "role": "normal", 196 | "email": "support@bearyinnovative.com", 197 | "name": "BearyBot", 198 | "type": "assistant", 199 | "created": "2017-01-11T12:28:31.000+0000", 200 | "id": "=bwMkR", 201 | "avatars": { 202 | "small": null, 203 | "medium": null, 204 | "large": null 205 | }, 206 | "team_id": "=bw52O", 207 | "full_name": "倍洽小助手", 208 | "mobile": null, 209 | "profile": { 210 | "bio": null, 211 | "position": null, 212 | "skype": null 213 | } 214 | } 215 | default: 216 | description: request fail 217 | schema: 218 | $ref: '#/definitions/Error' 219 | /user.update_me: 220 | patch: 221 | tags: 222 | - user 223 | description: | 224 | 更新当前用户信息。 225 | parameters: 226 | - in: body 227 | name: user_info 228 | required: false 229 | schema: 230 | type: object 231 | properties: 232 | name: 233 | type: string 234 | example: beary_bot 235 | description: 用户名 (@name) 236 | full_name: 237 | type: string 238 | example: bearybot 239 | description: 用户全名 240 | responses: 241 | '200': 242 | description: request success 243 | schema: 244 | $ref: '#/definitions/User' 245 | examples: 246 | user response: | 247 | { 248 | "inactive": false, 249 | "role": "normal", 250 | "email": "support@bearyinnovative.com", 251 | "name": "BearyBot", 252 | "type": "assistant", 253 | "created": "2017-01-11T12:28:31.000+0000", 254 | "id": "=bwMkR", 255 | "avatars": { 256 | "small": null, 257 | "medium": null, 258 | "large": null 259 | }, 260 | "team_id": "=bw52O", 261 | "full_name": "倍洽小助手", 262 | "mobile": null, 263 | "profile": { 264 | "bio": null, 265 | "position": null, 266 | "skype": null 267 | } 268 | } 269 | default: 270 | description: request fail 271 | schema: 272 | $ref: '#/definitions/Error' 273 | consumes: 274 | - application/json 275 | /vchannel.info: 276 | get: 277 | tags: 278 | - vchannel 279 | description: | 280 | 返回指定聊天会话的完整信息。 281 | responses: 282 | '200': 283 | description: request success 284 | schema: 285 | type: object 286 | description: | 287 | Channel / SessionChannel / P2PChannel 的其中一种 288 | examples: 289 | vchannel response: | 290 | // Channel 291 | { 292 | "private": false, 293 | "general": true, 294 | "latest_ts": 1486367046281, 295 | "uid": "=bw52O", 296 | "name": "所有人", 297 | "is_member": false, 298 | "is_active": true, 299 | "type": "normal", 300 | "topic": null, 301 | "member_uids": [ 302 | "=bw52O" 303 | ], 304 | "vchannel_id": "=bw52O", 305 | "id": "=bw52O", 306 | "team_id": "=bw52O" 307 | } 308 | 309 | // SessionChannel 310 | { 311 | "latest_ts": "1489242467694", 312 | "name": "临时讨论组名称", 313 | "is_member": true, 314 | "is_active": true, 315 | "type": "session", 316 | "member_uids": [ 317 | "=bw52O" 318 | ], 319 | "vchannel_id": "=bw52O", 320 | "id": "=bw52O", 321 | "team_id": "=bw52O" 322 | } 323 | 324 | // P2PChannel 325 | { 326 | "id": "=bw52O", 327 | "team_id": "=bw52O", 328 | "vchannel_id": "=bw52O", 329 | "type": "p2p", 330 | "is_active": true, 331 | "is_member": true, 332 | "member_uids": [ 333 | "=bw52O", 334 | "=bw52P" 335 | ], 336 | "latest_ts": 1485238998284 337 | } 338 | parameters: 339 | - name: vchannel_id 340 | in: query 341 | description: 聊天会话 id 342 | required: true 343 | type: string 344 | /channel.info: 345 | get: 346 | tags: 347 | - channel 348 | description: | 349 | 返回指定讨论组的完整信息。 350 | responses: 351 | '200': 352 | description: request success 353 | schema: 354 | $ref: '#/definitions/Channel' 355 | examples: 356 | channel response: | 357 | { 358 | "private": false, 359 | "general": true, 360 | "latest_ts": 1486367046281, 361 | "uid": "=bw52O", 362 | "name": "所有人", 363 | "is_member": false, 364 | "is_active": true, 365 | "type": "normal", 366 | "topic": null, 367 | "member_uids": [ 368 | "=bw52O" 369 | ], 370 | "vchannel_id": "=bw52O", 371 | "id": "=bw52O", 372 | "team_id": "=bw52O" 373 | } 374 | default: 375 | description: request fail 376 | schema: 377 | $ref: '#/definitions/TBD' 378 | parameters: 379 | - name: channel_id 380 | in: query 381 | description: 讨论组 id, 例如 \"=bw52O\" 382 | required: true 383 | type: string 384 | /channel.list: 385 | get: 386 | tags: 387 | - channel 388 | description: | 389 | 返回团队内的讨论组列表,获取某个讨论组的完整信息,请使用 `channel.info`. 390 | responses: 391 | '200': 392 | description: request success 393 | schema: 394 | type: array 395 | items: 396 | $ref: '#/definitions/Channel' 397 | examples: 398 | channels response: | 399 | [ 400 | { 401 | "private": false, 402 | "general": true, 403 | "latest_ts": 1486367046281, 404 | "uid": "=bw52O", 405 | "name": "所有人", 406 | "is_member": false, 407 | "is_active": true, 408 | "type": "normal", 409 | "topic": null, 410 | "member_uids": [ 411 | "=bw52O" 412 | ], 413 | "vchannel_id": "=bw52O", 414 | "id": "=bw52O", 415 | "team_id": "=bw52O" 416 | } 417 | ] 418 | default: 419 | description: request fail 420 | schema: 421 | $ref: '#/definitions/Error' 422 | /channel.create: 423 | post: 424 | tags: 425 | - channel 426 | description: | 427 | 创建一个讨论组 428 | responses: 429 | '201': 430 | description: request success 431 | schema: 432 | $ref: '#/definitions/Channel' 433 | examples: 434 | channel response: | 435 | { 436 | "private": false, 437 | "general": true, 438 | "latest_ts": 1486367046281, 439 | "uid": "=bw52O", 440 | "name": "所有人", 441 | "is_member": false, 442 | "is_active": true, 443 | "type": "normal", 444 | "topic": null, 445 | "member_uids": [ 446 | "=bw52O" 447 | ], 448 | "vchannel_id": "=bw52O", 449 | "id": "=bw52O", 450 | "team_id": "=bw52O" 451 | } 452 | default: 453 | description: request fail 454 | schema: 455 | $ref: '#/definitions/Error' 456 | consumes: 457 | - application/json 458 | parameters: 459 | - in: body 460 | name: vchannel_info 461 | required: true 462 | schema: 463 | type: object 464 | properties: 465 | name: 466 | type: string 467 | example: 吃喝玩乐在深圳 468 | description: >- 469 | 讨论组名称,可以包含 2 到 20 个英文字符或 1 到 10 个中文字符。允许使用数字、下划线 (`_`)、中线 470 | (`-`) 和点。 471 | topic: 472 | type: string 473 | example: 今天吃什么 474 | description: 讨论组话题 475 | private: 476 | type: boolean 477 | description: 讨论组是否为私密? 478 | default: false 479 | required: 480 | - name 481 | /channel.archive: 482 | post: 483 | tags: 484 | - channel 485 | description: | 486 | 归档一个讨论组。 487 | responses: 488 | '200': 489 | description: request success 490 | schema: 491 | $ref: '#/definitions/Channel' 492 | examples: 493 | channel response: | 494 | { 495 | "private": false, 496 | "general": true, 497 | "latest_ts": 1486367046281, 498 | "uid": "=bw52O", 499 | "name": "所有人", 500 | "is_member": false, 501 | "is_active": false, 502 | "type": "normal", 503 | "topic": null, 504 | "member_uids": [ 505 | "=bw52O" 506 | ], 507 | "vchannel_id": "=bw52O", 508 | "id": "=bw52O", 509 | "team_id": "=bw52O" 510 | } 511 | default: 512 | description: request fail 513 | schema: 514 | $ref: '#/definitions/Error' 515 | parameters: 516 | - in: body 517 | name: channel_info 518 | required: true 519 | schema: 520 | type: object 521 | properties: 522 | channel_id: 523 | type: string 524 | example: =bw52O 525 | description: 讨论组 id 526 | required: 527 | - channel_id 528 | /channel.unarchive: 529 | post: 530 | tags: 531 | - channel 532 | description: | 533 | 恢复一个已被归档的讨论组。 534 | responses: 535 | '200': 536 | description: request success 537 | schema: 538 | $ref: '#/definitions/Channel' 539 | examples: 540 | channel response: | 541 | { 542 | "private": false, 543 | "general": true, 544 | "latest_ts": 1486367046281, 545 | "uid": "=bw52O", 546 | "name": "所有人", 547 | "is_member": false, 548 | "is_active": true, 549 | "type": "normal", 550 | "topic": null, 551 | "member_uids": [ 552 | "=bw52O" 553 | ], 554 | "vchannel_id": "=bw52O", 555 | "id": "=bw52O", 556 | "team_id": "=bw52O" 557 | } 558 | default: 559 | description: request fail 560 | schema: 561 | $ref: '#/definitions/Error' 562 | parameters: 563 | - in: body 564 | name: channel_info 565 | required: true 566 | schema: 567 | type: object 568 | properties: 569 | channel_id: 570 | type: string 571 | example: =bw52O 572 | description: 讨论组 id 573 | required: 574 | - channel_id 575 | /channel.leave: 576 | post: 577 | tags: 578 | - channel 579 | description: | 580 | 当前用户离开讨论组。 581 | responses: 582 | '204': 583 | description: request success 584 | schema: 585 | $ref: '#/definitions/NoContent' 586 | default: 587 | description: request fail 588 | schema: 589 | $ref: '#/definitions/Error' 590 | parameters: 591 | - in: body 592 | name: channel_info 593 | required: true 594 | schema: 595 | type: object 596 | properties: 597 | channel_id: 598 | type: string 599 | example: =bw52O 600 | description: 讨论组 id 601 | required: 602 | - channel_id 603 | /channel.join: 604 | post: 605 | tags: 606 | - channel 607 | description: | 608 | 当前用户加入指定讨论组。 609 | responses: 610 | '200': 611 | description: request success 612 | schema: 613 | $ref: '#/definitions/Channel' 614 | examples: 615 | channel response: | 616 | { 617 | "private": false, 618 | "general": false, 619 | "latest_ts": 1486367046281, 620 | "uid": "=bw52O", 621 | "name": "吃喝玩乐在深圳", 622 | "is_member": false, 623 | "is_active": true, 624 | "type": "normal", 625 | "topic": null, 626 | "member_uids": [ 627 | "=bw52O" 628 | ], 629 | "vchannel_id": "=bw52O", 630 | "id": "=bw52O", 631 | "team_id": "=bw52O" 632 | } 633 | default: 634 | description: request fail 635 | schema: 636 | $ref: '#/definitions/Error' 637 | parameters: 638 | - in: body 639 | name: channel_info 640 | required: true 641 | schema: 642 | type: object 643 | properties: 644 | channel_id: 645 | type: string 646 | example: =bw52O 647 | description: 讨论组 id 648 | required: 649 | - channel_id 650 | /channel.invite: 651 | post: 652 | tags: 653 | - channel 654 | description: | 655 | 当前用户邀请一个团队成员加入讨论组。 656 | responses: 657 | '204': 658 | description: request success 659 | schema: 660 | $ref: '#/definitions/NoContent' 661 | default: 662 | description: request fail 663 | schema: 664 | $ref: '#/definitions/Error' 665 | parameters: 666 | - in: body 667 | name: channel_info 668 | required: true 669 | schema: 670 | type: object 671 | properties: 672 | channel_id: 673 | type: string 674 | example: =bw52O 675 | description: 讨论组 id 676 | invite_uid: 677 | type: string 678 | example: =bw52O 679 | description: 邀请用户 id 680 | required: 681 | - channel_id 682 | - invite_uid 683 | /channel.kick: 684 | post: 685 | tags: 686 | - channel 687 | description: | 688 | 当前用户移除一个讨论组成员。 689 | responses: 690 | '204': 691 | description: request success 692 | schema: 693 | $ref: '#/definitions/NoContent' 694 | default: 695 | description: request fail 696 | schema: 697 | $ref: '#/definitions/Error' 698 | parameters: 699 | - in: body 700 | name: channel_info 701 | required: true 702 | schema: 703 | type: object 704 | properties: 705 | channel_id: 706 | type: string 707 | example: =bw52O 708 | description: 讨论组 id 709 | kick_uid: 710 | type: string 711 | example: =bw52O 712 | description: 移除用户 id 713 | required: 714 | - channel_id 715 | - kick_uid 716 | /channel.kickout: 717 | post: 718 | tags: 719 | - channel 720 | description: | 721 | 当前用户移除一个讨论组成员。 722 | responses: 723 | '204': 724 | description: request success 725 | schema: 726 | $ref: '#/definitions/NoContent' 727 | default: 728 | description: request fail 729 | schema: 730 | $ref: '#/definitions/Error' 731 | parameters: 732 | - in: body 733 | name: channel_info 734 | required: true 735 | schema: 736 | type: object 737 | properties: 738 | channel_id: 739 | type: string 740 | example: =bw52O 741 | description: 讨论组 id 742 | kick_uid: 743 | type: string 744 | example: =bw52O 745 | description: 移除用户 id 746 | required: 747 | - channel_id 748 | - kick_uid 749 | /session_channel.info: 750 | get: 751 | tags: 752 | - session channel 753 | description: | 754 | 返回一个临时讨论组的完整信息。 755 | responses: 756 | '200': 757 | description: request success 758 | schema: 759 | $ref: '#/definitions/SessionChannel' 760 | examples: 761 | session channel response: | 762 | { 763 | "latest_ts": "1489242467694", 764 | "name": "临时讨论组名称", 765 | "is_member": true, 766 | "is_active": true, 767 | "type": "session", 768 | "member_uids": [ 769 | "=bw52O" 770 | ], 771 | "vchannel_id": "=bw52O", 772 | "id": "=bw52O", 773 | "team_id": "=bw52O" 774 | } 775 | default: 776 | description: request fail 777 | schema: 778 | $ref: '#/definitions/Error' 779 | parameters: 780 | - name: session_channel_id 781 | in: query 782 | description: 讨论组 id, 例如 \"=bw52O\" 783 | required: true 784 | type: string 785 | /session_channel.list: 786 | get: 787 | tags: 788 | - session channel 789 | description: | 790 | 返回团队内已经加入的临时讨论组列表,获取某个临时讨论组的完整信息, 791 | 请使用 `session_channel.info`. 792 | responses: 793 | '200': 794 | description: request success 795 | schema: 796 | type: array 797 | items: 798 | $ref: '#/definitions/SessionChannel' 799 | examples: 800 | session channels response: | 801 | [ 802 | { 803 | "latest_ts": "1489242467694", 804 | "name": "临时讨论组名称", 805 | "is_member": true, 806 | "is_active": true, 807 | "type": "session", 808 | "member_uids": [ 809 | "=bw52O" 810 | ], 811 | "vchannel_id": "=bw52O", 812 | "id": "=bw52O", 813 | "team_id": "=bw52O" 814 | } 815 | ] 816 | default: 817 | description: request fail 818 | schema: 819 | $ref: '#/definitions/Error' 820 | /session_channel.create: 821 | post: 822 | tags: 823 | - session channel 824 | description: | 825 | 创建一个临时讨论组。 826 | responses: 827 | '201': 828 | description: request success 829 | schema: 830 | $ref: '#/definitions/SessionChannel' 831 | examples: 832 | session channel responses: | 833 | { 834 | "latest_ts": "1489242467694", 835 | "name": "临时讨论组名称", 836 | "is_member": true, 837 | "is_active": true, 838 | "type": "session", 839 | "member_uids": [ 840 | "=bw52O" 841 | ], 842 | "vchannel_id": "=bw52O", 843 | "id": "=bw52O", 844 | "team_id": "=bw52O" 845 | } 846 | default: 847 | description: request fail 848 | schema: 849 | $ref: '#/definitions/Error' 850 | parameters: 851 | - in: body 852 | name: session_channel_info 853 | required: true 854 | schema: 855 | type: object 856 | properties: 857 | name: 858 | type: string 859 | example: 吃喝玩乐在深圳 860 | description: >- 861 | 讨论组名称,可以包含 2 到 20 个英文字符或 1 到 10 个中文字符。允许使用数字、下划线 (`_`)、中线 862 | (`-`) 和点。 863 | member_uids: 864 | type: array 865 | example: '["=bw52O", "=bw52P"]' 866 | description: 临时讨论组成员 id 列表 867 | items: 868 | $ref: '#/definitions/ResponseObjectId' 869 | required: 870 | - member_uids 871 | /session_channel.archive: 872 | post: 873 | tags: 874 | - session channel 875 | description: | 876 | 归档一个临时讨论组。 877 | responses: 878 | '200': 879 | description: request success 880 | schema: 881 | $ref: '#/definitions/SessionChannel' 882 | examples: 883 | session channel response: | 884 | { 885 | "latest_ts": "1489242467694", 886 | "name": "临时讨论组名称", 887 | "is_member": true, 888 | "is_active": false, 889 | "type": "session", 890 | "member_uids": [ 891 | "=bw52O" 892 | ], 893 | "vchannel_id": "=bw52O", 894 | "id": "=bw52O", 895 | "team_id": "=bw52O" 896 | } 897 | default: 898 | description: request fail 899 | schema: 900 | $ref: '#/definitions/Error' 901 | parameters: 902 | - in: body 903 | name: channel_info 904 | required: true 905 | schema: 906 | type: object 907 | properties: 908 | session_channel_id: 909 | type: string 910 | example: =bw52O 911 | description: 临时讨论组 id 912 | required: 913 | - session_channel_id 914 | /session_channel.convert_to_channel: 915 | post: 916 | tags: 917 | - session channel 918 | description: | 919 | 将临时讨论组转换为讨论组。 920 | responses: 921 | '201': 922 | description: request success 923 | schema: 924 | $ref: '#/definitions/Channel' 925 | examples: 926 | session channel response: | 927 | { 928 | "latest_ts": "1489242467694", 929 | "name": "临时讨论组名称", 930 | "is_member": true, 931 | "is_active": false, 932 | "type": "session", 933 | "member_uids": [ 934 | "=bw52O" 935 | ], 936 | "vchannel_id": "=bw52O", 937 | "id": "=bw52O", 938 | "team_id": "=bw52O" 939 | } 940 | default: 941 | description: request fail 942 | schema: 943 | $ref: '#/definitions/Error' 944 | parameters: 945 | - in: body 946 | name: channel_info 947 | required: true 948 | schema: 949 | type: object 950 | properties: 951 | session_channel_id: 952 | type: string 953 | example: =bw52O 954 | description: 临时讨论组 id 955 | name: 956 | type: string 957 | example: 吃喝玩乐在深圳 958 | description: >- 959 | 讨论组名称,可以包含 2 到 20 个英文字符或 1 到 10 个中文字符。允许使用数字、下划线 (`_`)、中线 960 | (`-`) 和点。 961 | private: 962 | type: boolean 963 | default: true 964 | description: 讨论组是否为私密? 965 | required: 966 | - session_channel_id 967 | - name 968 | /session_channel.leave: 969 | post: 970 | tags: 971 | - session channel 972 | description: | 973 | 离开临时讨论组。 974 | responses: 975 | '204': 976 | description: request success 977 | schema: 978 | $ref: '#/definitions/NoContent' 979 | default: 980 | description: request fail 981 | schema: 982 | $ref: '#/definitions/Error' 983 | parameters: 984 | - in: body 985 | name: session_channel_info 986 | required: true 987 | schema: 988 | type: object 989 | properties: 990 | session_channel_id: 991 | type: string 992 | example: =bw52O 993 | description: 临时讨论组 id 994 | required: 995 | - session_channel_id 996 | /session_channel.invite: 997 | post: 998 | tags: 999 | - session channel 1000 | description: | 1001 | 邀请一个团队成员加入临时讨论组。 1002 | responses: 1003 | '204': 1004 | description: request success 1005 | schema: 1006 | $ref: '#/definitions/NoContent' 1007 | default: 1008 | description: request fail 1009 | schema: 1010 | $ref: '#/definitions/Error' 1011 | parameters: 1012 | - in: body 1013 | name: session_channel_info 1014 | required: true 1015 | schema: 1016 | type: object 1017 | properties: 1018 | session_channel_id: 1019 | type: string 1020 | example: =bw52O 1021 | description: 临时讨论组 id 1022 | invite_uid: 1023 | type: string 1024 | example: =bw52O 1025 | description: 邀请用户 id 1026 | required: 1027 | - session_channel_id 1028 | - invite_uid 1029 | /session_channel.kick: 1030 | post: 1031 | tags: 1032 | - session channel 1033 | description: | 1034 | 移除一个临时讨论组成员。 1035 | responses: 1036 | '204': 1037 | description: request success 1038 | schema: 1039 | $ref: '#/definitions/NoContent' 1040 | default: 1041 | description: request fail 1042 | schema: 1043 | $ref: '#/definitions/Error' 1044 | parameters: 1045 | - in: body 1046 | name: session_channel_info 1047 | required: true 1048 | schema: 1049 | type: object 1050 | properties: 1051 | session_channel_id: 1052 | type: string 1053 | example: =bw52O 1054 | description: 临时讨论组 id 1055 | kick_uid: 1056 | type: string 1057 | example: =bw52O 1058 | description: 移除用户 id 1059 | required: 1060 | - session_channel_id 1061 | - kick_uid 1062 | /session_channel.kickout: 1063 | post: 1064 | tags: 1065 | - session channel 1066 | description: | 1067 | 移除一个临时讨论组成员。 1068 | responses: 1069 | '204': 1070 | description: request success 1071 | schema: 1072 | $ref: '#/definitions/NoContent' 1073 | default: 1074 | description: request fail 1075 | schema: 1076 | $ref: '#/definitions/Error' 1077 | parameters: 1078 | - in: body 1079 | name: session_channel_info 1080 | required: true 1081 | schema: 1082 | type: object 1083 | properties: 1084 | session_channel_id: 1085 | type: string 1086 | example: =bw52O 1087 | description: 临时讨论组 id 1088 | kick_uid: 1089 | type: string 1090 | example: =bw52O 1091 | description: 移除用户 id 1092 | required: 1093 | - session_channel_id 1094 | - kick_uid 1095 | /p2p.info: 1096 | get: 1097 | tags: 1098 | - p2p 1099 | description: | 1100 | 返回一个 P2P 聊天会话的完整信息。 1101 | responses: 1102 | '200': 1103 | description: request success 1104 | schema: 1105 | $ref: '#/definitions/P2PChannel' 1106 | examples: 1107 | p2p response: | 1108 | { 1109 | "id": "=bw52O", 1110 | "team_id": "=bw52O", 1111 | "vchannel_id": "=bw52O", 1112 | "type": "p2p", 1113 | "is_active": true, 1114 | "is_member": true, 1115 | "member_uids": [ 1116 | "=bw52O", 1117 | "=bw52P" 1118 | ], 1119 | "latest_ts": 1485238998284 1120 | } 1121 | default: 1122 | description: request fail 1123 | schema: 1124 | $ref: '#/definitions/Error' 1125 | parameters: 1126 | - name: p2p_channel_id 1127 | in: query 1128 | description: P2P 聊天会话 id, 例如\"=bw52O\" 1129 | required: true 1130 | type: string 1131 | /p2p.list: 1132 | get: 1133 | tags: 1134 | - p2p 1135 | description: | 1136 | 返回 P2P 聊天会话列表,获取某个 P2P 会话的完整信息,请使用 `p2p.info`. 1137 | responses: 1138 | '200': 1139 | description: request success 1140 | schema: 1141 | type: array 1142 | items: 1143 | $ref: '#/definitions/P2PChannel' 1144 | examples: 1145 | p2p list response: | 1146 | [ 1147 | { 1148 | "id": "=bw52O", 1149 | "team_id": "=bw52O", 1150 | "vchannel_id": "=bw52O", 1151 | "type": "p2p", 1152 | "is_active": true, 1153 | "is_member": true, 1154 | "member_uids": [ 1155 | "=bw52O", 1156 | "=bw52P" 1157 | ], 1158 | "latest_ts": 1485238998284 1159 | } 1160 | ] 1161 | default: 1162 | description: request fail 1163 | schema: 1164 | $ref: '#/definitions/Error' 1165 | /p2p.create: 1166 | post: 1167 | tags: 1168 | - p2p 1169 | description: | 1170 | 创建一个 P2P 聊天会话。 1171 | responses: 1172 | '201': 1173 | description: request success 1174 | schema: 1175 | $ref: '#/definitions/P2PChannel' 1176 | examples: 1177 | p2p response: | 1178 | { 1179 | "id": "=bw52O", 1180 | "team_id": "=bw52O", 1181 | "vchannel_id": "=bw52O", 1182 | "type": "p2p", 1183 | "is_active": true, 1184 | "is_member": true, 1185 | "member_uids": [ 1186 | "=bw52O", 1187 | "=bw52P" 1188 | ], 1189 | "latest_ts": 1485238998284 1190 | } 1191 | default: 1192 | description: request fail 1193 | schema: 1194 | $ref: '#/definitions/Error' 1195 | parameters: 1196 | - in: body 1197 | name: p2p_info 1198 | required: true 1199 | schema: 1200 | type: object 1201 | properties: 1202 | user_id: 1203 | type: string 1204 | example: =bw52O 1205 | description: P2P 聊天另外一方的用户 id 1206 | required: 1207 | - user_id 1208 | /message.query: 1209 | post: 1210 | tags: 1211 | - message 1212 | description: | 1213 | 查询指定 vchannel 下的消息列表。支持以下几种查询算法: 1214 | 1215 | ### `latest` 1216 | 1217 | 查询 vchannel 下最新的消息,支持参数: 1218 | 1219 | - `limit`: 查询数量限制,最大值为 100, 默认 20 1220 | 1221 | ### `since` 1222 | 1223 | 从指定位置开始拉取若干条消息,支持参数: 1224 | 1225 | - `key`: 开始位置的消息 key, 不可以和 `ts` 同时使用 1226 | - `ts`: 开始位置的消息 ts, 不可以和 `ts` 同时使用 1227 | - `forward`: 向前(时间发生方向)获取条数 1228 | - `backward`: 向后(时间发生方向)获取条数 1229 | 1230 | **注意**: 1231 | 1232 | 1. 使用 `key` 查询时,查询区间不包括 key 对应的消息 1233 | 2. 使用 `ts` 查询时,查询区间包括 ts 对应的消息 1234 | 3. `forward` / `backward` 参数可以同时使用 1235 | 4. `forward` / `backward` 参数最大值为 100, 1236 | 5. `forward` / `backward` 均未指定时,默认使用 `forward=100` 1237 | 1238 | ### `window` 1239 | 1240 | 拉取一定时间窗口内的消息,支持参数: 1241 | 1242 | - `from_key` / `to_key`: 窗口区间的消息 key 1243 | - `from_ts` / `to_ts`: 窗口区间的消息 ts 1244 | - `forward`: 从 from 方向往 to 方向取的消息数 1245 | - `backward`: 从 to 方向往 from 方向取的消息数 1246 | 1247 | **注意**: 1248 | 1249 | 1. `{from,to}_key` 和 `{from,to}_ts` 不可以混用 1250 | 2. 使用 `{from,to}_key` 查询时,查询区间不包括 key 对应的消息 1251 | 3. 使用 `{from,to}_ts` 查询时,查询区间包括 ts 对应的消息 1252 | 4. `forward` 和 `backward` 参数只能选其中一个 1253 | 5. `forward` / `backward` 均未指定时,默认使用 `forward=100` 1254 | 6. 如果查询区间开始值比结束值大,返回空结果 1255 | responses: 1256 | '200': 1257 | description: request success 1258 | schema: 1259 | $ref: '#/definitions/MessageQueryResult' 1260 | examples: 1261 | message query response: | 1262 | { 1263 | "messages": [ 1264 | { 1265 | "key": "1485236262366.0193", 1266 | "updated": "2017-01-24T13:37:42.000+0000", 1267 | "is_channel": false, 1268 | "uid": "=bw52O", 1269 | "fallback": null, 1270 | "attachments": [], 1271 | "created": "2017-01-24T13:37:42.000+0000", 1272 | "vchannel_id": "=bw52O", 1273 | "refer_key": null, 1274 | "robot_id": null, 1275 | "created_ts": 1485236262366, 1276 | "team_id": "=bw52O", 1277 | "subtype": "normal", 1278 | "text": "hello" 1279 | } 1280 | ] 1281 | } 1282 | default: 1283 | description: request fail 1284 | schema: 1285 | $ref: '#/definitions/Error' 1286 | parameters: 1287 | - in: body 1288 | name: message_info 1289 | required: true 1290 | schema: 1291 | type: object 1292 | properties: 1293 | vchannel_id: 1294 | type: string 1295 | example: =bw52O 1296 | description: 待查询 vchannel_id 1297 | query: 1298 | $ref: '#/definitions/MessageQuery' 1299 | required: 1300 | - vchannel_id 1301 | - query 1302 | /message.info: 1303 | get: 1304 | tags: 1305 | - message 1306 | description: | 1307 | 返回一条消息的信息。 1308 | responses: 1309 | '200': 1310 | description: request success 1311 | schema: 1312 | $ref: '#/definitions/Message' 1313 | examples: 1314 | message response: | 1315 | { 1316 | "key": "1485236262366.0193", 1317 | "updated": "2017-01-24T13:37:42.000+0000", 1318 | "is_channel": false, 1319 | "uid": "=bw52O", 1320 | "fallback": null, 1321 | "attachments": [], 1322 | "created": "2017-01-24T13:37:42.000+0000", 1323 | "vchannel_id": "=bw52O", 1324 | "refer_key": null, 1325 | "robot_id": null, 1326 | "created_ts": 1485236262366, 1327 | "team_id": "=bw52O", 1328 | "subtype": "normal", 1329 | "text": "hello" 1330 | } 1331 | default: 1332 | description: request fail 1333 | schema: 1334 | $ref: '#/definitions/Error' 1335 | parameters: 1336 | - name: vchannel_id 1337 | type: string 1338 | in: query 1339 | description: 指定的目标聊天会话 id,例如 \"=bw52O\" 1340 | required: true 1341 | - name: message_key 1342 | type: string 1343 | in: query 1344 | description: 获取消息的 key,例如 \"1487667236785.0077\" 1345 | required: true 1346 | /message.create: 1347 | post: 1348 | tags: 1349 | - message 1350 | description: | 1351 | 发送一条消息到指定聊天会话。 1352 | responses: 1353 | '201': 1354 | description: request success 1355 | schema: 1356 | $ref: '#/definitions/Message' 1357 | examples: 1358 | message response: | 1359 | { 1360 | "key": "1485236262366.0193", 1361 | "updated": "2017-01-24T13:37:42.000+0000", 1362 | "is_channel": false, 1363 | "uid": "=bw52O", 1364 | "fallback": null, 1365 | "attachments": [], 1366 | "created": "2017-01-24T13:37:42.000+0000", 1367 | "vchannel_id": "=bw52O", 1368 | "refer_key": null, 1369 | "robot_id": null, 1370 | "created_ts": 1485236262366, 1371 | "team_id": "=bw52O", 1372 | "subtype": "normal", 1373 | "text": "hello" 1374 | } 1375 | default: 1376 | description: request fail 1377 | schema: 1378 | $ref: '#/definitions/Error' 1379 | parameters: 1380 | - in: body 1381 | name: message_info 1382 | required: true 1383 | schema: 1384 | type: object 1385 | properties: 1386 | vchannel_id: 1387 | type: string 1388 | example: =bw52O 1389 | description: 指定的目标聊天会话 id 1390 | text: 1391 | type: string 1392 | example: 中午吃啥啊? 1393 | description: 消息内容 1394 | attachments: 1395 | type: array 1396 | example: 中午吃啥啊? 1397 | description: 消息附件 1398 | items: 1399 | $ref: '#/definitions/MessageAttachment' 1400 | required: 1401 | - vchannel_id 1402 | - text 1403 | /message.delete: 1404 | post: 1405 | tags: 1406 | - message 1407 | description: | 1408 | 删除一条消息。 1409 | responses: 1410 | '204': 1411 | description: request success 1412 | schema: 1413 | $ref: '#/definitions/NoContent' 1414 | default: 1415 | description: request fail 1416 | schema: 1417 | $ref: '#/definitions/Error' 1418 | parameters: 1419 | - in: body 1420 | name: message_info 1421 | required: true 1422 | schema: 1423 | type: object 1424 | properties: 1425 | vchannel_id: 1426 | type: string 1427 | example: =bw52O 1428 | description: 待查询 vchannel_id 1429 | message_key: 1430 | type: string 1431 | description: 删除的消息 key 1432 | example: '1487667236785.0077' 1433 | required: 1434 | - vchannel_id 1435 | - message_key 1436 | /message.update_text: 1437 | patch: 1438 | tags: 1439 | - message 1440 | description: | 1441 | 更新一条消息的内容。 1442 | responses: 1443 | '200': 1444 | description: request success 1445 | schema: 1446 | $ref: '#/definitions/Message' 1447 | examples: 1448 | message response: | 1449 | { 1450 | "key": "1485236262366.0193", 1451 | "updated": "2017-01-24T13:37:42.000+0000", 1452 | "is_channel": false, 1453 | "uid": "=bw52O", 1454 | "fallback": null, 1455 | "attachments": [], 1456 | "created": "2017-01-24T13:37:42.000+0000", 1457 | "vchannel_id": "=bw52O", 1458 | "refer_key": null, 1459 | "robot_id": null, 1460 | "created_ts": 1485236262366, 1461 | "team_id": "=bw52O", 1462 | "subtype": "normal", 1463 | "text": "hello" 1464 | } 1465 | default: 1466 | description: request fail 1467 | schema: 1468 | $ref: '#/definitions/Error' 1469 | parameters: 1470 | - in: body 1471 | name: message_info 1472 | required: true 1473 | schema: 1474 | type: object 1475 | properties: 1476 | vchannel_id: 1477 | type: string 1478 | example: =bw52O 1479 | description: 待查询 vchannel_id 1480 | message_key: 1481 | type: string 1482 | description: 更新的消息 key 1483 | example: '1487667236785.0077' 1484 | text: 1485 | type: string 1486 | description: 更新的消息内容 1487 | example: 中午吃啥啊? 1488 | required: 1489 | - vchannel_id 1490 | - message_key 1491 | - text 1492 | /message.forward: 1493 | post: 1494 | tags: 1495 | - message 1496 | description: | 1497 | 转发消息 1498 | responses: 1499 | '200': 1500 | description: request success 1501 | schema: 1502 | $ref: '#/definitions/MessageForward' 1503 | examples: 1504 | message response: | 1505 | { 1506 | "repost": { 1507 | "uid": "=bw52T", 1508 | "vchannel_id": "=bw52O", 1509 | "robot_id": null, 1510 | "created_ts": 1539056624039, 1511 | "message_key": "1539056624039.0143", 1512 | "id": "=bw52Q", 1513 | "team_id": "=bw52U", 1514 | "subtype": "normal", 1515 | "text": "当测不测,反受其乱" 1516 | }, 1517 | "key": "1539079267590.0001", 1518 | "updated": "2018-10-09T10:01:08.000+0000", 1519 | "is_channel": true, 1520 | "uid": "=bw52W", 1521 | "thread_key": null, 1522 | "created": "2018-10-09T10:01:08.000+0000", 1523 | "vchannel_id": "=bw52O", 1524 | "refer_key": null, 1525 | "robot_id": null, 1526 | "edited": false, 1527 | "created_ts": 1539079267590, 1528 | "pin_id": null, 1529 | "id": "=bw52Z", 1530 | "team_id": "=bw52U", 1531 | "text_i18n": { 1532 | "zh-CN": "转发了消息", 1533 | "en": "fowarded message" 1534 | }, 1535 | "reactions": [], 1536 | "subtype": "forwarded", 1537 | "text": "转发了消息" 1538 | } 1539 | default: 1540 | description: request fail 1541 | schema: 1542 | $ref: '#/definitions/Error' 1543 | parameters: 1544 | - in: body 1545 | name: message_info 1546 | required: true 1547 | schema: 1548 | type: object 1549 | properties: 1550 | vchannel_id: 1551 | type: string 1552 | example: =bw52O 1553 | description: 转发的消息所在的位置 id 1554 | key: 1555 | type: string 1556 | description: 更新的消息 key 1557 | example: '1487667236785.0077' 1558 | to_vchannel_id: 1559 | type: string 1560 | example: =bw52O 1561 | description: 转发目的会话 id 1562 | required: 1563 | - vchannel_id 1564 | - key 1565 | - to_vchannel_id 1566 | /message_pin.list: 1567 | get: 1568 | tags: 1569 | - message_pin 1570 | description: | 1571 | 查询某个聊天会话的置顶消息列表 1572 | responses: 1573 | '200': 1574 | description: request success 1575 | schema: 1576 | type: array 1577 | items: 1578 | $ref: '#/definitions/MessagePin' 1579 | examples: 1580 | message-pin response: | 1581 | [ 1582 | { 1583 | "id": "=bw52T", 1584 | "team_id": "=bw52U", 1585 | "uid": "=bw52W", 1586 | "vchannel_id": "=bw52O", 1587 | "message_id": "=bw53a", 1588 | "message_key": "1539079277448.0002", 1589 | "created_at": "2018-10-10T09:48:55.000+0800", 1590 | "updated_at": "2018-10-10T09:48:55.000+0800", 1591 | "message": null 1592 | } 1593 | ] 1594 | default: 1595 | description: request fail 1596 | schema: 1597 | $ref: '#/definitions/Error' 1598 | parameters: 1599 | - name: vchannel_id 1600 | in: query 1601 | description: 讨论组 id, 例如 \"=bw52O\" 1602 | required: true 1603 | type: string 1604 | /message_pin.create: 1605 | post: 1606 | tags: 1607 | - message_pin 1608 | description: | 1609 | 置顶消息 1610 | responses: 1611 | '200': 1612 | description: request success 1613 | schema: 1614 | $ref: '#/definitions/MessagePin' 1615 | examples: 1616 | message_pin response: | 1617 | { 1618 | "id": "=bw52T", 1619 | "team_id": "=bw52U", 1620 | "uid": "=bw52W", 1621 | "vchannel_id": "=bw52O", 1622 | "message_id": "=bw53a", 1623 | "message_key": "1539079277448.0002", 1624 | "created_at": "2018-10-10T09:48:55.000+0800", 1625 | "updated_at": "2018-10-10T09:48:55.000+0800" 1626 | } 1627 | default: 1628 | description: request fail 1629 | schema: 1630 | $ref: '#/definitions/Error' 1631 | parameters: 1632 | - in: body 1633 | name: message_pin_info 1634 | required: true 1635 | schema: 1636 | type: object 1637 | properties: 1638 | vchannel_id: 1639 | type: string 1640 | example: =bw52O 1641 | description: 消息所在的频道 1642 | message_key: 1643 | type: string 1644 | description: 想要置顶的消息 key 1645 | example: '1487667236785.0077' 1646 | required: 1647 | - vchannel_id 1648 | - message_key 1649 | /message_pin.delete: 1650 | post: 1651 | tags: 1652 | - message_pin 1653 | description: | 1654 | 删除置顶消息 1655 | responses: 1656 | '200': 1657 | description: request success 1658 | schema: 1659 | $ref: '#/definitions/NoContent' 1660 | default: 1661 | description: request fail 1662 | schema: 1663 | $ref: '#/definitions/Error' 1664 | parameters: 1665 | - in: body 1666 | name: message_pin_info 1667 | required: true 1668 | schema: 1669 | type: object 1670 | properties: 1671 | vchannel_id: 1672 | type: string 1673 | example: =bw52O 1674 | description: 消息所在的频道 1675 | pin_id: 1676 | type: string 1677 | description: 置顶消息的 id 1678 | example: =bw52O 1679 | required: 1680 | - vchannel_id 1681 | - pin_id 1682 | 1683 | /reaction.create: 1684 | post: 1685 | tags: 1686 | - reaction 1687 | description: | 1688 | 创建消息 Reaction 1689 | responses: 1690 | '200': 1691 | description: request success 1692 | schema: 1693 | $ref: '#/definitions/MessageReaction' 1694 | examples: 1695 | reaction created response: | 1696 | { 1697 | "id": "=bw52Q", 1698 | "team_id": "=bw52R", 1699 | "uid": "=bw52S", 1700 | "message_id": "=bw52Q", 1701 | "message_key": "1540460114044.0100", 1702 | "reaction": ":smile:" 1703 | "created_ts": 1540461431018, 1704 | "created": "2018-10-25T09:57:11.000+0000", 1705 | "updated": "2018-10-25T09:57:11.000+0000" 1706 | } 1707 | default: 1708 | description: request fail 1709 | schema: 1710 | $ref: '#/definitions/Error' 1711 | parameters: 1712 | - in: body 1713 | name: reaction_create_info 1714 | required: true 1715 | schema: 1716 | type: object 1717 | properties: 1718 | vchannel_id: 1719 | type: string 1720 | example: =bw52O 1721 | description: 消息所在的频道 1722 | key: 1723 | type: string 1724 | description: 想要加 sticker 的 message 的 key 1725 | example: '1540460114044.0100' 1726 | reaction: 1727 | type: string 1728 | description: 想要添加的 reaction 名 1729 | example: ':smile:' 1730 | required: 1731 | - vchannel_id 1732 | - key 1733 | - reaction 1734 | 1735 | /reaction.delete: 1736 | post: 1737 | tags: 1738 | - reaction 1739 | description: | 1740 | 删除消息 reaction 1741 | responses: 1742 | '200': 1743 | description: request success 1744 | schema: 1745 | $ref: '#/definitions/NoContent' 1746 | default: 1747 | description: unexpected error 1748 | schema: 1749 | $ref: '#/definitions/Error' 1750 | parameters: 1751 | - in: body 1752 | name: reaction_delete_info 1753 | required: true 1754 | schema: 1755 | type: object 1756 | properties: 1757 | vchannel_id: 1758 | type: string 1759 | example: =bw52O 1760 | description: 消息所在的频道 1761 | key: 1762 | type: string 1763 | description: 想要删 sticker 的 message 的 key 1764 | example: '1540460114044.0100' 1765 | reaction: 1766 | type: string 1767 | description: 想要删除的 reaction 名 1768 | example: ':smile:' 1769 | required: 1770 | - vchannel_id 1771 | - key 1772 | - reaction 1773 | /emoji.list: 1774 | get: 1775 | tags: 1776 | - emoji & sticker 1777 | description: | 1778 | 返回团队内的自定义 emoji 列表 1779 | responses: 1780 | '200': 1781 | description: request success 1782 | schema: 1783 | type: array 1784 | items: 1785 | $ref: '#/definitions/Emoji' 1786 | examples: 1787 | emojis response: | 1788 | [ 1789 | { 1790 | "id": "=bw52O", 1791 | "uid": "=bw52O", 1792 | "team_id": "=bw52O", 1793 | "name": "hello", 1794 | "type": "emoji", 1795 | "created": "2017-03-13T13:54:16.000+0000", 1796 | "updated": "2017-03-13T13:54:16.000+0000", 1797 | "url": "http://example.com/1.jpg" 1798 | } 1799 | ] 1800 | default: 1801 | description: unexpected error 1802 | schema: 1803 | $ref: '#/definitions/Error' 1804 | /sticker.list: 1805 | get: 1806 | tags: 1807 | - emoji & sticker 1808 | description: | 1809 | 返回当前用户的自定义 sticker 列表 1810 | responses: 1811 | '200': 1812 | description: request success 1813 | schema: 1814 | type: array 1815 | items: 1816 | $ref: '#/definitions/StickerPack' 1817 | examples: 1818 | sticker packs response: | 1819 | [ 1820 | { 1821 | "pack": "黑白熊静态", 1822 | "stickers": [ 1823 | { 1824 | "url": "https://dn-bearychat.qbox.me/sticker-gif-20.gif", 1825 | "name": "累", 1826 | "width": 240, 1827 | "height": 240 1828 | } 1829 | ] 1830 | } 1831 | ] 1832 | default: 1833 | description: unexpected error 1834 | schema: 1835 | $ref: '#/definitions/Error' 1836 | /rtm.start: 1837 | post: 1838 | tags: 1839 | - rtm 1840 | description: | 1841 | 打开 RTM 连接会话 1842 | responses: 1843 | '200': 1844 | description: request success 1845 | schema: 1846 | $ref: '#/definitions/RTMStart' 1847 | examples: 1848 | rtm response: | 1849 | { 1850 | "ws_host": "wss://rtm.bearychat.com/nimbus/ws:xxx", 1851 | "user": { 1852 | "inactive": false, 1853 | "role": "normal", 1854 | "email": "support@bearyinnovative.com", 1855 | "name": "BearyBot", 1856 | "type": "assistant", 1857 | "created": "2017-01-11T12:28:31.000+0000", 1858 | "id": "=bwMkR", 1859 | "avatars": { 1860 | "small": null, 1861 | "medium": null, 1862 | "large": null 1863 | }, 1864 | "team_id": "=bw52O", 1865 | "full_name": "倍洽小助手", 1866 | "mobile": null, 1867 | "profile": { 1868 | "bio": null, 1869 | "position": null, 1870 | "skype": null 1871 | } 1872 | } 1873 | } 1874 | default: 1875 | description: request fail 1876 | schema: 1877 | $ref: '#/definitions/Error' 1878 | definitions: 1879 | VChannelId: 1880 | description: 聊天会话 id 1881 | type: string 1882 | VChannelType: 1883 | description: 聊天会话类型 1884 | type: string 1885 | enum: 1886 | - normal 1887 | - session 1888 | - p2p 1889 | Meta: 1890 | required: 1891 | - version 1892 | properties: 1893 | version: 1894 | description: 当前 api 版本 1895 | type: string 1896 | Team: 1897 | required: 1898 | - id 1899 | - subdomain 1900 | - name 1901 | - email_domain 1902 | - logo_url 1903 | - description 1904 | - plan 1905 | - created 1906 | properties: 1907 | id: 1908 | $ref: '#/definitions/ResponseObjectId' 1909 | subdomain: 1910 | description: 团队 subdomain 1911 | type: string 1912 | name: 1913 | description: 团队名称 1914 | type: string 1915 | email_domain: 1916 | description: 团队邮箱域名 1917 | type: string 1918 | logo_url: 1919 | description: 团队头像地址 1920 | type: string 1921 | description: 1922 | description: 团队简介 1923 | type: string 1924 | plan: 1925 | $ref: '#/definitions/TeamPlan' 1926 | created: 1927 | description: 团队创建时间 1928 | type: string 1929 | format: data-time 1930 | TeamPlan: 1931 | type: string 1932 | enum: 1933 | - basic 1934 | - standard 1935 | User: 1936 | required: 1937 | - id 1938 | - team_id 1939 | - email 1940 | - mobile 1941 | - name 1942 | - full_name 1943 | - type 1944 | - role 1945 | - avatars 1946 | - profile 1947 | - inactive 1948 | - created 1949 | properties: 1950 | id: 1951 | $ref: '#/definitions/ResponseObjectId' 1952 | team_id: 1953 | $ref: '#/definitions/ResponseObjectId' 1954 | email: 1955 | description: 用户注册邮箱地址 1956 | type: string 1957 | format: email 1958 | mobile: 1959 | description: 用户注册手机号码 1960 | type: string 1961 | name: 1962 | description: 用户名 1963 | type: string 1964 | full_name: 1965 | description: 用户全名 1966 | type: string 1967 | type: 1968 | description: 用户类型 1969 | type: string 1970 | enum: 1971 | - normal 1972 | - assistant 1973 | - hubot 1974 | role: 1975 | description: 用户在团队内的身份 1976 | type: string 1977 | enum: 1978 | - owner 1979 | - admin 1980 | - normal 1981 | - visitor 1982 | avatars: 1983 | $ref: '#/definitions/UserAvatar' 1984 | profile: 1985 | $ref: '#/definitions/UserProfile' 1986 | inactive: 1987 | description: 用户是否已注销 1988 | type: boolean 1989 | created: 1990 | description: 用户加入时间 1991 | type: string 1992 | format: data-time 1993 | UserAvatar: 1994 | required: 1995 | - small 1996 | - medium 1997 | - large 1998 | properties: 1999 | small: 2000 | type: string 2001 | medium: 2002 | type: string 2003 | large: 2004 | type: string 2005 | UserProfile: 2006 | properties: 2007 | bio: 2008 | description: 用户个人简介 2009 | type: string 2010 | position: 2011 | description: 用户个人资料 2012 | type: string 2013 | skype: 2014 | description: 用户 skype 2015 | type: string 2016 | Channel: 2017 | required: 2018 | - id 2019 | - team_id 2020 | - uid 2021 | - vchannel_id 2022 | - name 2023 | - topic 2024 | - type 2025 | - general 2026 | - private 2027 | - is_active 2028 | - is_member 2029 | - member_uids 2030 | - latest_ts 2031 | properties: 2032 | id: 2033 | $ref: '#/definitions/ResponseObjectId' 2034 | team_id: 2035 | $ref: '#/definitions/ResponseObjectId' 2036 | uid: 2037 | $ref: '#/definitions/ResponseObjectId' 2038 | vchannel_id: 2039 | $ref: '#/definitions/VChannelId' 2040 | name: 2041 | description: 讨论组名称 2042 | type: string 2043 | topic: 2044 | description: 讨论组话题 2045 | type: string 2046 | type: 2047 | $ref: '#/definitions/VChannelType' 2048 | general: 2049 | description: 讨论组是否为`所有人`讨论组? 2050 | type: boolean 2051 | private: 2052 | description: 讨论组是否为私密讨论组? 2053 | type: boolean 2054 | is_active: 2055 | description: 会话是否有效 2056 | type: boolean 2057 | is_member: 2058 | description: 当前用户是否为讨论组成员? 2059 | type: boolean 2060 | member_uids: 2061 | description: 讨论组成员 id 列表 2062 | type: array 2063 | items: 2064 | $ref: '#/definitions/ResponseObjectId' 2065 | latest_ts: 2066 | description: 讨论组最新一条消息的 ts 2067 | type: integer 2068 | SessionChannel: 2069 | required: 2070 | - id 2071 | - team_id 2072 | - vchannel_id 2073 | - name 2074 | - type 2075 | - is_active 2076 | - is_member 2077 | - member_uids 2078 | - latest_ts 2079 | properties: 2080 | id: 2081 | $ref: '#/definitions/ResponseObjectId' 2082 | team_id: 2083 | $ref: '#/definitions/ResponseObjectId' 2084 | vchannel_id: 2085 | $ref: '#/definitions/VChannelId' 2086 | name: 2087 | description: 临时讨论组名称,如果为 null 则表示未设置名称 2088 | type: string 2089 | type: 2090 | $ref: '#/definitions/VChannelType' 2091 | is_active: 2092 | description: 会话是否有效 2093 | type: boolean 2094 | is_member: 2095 | description: 当前用户是否为临时讨论组成员? 2096 | type: boolean 2097 | member_uids: 2098 | description: 临时讨论组成员 id 列表 2099 | type: array 2100 | items: 2101 | $ref: '#/definitions/ResponseObjectId' 2102 | latest_ts: 2103 | description: 临时讨论组最新一条消息的 ts 2104 | type: integer 2105 | P2PChannel: 2106 | required: 2107 | - id 2108 | - team_id 2109 | - vchannel_id 2110 | - type 2111 | - is_active 2112 | - is_member 2113 | - member_uids 2114 | - latest_ts 2115 | properties: 2116 | id: 2117 | $ref: '#/definitions/ResponseObjectId' 2118 | team_id: 2119 | $ref: '#/definitions/ResponseObjectId' 2120 | vchannel_id: 2121 | $ref: '#/definitions/VChannelId' 2122 | type: 2123 | $ref: '#/definitions/VChannelType' 2124 | is_active: 2125 | description: 会话是否有效 2126 | type: boolean 2127 | is_member: 2128 | description: 当前用户是否为对话成员? 2129 | type: boolean 2130 | member_uids: 2131 | description: P2P 对话成员 id 列表 2132 | type: array 2133 | items: 2134 | $ref: '#/definitions/ResponseObjectId' 2135 | latest_ts: 2136 | description: P2P 对话最新一条消息的 ts 2137 | type: integer 2138 | MessageKey: 2139 | description: 消息唯一索引 key 2140 | type: string 2141 | MessageSubtype: 2142 | description: 消息类型 2143 | type: string 2144 | enum: 2145 | - normal 2146 | - info 2147 | MessageAttachment: 2148 | description: 消息附件 (TBD) 2149 | type: string 2150 | Message: 2151 | required: 2152 | - key 2153 | - team_id 2154 | - uid 2155 | - robot_id 2156 | - vchannel_id 2157 | - refer_key 2158 | - subtype 2159 | - text 2160 | - fallback 2161 | - attachments 2162 | - created 2163 | - created_ts 2164 | - updated 2165 | - is_channel 2166 | properties: 2167 | key: 2168 | $ref: '#/definitions/MessageKey' 2169 | team_id: 2170 | $ref: '#/definitions/ResponseObjectId' 2171 | uid: 2172 | $ref: '#/definitions/ResponseObjectId' 2173 | robot_id: 2174 | $ref: '#/definitions/ResponseObjectId' 2175 | vchannel_id: 2176 | $ref: '#/definitions/VChannelId' 2177 | refer_key: 2178 | $ref: '#/definitions/MessageKey' 2179 | subtype: 2180 | $ref: '#/definitions/MessageSubtype' 2181 | text: 2182 | description: 消息正文 2183 | type: string 2184 | fallback: 2185 | description: 消息提醒使用正文 2186 | type: string 2187 | attachments: 2188 | description: 消息附件 2189 | type: array 2190 | items: 2191 | $ref: '#/definitions/MessageAttachment' 2192 | created: 2193 | description: 消息创建时间 2194 | type: string 2195 | format: date-time 2196 | created_ts: 2197 | description: 消息创建时间戳 2198 | type: integer 2199 | format: int32 2200 | updated: 2201 | description: 消息最后修改时间 2202 | type: string 2203 | format: date-time 2204 | is_channel: 2205 | description: 消息是否为讨论组消息? 2206 | type: boolean 2207 | MessagePin: 2208 | description: 置顶消息 2209 | properties: 2210 | id: 2211 | $ref: '#/definitions/ResponseObjectId' 2212 | team_id: 2213 | $ref: '#/definitions/ResponseObjectId' 2214 | uid: 2215 | $ref: '#/definitions/ResponseObjectId' 2216 | vchannel_id: 2217 | $ref: '#/definitions/ResponseObjectId' 2218 | message_id: 2219 | $ref: '#/definitions/ResponseObjectId' 2220 | message_key: 2221 | $ref: '#/definitions/MessageKey' 2222 | created_at: 2223 | description: 创建时间 2224 | type: string 2225 | format: data-time 2226 | updated_at: 2227 | description: 更新时间 2228 | type: string 2229 | format: data-time 2230 | message: 2231 | description: 消息 2232 | type: string 2233 | MessageReaction: 2234 | description: | 2235 | 消息 Reaction 2236 | properties: 2237 | id: 2238 | $ref: '#/definitions/ResponseObjectId' 2239 | uid: 2240 | $ref: '#/definitions/ResponseObjectId' 2241 | team_id: 2242 | $ref: '#/definitions/ResponseObjectId' 2243 | message_id: 2244 | $ref: '#/definitions/ResponseObjectId' 2245 | message_key: 2246 | $ref: '#/definitions/MessageKey' 2247 | reaction: 2248 | description: reaction 名 2249 | type: string 2250 | created_ts: 2251 | description: 消息创建时间戳 2252 | type: integer 2253 | format: int32 2254 | created: 2255 | description: 创建时间 2256 | type: string 2257 | format: data-time 2258 | updated: 2259 | description: 更新时间 2260 | type: string 2261 | format: data-time 2262 | MessageQueryWindow: 2263 | description: | 2264 | 拉取一定时间窗口里面的消息 2265 | {from,to}_key / {from,to}_ts 不能混用,优先使用 {from,to}_key 对 2266 | from_{key,ts} to_{key,ts} 必须成对出现 2267 | 使用消息 key 查询的时候,查询区间为 (from_key, to_key) 2268 | 使用消息 ts 查询的时候,查询区间为 [from_ts, to_ts] 2269 | forward / backward 可选其一 2270 | 查询结果最多返回 100 条消息: 2271 | - forward / backward 最大值为 100 2272 | - 不指定 forward / backward 时,默认返回 forward=100 的消息记录 2273 | - 如果查询区间开始值比结束值大,返回空结果 2274 | properties: 2275 | form_key: 2276 | description: 区间开始的消息 `key` 2277 | type: string 2278 | to_key: 2279 | description: 区间结束的消息 `key` 2280 | type: string 2281 | from_ts: 2282 | description: 区间开始的消息时间戳 2283 | type: integer 2284 | format: int32 2285 | to_ts: 2286 | description: 区间结束的消息时间戳 2287 | type: integer 2288 | format: int32 2289 | forward: 2290 | description: 向前获取 n 条消息 2291 | type: integer 2292 | format: int32 2293 | backward: 2294 | description: 向后获取 n 条消息 2295 | type: integer 2296 | format: int32 2297 | MessageQuerySince: 2298 | description: | 2299 | 从指定位置开始拉取若干条消息 2300 | key / ts 不能混用,优先使用 key 2301 | forward / backward 可同时使用,默认为 forward=100 2302 | 使用消息 key 查询的时候,查询区间为 (key, +inf) / (-inf, key) 2303 | 使用消息 ts 查询的时候,查询区间为 [ts, +inf) / (-inf, ts] 2304 | forward / backward 可选其一 2305 | 查询结果最多返回 100 条消息: 2306 | - forward / backward 最大值为 100 2307 | - 不指定 forward / backward 时,默认返回 forward=100 的消息记录 2308 | - 如果同时使用 forward / backward 查询,返回消息保证 总数 <= forward + backward 2309 | properties: 2310 | key: 2311 | description: 指定位置的消息 `key` 2312 | type: string 2313 | ts: 2314 | description: 指定位置的消息时间戳 2315 | type: integer 2316 | format: int32 2317 | forward: 2318 | description: 向前获取 n 条消息 2319 | type: integer 2320 | format: int32 2321 | backward: 2322 | description: 向后获取 n 条消息 2323 | type: integer 2324 | format: int32 2325 | MessageQueryLatest: 2326 | description: | 2327 | 获取该 vchannel 下的最新消息列表 2328 | 查询结果最多返回 100 条消息: 2329 | - limit 最大值为 100 2330 | - 不指定 limit 时,limit 默认为 20 2331 | properties: 2332 | limit: 2333 | description: 获取 n 条消息 2334 | type: integer 2335 | format: int32 2336 | MessageQuery: 2337 | description: | 2338 | window / since / latest / thread 只能存在其中一种查询方法 2339 | 如果带有多种查询方法,则只以第一个方法为准 2340 | properties: 2341 | window: 2342 | $ref: '#/definitions/MessageQueryWindow' 2343 | since: 2344 | $ref: '#/definitions/MessageQuerySince' 2345 | latest: 2346 | $ref: '#/definitions/MessageQueryLatest' 2347 | MessageQueryResult: 2348 | required: 2349 | - messages 2350 | properties: 2351 | messages: 2352 | description: 查询到的消息列表 2353 | type: array 2354 | items: 2355 | $ref: '#/definitions/Message' 2356 | MessageForward: 2357 | properties: 2358 | repost: 2359 | $ref: '#/definitions/Message' 2360 | key: 2361 | description: 转发后的消息的 key 2362 | type: string 2363 | updated: 2364 | description: 更新时间 2365 | type: string 2366 | format: data-time 2367 | is_channel: 2368 | description: 是否为在群组内发送的消息 2369 | type: boolean 2370 | uid: 2371 | $ref: '#/definitions/ResponseObjectId' 2372 | thread_key: 2373 | description: 线程 key 2374 | type: string 2375 | created: 2376 | description: 创建时间 2377 | type: string 2378 | format: data-time 2379 | vchannel_id: 2380 | $ref: '#/definitions/ResponseObjectId' 2381 | refer_key: 2382 | description: 转发 key 2383 | type: string 2384 | robot_id: 2385 | $ref: '#/definitions/ResponseObjectId' 2386 | edited: 2387 | description: 是否修改过 2388 | type: boolean 2389 | created_ts: 2390 | description: 消息创建时间戳 2391 | type: integer 2392 | format: int32 2393 | RTMStart: 2394 | required: 2395 | - user 2396 | - ws_host 2397 | properties: 2398 | user: 2399 | $ref: '#/definitions/User' 2400 | ws_host: 2401 | description: rtm 连接地址 2402 | type: string 2403 | Emoji: 2404 | required: 2405 | - id 2406 | - uid 2407 | - team_id 2408 | - name 2409 | - type 2410 | - created 2411 | - updated 2412 | - url 2413 | properties: 2414 | id: 2415 | description: emoji id 2416 | type: string 2417 | uid: 2418 | description: 创建用户 id 2419 | type: string 2420 | team_id: 2421 | description: 所属团队 id 2422 | type: string 2423 | name: 2424 | description: 名称 2425 | type: string 2426 | type: 2427 | description: 资源类型 2428 | type: string 2429 | created: 2430 | description: 创建时间 2431 | type: string 2432 | format: date-time 2433 | updated: 2434 | description: 最后修改时间 2435 | type: string 2436 | format: date-time 2437 | url: 2438 | description: emoji url 2439 | Sticker: 2440 | required: 2441 | - url 2442 | - name 2443 | - width 2444 | - height 2445 | properties: 2446 | url: 2447 | description: sticker url 2448 | type: string 2449 | name: 2450 | description: 名称 2451 | type: string 2452 | width: 2453 | description: 图片宽度 2454 | type: integer 2455 | format: int32 2456 | height: 2457 | description: 图片高度 2458 | type: integer 2459 | format: int32 2460 | StickerPack: 2461 | description: 表情包 2462 | required: 2463 | - pack 2464 | - stickers 2465 | properties: 2466 | pack: 2467 | description: 表情包名称 2468 | type: string 2469 | stickers: 2470 | description: 包含的表情 2471 | type: array 2472 | items: 2473 | $ref: '#/definitions/Sticker' 2474 | Error: 2475 | required: 2476 | - code 2477 | - error 2478 | properties: 2479 | code: 2480 | $ref: '#/definitions/ResponseCode' 2481 | error: 2482 | $ref: '#/definitions/ResponseError' 2483 | NoContent: 2484 | description: NO CONTENT 2485 | TBD: 2486 | description: 待定义 2487 | type: string 2488 | ResponseObjectId: 2489 | type: string 2490 | ResponseCode: 2491 | type: integer 2492 | format: int32 2493 | ResponseError: 2494 | type: string 2495 | format: string 2496 | --------------------------------------------------------------------------------