aboutsummaryrefslogblamecommitdiff
path: root/connector/connector.go
blob: 38ce8282634f77531854f0e723980e2db40ad90b (plain) (tree)
1
2
3
4
5
6

                 



            







                                                                                      
 


                                                                                   
 


































                                                                                   
                                             
                                                              

                                                






















                                                                                     
                                                                     



                                                                                    






                                                                                      


                  
 









                                   




                                                                                  













                                                                                    
                   

                                        
                                 


                      
                          



                                                                                                                 
                          


                      

                    

                                                            



                            


                         
 


                                                                        

                                           
 


                                                               
 

                       
                  

                  
package connector

import (
	"io"
)

/*
	A generic connector framework for instant messaging protocols.

	Model:

	- A connector represents a connection to an outgoing service (IRC, XMPP, etc)
	  It satisfies a generic interface representing the actions that can be called
	  (send messages, join room, etc)

	- A handler represents a consumer of events happening on a connection
	  It satisfies a generic interface representing the events that can happend
	  (message received, rooms autojoined, etc)

	- A connector implements a given protocol that has an identifier
	  Each protocol identifier determines a namespace for user identifiers
	  and room identifiers which are globally unique for all connections using
	  this protocol.
	  For instance, a user can have two IRC conections to different servers.
	  Internally used user names and room identifiers must contain
	  the server name to be able to differentiate.
*/

type UserID string
type RoomID string

type Connector interface {
	// Set the handler that will receive events happening on this connection
	SetHandler(handler Handler)

	// Configure (or reconfigure) the connector and attempt to connect
	Configure(conf Configuration) error

	// Get the identifier of the protocol that is implemented by this connector
	Protocol() string

	// Get the user id of the connected user
	User() UserID

	// Set user information (nickname, picture, etc)
	SetUserInfo(info *UserInfo) error

	// Set room information (name, description, picture, etc)
	SetRoomInfo(roomId RoomID, info *RoomInfo) error

	// Try to join a channel
	// If no error happens, it must fire a Handler.Joined event
	Join(roomId RoomID) error

	// Try to invite someone to a channel
	// Or if roomId == "", just try adding them as friends
	Invite(user UserID, roomId RoomID) error

	// Leave a channel
	Leave(roomId RoomID)

	// Send an event
	Send(event *Event) error

	// Close the connection
	Close()
}

type Handler interface {
	// Called when a room was joined (automatically or by call to Connector.Join)
	Joined(roomId RoomID)

	// Called when the user left a room
	Left(roomId RoomID)

	// Called when a user's info is updated (changed their nickname, status, etc)
	// Can also be called with our own user ID when first loaded our user info
	UserInfoUpdated(user UserID, info *UserInfo)

	// Called when a room's info was updated,
	// or the first tome a room's info is retreived
	RoomInfoUpdated(roomId RoomID, author UserID, info *RoomInfo)

	// Called when an event occurs in a room
	// This must not be called for events authored by the user of the connection
	Event(event *Event)

	// These two functions enable the connector to access a simple key/value
	// database to cache some information in order not to generate useless events.
	// The connector should function when they are not implemented,
	// in which case CacheGet always returns ""
	CachePut(key string, value string)
	CacheGet(key string) string
}

type EventType int

const (
	EVENT_JOIN EventType = iota
	EVENT_LEAVE
	EVENT_MESSAGE
	EVENT_ACTION
)

type Event struct {
	Type EventType

	// If non-empty, the event Id is used to deduplicate events in a channel
	// This is usefull for backends that provide a backlog of channel messages
	// when (re-)joining a room
	Id string

	// UserID of the user that sent the event
	// If this is a direct message event, this event can only have been authored
	// by the user we are talking to (and not by ourself)
	Author UserID

	// UserID of the targetted user in the case of a direct message,
	// empty if targetting a room
	Recipient UserID

	// RoomID of the room where the event happenned or of the targetted room,
	// or empty string if it happenned by direct message
	Room RoomID

	// Message text or action text
	Text string

	// Attached files such as images
	Attachments []MediaObject
}

type UserInfo struct {
	DisplayName string

	// If non-empty, the Filename of the avatar object will be used by Easybridge
	// to deduplicate the update events and prevent needless reuploads.
	// Example strategy that works for the mattermost backend: use the update timestamp as fictious file name
	Avatar MediaObject
}

type RoomInfo struct {
	Name  string
	Topic string

	// Same deduplication comment as for UserInfo.Avatar
	Picture MediaObject
}

type MediaObject interface {
	Filename() string
	Size() int64
	Mimetype() string

	// Returns the size of an image if it is an image, otherwise nil
	ImageSize() *ImageSize

	// Read: must always be implemented
	Read() (io.ReadCloser, error)

	// URL(): not mandatory, may return an empty string
	// If so, Read() is the only way to retrieve the object
	URL() string
}

type ImageSize struct {
	Width  int
	Height int
}