Skip to content

Commit

Permalink
Pull changes from upstream (#4)
Browse files Browse the repository at this point in the history
* Change ActionType to public

* Changed type of GetConversationsParameters.ExcludeArchived to bool instead of string.

* Make possible to get authorized user's profile providing empty userID to GetUserProfileContext

* Added coverage for audit API endpoint

* Added all of the other possible entity types for completeness

* Update audit.go

Just cleaning up a comment

* Changed field Ua to UA to better match Go standard

* Add support for "channel_created" in the Events API.

* add thread_ts to container

* restore go.mod and go.sum

* refact: missing attachement fields

* Make UserID optional in GetUserProfile()

`users.profile.get` API takes user parameter as optional.
https://api.slack.com/methods/users.profile.get

This change breaks GetUserProfile interface.
The current interface does not allow the bot to retrieve
its own user profile.

* Handle token_revoked event

This is a critical event and the client should stop trying to reconnect.

Signed-off-by: Andrea Barberio <insomniac@slackware.it>

* Add ReplyTo information to ack error events.

This allows clients to better handle ack errors by linking them
to the original outbound message.

* Make more examples directly runnable

* add the condition to the validation func for TextBlockObject

* Seems the token was missing from the request.

* Token is also added to URL parameters

* Update slackevents/inner_events.go

* Remove deprecated methods

Related issues:

- slack-go#748
- slack-go#876

More details:

- https://api.slack.com/changelog/2020-01-deprecating-antecedents-to-the-conversations-api

* slacktest: Save thread_ts to message

* Add timepicker to UnmarshalJSON

* Fix authorization on methods which uses get requests

* [socketmode] Add methods with passing context

- added socketmode.Client.RunContext
- added socketmode.Client.OpenContext
- changed socketmode.Client.openAndDial to pass context
- added test coverage for socketmode.Client.openAndDial
- added test coverage for socketmode.Client.RunContext
- added test coverage for socketmode.Client.OpenContext

* [socketmode] Use DialContext instead of Dial

* [socketmode] Graceful shutdown websocket.Conn

websocket connection freeze on conn.ReadJSON

- returned context errors to stop reconnect
- closed channel of messages when exit from Client.run
- closed websocket connection when context canceled

* [socketmode] mark test only for go 1.13 and higher

* [socketmode] fix typo in json tag

* Drop support of Go 1.12

* Remove travis badge

* Fix broken examples

* Add support for Go1.16

* [skip-ci] Replace badge

* feat: support response_urls field for view_submission payload

view_submission payload includes response_urls field when specific blocks have
a special parameter(response_url_enabled paramter = true).

See the following Slack docs for more details:

* https://api.slack.com/surfaces/modals/using#modal_response_url
* https://api.slack.com/reference/interaction-payloads/views#view_submission

* add missing token values

* added `external` data_source for dynamic data

`external` kind of input was missing in the slack api
but makes sense to pass this as option rather than separating into
two funcs; also makes sense to pass Optional as option but not hardcoded

* fix: renamed from dynamic to external for dialog input

* slacktest: Fix broken json if newline in text

* support team id param

* Trivial typo fix in the bug reporting template

* Updating audit.go 

Updated audit api code to use the updated getMethod w/ token function

* fix button sample

* fix limit url param

This should be "limit" not "count" according to the current
API docs: https://api.slack.com/admins/audit-logs#monitoring-workspace-events-with-the-audit-logs-api__how-to-call-the-audit-logs-api__audit-logs-endpoints

* Don't include secrets in url

* replace deprecated method

I believe this GetGroups was deleted as a part of this commit:
slack-go@9152ed0

* Rename the member socketmode.Client.apiClient to Client, and be an embedded structure for compatibility

* Fix path

* New events (WIP)

* New events (WIP)

* New events (WIP)

* fix block_context.go doc link

* New events (WIP)

* New events (WIP)

* Restore original paths

* Restore original intents

* Add test setup for Go1.17 environment to CI

* Add Enterprise property

* Fixed LinkSharedEvent and added context aware UnfurlMessage

The MessageTimeStamp was incorrectly marked as a number. It should be
a string as any other timestamp, and it required for Unfurl to work

* Revert conversion to string for now

* Add expires_in and refresh token handling

* Update users example with input examples

* Add Dispatch Action Config to InputBlock

* use pointer

* add TeamJoinEvent

* Update socketmode.go

* webhooks: add additional fields

no issue

These fields allow users to replace original messages sent by bots

eg first sending a ephemeral message and replacing it with one thats in-channel

* add message subType constants from https://api.slack.com/events/message

* Allow wrapping of error metadata. Addresses issue slack-go#939

* Support Rich Text blocks

* Update CHANGELOG.md

* Update bug report template

* fix: don't add API token as a query string in users.setPhoto method

resolve slack-go#992

* sometimes the message_ts isn't a json.Number

* add a new test with the payload from link_shared docs re: unfurls in the message composer

* add a comment for why MessageTimeStamp is a string, not json.Number

* [ci-skip] doc: guide to Slack channel

* [skip-ci] slacktest: fix license issue

Resolved: slack-go#625, slack-go#948, slack-go#979

* add socket mode example link to README

As mentioned in the documentation in https://api.slack.com/rtm:
"For most applications, Socket Mode is a better way to communicate with Slack."

(Personally I got confused between RTM and Socket Mode, and I think this might help future developers)

* Update README.md

* add empty line to be consistent

* add latest_reply property to Msg struct

* introduce workflow step app functionality

* tests for workflowStep added

* example workflowStep app added

* readme improved

* unused variable in example removed, switch line indention to tabulator

* using snake case for new directory and file

* Add refresh_token and token_type to OAuthV2Response fields

* all: add new //go:build lines

$ go version
go version go1.17.7 darwin/amd64

$ make fmt

Signed-off-by: Koichi Shiraishi <zchee.io@gmail.com>

* all: remove github.com/pkg/errors dependency

The github.com/pkg/errors package has been deprecated.

Signed-off-by: Koichi Shiraishi <zchee.io@gmail.com>

* vendor: run go mod vendor

Signed-off-by: Koichi Shiraishi <zchee.io@gmail.com>

* messageID: add benchmark for NewSafeID

Signed-off-by: Koichi Shiraishi <zchee.io@gmail.com>

* messageID: optimize NewSafeID using atomic instead of mutex lock

name                  old time/op    new time/op    delta
NewSafeID-20            13.9ns ± 2%     7.5ns ± 1%  -46.16%  (p=0.008 n=5+5)
NewSafeIDParallel-20    24.2ns ± 6%    22.1ns ± 1%   -9.06%  (p=0.008 n=5+5)

name                  old alloc/op   new alloc/op   delta
NewSafeID-20             0.00B          0.00B          ~     (all equal)
NewSafeIDParallel-20     8.00B ± 0%     8.00B ± 0%     ~     (all equal)

name                  old allocs/op  new allocs/op  delta
NewSafeID-20              0.00           0.00          ~     (all equal)
NewSafeIDParallel-20      1.00 ± 0%      1.00 ± 0%     ~     (all equal)

Signed-off-by: Koichi Shiraishi <zchee.io@gmail.com>

* messageID: add NewSafeID testcase

Signed-off-by: Koichi Shiraishi <zchee.io@gmail.com>

* switch go code style for imports from gofmt to goimports

* all: support pass context.Context to all methods

Signed-off-by: Koichi Shiraishi <zchee.io@gmail.com>

* webhooks: remove go1.12 support

Signed-off-by: Koichi Shiraishi <zchee.io@gmail.com>

* misc: use NewRequestWithContext

Signed-off-by: Koichi Shiraishi <zchee.io@gmail.com>

* misc: use http.MethodXXX constant

Signed-off-by: Koichi Shiraishi <zchee.io@gmail.com>

* messageID: fix atomic operation suggested by brainexe

name                  old time/op    new time/op    delta
NewSafeID-20            7.60ns ± 1%    5.93ns ± 1%  -21.97%  (p=0.008 n=5+5)
NewSafeIDParallel-20    21.0ns ± 1%    21.0ns ± 2%     ~     (p=0.952 n=5+5)

name                  old alloc/op   new alloc/op   delta
NewSafeID-20             0.00B          0.00B          ~     (all equal)
NewSafeIDParallel-20     8.00B ± 0%     8.00B ± 0%     ~     (all equal)

name                  old allocs/op  new allocs/op  delta
NewSafeID-20              0.00           0.00          ~     (all equal)
NewSafeIDParallel-20      1.00 ± 0%      1.00 ± 0%     ~     (all equal)

See also:
- slack-go#1035 (review)

Signed-off-by: Koichi Shiraishi <zchee.io@gmail.com>

* messageID: add documentation

Signed-off-by: Koichi Shiraishi <zchee.io@gmail.com>

* chat: add some BuildRequestContext methods for backwards compatibility

Signed-off-by: Koichi Shiraishi <zchee.io@gmail.com>

* webhook: remove unnecessary PostWebhookContextCustomHTTP function

Signed-off-by: Koichi Shiraishi <zchee.io@gmail.com>

* introduce workflow step app functionality

* tests for workflowStep added

* example workflowStep app added

* readme improved

* unused variable in example removed, switch line indention to tabulator

* using snake case for new directory and file

* switch go code style for imports from gofmt to goimports

* optimize slackutilsx.EscapeMessage function

* workflow_step: add SaveWorkflowStepConfigurationConetxt & fix return err

Signed-off-by: Koichi Shiraishi <zchee.io@gmail.com>

* workflow_step: fix typo on SaveWorkflowStepConfigurationContext

Signed-off-by: Koichi Shiraishi <zchee.io@gmail.com>

* github/workflow: drop go1.15 and add go1.18 (slack-go#1048)

* github/workflow: drop go1.15 and add go1.18

* all: run goimports

* WithStyle should be fluent

* Add a fluent WithConfirm for buttons

Co-authored-by: GLOFonseca <guilofonseca@gmail.com>
Co-authored-by: mzduke <support@raidboss.io>
Co-authored-by: Alexander Tunik <2braven@gmail.com>
Co-authored-by: Justin Judd <jbj@google.com>
Co-authored-by: Ward Vandewege <ward@jhvc.com>
Co-authored-by: Ian Hall <ihall@fanatics.com>
Co-authored-by: xnok <nokwebspace@gmail.com>
Co-authored-by: Takuya Kosugiyama <re@itkq.jp>
Co-authored-by: Andrea Barberio <insomniac@slackware.it>
Co-authored-by: Nolan Lum <nolan@nolm.name>
Co-authored-by: David Parsley <parsley@linuxjedi.org>
Co-authored-by: sryoya <sryoya0814@gmail.com>
Co-authored-by: Naoki Kanatani <k12naoki@gmail.com>
Co-authored-by: arran <a.ubels@base2services.com>
Co-authored-by: “Anton <a.kaymakchi@dodobrands.io>
Co-authored-by: Hiroshi Muraoka <h.muraoka714@gmail.com>
Co-authored-by: Aleksandr Kozlov <avlkozlov@avito.ru>
Co-authored-by: Evgeniy Kulikov <im@kulikov.im>
Co-authored-by: Takayuki WATANABE <takanabe.w@gmail.com>
Co-authored-by: Chris Lee <chris@delightroom.com>
Co-authored-by: Myroslav Gavryliak <efristical@gmail.com>
Co-authored-by: Daniel Metz <danielmmetz@gmail.com>
Co-authored-by: Justin Clift <jclift@dgitsystems.com>
Co-authored-by: Justin Judd <Justin@justinjudd.org>
Co-authored-by: sivchari <shibuuuu5@gmail.com>
Co-authored-by: Henry Foster <ahoy>
Co-authored-by: thorntonmc <mcthornton5@gmail.com>
Co-authored-by: Yoshio HANAWA <y@hnw.jp>
Co-authored-by: Valerian Saliou <valerian@valeriansaliou.name>
Co-authored-by: Pavel Lakosnikov <plakosnikov@avito.ru>
Co-authored-by: norabal <norabal.works@gmail.com>
Co-authored-by: Peter Kristensen <peter@ptx.dk>
Co-authored-by: Ryota <rytswd@gmail.com>
Co-authored-by: Karl-Johan Grahn <6355577+karl-johan-grahn@users.noreply.github.com>
Co-authored-by: Karl-Johan Grahn <Karl.Johan.Grahn@sinch.com>
Co-authored-by: Karl Keefer <karl@karlkeefer.com>
Co-authored-by: Rafael Almeida <rafaelcpalmeida@users.noreply.github.com>
Co-authored-by: James Loh <git@jloh.co>
Co-authored-by: Alexandre Bourget <alex@bourget.cc>
Co-authored-by: Chris Toshok <toshok@hound.sh>
Co-authored-by: Itay Donanhirsh <itay@bazoo.org>
Co-authored-by: amelia gapin <amelia@entirelyamelia.com>
Co-authored-by: Steffen Mahler <steffen.mahler@haendlerbund.de>
Co-authored-by: hidenami-i <shuhei.iwamoto.work@gmail.com>
Co-authored-by: Koichi Shiraishi <zchee.io@gmail.com>
Co-authored-by: Matthias Dötsch <matze@mdoetsch.de>
Co-authored-by: Leo Zhang <leo@leozhang.me>
  • Loading branch information
Show file tree
Hide file tree
Showing 112 changed files with 7,588 additions and 2,547 deletions.
6 changes: 5 additions & 1 deletion .github/ISSUE_TEMPLATE/bug_report.md
Expand Up @@ -3,12 +3,16 @@ name: Bug Report
about: Create a report to help us improve
---

### What happend
### What happened

### Expected behavior

### Steps to reproduce

#### reproducible code

#### manifest.yaml

### Versions
- Go:
- slack-go/slack:
31 changes: 15 additions & 16 deletions .github/workflows/test.yml
Expand Up @@ -7,31 +7,30 @@ on:
pull_request:

jobs:
ci:
runs-on: ubuntu-latest
name: lint
steps:
- uses: actions/checkout@v2
- name: golangci-lint
uses: golangci/golangci-lint-action@v2
with:
version: v1.32
test:
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
strategy:
matrix:
go:
- '1.12'
- '1.13'
- '1.14'
- '1.15'
- '1.16'
- '1.17'
- '1.18'
name: test go-${{ matrix.go }}
steps:
- uses: actions/checkout@v2
- uses: actions/setup-go@v2
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go }}
- name: run test
run: go test -v -race ./...
env:
GO111MODULE: on
lint:
runs-on: ubuntu-20.04
name: lint
steps:
- uses: actions/checkout@v3
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
version: latest
18 changes: 13 additions & 5 deletions README.md
@@ -1,8 +1,9 @@
Slack API in Go [![GoDoc](https://godoc.org/github.com/slack-go/slack?status.svg)](https://godoc.org/github.com/slack-go/slack) [![Build Status](https://travis-ci.org/slack-go/slack.svg)](https://travis-ci.org/slack-go/slack)
Slack API in Go [![Go Reference](https://pkg.go.dev/badge/github.com/slack-go/slack.svg)](https://pkg.go.dev/github.com/slack-go/slack)
===============
This is the original Slack library for Go created by Norberto Lopes, transferred to a Github organization.

[![Join the chat at https://gitter.im/go-slack/Lobby](https://badges.gitter.im/go-slack/Lobby.svg)](https://gitter.im/go-slack/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
This is the original Slack library for Go created by Norberto Lopes, transferred to a GitHub organization.

You can also chat with us on the #slack-go, #slack-go-ja Slack channel on the Gophers Slack.

![logo](logo.png "icon")

Expand All @@ -14,7 +15,7 @@ a fully managed way.
There is currently no major version released.
Therefore, minor version releases may include backward incompatible changes.

See [CHANGELOG.md](https://github.com/slack-go/slack/blob/master/CHANGELOG.md) for more information about the changes.
See [CHANGELOG.md](https://github.com/slack-go/slack/blob/master/CHANGELOG.md) or [Releases](https://github.com/slack-go/slack/releases) for more information about the changes.

## Installing

Expand All @@ -38,7 +39,7 @@ func main() {
// If you set debugging, it will log all requests to the console
// Useful when encountering issues
// slack.New("YOUR_TOKEN_HERE", slack.OptionDebug(true))
groups, err := api.GetGroups(false)
groups, err := api.GetUserGroups(false)
if err != nil {
fmt.Printf("%s\n", err)
return
Expand Down Expand Up @@ -69,8 +70,15 @@ func main() {
}
```

## Minimal Socket Mode usage:

See https://github.com/slack-go/slack/blob/master/examples/socketmode/socketmode.go


## Minimal RTM usage:

As mentioned in https://api.slack.com/rtm - for most applications, Socket Mode is a better way to communicate with Slack.

See https://github.com/slack-go/slack/blob/master/examples/websocket/websocket.go


Expand Down
7 changes: 5 additions & 2 deletions apps.go
Expand Up @@ -44,15 +44,18 @@ func (api *Client) ListEventAuthorizationsContext(ctx context.Context, eventCont
}

func (api *Client) UninstallApp(clientID, clientSecret string) error {
return api.UninstallAppContext(context.Background(), clientID, clientSecret)
}

func (api *Client) UninstallAppContext(ctx context.Context, clientID, clientSecret string) error {
values := url.Values{
"token": {api.token},
"client_id": {clientID},
"client_secret": {clientSecret},
}

response := SlackResponse{}

err := api.getMethod(context.Background(), "apps.uninstall", values, &response)
err := api.getMethod(ctx, "apps.uninstall", api.token, values, &response)
if err != nil {
return err
}
Expand Down
9 changes: 7 additions & 2 deletions attachments.go
Expand Up @@ -17,7 +17,7 @@ type AttachmentAction struct {
Name string `json:"name"` // Required.
Text string `json:"text"` // Required.
Style string `json:"style,omitempty"` // Optional. Allowed values: "default", "primary", "danger".
Type actionType `json:"type"` // Required. Must be set to "button" or "select".
Type ActionType `json:"type"` // Required. Must be set to "button" or "select".
Value string `json:"value,omitempty"` // Optional.
DataSource string `json:"data_source,omitempty"` // Optional.
MinQueryLength int `json:"min_query_length,omitempty"` // Optional. Default value is 1.
Expand All @@ -29,7 +29,7 @@ type AttachmentAction struct {
}

// actionType returns the type of the action
func (a AttachmentAction) actionType() actionType {
func (a AttachmentAction) actionType() ActionType {
return a.Type
}

Expand Down Expand Up @@ -80,6 +80,11 @@ type Attachment struct {
ImageURL string `json:"image_url,omitempty"`
ThumbURL string `json:"thumb_url,omitempty"`

ServiceName string `json:"service_name,omitempty"`
ServiceIcon string `json:"service_icon,omitempty"`
FromURL string `json:"from_url,omitempty"`
OriginalURL string `json:"original_url,omitempty"`

Fields []AttachmentField `json:"fields,omitempty"`
Actions []AttachmentAction `json:"actions,omitempty"`
MarkdownIn []string `json:"mrkdwn_in,omitempty"`
Expand Down
142 changes: 142 additions & 0 deletions audit.go
@@ -0,0 +1,142 @@
package slack

import (
"context"
"net/url"
"strconv"
)

type AuditLogResponse struct {
Entries []AuditEntry `json:"entries"`
SlackResponse
}

type AuditEntry struct {
ID string `json:"id"`
DateCreate int `json:"date_create"`
Action string `json:"action"`
Actor struct {
Type string `json:"type"`
User AuditUser `json:"user"`
} `json:"actor"`
Entity struct {
Type string `json:"type"`
// Only one of the below will be completed, based on the value of Type a user, a channel, a file, an app, a workspace, or an enterprise
User AuditUser `json:"user"`
Channel AuditChannel `json:"channel"`
File AuditFile `json:"file"`
App AuditApp `json:"app"`
Workspace AuditWorkspace `json:"workspace"`
Enterprise AuditEnterprise `json:"enterprise"`
} `json:"entity"`
Context struct {
Location struct {
Type string `json:"type"`
ID string `json:"id"`
Name string `json:"name"`
Domain string `json:"domain"`
} `json:"location"`
UA string `json:"ua"`
IPAddress string `json:"ip_address"`
} `json:"context"`
}

type AuditUser struct {
ID string `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
Team string `json:"team"`
}

type AuditChannel struct {
ID string `json:"id"`
Name string `json:"name"`
Privacy string `json:"privacy"`
IsShared bool `json:"is_shared"`
IsOrgShared bool `json:"is_org_shared"`
}

type AuditFile struct {
ID string `json:"id"`
Name string `json:"name"`
Filetype string `json:"filetype"`
Title string `json:"title"`
}

type AuditApp struct {
ID string `json:"id"`
Name string `json:"name"`
IsDistributed bool `json:"is_distributed"`
IsDirectoryApproved bool `json:"is_directory_approved"`
IsWorkflowApp bool `json:"is_workflow_app"`
Scopes []string `json:"scopes"`
}

type AuditWorkspace struct {
ID string `json:"id"`
Name string `json:"name"`
Domain string `json:"domain"`
}

type AuditEnterprise struct {
ID string `json:"id"`
Name string `json:"name"`
Domain string `json:"domain"`
}

// AuditLogParameters contains all the parameters necessary (including the optional ones) for a GetAuditLogs() request
type AuditLogParameters struct {
Limit int
Cursor string
Latest int
Oldest int
Action string
Actor string
Entity string
}

func (api *Client) auditLogsRequest(ctx context.Context, path string, values url.Values) (*AuditLogResponse, error) {
response := &AuditLogResponse{}
err := api.getMethod(ctx, path, api.token, values, response)
if err != nil {
return nil, err
}
return response, response.Err()
}

// GetAuditLogs retrieves a page of audit entires according to the parameters given
func (api *Client) GetAuditLogs(params AuditLogParameters) (entries []AuditEntry, nextCursor string, err error) {
return api.GetAuditLogsContext(context.Background(), params)
}

// GetAuditLogsContext retrieves a page of audit entries according to the parameters given with a custom context
func (api *Client) GetAuditLogsContext(ctx context.Context, params AuditLogParameters) (entries []AuditEntry, nextCursor string, err error) {
values := url.Values{}
if params.Limit != 0 {
values.Add("limit", strconv.Itoa(params.Limit))
}
if params.Oldest != 0 {
values.Add("oldest", strconv.Itoa(params.Oldest))
}
if params.Latest != 0 {
values.Add("latest", strconv.Itoa(params.Latest))
}
if params.Cursor != "" {
values.Add("cursor", params.Cursor)
}
if params.Action != "" {
values.Add("action", params.Action)
}
if params.Actor != "" {
values.Add("actor", params.Actor)
}
if params.Entity != "" {
values.Add("entity", params.Entity)
}

response, err := api.auditLogsRequest(ctx, "audit/v1/logs", values)
if err != nil {
return nil, "", err
}
return response.Entries, response.ResponseMetadata.Cursor, response.Err()
}
85 changes: 85 additions & 0 deletions audit_test.go
@@ -0,0 +1,85 @@
package slack

import (
"net/http"
"testing"
)

func getAuditLogs(rw http.ResponseWriter, r *http.Request) {
rw.Header().Set("Content-Type", "application/json")
response := []byte(`{"entries": [
{
"id": "0123a45b-6c7d-8900-e12f-3456789gh0i1",
"date_create": 1521214343,
"action": "user_login",
"actor": {
"type": "user",
"user": {
"id": "W123AB456",
"name": "Charlie Parker",
"email": "bird@slack.com"
}
},
"entity": {
"type": "user",
"user": {
"id": "W123AB456",
"name": "Charlie Parker",
"email": "bird@slack.com"
}
},
"context": {
"location": {
"type": "enterprise",
"id": "E1701NCCA",
"name": "Birdland",
"domain": "birdland"
},
"ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36",
"ip_address": "1.23.45.678"
}
}
]
}`)
rw.Write(response)
}

func TestGetAuditLogs(t *testing.T) {
http.HandleFunc("/audit/v1/logs", getAuditLogs)

once.Do(startServer)
api := New("testing-token", OptionAPIURL("http://"+serverAddr+"/"))

events, nextCursor, err := api.GetAuditLogs(AuditLogParameters{})
if err != nil {
t.Errorf("Unexpected error: %s", err)
return
}

if len(events) != 1 {
t.Fatal("Should have been 1 event")
}

// test the first login
event1 := events[0]

if event1.Action != "user_login" {
t.Fatal(ErrIncorrectResponse)
}
if event1.Entity.User.Email != "bird@slack.com" {
t.Fatal(ErrIncorrectResponse)
}
if event1.Context.Location.Domain != "birdland" {
t.Fatal(ErrIncorrectResponse)
}
if event1.DateCreate != 1521214343 {
t.Fatal(ErrIncorrectResponse)
}
if event1.Context.IPAddress != "1.23.45.678" {
t.Fatal(ErrIncorrectResponse)
}

if nextCursor != "" {
t.Fatal(ErrIncorrectResponse)
}
}

0 comments on commit 8be679f

Please sign in to comment.