package module
Version: v0.0.0-...-cf13930 Latest Latest

This package is not in the latest version of its module.

Go to latest
Published: May 7, 2017 License: MIT Imports: 20 Imported by: 0



GoDoc MIT License

The Stack Exchange chat network does not provide an official API. This package aims to bridge that gap for Go applications by providing a simple interface with native Go primitives (channels, etc.).


As go-sechat grows, more and more chat functionality is exposed through the package. Here's a list of just some of the things go-sechat can do:

  • Run completely headless with no UI or embedded browser
  • Login using Stack Exchange credentials
  • Maintain a persistent connection to the chat server; reauthenticating, pausing, and reconnecting when a failure occurs
  • Join, create, leave, and invite users to rooms
  • Perform basic chat activities, such as posting and starring messages
  • Receive a stream of all events from rooms that have been joined
  • Intelligently retry failed messages when throttling occurs
  • Upload images to


To use the package in an application, simply import it:

import ""

Examples are provided in the package documentation.



Package go-sechat aims to bridge the gap between the Stack Exchange chat network and Go applications by providing a simple interface with native Go primitives.

Basic Usage

In order to make requests, create a `Conn` object:

c, err := sechat.New("", "passw0rd", 1)
if err != nil {
    // handle error
defer c.Close()

Since authentication and connection are done asynchronously, waiting for them to complete is highly recommended:

if c.WaitForConnected() {
    // do stuff

Interacting with Rooms

To join an additional room, use the `Join()` method:

// Join the Ask Ubuntu General Room (#201)
if err := c.Join(201); err != nil {
    // handle error

To leave, use the (appropriately named) `Leave()` method:

if err := c.Leave(201); err != nil {
    // handle error

To obtain a list of users in the room, use `UsersInRoom()`:

if users, err := c.UsersInRoom(201); err == nil {
    for _, u := range users {
        fmt.Printf("User: %s\n", u.Name)

To obtain a list of rooms that a user is in, use `User()`:

if user, err := c.User(1345); err == nil {
    for _, r := range user.Rooms {
        log.Printf("Room: %s\n", r.Name)

The `NewRoom()` method can be used to create new rooms:

r, err := c.NewRoom(
    "Room Name",
    "Room description",
    "",        // room host
    sechat.AccessReadWrite, // access
if err != nil {
    // handle error

In the example above, `r` is an `int` containing the ID of the new room that was created.

Receiving Events

To receive events from the chat server, simply receive from the `Events` channel in `Conn`:

for e := range c.Events {
    // e is of type *Event

Interacting with Messages

To post a message, simply invoke `Send()`:

if err := c.Send(201, "Testing go-sechat..."); err != nil {
    // handle error

If the message is in response to an earlier event, the `Reply()` method is also available:

if err := c.Reply(e, "Reply to event"); err != nil {
    // handle error

Uploading Images

To upload an image, prepare an `io.Reader` and pass it to `Image()`:

f, err := os.Open("/path/to/image.png")
if err != nil {
    // handle error
defer f.Close()
u, err := c.Image(f)
if err != nil {
    // handle error

In the example above, `u` is the URL of the newly uploaded image.



View Source
const (
	AccessReadWrite = "read-write"
	AccessReadOnly  = "read-only"
	AccessRequest   = "request"
View Source
const (
	EventMessagePosted           = 1
	EventMessageEdited           = 2
	EventUserJoined              = 3
	EventUserLeft                = 4
	EventRoomNameChanged         = 5
	EventMessageStarred          = 6
	EventDebugMessage            = 7
	EventUserMentioned           = 8
	EventMessageFlagged          = 9
	EventMessageDeleted          = 10
	EventFileAdded               = 11
	EventModeratorFlag           = 12
	EventUserSettingsChanged     = 13
	EventGlobalNotification      = 14
	EventAccessLevelChanged      = 15
	EventUserNotification        = 16
	EventInvitation              = 17
	EventMessageReply            = 18
	EventMessageMovedOut         = 19
	EventMessageMovedIn          = 20
	EventTimeBreak               = 21
	EventFeedTicker              = 22
	EventUserSuspended           = 29
	EventUserMerged              = 30
	EventUserNameOrAvatarChanged = 34


View Source
var (
	ErrNetworkFkey = errors.New("unable to find network fkey")
	ErrChatFkey    = errors.New("unable to find chat fkey")
	ErrChatUserID  = errors.New("unable to find user ID")
	ErrAuthURL     = errors.New("unable to find auth URL")
	ErrIncomplete  = errors.New("incomplete login (invalid credentials)")
View Source
var (
	ErrInvalidUserResponse = errors.New("invalid user response")
	ErrInvalidJavaScript   = errors.New("invalid JavaScript (no access to room)")
View Source
var ErrRoomID = errors.New("unable to find room ID")


This section is empty.


type Conn

type Conn struct {
	Events <-chan *Event
	// contains filtered or unexported fields

Conn represents a connection to the Stack Exchange chat network. HTTP requests are used to trigger actions and websockets are used for event notifications.

func New

func New(email, password string, room int) (*Conn, error)

New creates a new Conn instance.

func (*Conn) Close

func (c *Conn) Close()

Close disconnects the websocket and shuts down the connection.

func (*Conn) Image

func (c *Conn) Image(r io.Reader) (string, error)

Image uploads an image and returns its new URL.

func (*Conn) Invite

func (c *Conn) Invite(user, room int) error

Invite sends an invitation to a user inviting them to join a room.

func (*Conn) Join

func (c *Conn) Join(room int) error

Join listens for events in the specified room in addition to those already joined.

func (*Conn) Leave

func (c *Conn) Leave(room int) error

Leave stops listening for events in the specified room.

func (*Conn) NewRoom

func (c *Conn) NewRoom(name, description, host, defaultAccess string) (int, error)

NewRoom creates a new room with the specified parameters. defaultAccess should normally be set to AccessReadWrite.

func (*Conn) NewRoomWithUser

func (c *Conn) NewRoomWithUser(user int, name string) (int, error)

NewRoomWithUser creates a new room with the specified name and invites the specifed user to the new room. The ID of the new room is returned.

func (*Conn) Reply

func (c *Conn) Reply(e *Event, text string) error

Reply sends a reply for the specified event.

func (*Conn) Send

func (c *Conn) Send(room int, text string) error

Send posts the specified message to the specified room.

func (*Conn) Star

func (c *Conn) Star(message int) error

Star stars the specified message.

func (*Conn) User

func (c *Conn) User(user int) (*User, error)

User retrieves extended information for a specific user.

func (*Conn) UserID

func (c *Conn) UserID() int

UserID returns the chat ID of the current user.

func (*Conn) Users

func (c *Conn) Users(room int, users []int) ([]*User, error)

Users retrieves limited information for the specified users. Only the first few fields in the User struct are filled in.

func (*Conn) UsersInRoom

func (c *Conn) UsersInRoom(room int) ([]*User, error)

UsersInRoom retrieves a list of users in the specified room. Only the first few fields in the User struct are filled in.

func (*Conn) WaitForConnected

func (c *Conn) WaitForConnected() bool

WaitForConnected waits until authentication is complete and the websocket is connected.

type Event

type Event struct {
	Content      string `json:"content"`
	EventType    int    `json:"event_type"`
	ID           int    `json:"id"`
	MessageEdits int    `json:"message_edits"`
	MessageID    int    `json:"message_id"`
	MessageStars int    `json:"message_stars"`
	Moved        bool   `json:"moved"`
	ParentID     int    `json:"parent_id"`
	RoomID       int    `json:"room_id"`
	RoomName     string `json:"room_name"`
	ShowParent   bool   `json:"show_parent"`
	TargetUserID int    `json:"target_user_id"`
	TimeStamp    int    `json:"time_stamp"`
	UserID       int    `json:"user_id"`
	UserName     string `json:"user_name"`

	// A few additional values are precomputed to simplify analysis later on
	IsMention   bool
	TextContent string

Event represents an individual chat event received from the server. Note that not all event types use all members of this struct.

type InviteTarget

type InviteTarget struct {
	ID   int    `json:"id"`
	Name string `json:"name"`

InviteTarget describes a site that another user may be invited to.

type Room

type Room struct {
	ID       int    `json:"id"`
	Name     string `json:"name"`
	LastPost int    `json:"last_post"`
	Activity int    `json:"activity"`

Room provides information about a room that a user is currently present in.

type Site

type Site struct {
	Icon    string `json:"icon"`
	Caption string `json:"caption"`

Site describes a user's parent site.

type User

type User struct {
	ID           int     `json:"id"`
	Name         string  `json:"name"`
	EmailHash    string  `json:"email_hash"`
	Reputation   int     `json:"reputation"`
	IsModerator  bool    `json:"is_moderator"`
	IsOwner      bool    `json:"is_owner"`
	IsRegistered bool    `json:"is_registered"`
	LastPost     int     `json:"last_post"`
	LastSeen     int     `json:"last_seen"`
	Rooms        []*Room `json:"rooms"`
	UserMessage  string  `json:"user_message"`
	ProfileURL   string  `json:"profileUrl"`
	Site         *Site   `json:"site"`
	Host         string  `json:"host"`
	MayPairoff   bool    `json:"may_pairoff"`
	Issues       int     `json:"issues"`

User provides information about a chat user, such as their display name, moderator status, etc. Not every method that returns an instance of this type populates all fields.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL