mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-12-20 21:33:19 -06:00
Groundwork for send-to-device messaging
This commit is contained in:
parent
57841fc35e
commit
a90ea4c320
|
|
@ -14,6 +14,7 @@ package producers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/eduserver/api"
|
"github.com/matrix-org/dendrite/eduserver/api"
|
||||||
|
|
@ -52,3 +53,25 @@ func (p *EDUServerProducer) SendTyping(
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SendToDevice sends a typing event to EDU server
|
||||||
|
func (p *EDUServerProducer) SendToDevice(
|
||||||
|
ctx context.Context, userID, deviceID, eventType string,
|
||||||
|
message interface{},
|
||||||
|
) error {
|
||||||
|
js, err := json.Marshal(message)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
requestData := api.InputSendToDeviceEvent{
|
||||||
|
UserID: userID,
|
||||||
|
DeviceID: deviceID,
|
||||||
|
EventType: eventType,
|
||||||
|
Message: js,
|
||||||
|
}
|
||||||
|
request := api.InputSendToDeviceEventRequest{
|
||||||
|
InputSendToDeviceEvent: requestData,
|
||||||
|
}
|
||||||
|
response := api.InputSendToDeviceEventResponse{}
|
||||||
|
return p.InputAPI.InputSendToDeviceEvent(ctx, &request, &response)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -274,6 +274,17 @@ func Setup(
|
||||||
}),
|
}),
|
||||||
).Methods(http.MethodPut, http.MethodOptions)
|
).Methods(http.MethodPut, http.MethodOptions)
|
||||||
|
|
||||||
|
r0mux.Handle("/sendToDevice/{eventType}/{txnID}",
|
||||||
|
internal.MakeAuthAPI("send_to_device", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
|
||||||
|
vars, err := internal.URLDecodeMapValues(mux.Vars(req))
|
||||||
|
if err != nil {
|
||||||
|
return util.ErrorResponse(err)
|
||||||
|
}
|
||||||
|
txnID := vars["txnID"]
|
||||||
|
return SendToDevice(req, device, eduProducer, transactionsCache, vars["eventType"], &txnID)
|
||||||
|
}),
|
||||||
|
).Methods(http.MethodPut, http.MethodOptions)
|
||||||
|
|
||||||
r0mux.Handle("/account/whoami",
|
r0mux.Handle("/account/whoami",
|
||||||
internal.MakeAuthAPI("whoami", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
|
internal.MakeAuthAPI("whoami", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
|
||||||
return Whoami(req, device)
|
return Whoami(req, device)
|
||||||
|
|
|
||||||
66
clientapi/routing/sendtodevice.go
Normal file
66
clientapi/routing/sendtodevice.go
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package routing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
|
||||||
|
"github.com/matrix-org/dendrite/clientapi/httputil"
|
||||||
|
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||||
|
"github.com/matrix-org/dendrite/clientapi/producers"
|
||||||
|
"github.com/matrix-org/dendrite/internal/transactions"
|
||||||
|
"github.com/matrix-org/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SendToDevice handles PUT /_matrix/client/r0/sendToDevice/{eventType}/{txnId}
|
||||||
|
// sends the device events to the EDU Server
|
||||||
|
func SendToDevice(
|
||||||
|
req *http.Request, device *authtypes.Device,
|
||||||
|
eduProducer *producers.EDUServerProducer,
|
||||||
|
txnCache *transactions.Cache,
|
||||||
|
eventType string, txnID *string,
|
||||||
|
) util.JSONResponse {
|
||||||
|
if txnID != nil {
|
||||||
|
// Try to fetch response from transactionsCache
|
||||||
|
if res, ok := txnCache.FetchTransaction(device.AccessToken, *txnID); ok {
|
||||||
|
return *res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse the incoming http request
|
||||||
|
var httpReq struct {
|
||||||
|
Messages map[string]map[string]json.RawMessage `json:"messages"`
|
||||||
|
}
|
||||||
|
resErr := httputil.UnmarshalJSONRequest(req, &req)
|
||||||
|
if resErr != nil {
|
||||||
|
return *resErr
|
||||||
|
}
|
||||||
|
|
||||||
|
for userID, byUser := range httpReq.Messages {
|
||||||
|
for deviceID, message := range byUser {
|
||||||
|
if err := eduProducer.SendToDevice(
|
||||||
|
req.Context(), userID, deviceID, eventType, message,
|
||||||
|
); err != nil {
|
||||||
|
util.GetLogger(req.Context()).WithError(err).Error("eduProducer.SendToDevice failed")
|
||||||
|
return jsonerror.InternalServerError()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusOK,
|
||||||
|
JSON: struct{}{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -15,6 +15,7 @@ package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
|
@ -37,6 +38,17 @@ type InputTypingEvent struct {
|
||||||
OriginServerTS gomatrixserverlib.Timestamp `json:"origin_server_ts"`
|
OriginServerTS gomatrixserverlib.Timestamp `json:"origin_server_ts"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type InputSendToDeviceEvent struct {
|
||||||
|
// The user ID to send the update to.
|
||||||
|
UserID string `json:"user_id"`
|
||||||
|
// The device ID to send the update to.
|
||||||
|
DeviceID string `json:"device_id"`
|
||||||
|
// The type of the event.
|
||||||
|
EventType string `json:"event_type"`
|
||||||
|
// The contents of the message.
|
||||||
|
Message json.RawMessage `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
// InputTypingEventRequest is a request to EDUServerInputAPI
|
// InputTypingEventRequest is a request to EDUServerInputAPI
|
||||||
type InputTypingEventRequest struct {
|
type InputTypingEventRequest struct {
|
||||||
InputTypingEvent InputTypingEvent `json:"input_typing_event"`
|
InputTypingEvent InputTypingEvent `json:"input_typing_event"`
|
||||||
|
|
@ -45,6 +57,14 @@ type InputTypingEventRequest struct {
|
||||||
// InputTypingEventResponse is a response to InputTypingEvents
|
// InputTypingEventResponse is a response to InputTypingEvents
|
||||||
type InputTypingEventResponse struct{}
|
type InputTypingEventResponse struct{}
|
||||||
|
|
||||||
|
// InputSendToDeviceEventRequest is a request to EDUServerInputAPI
|
||||||
|
type InputSendToDeviceEventRequest struct {
|
||||||
|
InputSendToDeviceEvent InputSendToDeviceEvent `json:"input_send_to_device_event"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// InputSendToDeviceEventResponse is a response to InputSendToDeviceEventRequest
|
||||||
|
type InputSendToDeviceEventResponse struct{}
|
||||||
|
|
||||||
// EDUServerInputAPI is used to write events to the typing server.
|
// EDUServerInputAPI is used to write events to the typing server.
|
||||||
type EDUServerInputAPI interface {
|
type EDUServerInputAPI interface {
|
||||||
InputTypingEvent(
|
InputTypingEvent(
|
||||||
|
|
@ -52,11 +72,20 @@ type EDUServerInputAPI interface {
|
||||||
request *InputTypingEventRequest,
|
request *InputTypingEventRequest,
|
||||||
response *InputTypingEventResponse,
|
response *InputTypingEventResponse,
|
||||||
) error
|
) error
|
||||||
|
|
||||||
|
InputSendToDeviceEvent(
|
||||||
|
ctx context.Context,
|
||||||
|
request *InputSendToDeviceEventRequest,
|
||||||
|
response *InputSendToDeviceEventResponse,
|
||||||
|
) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// EDUServerInputTypingEventPath is the HTTP path for the InputTypingEvent API.
|
// EDUServerInputTypingEventPath is the HTTP path for the InputTypingEvent API.
|
||||||
const EDUServerInputTypingEventPath = "/eduserver/input"
|
const EDUServerInputTypingEventPath = "/eduserver/input"
|
||||||
|
|
||||||
|
// EDUServerInputSendToDeviceEventPath is the HTTP path for the InputSendToDeviceEvent API.
|
||||||
|
const EDUServerInputSendToDeviceEventPath = "/eduserver/sendToDevice"
|
||||||
|
|
||||||
// NewEDUServerInputAPIHTTP creates a EDUServerInputAPI implemented by talking to a HTTP POST API.
|
// NewEDUServerInputAPIHTTP creates a EDUServerInputAPI implemented by talking to a HTTP POST API.
|
||||||
func NewEDUServerInputAPIHTTP(eduServerURL string, httpClient *http.Client) (EDUServerInputAPI, error) {
|
func NewEDUServerInputAPIHTTP(eduServerURL string, httpClient *http.Client) (EDUServerInputAPI, error) {
|
||||||
if httpClient == nil {
|
if httpClient == nil {
|
||||||
|
|
@ -70,7 +99,7 @@ type httpEDUServerInputAPI struct {
|
||||||
httpClient *http.Client
|
httpClient *http.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
// InputRoomEvents implements EDUServerInputAPI
|
// InputTypingEvent implements EDUServerInputAPI
|
||||||
func (h *httpEDUServerInputAPI) InputTypingEvent(
|
func (h *httpEDUServerInputAPI) InputTypingEvent(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
request *InputTypingEventRequest,
|
request *InputTypingEventRequest,
|
||||||
|
|
@ -82,3 +111,16 @@ func (h *httpEDUServerInputAPI) InputTypingEvent(
|
||||||
apiURL := h.eduServerURL + EDUServerInputTypingEventPath
|
apiURL := h.eduServerURL + EDUServerInputTypingEventPath
|
||||||
return internalHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
return internalHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InputSendToDeviceEvent implements EDUServerInputAPI
|
||||||
|
func (h *httpEDUServerInputAPI) InputSendToDeviceEvent(
|
||||||
|
ctx context.Context,
|
||||||
|
request *InputSendToDeviceEventRequest,
|
||||||
|
response *InputSendToDeviceEventResponse,
|
||||||
|
) error {
|
||||||
|
span, ctx := opentracing.StartSpanFromContext(ctx, "InputSendToDeviceEvent")
|
||||||
|
defer span.Finish()
|
||||||
|
|
||||||
|
apiURL := h.eduServerURL + EDUServerInputSendToDeviceEventPath
|
||||||
|
return internalHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,10 @@
|
||||||
|
|
||||||
package api
|
package api
|
||||||
|
|
||||||
import "time"
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
// OutputTypingEvent is an entry in typing server output kafka log.
|
// OutputTypingEvent is an entry in typing server output kafka log.
|
||||||
// This contains the event with extra fields used to create 'm.typing' event
|
// This contains the event with extra fields used to create 'm.typing' event
|
||||||
|
|
@ -32,3 +35,13 @@ type TypingEvent struct {
|
||||||
UserID string `json:"user_id"`
|
UserID string `json:"user_id"`
|
||||||
Typing bool `json:"typing"`
|
Typing bool `json:"typing"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OutputTypingEvent is an entry in typing server output kafka log.
|
||||||
|
// This contains the event with extra fields used to create 'm.typing' event
|
||||||
|
// in clientapi & federation.
|
||||||
|
type OutputSendToDeviceEvent struct {
|
||||||
|
UserID string `json:"user_id"`
|
||||||
|
DeviceID string `json:"device_id"`
|
||||||
|
EventType string `json:"event_type"`
|
||||||
|
Message json.RawMessage `json:"message"`
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ func SetupEDUServerComponent(
|
||||||
Cache: eduCache,
|
Cache: eduCache,
|
||||||
Producer: base.KafkaProducer,
|
Producer: base.KafkaProducer,
|
||||||
OutputTypingEventTopic: string(base.Cfg.Kafka.Topics.OutputTypingEvent),
|
OutputTypingEventTopic: string(base.Cfg.Kafka.Topics.OutputTypingEvent),
|
||||||
|
OutputSendToDeviceEventTopic: string(base.Cfg.Kafka.Topics.OutputSendToDeviceEventTopic),
|
||||||
}
|
}
|
||||||
|
|
||||||
inputAPI.SetupHTTP(base.InternalAPIMux)
|
inputAPI.SetupHTTP(base.InternalAPIMux)
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,8 @@ type EDUServerInputAPI struct {
|
||||||
Cache *cache.EDUCache
|
Cache *cache.EDUCache
|
||||||
// The kafka topic to output new typing events to.
|
// The kafka topic to output new typing events to.
|
||||||
OutputTypingEventTopic string
|
OutputTypingEventTopic string
|
||||||
|
// The kafka topic to output new send to device events to.
|
||||||
|
OutputSendToDeviceEventTopic string
|
||||||
// kafka producer
|
// kafka producer
|
||||||
Producer sarama.SyncProducer
|
Producer sarama.SyncProducer
|
||||||
}
|
}
|
||||||
|
|
@ -54,10 +56,20 @@ func (t *EDUServerInputAPI) InputTypingEvent(
|
||||||
t.Cache.RemoveUser(ite.UserID, ite.RoomID)
|
t.Cache.RemoveUser(ite.UserID, ite.RoomID)
|
||||||
}
|
}
|
||||||
|
|
||||||
return t.sendEvent(ite)
|
return t.sendTypingEvent(ite)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *EDUServerInputAPI) sendEvent(ite *api.InputTypingEvent) error {
|
// InputTypingEvent implements api.EDUServerInputAPI
|
||||||
|
func (t *EDUServerInputAPI) InputSendToDeviceEvent(
|
||||||
|
ctx context.Context,
|
||||||
|
request *api.InputSendToDeviceEventRequest,
|
||||||
|
response *api.InputSendToDeviceEventResponse,
|
||||||
|
) error {
|
||||||
|
ise := &request.InputSendToDeviceEvent
|
||||||
|
return t.sendToDeviceEvent(ise)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *EDUServerInputAPI) sendTypingEvent(ite *api.InputTypingEvent) error {
|
||||||
ev := &api.TypingEvent{
|
ev := &api.TypingEvent{
|
||||||
Type: gomatrixserverlib.MTyping,
|
Type: gomatrixserverlib.MTyping,
|
||||||
RoomID: ite.RoomID,
|
RoomID: ite.RoomID,
|
||||||
|
|
@ -90,6 +102,29 @@ func (t *EDUServerInputAPI) sendEvent(ite *api.InputTypingEvent) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *EDUServerInputAPI) sendToDeviceEvent(ise *api.InputSendToDeviceEvent) error {
|
||||||
|
ote := &api.OutputSendToDeviceEvent{
|
||||||
|
UserID: ise.UserID,
|
||||||
|
DeviceID: ise.DeviceID,
|
||||||
|
EventType: ise.EventType,
|
||||||
|
Message: ise.Message,
|
||||||
|
}
|
||||||
|
|
||||||
|
eventJSON, err := json.Marshal(ote)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
m := &sarama.ProducerMessage{
|
||||||
|
Topic: string(t.OutputSendToDeviceEventTopic),
|
||||||
|
Key: sarama.StringEncoder(ote.UserID),
|
||||||
|
Value: sarama.ByteEncoder(eventJSON),
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _, err = t.Producer.SendMessage(m)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// SetupHTTP adds the EDUServerInputAPI handlers to the http.ServeMux.
|
// SetupHTTP adds the EDUServerInputAPI handlers to the http.ServeMux.
|
||||||
func (t *EDUServerInputAPI) SetupHTTP(internalAPIMux *mux.Router) {
|
func (t *EDUServerInputAPI) SetupHTTP(internalAPIMux *mux.Router) {
|
||||||
internalAPIMux.Handle(api.EDUServerInputTypingEventPath,
|
internalAPIMux.Handle(api.EDUServerInputTypingEventPath,
|
||||||
|
|
@ -105,4 +140,17 @@ func (t *EDUServerInputAPI) SetupHTTP(internalAPIMux *mux.Router) {
|
||||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
internalAPIMux.Handle(api.EDUServerInputSendToDeviceEventPath,
|
||||||
|
internal.MakeInternalAPI("inputSendToDeviceEvents", func(req *http.Request) util.JSONResponse {
|
||||||
|
var request api.InputSendToDeviceEventRequest
|
||||||
|
var response api.InputSendToDeviceEventResponse
|
||||||
|
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||||
|
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||||
|
}
|
||||||
|
if err := t.InputSendToDeviceEvent(req.Context(), &request, &response); err != nil {
|
||||||
|
return util.ErrorResponse(err)
|
||||||
|
}
|
||||||
|
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||||
|
}),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -265,6 +265,25 @@ func (t *txnReq) processEDUs(edus []gomatrixserverlib.EDU) {
|
||||||
if err := t.eduProducer.SendTyping(t.context, typingPayload.UserID, typingPayload.RoomID, typingPayload.Typing, 30*1000); err != nil {
|
if err := t.eduProducer.SendTyping(t.context, typingPayload.UserID, typingPayload.RoomID, typingPayload.Typing, 30*1000); err != nil {
|
||||||
util.GetLogger(t.context).WithError(err).Error("Failed to send typing event to edu server")
|
util.GetLogger(t.context).WithError(err).Error("Failed to send typing event to edu server")
|
||||||
}
|
}
|
||||||
|
case gomatrixserverlib.MDirectToDevice:
|
||||||
|
// https://matrix.org/docs/spec/server_server/r0.1.3#m-direct-to-device-schema
|
||||||
|
var directPayload struct {
|
||||||
|
Sender string `json:"sender"`
|
||||||
|
EventType string `json:"type"`
|
||||||
|
MessageID string `json:"message_id"`
|
||||||
|
Messages map[string]map[string]json.RawMessage `json:"message"`
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(e.Content, &directPayload); err != nil {
|
||||||
|
util.GetLogger(t.context).WithError(err).Error("Failed to unmarshal send-to-device events")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for userID, byUser := range directPayload.Messages {
|
||||||
|
for deviceID, message := range byUser {
|
||||||
|
if err := t.eduProducer.SendToDevice(t.context, userID, deviceID, directPayload.EventType, message); err != nil {
|
||||||
|
util.GetLogger(t.context).WithError(err).Error("Failed to send send-to-device event to edu server")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
util.GetLogger(t.context).WithField("type", e.Type).Warn("unhandled edu")
|
util.GetLogger(t.context).WithField("type", e.Type).Warn("unhandled edu")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,14 @@ func (p *testEDUProducer) InputTypingEvent(
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *testEDUProducer) InputSendToDeviceEvent(
|
||||||
|
ctx context.Context,
|
||||||
|
request *eduAPI.InputSendToDeviceEventRequest,
|
||||||
|
response *eduAPI.InputSendToDeviceEventResponse,
|
||||||
|
) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type testRoomserverAPI struct {
|
type testRoomserverAPI struct {
|
||||||
inputRoomEvents []api.InputRoomEvent
|
inputRoomEvents []api.InputRoomEvent
|
||||||
queryStateAfterEvents func(*api.QueryStateAfterEventsRequest) api.QueryStateAfterEventsResponse
|
queryStateAfterEvents func(*api.QueryStateAfterEventsRequest) api.QueryStateAfterEventsResponse
|
||||||
|
|
|
||||||
2
go.mod
2
go.mod
|
|
@ -18,7 +18,7 @@ require (
|
||||||
github.com/matrix-org/go-http-js-libp2p v0.0.0-20200518170932-783164aeeda4
|
github.com/matrix-org/go-http-js-libp2p v0.0.0-20200518170932-783164aeeda4
|
||||||
github.com/matrix-org/go-sqlite3-js v0.0.0-20200522092705-bc8506ccbcf3
|
github.com/matrix-org/go-sqlite3-js v0.0.0-20200522092705-bc8506ccbcf3
|
||||||
github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26
|
github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26
|
||||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20200521102632-2a81324a04ae
|
github.com/matrix-org/gomatrixserverlib v0.0.0-20200527122606-3151c3b2d2f2
|
||||||
github.com/matrix-org/naffka v0.0.0-20200422140631-181f1ee7401f
|
github.com/matrix-org/naffka v0.0.0-20200422140631-181f1ee7401f
|
||||||
github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7
|
github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7
|
||||||
github.com/mattn/go-sqlite3 v2.0.2+incompatible
|
github.com/mattn/go-sqlite3 v2.0.2+incompatible
|
||||||
|
|
|
||||||
2
go.sum
2
go.sum
|
|
@ -360,6 +360,8 @@ github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26 h1:Hr3zjRsq2bh
|
||||||
github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26/go.mod h1:3fxX6gUjWyI/2Bt7J1OLhpCzOfO/bB3AiX0cJtEKud0=
|
github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26/go.mod h1:3fxX6gUjWyI/2Bt7J1OLhpCzOfO/bB3AiX0cJtEKud0=
|
||||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20200521102632-2a81324a04ae h1:kFMh2aU3pMCkVCUeH57rtgm05XImbxKOHFYeUp80RCk=
|
github.com/matrix-org/gomatrixserverlib v0.0.0-20200521102632-2a81324a04ae h1:kFMh2aU3pMCkVCUeH57rtgm05XImbxKOHFYeUp80RCk=
|
||||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20200521102632-2a81324a04ae/go.mod h1:JsAzE1Ll3+gDWS9JSUHPJiiyAksvOOnGWF2nXdg4ZzU=
|
github.com/matrix-org/gomatrixserverlib v0.0.0-20200521102632-2a81324a04ae/go.mod h1:JsAzE1Ll3+gDWS9JSUHPJiiyAksvOOnGWF2nXdg4ZzU=
|
||||||
|
github.com/matrix-org/gomatrixserverlib v0.0.0-20200527122606-3151c3b2d2f2 h1:uwaQb5X4sf66lxcfUqPNbOU26dHYLyzrjNvKUqTwNgg=
|
||||||
|
github.com/matrix-org/gomatrixserverlib v0.0.0-20200527122606-3151c3b2d2f2/go.mod h1:JsAzE1Ll3+gDWS9JSUHPJiiyAksvOOnGWF2nXdg4ZzU=
|
||||||
github.com/matrix-org/naffka v0.0.0-20200422140631-181f1ee7401f h1:pRz4VTiRCO4zPlEMc3ESdUOcW4PXHH4Kj+YDz1XyE+Y=
|
github.com/matrix-org/naffka v0.0.0-20200422140631-181f1ee7401f h1:pRz4VTiRCO4zPlEMc3ESdUOcW4PXHH4Kj+YDz1XyE+Y=
|
||||||
github.com/matrix-org/naffka v0.0.0-20200422140631-181f1ee7401f/go.mod h1:y0oDTjZDv5SM9a2rp3bl+CU+bvTRINQsdb7YlDql5Go=
|
github.com/matrix-org/naffka v0.0.0-20200422140631-181f1ee7401f/go.mod h1:y0oDTjZDv5SM9a2rp3bl+CU+bvTRINQsdb7YlDql5Go=
|
||||||
github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7 h1:ntrLa/8xVzeSs8vHFHK25k0C+NV74sYMJnNSg5NoSRo=
|
github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7 h1:ntrLa/8xVzeSs8vHFHK25k0C+NV74sYMJnNSg5NoSRo=
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,8 @@ type Dendrite struct {
|
||||||
OutputClientData Topic `yaml:"output_client_data"`
|
OutputClientData Topic `yaml:"output_client_data"`
|
||||||
// Topic for eduserver/api.OutputTypingEvent events.
|
// Topic for eduserver/api.OutputTypingEvent events.
|
||||||
OutputTypingEvent Topic `yaml:"output_typing_event"`
|
OutputTypingEvent Topic `yaml:"output_typing_event"`
|
||||||
|
// Topic for eduserver/api.OutputSendToDeviceEvent events.
|
||||||
|
OutputSendToDeviceEventTopic Topic `yaml:"output_send_to_device_event"`
|
||||||
// Topic for user updates (profile, presence)
|
// Topic for user updates (profile, presence)
|
||||||
UserUpdates Topic `yaml:"user_updates"`
|
UserUpdates Topic `yaml:"user_updates"`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue