Added more lightweight API docs.
This commit is contained in:
parent
84da2d6a29
commit
871026b031
18
README.md
18
README.md
@ -62,7 +62,16 @@
|
|||||||
* [API](https://github.com/42wim/matterbridge/wiki/Features#api)
|
* [API](https://github.com/42wim/matterbridge/wiki/Features#api)
|
||||||
|
|
||||||
### API
|
### API
|
||||||
The API is very basic at the moment and rather undocumented.
|
The API is very basic at the moment. It uses the [Swagger/OpenAPI
|
||||||
|
specification](https://swagger.io/), and so will have documentation and
|
||||||
|
an interactive web interface accessible on your instance. To view it,
|
||||||
|
simply visit your own top level `/api` path or [view online][github-api-docs].
|
||||||
|
|
||||||
|
Note: The online API docs viewer won't be interactive.
|
||||||
|
|
||||||
|
[][github-api-docs]
|
||||||
|
|
||||||
|
[github-api-docs]: https://petstore.swagger.io/?url=https://raw.githubusercontent.com/42wim/matterbridge/master/docs/swagger/swagger.yaml
|
||||||
|
|
||||||
Used by at least 3 projects. Feel free to make a PR to add your project to this list.
|
Used by at least 3 projects. Feel free to make a PR to add your project to this list.
|
||||||
|
|
||||||
@ -112,6 +121,13 @@ $ ls bin/
|
|||||||
matterbridge
|
matterbridge
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The Swagger API documentation can be updated by editting
|
||||||
|
[`/docs/swagger/swagger.yaml`][api-yml]. This is simplest to do via the
|
||||||
|
hosted editor tool, into which you can [import our file][editor].
|
||||||
|
|
||||||
|
[api-yml]: docs/swagger/swagger.yaml
|
||||||
|
[editor]: https://raw.githubusercontent.com/42wim/matterbridge/master/docs/swagger/swagger.yaml
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
### Basic configuration
|
### Basic configuration
|
||||||
See [howto](https://github.com/42wim/matterbridge/wiki/How-to-create-your-config) for a step by step walkthrough for creating your configuration.
|
See [howto](https://github.com/42wim/matterbridge/wiki/How-to-create-your-config) for a step by step walkthrough for creating your configuration.
|
||||||
|
@ -2,7 +2,9 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -36,9 +38,31 @@ func New(cfg *bridge.Config) bridge.Bridger {
|
|||||||
if b.GetInt("Buffer") != 0 {
|
if b.GetInt("Buffer") != 0 {
|
||||||
b.Messages.SetCapacity(b.GetInt("Buffer"))
|
b.Messages.SetCapacity(b.GetInt("Buffer"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set up Swagger API docs and helpful redirects.
|
||||||
|
e.Pre(middleware.RemoveTrailingSlash())
|
||||||
|
e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
|
||||||
|
AllowOrigins: []string{"https://petstore.swagger.io", "http://petstore.swagger.io"},
|
||||||
|
}))
|
||||||
|
e.File("/swagger/docs.yaml", "docs/swagger/swagger.yaml")
|
||||||
|
for _, path := range strings.Fields("/ /api /swagger") {
|
||||||
|
e.GET(path, b.handleDocsRedirect)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up token auth with exclusions for non-sensitive endpoints and redirects.
|
||||||
if b.GetString("Token") != "" {
|
if b.GetString("Token") != "" {
|
||||||
e.Use(middleware.KeyAuth(func(key string, c echo.Context) (bool, error) {
|
e.Use(middleware.KeyAuthWithConfig(middleware.KeyAuthConfig{
|
||||||
|
Validator: func(key string, c echo.Context) (bool, error) {
|
||||||
return key == b.GetString("Token"), nil
|
return key == b.GetString("Token"), nil
|
||||||
|
},
|
||||||
|
Skipper: func(c echo.Context) bool {
|
||||||
|
for _, path := range strings.Fields("/ /api /api/health /swagger /swagger/*") {
|
||||||
|
if c.Path() == path {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
},
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
e.GET("/api/health", b.handleHealthcheck)
|
e.GET("/api/health", b.handleHealthcheck)
|
||||||
@ -58,13 +82,13 @@ func New(cfg *bridge.Config) bridge.Bridger {
|
|||||||
func (b *API) Connect() error {
|
func (b *API) Connect() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *API) Disconnect() error {
|
func (b *API) Disconnect() error {
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *API) JoinChannel(channel config.ChannelInfo) error {
|
func (b *API) JoinChannel(channel config.ChannelInfo) error {
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *API) Send(msg config.Message) (string, error) {
|
func (b *API) Send(msg config.Message) (string, error) {
|
||||||
@ -82,6 +106,17 @@ func (b *API) handleHealthcheck(c echo.Context) error {
|
|||||||
return c.String(http.StatusOK, "OK")
|
return c.String(http.StatusOK, "OK")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *API) handleDocsRedirect(c echo.Context) error {
|
||||||
|
host := c.Request().Host
|
||||||
|
scheme := c.Request().URL.Scheme
|
||||||
|
// Special-case where this is blank for localhost.
|
||||||
|
if scheme == "" {
|
||||||
|
scheme = "http"
|
||||||
|
}
|
||||||
|
urlTemplate := "https://petstore.swagger.io/?url=%s://%s/swagger/docs.yaml"
|
||||||
|
return c.Redirect(http.StatusMovedPermanently, fmt.Sprintf(urlTemplate, scheme, host))
|
||||||
|
}
|
||||||
|
|
||||||
func (b *API) handlePostMessage(c echo.Context) error {
|
func (b *API) handlePostMessage(c echo.Context) error {
|
||||||
message := config.Message{}
|
message := config.Message{}
|
||||||
if err := c.Bind(&message); err != nil {
|
if err := c.Bind(&message); err != nil {
|
||||||
|
BIN
docs/screenshot-swagger-api.png
Normal file
BIN
docs/screenshot-swagger-api.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 38 KiB |
127
docs/swagger/swagger.yaml
Normal file
127
docs/swagger/swagger.yaml
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
basePath: /api
|
||||||
|
definitions:
|
||||||
|
config.Message:
|
||||||
|
properties:
|
||||||
|
account:
|
||||||
|
description: Unique account name of format "[protocol].[slug]"
|
||||||
|
example: slack.myteam
|
||||||
|
type: string
|
||||||
|
avatar:
|
||||||
|
description: URL to an avatar image
|
||||||
|
example: https://secure.gravatar.com/avatar/1234567890abcdef1234567890abcdef.jpg
|
||||||
|
type: string
|
||||||
|
channel:
|
||||||
|
description: Human-readable channel name
|
||||||
|
example: test-channel
|
||||||
|
type: string
|
||||||
|
event:
|
||||||
|
description: Can be blank.
|
||||||
|
type: string
|
||||||
|
extra:
|
||||||
|
description: Extra data that doesn't fit in other fields. Used for processing
|
||||||
|
incoming messages.
|
||||||
|
type: object
|
||||||
|
gateway:
|
||||||
|
description: Name of the gateway
|
||||||
|
example: test-channel-gateway
|
||||||
|
type: string
|
||||||
|
id:
|
||||||
|
description: Unique ID of message on the gateway
|
||||||
|
example: slack 1541361213.030700
|
||||||
|
type: string
|
||||||
|
parent_id:
|
||||||
|
description: Unique ID of a parent message, if threaded
|
||||||
|
type: string
|
||||||
|
protocol:
|
||||||
|
description: Chat protocol of incoming message
|
||||||
|
example: slack
|
||||||
|
type: string
|
||||||
|
text:
|
||||||
|
description: Content of the message
|
||||||
|
example: Testing, testing, 1-2-3.
|
||||||
|
type: string
|
||||||
|
timestamp:
|
||||||
|
example: "1541361213.030700"
|
||||||
|
type: string
|
||||||
|
userid:
|
||||||
|
description: userid on the bridge
|
||||||
|
example: U4MCXJKNC
|
||||||
|
type: string
|
||||||
|
username:
|
||||||
|
description: Human-readable username
|
||||||
|
example: alice
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
info:
|
||||||
|
contact: {}
|
||||||
|
description: A read/write API for the Matterbridge chat bridge.
|
||||||
|
license:
|
||||||
|
name: Apache 2.0
|
||||||
|
url: https://github.com/42wim/matterbridge/blob/master/LICENSE
|
||||||
|
title: Matterbridge API
|
||||||
|
paths:
|
||||||
|
/health:
|
||||||
|
get:
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
summary: Checks if the server is alive.
|
||||||
|
/message:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 'Required fields: text, gateway. Optional fields: username, avatar.'
|
||||||
|
parameters:
|
||||||
|
- description: Message object to create
|
||||||
|
in: body
|
||||||
|
name: message
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/config.Message'
|
||||||
|
type: object
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/config.Message'
|
||||||
|
type: object
|
||||||
|
security:
|
||||||
|
- ApiKeyAuth: []
|
||||||
|
summary: Create/Update a message
|
||||||
|
/messages:
|
||||||
|
get:
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/config.Message'
|
||||||
|
type: array
|
||||||
|
security:
|
||||||
|
- ApiKeyAuth: []
|
||||||
|
summary: List new messages
|
||||||
|
/stream:
|
||||||
|
get:
|
||||||
|
produces:
|
||||||
|
- application/x-json-stream
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/config.Message'
|
||||||
|
type: object
|
||||||
|
security:
|
||||||
|
- ApiKeyAuth: []
|
||||||
|
summary: Stream realtime messages
|
||||||
|
securityDefinitions:
|
||||||
|
ApiKeyAuth:
|
||||||
|
in: header
|
||||||
|
name: Authorization
|
||||||
|
type: apiKey
|
||||||
|
swagger: "2.0"
|
Loading…
x
Reference in New Issue
Block a user