forked from slack-go/slack
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add ParseEvent method to client * Add app_mention event * Refactor ParseEvent * parse outer and inner events; package in one * refactor parsing * Catch unmapped inner events * return errors * update comment * return errors; update test * return proper error * add events api example * s/ACollectionOfAtoms/nlopes/g * attempt to fix test * remove events.go * create slackevents packages; support more events; add test * add TokenComparator support * update example * update parsers_test.go * update example again * Rename function * fix example * Update readme * Update README.md additional changes to readme.
- Loading branch information
1 parent
6609ec0
commit 41bf61c
Showing
9 changed files
with
720 additions
and
3 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
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,46 @@ | ||
package main | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"fmt" | ||
"net/http" | ||
|
||
"github.com/nlopes/slack" | ||
"github.com/nlopes/slack/slackevents" | ||
) | ||
|
||
// You more than likely want your "Bot User OAuth Access Token" which starts with "xoxb-" | ||
var api = slack.New("TOKEN") | ||
|
||
func main() { | ||
http.HandleFunc("/events-endpoint", func(w http.ResponseWriter, r *http.Request) { | ||
buf := new(bytes.Buffer) | ||
buf.ReadFrom(r.Body) | ||
body := buf.String() | ||
eventsAPIEvent, e := slackevents.ParseEvent(json.RawMessage(body), slackevents.OptionVerifyToken(&slackevents.TokenComparator{"TOKEN"})) | ||
if e != nil { | ||
w.WriteHeader(http.StatusInternalServerError) | ||
} | ||
|
||
if eventsAPIEvent.Type == slackevents.URLVerification { | ||
var r *slackevents.ChallengeResponse | ||
err := json.Unmarshal([]byte(body), &r) | ||
if err != nil { | ||
w.WriteHeader(http.StatusInternalServerError) | ||
} | ||
w.Header().Set("Content-Type", "text") | ||
w.Write([]byte(r.Challenge)) | ||
} | ||
if eventsAPIEvent.Type == slackevents.CallbackEvent { | ||
postParams := slack.PostMessageParameters{} | ||
innerEvent := eventsAPIEvent.InnerEvent | ||
switch ev := innerEvent.Data.(type) { | ||
case *slackevents.AppMentionEvent: | ||
api.PostMessage(ev.Channel, "Yes, hello.", postParams) | ||
} | ||
} | ||
}) | ||
fmt.Println("[INFO] Server listening") | ||
http.ListenAndServe(":3000", nil) | ||
} |
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,97 @@ | ||
// inner_events.go provides EventsAPI particular inner events | ||
|
||
package slackevents | ||
|
||
import "encoding/json" | ||
|
||
// EventsAPIInnerEvent the inner event of a EventsAPI event_callback Event. | ||
type EventsAPIInnerEvent struct { | ||
Type string `json:"type"` | ||
Data interface{} | ||
} | ||
|
||
// AppMentionEvent is an (inner) EventsAPI subscribable event. | ||
type AppMentionEvent struct { | ||
Type string `json:"type"` | ||
User string `json:"user"` | ||
Text string `json:"text"` | ||
TimeStamp string `json:"ts"` | ||
Channel string `json:"channel"` | ||
EventTimeStamp json.Number `json:"event_ts"` | ||
} | ||
|
||
// AppUninstalledEvent Your Slack app was uninstalled. | ||
type AppUninstalledEvent struct { | ||
Type string `json:"type"` | ||
} | ||
|
||
// GridMigrationFinishedEvent An enterprise grid migration has finished on this workspace. | ||
type GridMigrationFinishedEvent struct { | ||
Type string `json:"type"` | ||
EnterpriseID string `json:"enterprise_id"` | ||
} | ||
|
||
// GridMigrationStartedEvent An enterprise grid migration has started on this workspace. | ||
type GridMigrationStartedEvent struct { | ||
Type string `json:"type"` | ||
EnterpriseID string `json:"enterprise_id"` | ||
} | ||
|
||
// LinkSharedEvent A message was posted containing one or more links relevant to your application | ||
type LinkSharedEvent struct { | ||
Type string `json:"type"` | ||
User string `json:"user"` | ||
TimeStamp string `json:"ts"` | ||
Channel string `json:"channel"` | ||
MessageTimeStamp json.Number `json:"message_ts"` | ||
Links []sharedLinks `json:"links"` | ||
} | ||
|
||
type sharedLinks struct { | ||
Domain string `json:"domain"` | ||
URL string `json:"url"` | ||
} | ||
|
||
// MessageEvent occurs when a variety of types of messages has been posted. | ||
// Parse ChannelType to see which | ||
// if ChannelType = "group", this is a private channel message | ||
// if ChannelType = "channel", this message was sent to a channel | ||
// if ChannelType = "im", this is a private message | ||
// if ChannelType = "mim", A message was posted in a multiparty direct message channel | ||
// TODO: Improve this so that it is not required to manually parse ChannelType | ||
type MessageEvent struct { | ||
Type string `json:"type"` | ||
User string `json:"user"` | ||
Text string `json:"text"` | ||
TimeStamp string `json:"ts"` | ||
Channel string `json:"channel"` | ||
ChannelType string `json:"channel_type"` | ||
EventTimeStamp json.Number `json:"event_ts"` | ||
} | ||
|
||
const ( | ||
// AppMention is an Events API subscribable event | ||
AppMention = "app_mention" | ||
// AppUninstalled Your Slack app was uninstalled. | ||
AppUninstalled = "app_uninstalled" | ||
// GridMigrationFinished An enterprise grid migration has finished on this workspace. | ||
GridMigrationFinished = "grid_migration_finished" | ||
// GridMigrationStarted An enterprise grid migration has started on this workspace. | ||
GridMigrationStarted = "grid_migration_started" | ||
// LinkShared A message was posted containing one or more links relevant to your application | ||
LinkShared = "link_shared" | ||
// Message A message was posted to a channel, private channel (group), im, or mim | ||
Message = "message" | ||
) | ||
|
||
// EventsAPIInnerEventMapping maps INNER Event API events to their corresponding struct | ||
// implementations. The structs should be instances of the unmarshalling | ||
// target for the matching event type. | ||
var EventsAPIInnerEventMapping = map[string]interface{}{ | ||
AppMention: AppMentionEvent{}, | ||
AppUninstalled: AppUninstalledEvent{}, | ||
GridMigrationFinished: GridMigrationFinishedEvent{}, | ||
GridMigrationStarted: GridMigrationStartedEvent{}, | ||
LinkShared: LinkSharedEvent{}, | ||
Message: MessageEvent{}, | ||
} |
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,117 @@ | ||
package slackevents | ||
|
||
import ( | ||
"encoding/json" | ||
"testing" | ||
) | ||
|
||
func TestAppMention(t *testing.T) { | ||
rawE := []byte(` | ||
{ | ||
"type": "app_mention", | ||
"user": "U061F7AUR", | ||
"text": "<@U0LAN0Z89> is it everything a river should be?", | ||
"ts": "1515449522.000016", | ||
"channel": "C0LAN2Q65", | ||
"event_ts": "1515449522000016" | ||
} | ||
`) | ||
err := json.Unmarshal(rawE, &AppMentionEvent{}) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
} | ||
|
||
func TestAppUninstalled(t *testing.T) { | ||
rawE := []byte(` | ||
{ | ||
"type": "app_uninstalled" | ||
} | ||
`) | ||
err := json.Unmarshal(rawE, &AppUninstalledEvent{}) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
} | ||
|
||
func TestGridMigrationFinishedEvent(t *testing.T) { | ||
rawE := []byte(` | ||
{ | ||
"type": "grid_migration_finished", | ||
"enterprise_id": "EXXXXXXXX" | ||
} | ||
`) | ||
err := json.Unmarshal(rawE, &GridMigrationFinishedEvent{}) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
} | ||
|
||
func TestGridMigrationStartedEvent(t *testing.T) { | ||
rawE := []byte(` | ||
{ | ||
"token": "XXYYZZ", | ||
"team_id": "TXXXXXXXX", | ||
"api_app_id": "AXXXXXXXXX", | ||
"event": { | ||
"type": "grid_migration_started", | ||
"enterprise_id": "EXXXXXXXX" | ||
}, | ||
"type": "event_callback", | ||
"event_id": "EvXXXXXXXX", | ||
"event_time": 1234567890 | ||
} | ||
`) | ||
err := json.Unmarshal(rawE, &GridMigrationStartedEvent{}) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
} | ||
|
||
func TestLinkSharedEvent(t *testing.T) { | ||
rawE := []byte(` | ||
{ | ||
"type": "link_shared", | ||
"channel": "Cxxxxxx", | ||
"user": "Uxxxxxxx", | ||
"message_ts": "123456789.9875", | ||
"links": | ||
[ | ||
{ | ||
"domain": "example.com", | ||
"url": "https://example.com/12345" | ||
}, | ||
{ | ||
"domain": "example.com", | ||
"url": "https://example.com/67890" | ||
}, | ||
{ | ||
"domain": "another-example.com", | ||
"url": "https://yet.another-example.com/v/abcde" | ||
} | ||
] | ||
} | ||
`) | ||
err := json.Unmarshal(rawE, &LinkSharedEvent{}) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
} | ||
|
||
func TestMessageEvent(t *testing.T) { | ||
rawE := []byte(` | ||
{ | ||
"type": "message", | ||
"channel": "G024BE91L", | ||
"user": "U2147483697", | ||
"text": "Live long and prospect.", | ||
"ts": "1355517523.000005", | ||
"event_ts": "1355517523.000005", | ||
"channel_type": "channel" | ||
} | ||
`) | ||
err := json.Unmarshal(rawE, &MessageEvent{}) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
} |
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,66 @@ | ||
// outer_events.go provides EventsAPI particular outer events | ||
|
||
package slackevents | ||
|
||
import ( | ||
"encoding/json" | ||
) | ||
|
||
// EventsAPIEvent is the base EventsAPIEvent | ||
type EventsAPIEvent struct { | ||
Token string `json:"token"` | ||
Type string `json:"type"` | ||
Data interface{} | ||
InnerEvent EventsAPIInnerEvent | ||
} | ||
|
||
// EventsAPIURLVerificationEvent recieved when configuring a EventsAPI driven app | ||
type EventsAPIURLVerificationEvent struct { | ||
Token string `json:"token"` | ||
Challenge string `json:"challenge"` | ||
Type string `json:"type"` | ||
} | ||
|
||
// ChallengeResponse is a response to a EventsAPIEvent URLVerification challenge | ||
type ChallengeResponse struct { | ||
Challenge string | ||
} | ||
|
||
// EventsAPICallbackEvent is the main (outer) EventsAPI event. | ||
type EventsAPICallbackEvent struct { | ||
Type string `json:"type"` | ||
Token string `json:"token"` | ||
TeamID string `json:"team_id"` | ||
APIAppID string `json:"api_app_id"` | ||
InnerEvent *json.RawMessage `json:"event"` | ||
AuthedUsers []string `json:"authed_users"` | ||
EventID string `json:"event_id"` | ||
EventTime int `json:"event_time"` | ||
} | ||
|
||
// EventsAPIAppRateLimited indicates your app's event subscriptions are being rate limited | ||
type EventsAPIAppRateLimited struct { | ||
Type string `json:"type"` | ||
Token string `json:"token"` | ||
TeamID string `json:"team_id"` | ||
MinuteRateLimited int `json:"minute_rate_limited"` | ||
APIAppID string `json:"api_app_id"` | ||
} | ||
|
||
const ( | ||
// CallbackEvent is the "outer" event of an EventsAPI event. | ||
CallbackEvent = "event_callback" | ||
// URLVerification is an event used when configuring your EventsAPI app | ||
URLVerification = "url_verification" | ||
// AppRateLimited indicates your app's event subscriptions are being rate limited | ||
AppRateLimited = "app_rate_limited" | ||
) | ||
|
||
// EventsAPIEventMap maps OUTTER Event API events to their corresponding struct | ||
// implementations. The structs should be instances of the unmarshalling | ||
// target for the matching event type. | ||
var EventsAPIEventMap = map[string]interface{}{ | ||
CallbackEvent: EventsAPICallbackEvent{}, | ||
URLVerification: EventsAPIURLVerificationEvent{}, | ||
AppRateLimited: EventsAPIAppRateLimited{}, | ||
} |
Oops, something went wrong.