func (s *Slack) dumpRequest(req *http.Request) {
	if s.tracelog != nil {
		out, err := httputil.DumpRequestOut(req, true)
		if err == nil {
			s.tracef("%s\n", string(out))
		}
	}
}
dumpRequest dumps a request to the debug logger if it was defined
package slack
import (
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"net/http/httputil"
	"net/url"
	"strings"
	"sync"
	"time"
	"github.com/gorilla/websocket"
)
const (
	DefaultURL = "https://slack.com/api/"
)
type Error struct {
	ID     string `json:"id"`
	Detail string `json:"detail"`
}
func newError(code, format string, args ...interface{}) *Error {
	return &Error{code, fmt.Sprintf(format, args...)}
}
func (e *Error) Error() string {
	return fmt.Sprintf("%s: %s", e.ID, e.Detail)
}
var (
	ErrBadToken = &Error{"bad_token", "Bad token was provided to the API"}
	ErrNoToken = &Error{"no_token", "You must provide a Slack token to use the API"}
	ErrBadOAuth = &Error{"bad_oauth", "Bad OAuth credentials provided"}
)
type Slack struct {
	token    string           
	url      string           
	errorlog *log.Logger      
	tracelog *log.Logger      
	c        *http.Client     
	ws       *websocket.Conn  
	mid      int              
	mutex    sync.Mutex       
}
type OptionFunc func(*Slack) error
func (s *Slack) errorf(format string, args ...interface{}) {
	if s.errorlog != nil {
		s.errorlog.Printf(format, args...)
	}
}
func (s *Slack) tracef(format string, args ...interface{}) {
	if s.tracelog != nil {
		s.tracelog.Printf(format, args...)
	}
}
func New(options ...OptionFunc) (*Slack, error) {
	s := &Slack{
		url: "",
		c:   http.DefaultClient,
	}
	for _, option := range options {
		if err := option(s); err != nil {
			return nil, err
		}
	}
	if s.url == "" {
		s.url = DefaultURL
	}
	s.tracef("Using URL [%s]\n", s.url)
	if s.token == "" {
		s.errorf("%s\n", ErrNoToken.Error())
		return nil, ErrNoToken
	}
	return s, nil
}
func SetToken(token string) OptionFunc {
	return func(s *Slack) error {
		if token == "" {
			s.errorf("%s\n", ErrBadToken.Error())
			return ErrBadToken
		}
		s.token = token
		return nil
	}
}
func SetHTTPClient(httpClient *http.Client) OptionFunc {
	return func(s *Slack) error {
		if httpClient != nil {
			s.c = httpClient
		} else {
			s.c = http.DefaultClient
		}
		return nil
	}
}
func SetURL(rawurl string) OptionFunc {
	return func(s *Slack) error {
		if rawurl == "" {
			rawurl = DefaultURL
		}
		u, err := url.Parse(rawurl)
		if err != nil {
			e := newError("bad_url", "Invalid URL [%s] - %v\n", rawurl, err.Error())
			s.errorf("%s\n", e.Error())
			return e
		}
		if u.Scheme != "http" && u.Scheme != "https" {
			err = newError("bad_url", "Invalid schema specified [%s]", rawurl)
			s.errorf("%v", err)
			return err
		}
		s.url = rawurl
		if !strings.HasSuffix(s.url, "/") {
			s.url += "/"
		}
		return nil
	}
}
func SetErrorLog(logger *log.Logger) func(*Slack) error {
	return func(s *Slack) error {
		s.errorlog = logger
		return nil
	}
}
func SetTraceLog(logger *log.Logger) func(*Slack) error {
	return func(s *Slack) error {
		s.tracelog = logger
		return nil
	}
}