forked from slack-go/slack
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement most of the API and a couple of tests
- Loading branch information
Showing
27 changed files
with
1,990 additions
and
233 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
*.test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
Copyright (c) 2015, Norberto Lopes | ||
All rights reserved. | ||
|
||
Redistribution and use in source and binary forms, with or without modification, | ||
are permitted provided that the following conditions are met: | ||
|
||
1. Redistributions of source code must retain the above copyright notice, this | ||
list of conditions and the following disclaimer. | ||
|
||
2. Redistributions in binary form must reproduce the above copyright notice, | ||
this list of conditions and the following disclaimer in the documentation and/or | ||
other materials provided with the distribution. | ||
|
||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR | ||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
Slack API in Go | ||
|
||
## Why? | ||
I am currently learning Go and this seemed like a good idea. | ||
|
||
## Stability | ||
As with any other piece of software expect bugs. Also, the design isn't finalized yet because I am not happy with how I laid out some things. Especially the websocket stuff. It is functional but very incomplete and buggy. | ||
|
||
## Help | ||
Anyone is welcome to contribute. Either open a PR or create an issue. | ||
|
||
## License | ||
BSD 2 Clause license |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
- Add more tests!!! | ||
- Add timeouts | ||
- Add examples | ||
- Fix the Websocket mess | ||
- Implement Upload File | ||
- Add support to have markdown hints | ||
- See section Message Formatting at https://api.slack.com/docs/formatting |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,256 @@ | ||
package slack | ||
|
||
import ( | ||
"errors" | ||
"net/url" | ||
"strconv" | ||
) | ||
|
||
type channelResponseFull struct { | ||
Channel Channel `json:"channel"` | ||
Channels []Channel `json:"channels"` | ||
Purpose string `json:"purpose"` | ||
Topic string `json:"topic"` | ||
NotInChannel bool `json:"not_in_channel"` | ||
History | ||
SlackResponse | ||
} | ||
|
||
type ChannelTopic struct { | ||
Value string `json:"value"` | ||
Creator string `json:"creator"` | ||
LastSet JSONTime `json:"last_set"` | ||
} | ||
|
||
type ChannelPurpose struct { | ||
Value string `json:"value"` | ||
Creator string `json:"creator"` | ||
LastSet JSONTime `json:"last_set"` | ||
} | ||
|
||
type Channel struct { | ||
Id string `json:"id"` | ||
Name string `json:"name"` | ||
IsChannel bool `json:"is_channel"` | ||
Created JSONTime `json:"created"` | ||
Creator string `json:"creator"` | ||
IsArchived bool `json:"is_archived"` | ||
IsGeneral bool `json:"is_general"` | ||
IsGroup bool `json:"is_group"` | ||
Members []string `json:"members"` | ||
Topic ChannelTopic `json:"topic"` | ||
Purpose ChannelPurpose `json:"purpose"` | ||
IsMember bool `json:"is_member"` | ||
LastRead string `json:"last_read,omitempty"` | ||
Latest Message `json:"latest,omitempty"` | ||
UnreadCount int `json:"unread_count,omitempty"` | ||
NumMembers int `json:"num_members,omitempty"` | ||
} | ||
|
||
func channelRequest(path string, values url.Values, debug bool) (*channelResponseFull, error) { | ||
response := &channelResponseFull{} | ||
err := ParseResponse(path, values, response, debug) | ||
if err != nil { | ||
return nil, err | ||
} | ||
if !response.Ok { | ||
return nil, errors.New(response.Error) | ||
} | ||
return response, nil | ||
} | ||
|
||
func (api *Slack) ArchiveChannel(channelId string) error { | ||
values := url.Values{ | ||
"token": {api.config.token}, | ||
"channel": {channelId}, | ||
} | ||
_, err := channelRequest("channels.archive", values, api.debug) | ||
if err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
func (api *Slack) UnarchiveChannel(channelId string) error { | ||
values := url.Values{ | ||
"token": {api.config.token}, | ||
"channel": {channelId}, | ||
} | ||
_, err := channelRequest("channels.unarchive", values, api.debug) | ||
if err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
func (api *Slack) CreateChannel(channel string) (*Channel, error) { | ||
values := url.Values{ | ||
"token": {api.config.token}, | ||
"name": {channel}, | ||
} | ||
response, err := channelRequest("channels.create", values, api.debug) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return &response.Channel, nil | ||
} | ||
|
||
func (api *Slack) GetChannelHistory(channelId string, params HistoryParameters) (*History, error) { | ||
values := url.Values{ | ||
"token": {api.config.token}, | ||
"channel": {channelId}, | ||
} | ||
if params.Latest != DEFAULT_HISTORY_LATEST { | ||
values.Add("latest", params.Latest) | ||
} | ||
if params.Oldest != DEFAULT_HISTORY_OLDEST { | ||
values.Add("oldest", params.Oldest) | ||
} | ||
if params.Count != DEFAULT_HISTORY_COUNT { | ||
values.Add("count", strconv.Itoa(params.Count)) | ||
} | ||
response, err := channelRequest("channels.history", values, api.debug) | ||
if err != nil { | ||
return nil, err | ||
} | ||
channelHistory := response.History | ||
return &channelHistory, nil | ||
} | ||
|
||
func (api *Slack) GetChannelInfo(channelId string) (*Channel, error) { | ||
values := url.Values{ | ||
"token": {api.config.token}, | ||
"channel": {channelId}, | ||
} | ||
response, err := channelRequest("channels.info", values, api.debug) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return &response.Channel, nil | ||
} | ||
|
||
func (api *Slack) InviteUserToChannel(channelId, userId string) (*Channel, error) { | ||
values := url.Values{ | ||
"token": {api.config.token}, | ||
"channel": {channelId}, | ||
"user": {userId}, | ||
} | ||
response, err := channelRequest("channels.invite", values, api.debug) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return &response.Channel, nil | ||
} | ||
|
||
func (api *Slack) JoinChannel(channel string) (*Channel, error) { | ||
values := url.Values{ | ||
"token": {api.config.token}, | ||
"name": {channel}, | ||
} | ||
response, err := channelRequest("channels.join", values, api.debug) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return &response.Channel, nil | ||
} | ||
|
||
func (api *Slack) LeaveChannel(channelId string) (bool, error) { | ||
values := url.Values{ | ||
"token": {api.config.token}, | ||
"channel": {channelId}, | ||
} | ||
response, err := channelRequest("channels.leave", values, api.debug) | ||
if err != nil { | ||
return false, err | ||
} | ||
if response.NotInChannel { | ||
return response.NotInChannel, nil | ||
} | ||
return false, nil | ||
} | ||
|
||
func (api *Slack) KickUserFromChannel(channelId, userId string) error { | ||
values := url.Values{ | ||
"token": {api.config.token}, | ||
"channel": {channelId}, | ||
"user": {userId}, | ||
} | ||
_, err := channelRequest("channels.kick", values, api.debug) | ||
if err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
func (api *Slack) GetChannels(excludeArchived bool) ([]Channel, error) { | ||
values := url.Values{ | ||
"token": {api.config.token}, | ||
} | ||
if excludeArchived { | ||
values.Add("exclude_archived", "1") | ||
} | ||
response, err := channelRequest("channels.list", values, api.debug) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return response.Channels, nil | ||
} | ||
|
||
/* Clients should try to avoid making this call too often. When needing to mark a read position, a client should set a | ||
timer before making the call. In this way, any further updates needed during the timeout will not generate extra calls | ||
(just one per channel). This is useful for when reading scroll-back history, or following a busy live channel. A | ||
timeout of 5 seconds is a good starting point. Be sure to flush these calls on shutdown/logout. */ | ||
func (api *Slack) SetChannelReadMark(channelId, ts string) error { | ||
values := url.Values{ | ||
"token": {api.config.token}, | ||
"channel": {channelId}, | ||
"ts": {ts}, | ||
} | ||
_, err := channelRequest("channels.mark", values, api.debug) | ||
if err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
func (api *Slack) RenameChannel(channelId, name string) (*Channel, error) { | ||
values := url.Values{ | ||
"token": {api.config.token}, | ||
"channel": {channelId}, | ||
"name": {name}, | ||
} | ||
// XXX: the created entry in this call returns a string instead of a number | ||
// so I may have to do some workaround to solve it. | ||
response, err := channelRequest("channels.rename", values, api.debug) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return &response.Channel, nil | ||
|
||
} | ||
|
||
func (api *Slack) SetChannelPurpose(channelId, purpose string) (string, error) { | ||
values := url.Values{ | ||
"token": {api.config.token}, | ||
"channel": {channelId}, | ||
"purpose": {purpose}, | ||
} | ||
response, err := channelRequest("channels.setPurpose", values, api.debug) | ||
if err != nil { | ||
return "", err | ||
} | ||
return response.Purpose, nil | ||
} | ||
|
||
func (api *Slack) SetChannelTopic(channelId, topic string) (string, error) { | ||
values := url.Values{ | ||
"token": {api.config.token}, | ||
"channel": {channelId}, | ||
"topic": {topic}, | ||
} | ||
response, err := channelRequest("channels.setTopic", values, api.debug) | ||
if err != nil { | ||
return "", err | ||
} | ||
return response.Topic, nil | ||
} |
Oops, something went wrong.