diff --git a/blocks_api.go b/blocks_api.go index cfcc4bb..363f38b 100644 --- a/blocks_api.go +++ b/blocks_api.go @@ -1,12 +1,14 @@ +// Package groupme defines a client capable of executing API commands for the GroupMe chat service package groupme import ( + "context" "net/http" ) // GroupMe documentation: https://dev.groupme.com/docs/v3#blocks -////////// Endpoints ////////// +/*//////// Endpoints ////////*/ const ( // Used to build other endpoints blocksEndpointRoot = "/blocks" @@ -18,19 +20,10 @@ const ( unblockEndpoint = blocksEndpointRoot // DELETE ) -////////// API Requests ////////// +/*//////// API Requests ////////*/ -// Index - -/* -IndexBlock - - -A list of contacts you have blocked. These people cannot DM you - -Parameters: - userID - required, ID(string) -*/ -func (c *Client) IndexBlock(userID ID) ([]*Block, error) { +// IndexBlock - A list of contacts you have blocked. These people cannot DM you +func (c *Client) IndexBlock(ctx context.Context, userID string) ([]*Block, error) { httpReq, err := http.NewRequest("GET", c.endpointBase+indexBlocksEndpoint, nil) if err != nil { return nil, err @@ -38,13 +31,13 @@ func (c *Client) IndexBlock(userID ID) ([]*Block, error) { URL := httpReq.URL query := URL.Query() - query.Set("user", userID.String()) + query.Set("user", userID) URL.RawQuery = query.Encode() var resp struct { Blocks []*Block `json:"blocks"` } - err = c.doWithAuthToken(httpReq, &resp) + err = c.doWithAuthToken(ctx, httpReq, &resp) if err != nil { return nil, err } @@ -52,17 +45,8 @@ func (c *Client) IndexBlock(userID ID) ([]*Block, error) { return resp.Blocks, nil } -// Between - -/* -BlockBetween - - -Asks if a block exists between you and another user id - -Parameters: - otherUserID - required, ID(string) -*/ -func (c *Client) BlockBetween(userID, otherUserID ID) (bool, error) { +// BlockBetween - Asks if a block exists between you and another user id +func (c *Client) BlockBetween(ctx context.Context, userID, otherUserID string) (bool, error) { httpReq, err := http.NewRequest("GET", c.endpointBase+blockBetweenEndpoint, nil) if err != nil { return false, err @@ -70,14 +54,14 @@ func (c *Client) BlockBetween(userID, otherUserID ID) (bool, error) { URL := httpReq.URL query := URL.Query() - query.Set("user", userID.String()) - query.Set("otherUser", otherUserID.String()) + query.Set("user", userID) + query.Set("otherUser", otherUserID) URL.RawQuery = query.Encode() var resp struct { Between bool `json:"between"` } - err = c.doWithAuthToken(httpReq, &resp) + err = c.doWithAuthToken(ctx, httpReq, &resp) if err != nil { return false, err } @@ -85,18 +69,8 @@ func (c *Client) BlockBetween(userID, otherUserID ID) (bool, error) { return resp.Between, nil } -// Create - -/* -CreateBlock - - -Creates a block between you and the contact - -Parameters: - userID - required, ID(string) - otherUserID - required, ID(string) -*/ -func (c *Client) CreateBlock(userID, otherUserID ID) (*Block, error) { +// CreateBlock - Creates a block between you and the contact +func (c *Client) CreateBlock(ctx context.Context, userID, otherUserID string) (*Block, error) { httpReq, err := http.NewRequest("POST", c.endpointBase+createBlockEndpoint, nil) if err != nil { return nil, err @@ -104,14 +78,14 @@ func (c *Client) CreateBlock(userID, otherUserID ID) (*Block, error) { URL := httpReq.URL query := URL.Query() - query.Set("user", userID.String()) - query.Set("otherUser", otherUserID.String()) + query.Set("user", userID) + query.Set("otherUser", otherUserID) URL.RawQuery = query.Encode() var resp struct { Block *Block `json:"block"` } - err = c.doWithAuthToken(httpReq, &resp) + err = c.doWithAuthToken(ctx, httpReq, &resp) if err != nil { return nil, err } @@ -119,18 +93,8 @@ func (c *Client) CreateBlock(userID, otherUserID ID) (*Block, error) { return resp.Block, nil } -// Unblock - -/* -Unblock - - -Removes block between you and other user - -Parameters: - userID - required, ID(string) - otherUserID - required, ID(string) -*/ -func (c *Client) Unblock(userID, otherUserID ID) error { +// Unblock - Removes block between you and other user +func (c *Client) Unblock(ctx context.Context, userID, otherUserID string) error { httpReq, err := http.NewRequest("DELETE", c.endpointBase+unblockEndpoint, nil) if err != nil { return err @@ -138,11 +102,11 @@ func (c *Client) Unblock(userID, otherUserID ID) error { URL := httpReq.URL query := URL.Query() - query.Set("user", userID.String()) - query.Set("otherUser", otherUserID.String()) + query.Set("user", userID) + query.Set("otherUser", otherUserID) URL.RawQuery = query.Encode() - err = c.doWithAuthToken(httpReq, nil) + err = c.doWithAuthToken(ctx, httpReq, nil) if err != nil { return err } diff --git a/blocks_api_test.go b/blocks_api_test.go index a856c86..0db678e 100644 --- a/blocks_api_test.go +++ b/blocks_api_test.go @@ -1,6 +1,8 @@ +// Package groupme defines a client capable of executing API commands for the GroupMe chat service package groupme import ( + "context" "fmt" "net/http" "testing" @@ -17,7 +19,7 @@ func (s *BlocksAPISuite) SetupSuite() { } func (s *BlocksAPISuite) TestBlocksIndex() { - blocks, err := s.client.IndexBlock("1") + blocks, err := s.client.IndexBlock(context.Background(), "1") s.Require().NoError(err) s.Require().NotZero(blocks) for _, block := range blocks { @@ -26,19 +28,19 @@ func (s *BlocksAPISuite) TestBlocksIndex() { } func (s *BlocksAPISuite) TestBlocksBetween() { - between, err := s.client.BlockBetween("1", "2") + between, err := s.client.BlockBetween(context.Background(), "1", "2") s.Require().NoError(err) s.Assert().True(between) } func (s *BlocksAPISuite) TestBlocksCreate() { - block, err := s.client.CreateBlock("1", "2") + block, err := s.client.CreateBlock(context.Background(), "1", "2") s.Require().NoError(err) s.Assert().NotZero(block) } func (s *BlocksAPISuite) TestBlocksUnblock() { - s.Assert().NoError(s.client.Unblock("1", "2")) + s.Assert().NoError(s.client.Unblock(context.Background(), "1", "2")) } func TestBlocksAPISuite(t *testing.T) { diff --git a/bots_api.go b/bots_api.go index 24097b3..7b58eff 100644 --- a/bots_api.go +++ b/bots_api.go @@ -1,7 +1,9 @@ +// Package groupme defines a client capable of executing API commands for the GroupMe chat service package groupme import ( "bytes" + "context" "encoding/json" "fmt" "net/http" @@ -9,7 +11,7 @@ import ( // GroupMe documentation: https://dev.groupme.com/docs/v3#bots -////////// Endpoints ////////// +/*//////// Endpoints ////////*/ const ( // Used to build other endpoints botsEndpointRoot = "/bots" @@ -21,22 +23,11 @@ const ( destroyBotEndpoint = botsEndpointRoot + "/destroy" // POST ) -////////// API Requests ////////// +/*//////// API Requests ////////*/ -// Create - -/* -CreateBot - - -Create a bot. See the Bots Tutorial (https://dev.groupme.com/tutorials/bots) -for a full walkthrough. - -Parameters: - See Bot - Name - required - GroupID - required -*/ -func (c *Client) CreateBot(bot *Bot) (*Bot, error) { +// CreateBot - Create a bot. See the Bots Tutorial (https://dev.groupme.com/tutorials/bots) +// for a full walkthrough. +func (c *Client) CreateBot(ctx context.Context, bot *Bot) (*Bot, error) { URL := c.endpointBase + createBotEndpoint var data = struct { @@ -56,7 +47,7 @@ func (c *Client) CreateBot(bot *Bot) (*Bot, error) { } var resp Bot - err = c.doWithAuthToken(httpReq, &resp) + err = c.doWithAuthToken(ctx, httpReq, &resp) if err != nil { return nil, err } @@ -64,21 +55,9 @@ func (c *Client) CreateBot(bot *Bot) (*Bot, error) { return &resp, nil } -// PostMessage - -/* -PostBotMessage - - -Post a message from a bot - -Parameters: - botID - required, ID(string) - text - required, string - pictureURL - string; image must be processed through image - service (https://dev.groupme.com/docs/image_service) -*/ +// PostBotMessage - Post a message from a bot // TODO: Move PostBotMessage to bot object, since it doesn't require access token -func (c *Client) PostBotMessage(botID ID, text string, pictureURL *string) error { +func (c *Client) PostBotMessage(ctx context.Context, botID ID, text string, pictureURL *string) error { URL := fmt.Sprintf(c.endpointBase + postBotMessageEndpoint) var data = struct { @@ -101,24 +80,18 @@ func (c *Client) PostBotMessage(botID ID, text string, pictureURL *string) error return err } - return c.do(httpReq, nil) + return c.do(ctx, httpReq, nil) } -// Index - -/* -IndexBots - - -List bots that you have created -*/ -func (c *Client) IndexBots() ([]*Bot, error) { +// IndexBots - list bots that you have created +func (c *Client) IndexBots(ctx context.Context) ([]*Bot, error) { httpReq, err := http.NewRequest("GET", c.endpointBase+indexBotsEndpoint, nil) if err != nil { return nil, err } var resp []*Bot - err = c.doWithAuthToken(httpReq, &resp) + err = c.doWithAuthToken(ctx, httpReq, &resp) if err != nil { return nil, err } @@ -126,17 +99,8 @@ func (c *Client) IndexBots() ([]*Bot, error) { return resp, nil } -// Destroy - -/* -DestroyBot - - -Remove a bot that you have created - -Parameters: - botID - required, ID(string) -*/ -func (c *Client) DestroyBot(botID ID) error { +// DestroyBot - Remove a bot that you have created +func (c *Client) DestroyBot(ctx context.Context, botID ID) error { URL := fmt.Sprintf(c.endpointBase + destroyBotEndpoint) var data = struct { @@ -155,5 +119,5 @@ func (c *Client) DestroyBot(botID ID) error { return err } - return c.doWithAuthToken(httpReq, nil) + return c.doWithAuthToken(ctx, httpReq, nil) } diff --git a/bots_api_test.go b/bots_api_test.go index 49f87ae..a5da222 100644 --- a/bots_api_test.go +++ b/bots_api_test.go @@ -1,6 +1,8 @@ +// Package groupme defines a client capable of executing API commands for the GroupMe chat service package groupme import ( + "context" "fmt" "net/http" "testing" @@ -17,7 +19,7 @@ func (s *BotsAPISuite) SetupSuite() { } func (s *BotsAPISuite) TestBotsCreate() { - bot, err := s.client.CreateBot(&Bot{ + bot, err := s.client.CreateBot(context.Background(), &Bot{ Name: "test", GroupID: "1", AvatarURL: "url.com", @@ -29,12 +31,12 @@ func (s *BotsAPISuite) TestBotsCreate() { } func (s *BotsAPISuite) TestBotsPostMessage() { - err := s.client.PostBotMessage("1", "test message", nil) + err := s.client.PostBotMessage(context.Background(), "1", "test message", nil) s.Require().NoError(err) } func (s *BotsAPISuite) TestBotsIndex() { - bots, err := s.client.IndexBots() + bots, err := s.client.IndexBots(context.Background()) s.Require().NoError(err) s.Require().NotZero(bots) for _, bot := range bots { @@ -43,7 +45,7 @@ func (s *BotsAPISuite) TestBotsIndex() { } func (s *BotsAPISuite) TestBotsDestroy() { - s.Require().NoError(s.client.DestroyBot("1")) + s.Require().NoError(s.client.DestroyBot(context.Background(), "1")) } func TestBotsAPISuite(t *testing.T) { diff --git a/chats_api.go b/chats_api.go index 1d5082f..66fd39b 100644 --- a/chats_api.go +++ b/chats_api.go @@ -1,13 +1,15 @@ +// Package groupme defines a client capable of executing API commands for the GroupMe chat service package groupme import ( + "context" "net/http" "strconv" ) // GroupMe documentation: https://dev.groupme.com/docs/v3#chats -////////// Endpoints ////////// +/*//////// Endpoints ////////*/ const ( // Used to build other endpoints chatsEndpointRoot = "/chats" @@ -15,9 +17,7 @@ const ( indexChatsEndpoint = chatsEndpointRoot // GET ) -// Index - -// ChatsQuery defines the optional URL parameters for IndexChats +// IndexChatsQuery defines the optional URL parameters for IndexChats type IndexChatsQuery struct { // Page Number Page int `json:"page"` @@ -25,15 +25,9 @@ type IndexChatsQuery struct { PerPage int `json:"per_page"` } -/* -IndexChats - - -Returns a paginated list of direct message chats, or -conversations, sorted by updated_at descending. - -Parameters: See ChatsQuery -*/ -func (c *Client) IndexChats(req *IndexChatsQuery) ([]*Chat, error) { +// IndexChats - Returns a paginated list of direct message chats, or +// conversations, sorted by updated_at descending. +func (c *Client) IndexChats(ctx context.Context, req *IndexChatsQuery) ([]*Chat, error) { httpReq, err := http.NewRequest("GET", c.endpointBase+indexChatsEndpoint, nil) if err != nil { return nil, err @@ -52,7 +46,7 @@ func (c *Client) IndexChats(req *IndexChatsQuery) ([]*Chat, error) { URL.RawQuery = query.Encode() var resp []*Chat - err = c.doWithAuthToken(httpReq, &resp) + err = c.doWithAuthToken(ctx, httpReq, &resp) if err != nil { return nil, err } diff --git a/chats_api_test.go b/chats_api_test.go index c7239be..80cf550 100644 --- a/chats_api_test.go +++ b/chats_api_test.go @@ -1,6 +1,8 @@ +// Package groupme defines a client capable of executing API commands for the GroupMe chat service package groupme import ( + "context" "fmt" "net/http" "testing" @@ -18,6 +20,7 @@ func (s *ChatsAPISuite) SetupSuite() { func (s *ChatsAPISuite) TestChatsIndex() { chats, err := s.client.IndexChats( + context.Background(), &IndexChatsQuery{ Page: 1, PerPage: 20, diff --git a/client.go b/client.go index a3c1b57..1c7723d 100644 --- a/client.go +++ b/client.go @@ -1,13 +1,15 @@ +// Package groupme defines a client capable of executing API commands for the GroupMe chat service package groupme import ( "bytes" + "context" "encoding/json" "io/ioutil" "net/http" ) -// Endpoints are added on to the GroupMeAPIBase to get the full URI. +// GroupMeAPIBase - Endpoints are added on to this to get the full URI. // Overridable for testing const GroupMeAPIBase = "https://api.groupme.com/v3" @@ -40,7 +42,7 @@ func (c Client) String() string { return marshal(&c) } -///// Handle parsing of nested interface type response ///// +/*/// Handle parsing of nested interface type response ///*/ type jsonResponse struct { Response response `json:"response"` Meta `json:"meta"` @@ -58,7 +60,10 @@ func (r response) UnmarshalJSON(bs []byte) error { return json.NewDecoder(bytes.NewBuffer(bs)).Decode(r.i) } -func (c Client) do(req *http.Request, i interface{}) error { +const errorStatusCodeMin = 300 + +func (c Client) do(ctx context.Context, req *http.Request, i interface{}) error { + req = req.WithContext(ctx) if req.Method == "POST" { req.Header.Set("Content-Type", "application/json") } @@ -69,9 +74,10 @@ func (c Client) do(req *http.Request, i interface{}) error { } defer getResp.Body.Close() + var readBytes []byte // Check Status Code is 1XX or 2XX - if getResp.StatusCode/100 > 2 { - bytes, err := ioutil.ReadAll(getResp.Body) + if getResp.StatusCode >= errorStatusCodeMin { + readBytes, err = ioutil.ReadAll(getResp.Body) if err != nil { // We couldn't read the output. Oh well; generate the appropriate error type anyway. return &Meta{ @@ -80,7 +86,7 @@ func (c Client) do(req *http.Request, i interface{}) error { } resp := newJSONResponse(nil) - if err := json.Unmarshal(bytes, &resp); err != nil { + if err = json.Unmarshal(readBytes, &resp); err != nil { // We couldn't parse the output. Oh well; generate the appropriate error type anyway. return &Meta{ Code: HTTPStatusCode(getResp.StatusCode), @@ -93,24 +99,24 @@ func (c Client) do(req *http.Request, i interface{}) error { return nil } - bytes, err := ioutil.ReadAll(getResp.Body) + readBytes, err = ioutil.ReadAll(getResp.Body) if err != nil { return err } resp := newJSONResponse(i) - if err := json.Unmarshal(bytes, &resp); err != nil { + if err := json.Unmarshal(readBytes, &resp); err != nil { return err } return nil } -func (c Client) doWithAuthToken(req *http.Request, i interface{}) error { +func (c Client) doWithAuthToken(ctx context.Context, req *http.Request, i interface{}) error { URL := req.URL query := URL.Query() query.Set("token", c.authorizationToken) URL.RawQuery = query.Encode() - return c.do(req, i) + return c.do(ctx, req, i) } diff --git a/client_test.go b/client_test.go index 2186239..23e0ff2 100644 --- a/client_test.go +++ b/client_test.go @@ -1,6 +1,8 @@ +// Package groupme defines a client capable of executing API commands for the GroupMe chat service package groupme import ( + "context" "net/http" "testing" @@ -34,7 +36,7 @@ func (s *ClientSuite) TestClient_do_PostContentType() { req, err := http.NewRequest("POST", "", nil) s.Require().NoError(err) - s.Assert().Error(s.client.do(req, struct{}{})) + s.Assert().Error(s.client.do(context.Background(), req, struct{}{})) s.Assert().EqualValues(req.Header.Get("Content-Type"), "application/json") } @@ -42,14 +44,14 @@ func (s *ClientSuite) TestClient_do_DoError() { req, err := http.NewRequest("", "", nil) s.Require().NoError(err) - s.Assert().Error(s.client.do(req, struct{}{})) + s.Assert().Error(s.client.do(context.Background(), req, struct{}{})) } func (s *ClientSuite) TestClient_do_UnmarshalError() { req, err := http.NewRequest("GET", s.addr, nil) s.Require().NoError(err) - s.Assert().Error(s.client.do(req, struct{}{})) + s.Assert().Error(s.client.do(context.Background(), req, struct{}{})) } func TestClientSuite(t *testing.T) { diff --git a/data_types.go b/data_types.go index 903731b..9aec5af 100644 --- a/data_types.go +++ b/data_types.go @@ -1,3 +1,4 @@ +// Package groupme defines a client capable of executing API commands for the GroupMe chat service package groupme import ( @@ -44,7 +45,7 @@ func (t Timestamp) String() string { type PhoneNumber string // Treated as a constant -var phoneNumberRegex = regexp.MustCompile(`^\+[0-9]+ [0-9]{10}$`) +var phoneNumberRegex = regexp.MustCompile(`^\+\d+ \d{10}$`) // Valid checks if the ID string is alpha numeric func (pn PhoneNumber) Valid() bool { @@ -55,40 +56,40 @@ func (pn PhoneNumber) String() string { return string(pn) } -// StatusCodes are returned by HTTP requests in +// HTTPStatusCode are returned by HTTP requests in // the header and the json "meta" field type HTTPStatusCode int // Text used as constant name const ( - HTTP_Ok HTTPStatusCode = 200 - HTTP_Created HTTPStatusCode = 201 - HTTP_NoContent HTTPStatusCode = 204 - HTTP_NotModified HTTPStatusCode = 304 - HTTP_BadRequest HTTPStatusCode = 400 - HTTP_Unauthorized HTTPStatusCode = 401 - HTTP_Forbidden HTTPStatusCode = 403 - HTTP_NotFound HTTPStatusCode = 404 - HTTP_EnhanceYourCalm HTTPStatusCode = 420 - HTTP_InternalServerError HTTPStatusCode = 500 - HTTP_BadGateway HTTPStatusCode = 502 - HTTP_ServiceUnavailable HTTPStatusCode = 503 + HTTPOk HTTPStatusCode = 200 + HTTPCreated HTTPStatusCode = 201 + HTTPNoContent HTTPStatusCode = 204 + HTTPNotModified HTTPStatusCode = 304 + HTTPBadRequest HTTPStatusCode = 400 + HTTPUnauthorized HTTPStatusCode = 401 + HTTPForbidden HTTPStatusCode = 403 + HTTPNotFound HTTPStatusCode = 404 + HTTPEnhanceYourCalm HTTPStatusCode = 420 + HTTPInternalServerError HTTPStatusCode = 500 + HTTPBadGateway HTTPStatusCode = 502 + HTTPServiceUnavailable HTTPStatusCode = 503 ) // String returns the description of the status code according to GroupMe func (c HTTPStatusCode) String() string { return map[HTTPStatusCode]string{ - HTTP_Ok: "success", - HTTP_Created: "resource was created successfully", - HTTP_NoContent: "resource was deleted successfully", - HTTP_NotModified: "no new data to return", - HTTP_BadRequest: "invalid format or data specified in the request", - HTTP_Unauthorized: "authentication credentials missing or incorrect", - HTTP_Forbidden: "request refused due to update limits", - HTTP_NotFound: "URI is invalid or resource does not exist", - HTTP_EnhanceYourCalm: "application is being rate limited", - HTTP_InternalServerError: "something unexpected occurred", - HTTP_BadGateway: "GroupMe is down or being upgraded", - HTTP_ServiceUnavailable: "servers are overloaded, try again later", + HTTPOk: "success", + HTTPCreated: "resource was created successfully", + HTTPNoContent: "resource was deleted successfully", + HTTPNotModified: "no new data to return", + HTTPBadRequest: "invalid format or data specified in the request", + HTTPUnauthorized: "authentication credentials missing or incorrect", + HTTPForbidden: "request refused due to update limits", + HTTPNotFound: "URI is invalid or resource does not exist", + HTTPEnhanceYourCalm: "application is being rate limited", + HTTPInternalServerError: "something unexpected occurred", + HTTPBadGateway: "GroupMe is down or being upgraded", + HTTPServiceUnavailable: "servers are overloaded, try again later", }[c] } diff --git a/data_types_test.go b/data_types_test.go index e1c535f..06d920d 100644 --- a/data_types_test.go +++ b/data_types_test.go @@ -1,3 +1,4 @@ +// Package groupme defines a client capable of executing API commands for the GroupMe chat service package groupme import ( diff --git a/direct_messages_api.go b/direct_messages_api.go index 180cb12..c73ab90 100644 --- a/direct_messages_api.go +++ b/direct_messages_api.go @@ -1,7 +1,9 @@ +// Package groupme defines a client capable of executing API commands for the GroupMe chat service package groupme import ( "bytes" + "context" "encoding/json" "fmt" "net/http" @@ -11,7 +13,7 @@ import ( // GroupMe documentation: https://dev.groupme.com/docs/v3#direct_messages -////////// Endpoints ////////// +/*//////// Endpoints ////////*/ const ( // Used to build other endpoints directMessagesEndpointRoot = "/direct_messages" @@ -21,11 +23,9 @@ const ( createDirectMessageEndpoint = directMessagesEndpointRoot // POST ) -////////// API Requests ////////// +/*//////// API Requests ////////*/ -// Index - -// MessagesQuery defines the optional URL parameters for IndexDirectMessages +// IndexDirectMessagesQuery defines the optional URL parameters for IndexDirectMessages type IndexDirectMessagesQuery struct { // Returns 20 messages created before the given message ID BeforeID ID `json:"before_id"` @@ -66,14 +66,14 @@ Parameters: otherUserID - required, ID(string); the other participant in the conversation. See IndexDirectMessagesQuery */ -func (c *Client) IndexDirectMessages(otherUserID ID, req *IndexDirectMessagesQuery) (IndexDirectMessagesResponse, error) { +func (c *Client) IndexDirectMessages(ctx context.Context, otherUserID string, req *IndexDirectMessagesQuery) (IndexDirectMessagesResponse, error) { httpReq, err := http.NewRequest("GET", c.endpointBase+indexDirectMessagesEndpoint, nil) if err != nil { return IndexDirectMessagesResponse{}, err } query := httpReq.URL.Query() - query.Set("other_user_id", otherUserID.String()) + query.Set("other_user_id", otherUserID) if req != nil { if req.BeforeID != "" { query.Add("before_ID", req.BeforeID.String()) @@ -84,7 +84,7 @@ func (c *Client) IndexDirectMessages(otherUserID ID, req *IndexDirectMessagesQue } var resp IndexDirectMessagesResponse - err = c.doWithAuthToken(httpReq, &resp) + err = c.doWithAuthToken(ctx, httpReq, &resp) if err != nil { return IndexDirectMessagesResponse{}, err } @@ -92,12 +92,8 @@ func (c *Client) IndexDirectMessages(otherUserID ID, req *IndexDirectMessagesQue return resp, nil } -// Create - /* -CreateDirectMessage - - -Send a DM to another user +CreateDirectMessage - Send a DM to another user If you want to attach an image, you must first process it through our image service. @@ -109,18 +105,8 @@ specify a replacement charmap to substitute emoji characters The character map is an array of arrays containing rune data ([[{pack_id,offset}],...]). - -Parameters: - See Message. - recipientID - required, ID(string); The GroupMe user ID of the recipient of this message. - text - required, string. Can be ommitted if at least one - attachment is present - attachments - a polymorphic list of attachments (locations, - images, etc). You may have You may have more than - one of any type of attachment, provided clients can - display it. */ -func (c *Client) CreateDirectMessage(m *Message) (*Message, error) { +func (c *Client) CreateDirectMessage(ctx context.Context, m *Message) (*Message, error) { URL := fmt.Sprintf(c.endpointBase + createDirectMessageEndpoint) m.SourceGUID = uuid.New().String() @@ -143,7 +129,7 @@ func (c *Client) CreateDirectMessage(m *Message) (*Message, error) { var resp struct { *Message `json:"message"` } - err = c.doWithAuthToken(httpReq, &resp) + err = c.doWithAuthToken(ctx, httpReq, &resp) if err != nil { return nil, err } diff --git a/direct_messages_api_test.go b/direct_messages_api_test.go index 6c6a161..3b38829 100644 --- a/direct_messages_api_test.go +++ b/direct_messages_api_test.go @@ -1,6 +1,8 @@ +// Package groupme defines a client capable of executing API commands for the GroupMe chat service package groupme import ( + "context" "fmt" "net/http" "testing" @@ -18,7 +20,8 @@ func (s *DirectMessagesAPISuite) SetupSuite() { func (s *DirectMessagesAPISuite) TestDirectMessagesIndex() { resp, err := s.client.IndexDirectMessages( - ID("123"), + context.Background(), + "123", &IndexDirectMessagesQuery{ BeforeID: "0123456789", SinceID: "9876543210", @@ -33,6 +36,7 @@ func (s *DirectMessagesAPISuite) TestDirectMessagesIndex() { func (s *DirectMessagesAPISuite) TestDirectMessagesCreate() { message, err := s.client.CreateDirectMessage( + context.Background(), &Message{ RecipientID: ID("123"), Text: "Test", @@ -47,6 +51,7 @@ func TestDirectMessagesAPISuite(t *testing.T) { suite.Run(t, new(DirectMessagesAPISuite)) } +// nolint // not duplicate code func directMessagesTestRouter() *mux.Router { router := mux.NewRouter().Queries("token", "").Subrouter() diff --git a/examples/group_messages/main.go b/examples/group_messages/main.go index d1a3597..175cace 100644 --- a/examples/group_messages/main.go +++ b/examples/group_messages/main.go @@ -1,6 +1,7 @@ package main import ( + "context" "fmt" "github.com/densestvoid/groupme" @@ -18,11 +19,14 @@ func main() { client := groupme.NewClient(authorizationToken) // Get the groups your user is part of - groups, err := client.IndexGroups(&groupme.GroupsQuery{ - Page: 0, - PerPage: 5, - Omit: "memberships", - }) + groups, err := client.IndexGroups( + context.Background(), + &groupme.GroupsQuery{ + Page: 0, + PerPage: 5, + Omit: "memberships", + }, + ) if err != nil { fmt.Println(err) @@ -32,11 +36,11 @@ func main() { fmt.Println(groups) // Get first 10 messages of the first group - if len(groups) <= 0 { + if len(groups) == 0 { fmt.Println("No groups") } - messages, err := client.IndexMessages(groups[0].ID, &groupme.IndexMessagesQuery{ + messages, err := client.IndexMessages(context.Background(), groups[0].ID, &groupme.IndexMessagesQuery{ Limit: 10, }) diff --git a/examples/post_bot_message/main.go b/examples/post_bot_message/main.go index 9f13d1d..6c4973a 100644 --- a/examples/post_bot_message/main.go +++ b/examples/post_bot_message/main.go @@ -1,6 +1,7 @@ package main import ( + "context" "fmt" "github.com/densestvoid/groupme" @@ -16,5 +17,5 @@ const botID = "0123456789ABCDEF" func main() { // Create a new client with your auth token client := groupme.NewClient("") - fmt.Println(client.PostBotMessage(botID, "Your message here!", nil)) + fmt.Println(client.PostBotMessage(context.Background(), botID, "Your message here!", nil)) } diff --git a/go.mod b/go.mod index bf9a613..a4551d9 100755 --- a/go.mod +++ b/go.mod @@ -1,18 +1,9 @@ module github.com/densestvoid/groupme -go 1.14 +go 1.15 require ( - github.com/go-critic/go-critic v0.5.0 // indirect - github.com/go-toolsmith/astinfo v1.0.0 // indirect - github.com/google/go-cmp v0.5.1 // indirect - github.com/google/uuid v1.1.1 - github.com/gorilla/mux v1.7.4 - github.com/logrusorgru/aurora v2.0.3+incompatible // indirect - github.com/mattn/goveralls v0.0.6 // indirect - github.com/quasilyte/go-consistent v0.0.0-20200404105227-766526bf1e96 // indirect - github.com/quasilyte/go-ruleguard v0.1.3 // indirect - github.com/quasilyte/regex/syntax v0.0.0-20200419152657-af9db7f4a3ab // indirect - github.com/stretchr/testify v1.5.1 - golang.org/x/tools v0.0.0-20200728190822-edd3c8e9e279 // indirect + github.com/google/uuid v1.2.0 + github.com/gorilla/mux v1.8.0 + github.com/stretchr/testify v1.7.0 ) diff --git a/go.sum b/go.sum index d003537..8634fb4 100755 --- a/go.sum +++ b/go.sum @@ -1,105 +1,16 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-critic/go-critic v0.5.0 h1:Ic2p5UCl5fX/2WX2w8nroPpPhxRNsNTMlJzsu/uqwnM= -github.com/go-critic/go-critic v0.5.0/go.mod h1:4jeRh3ZAVnRYhuWdOEvwzVqLUpxMSoAT0xZ74JsTPlo= -github.com/go-lintpack/lintpack v0.5.2/go.mod h1:NwZuYi2nUHho8XEIZ6SIxihrnPoqBTDqfpXvXAN0sXM= -github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g= -github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= -github.com/go-toolsmith/astcopy v1.0.0 h1:OMgl1b1MEpjFQ1m5ztEO06rz5CUd3oBv9RF7+DyvdG8= -github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= -github.com/go-toolsmith/astequal v0.0.0-20180903214952-dcb477bfacd6/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= -github.com/go-toolsmith/astequal v1.0.0 h1:4zxD8j3JRFNyLN46lodQuqz3xdKSrur7U/sr0SDS/gQ= -github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= -github.com/go-toolsmith/astfmt v0.0.0-20180903215011-8f8ee99c3086/go.mod h1:mP93XdblcopXwlyN4X4uodxXQhldPGZbcEJIimQHrkg= -github.com/go-toolsmith/astfmt v1.0.0 h1:A0vDDXt+vsvLEdbMFJAUBI/uTbRw1ffOPnxsILnFL6k= -github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw= -github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21 h1:wP6mXeB2V/d1P1K7bZ5vDUO3YqEzcvOREOxZPEu3gVI= -github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU= -github.com/go-toolsmith/astinfo v1.0.0 h1:rNuhpyhsnsze/Pe1l/GUHwxo1rmN7Dyb6oAnFcrXh+w= -github.com/go-toolsmith/astinfo v1.0.0/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU= -github.com/go-toolsmith/astp v0.0.0-20180903215135-0af7e3c24f30/go.mod h1:SV2ur98SGypH1UjcPpCatrV5hPazG6+IfNHbkDXBRrk= -github.com/go-toolsmith/astp v1.0.0 h1:alXE75TXgcmupDsMK1fRAy0YUzLzqPVvBKoyWV+KPXg= -github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI= -github.com/go-toolsmith/pkgload v0.0.0-20181119091011-e9e65178eee8/go.mod h1:WoMrjiy4zvdS+Bg6z9jZH82QXwkcgCBX6nOfnmdaHks= -github.com/go-toolsmith/pkgload v1.0.0 h1:4DFWWMXVfbcN5So1sBNW9+yeiMqLFGl1wFLTL5R0Tgg= -github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc= -github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUDxe2Jb4= -github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= -github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= -github.com/go-toolsmith/typep v1.0.2 h1:8xdsa1+FSIH/RhEkgnD1j2CJOy5mNllW1Q9tRiYwvlk= -github.com/go-toolsmith/typep v1.0.2/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= -github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.5.1 h1:JFrFEBb2xKufg6XkJsJr+WbKb4FQlURi5RUcBveYu9k= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc= -github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e h1:9MlwzLdW7QSDrhDjFlsEYmxpFyIoXmYRon3dt0io31k= -github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= -github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= -github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= -github.com/mattn/goveralls v0.0.2 h1:7eJB6EqsPhRVxvwEXGnqdO2sJI0PTsrWoTMXEk9/OQc= -github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= -github.com/mattn/goveralls v0.0.6 h1:cr8Y0VMo/MnEZBjxNN/vh6G90SZ7IMb6lms1dzMoO+Y= -github.com/mattn/goveralls v0.0.6/go.mod h1:h8b4ow6FxSPMQHF6o2ve3qsclnffZjYTNEKmLesRwqw= -github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c h1:JoUA0uz9U0FVFq5p4LjEq4C0VgQ0El320s3Ms0V4eww= -github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= -github.com/quasilyte/go-consistent v0.0.0-20200404105227-766526bf1e96 h1:6VBkISnfYpPtRvpE9wsVoxX+i0cDQFBPQPYzw259xWY= -github.com/quasilyte/go-consistent v0.0.0-20200404105227-766526bf1e96/go.mod h1:h5ob45vcE3sydtmo0lUDUmG3Y0HXudxMId1w+5G99VI= -github.com/quasilyte/go-ruleguard v0.1.2-0.20200318202121-b00d7a75d3d8 h1:DvnesvLtRPQOvaUbfXfh0tpMHg29by0H7F2U+QIkSu8= -github.com/quasilyte/go-ruleguard v0.1.2-0.20200318202121-b00d7a75d3d8/go.mod h1:CGFX09Ci3pq9QZdj86B+VGIdNj4VyCo2iPOGS9esB/k= -github.com/quasilyte/go-ruleguard v0.1.3 h1:6BU9UaNiSbTRYriG0PTZACIMi1dLHzIWWseSpX4icNM= -github.com/quasilyte/go-ruleguard v0.1.3/go.mod h1:CGFX09Ci3pq9QZdj86B+VGIdNj4VyCo2iPOGS9esB/k= -github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 h1:L8QM9bvf68pVdQ3bCFZMDmnt9yqcMBro1pC7F+IPYMY= -github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= -github.com/quasilyte/regex/syntax v0.0.0-20200419152657-af9db7f4a3ab h1:rjBjlam2Bbr6Dwp0T8HY2paibXTjMsNQU7vUH8hB+C4= -github.com/quasilyte/regex/syntax v0.0.0-20200419152657-af9db7f4a3ab/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/tools v0.0.0-20181117154741-2ddaf7f79a09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd h1:7E3PabyysDSEjnaANKBgums/hyvMI/HoHQ50qZEzTrg= -golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200728190822-edd3c8e9e279 h1:VUQjqirfpXJk5i+LtIdDjCAqYrCqTarkUCmMVLqMmVQ= -golang.org/x/tools v0.0.0-20200728190822-edd3c8e9e279/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/groups_api.go b/groups_api.go index 0d5a68d..0a8b8f7 100755 --- a/groups_api.go +++ b/groups_api.go @@ -1,7 +1,9 @@ +// Package groupme defines a client capable of executing API commands for the GroupMe chat service package groupme import ( "bytes" + "context" "encoding/json" "errors" "fmt" @@ -11,7 +13,7 @@ import ( // GroupMe documentation: https://dev.groupme.com/docs/v3#groups -////////// Endpoints ////////// +/*//////// Endpoints ////////*/ const ( // Used to build other endpoints groupsEndpointRoot = "/groups" @@ -29,7 +31,7 @@ const ( changeGroupOwnerEndpoint = groupsEndpointRoot + "/change_owners" // POST ) -////////// Common Request Parameters ////////// +/*//////// Common Request Parameters ////////*/ // GroupSettings is the settings for a group, used by CreateGroup and UpdateGroup type GroupSettings struct { @@ -51,9 +53,9 @@ func (gss GroupSettings) String() string { return marshal(&gss) } -////////// API Requests ////////// +/*//////// API Requests ////////*/ -///// Index ///// +/*/// Index ///*/ // GroupsQuery defines optional URL parameters for IndexGroups type GroupsQuery struct { @@ -84,7 +86,7 @@ app for users who are participating in huge groups. Parameters: See GroupsQuery */ -func (c *Client) IndexGroups(req *GroupsQuery) ([]*Group, error) { +func (c *Client) IndexGroups(ctx context.Context, req *GroupsQuery) ([]*Group, error) { httpReq, err := http.NewRequest("GET", c.endpointBase+indexGroupsEndpoint, nil) if err != nil { return nil, err @@ -106,7 +108,7 @@ func (c *Client) IndexGroups(req *GroupsQuery) ([]*Group, error) { URL.RawQuery = query.Encode() var resp []*Group - err = c.doWithAuthToken(httpReq, &resp) + err = c.doWithAuthToken(ctx, httpReq, &resp) if err != nil { return nil, err } @@ -114,21 +116,21 @@ func (c *Client) IndexGroups(req *GroupsQuery) ([]*Group, error) { return resp, nil } -///// Former ///// +/*/// Former ///*/ /* FormerGroups - List they groups you have left but can rejoin. */ -func (c *Client) FormerGroups() ([]*Group, error) { +func (c *Client) FormerGroups(ctx context.Context) ([]*Group, error) { httpReq, err := http.NewRequest("GET", c.endpointBase+formerGroupsEndpoint, nil) if err != nil { return nil, err } var resp []*Group - err = c.doWithAuthToken(httpReq, &resp) + err = c.doWithAuthToken(ctx, httpReq, &resp) if err != nil { return nil, err } @@ -136,7 +138,7 @@ func (c *Client) FormerGroups() ([]*Group, error) { return resp, nil } -///// Show ///// +/*/// Show ///*/ /* ShowGroup - @@ -146,7 +148,7 @@ Loads a specific group. Parameters: groupID - required, ID(string) */ -func (c *Client) ShowGroup(groupID ID) (*Group, error) { +func (c *Client) ShowGroup(ctx context.Context, groupID ID) (*Group, error) { URL := fmt.Sprintf(c.endpointBase+showGroupEndpoint, groupID) httpReq, err := http.NewRequest("GET", URL, nil) @@ -155,7 +157,7 @@ func (c *Client) ShowGroup(groupID ID) (*Group, error) { } var resp Group - err = c.doWithAuthToken(httpReq, &resp) + err = c.doWithAuthToken(ctx, httpReq, &resp) if err != nil { return nil, err } @@ -163,7 +165,7 @@ func (c *Client) ShowGroup(groupID ID) (*Group, error) { return &resp, nil } -///// Create ///// +/*/// Create ///*/ /* CreateGroup - @@ -172,7 +174,7 @@ Create a new group Parameters: See GroupSettings */ -func (c *Client) CreateGroup(gs GroupSettings) (*Group, error) { +func (c *Client) CreateGroup(ctx context.Context, gs GroupSettings) (*Group, error) { URL := fmt.Sprintf(c.endpointBase + createGroupEndpoint) jsonBytes, err := json.Marshal(&gs) @@ -186,7 +188,7 @@ func (c *Client) CreateGroup(gs GroupSettings) (*Group, error) { } var resp Group - err = c.doWithAuthToken(httpReq, &resp) + err = c.doWithAuthToken(ctx, httpReq, &resp) if err != nil { return nil, err } @@ -194,7 +196,7 @@ func (c *Client) CreateGroup(gs GroupSettings) (*Group, error) { return &resp, nil } -///// Update ///// +/*/// Update ///*/ /* UpdateGroup - @@ -205,7 +207,7 @@ Parameters: groupID - required, ID(string) See GroupSettings */ -func (c *Client) UpdateGroup(groupID ID, gs GroupSettings) (*Group, error) { +func (c *Client) UpdateGroup(ctx context.Context, groupID ID, gs GroupSettings) (*Group, error) { URL := fmt.Sprintf(c.endpointBase+updateGroupEndpoint, groupID) jsonBytes, err := json.Marshal(&gs) @@ -219,7 +221,7 @@ func (c *Client) UpdateGroup(groupID ID, gs GroupSettings) (*Group, error) { } var resp Group - err = c.doWithAuthToken(httpReq, &resp) + err = c.doWithAuthToken(ctx, httpReq, &resp) if err != nil { return nil, err } @@ -227,7 +229,7 @@ func (c *Client) UpdateGroup(groupID ID, gs GroupSettings) (*Group, error) { return &resp, nil } -///// Destroy ///// +/*/// Destroy ///*/ /* DestroyGroup - @@ -239,7 +241,7 @@ This action is only available to the group creator Parameters: groupID - required, ID(string) */ -func (c *Client) DestroyGroup(groupID ID) error { +func (c *Client) DestroyGroup(ctx context.Context, groupID ID) error { url := fmt.Sprintf(c.endpointBase+destroyGroupEndpoint, groupID) httpReq, err := http.NewRequest("POST", url, nil) @@ -247,10 +249,10 @@ func (c *Client) DestroyGroup(groupID ID) error { return err } - return c.doWithAuthToken(httpReq, nil) + return c.doWithAuthToken(ctx, httpReq, nil) } -///// Join ///// +/*/// Join ///*/ /* JoinGroup - @@ -261,7 +263,7 @@ Parameters: groupID - required, ID(string) shareToken - required, string */ -func (c *Client) JoinGroup(groupID ID, shareToken string) (*Group, error) { +func (c *Client) JoinGroup(ctx context.Context, groupID ID, shareToken string) (*Group, error) { URL := fmt.Sprintf(c.endpointBase+joinGroupEndpoint, groupID, shareToken) httpReq, err := http.NewRequest("POST", URL, nil) @@ -270,7 +272,7 @@ func (c *Client) JoinGroup(groupID ID, shareToken string) (*Group, error) { } var resp Group - err = c.doWithAuthToken(httpReq, &resp) + err = c.doWithAuthToken(ctx, httpReq, &resp) if err != nil { return nil, err } @@ -278,7 +280,7 @@ func (c *Client) JoinGroup(groupID ID, shareToken string) (*Group, error) { return &resp, nil } -///// Rejoin ///// +/*/// Rejoin ///*/ /* RejoinGroup - @@ -288,7 +290,7 @@ Rejoin a group. Only works if you previously removed yourself. Parameters: groupID - required, ID(string) */ -func (c *Client) RejoinGroup(groupID ID) (*Group, error) { +func (c *Client) RejoinGroup(ctx context.Context, groupID ID) (*Group, error) { URL := fmt.Sprintf(c.endpointBase + rejoinGroupEndpoint) var data = struct { @@ -308,7 +310,7 @@ func (c *Client) RejoinGroup(groupID ID) (*Group, error) { } var resp Group - err = c.doWithAuthToken(httpReq, &resp) + err = c.doWithAuthToken(ctx, httpReq, &resp) if err != nil { return nil, err } @@ -316,12 +318,10 @@ func (c *Client) RejoinGroup(groupID ID) (*Group, error) { return &resp, nil } -///// Change Owner ///// +/*/// Change Owner ///*/ /* -ChangeGroupOwner- - -Change owner of requested groups. +ChangeGroupOwner - Change owner of requested groups. This action is only available to the group creator. @@ -330,7 +330,7 @@ the result of change owner action for the request Parameters: See ChangeOwnerRequest */ -func (c *Client) ChangeGroupOwner(reqs ChangeOwnerRequest) (ChangeOwnerResult, error) { +func (c *Client) ChangeGroupOwner(ctx context.Context, reqs ChangeOwnerRequest) (ChangeOwnerResult, error) { URL := fmt.Sprintf(c.endpointBase + changeGroupOwnerEndpoint) var data = struct { @@ -353,7 +353,7 @@ func (c *Client) ChangeGroupOwner(reqs ChangeOwnerRequest) (ChangeOwnerResult, e Results []ChangeOwnerResult `json:"results"` } - err = c.doWithAuthToken(httpReq, &resp) + err = c.doWithAuthToken(ctx, httpReq, &resp) if err != nil { return ChangeOwnerResult{}, err } @@ -365,24 +365,25 @@ func (c *Client) ChangeGroupOwner(reqs ChangeOwnerRequest) (ChangeOwnerResult, e return resp.Results[0], nil } -type ChangeOwnerStatusCode string +type changeOwnerStatusCode string +// Change owner Status Codes const ( - ChangeOwner_Ok ChangeOwnerStatusCode = "200" - ChangeOwner_RequesterNewOwner ChangeOwnerStatusCode = "400" - ChangeOwner_NotOwner ChangeOwnerStatusCode = "403" - ChangeOwner_BadGroupOrOwner ChangeOwnerStatusCode = "404" - ChangeOwner_BadRequest ChangeOwnerStatusCode = "405" + ChangeOwnerOk changeOwnerStatusCode = "200" + ChangeOwnerRequesterNewOwner changeOwnerStatusCode = "400" + ChangeOwnerNotOwner changeOwnerStatusCode = "403" + ChangeOwnerBadGroupOrOwner changeOwnerStatusCode = "404" + ChangeOwnerBadRequest changeOwnerStatusCode = "405" ) // String returns the description of the status code according to GroupMe -func (c ChangeOwnerStatusCode) String() string { - return map[ChangeOwnerStatusCode]string{ - ChangeOwner_Ok: "success", - ChangeOwner_RequesterNewOwner: "requester is also a new owner", - ChangeOwner_NotOwner: "requester is not the owner of the group", - ChangeOwner_BadGroupOrOwner: "group or new owner not found or new owner is not memeber of the group", - ChangeOwner_BadRequest: "request object is missing required field or any of the required fields is not an ID", +func (c changeOwnerStatusCode) String() string { + return map[changeOwnerStatusCode]string{ + ChangeOwnerOk: "success", + ChangeOwnerRequesterNewOwner: "requester is also a new owner", + ChangeOwnerNotOwner: "requester is not the owner of the group", + ChangeOwnerBadGroupOrOwner: "group or new owner not found or new owner is not member of the group", + ChangeOwnerBadRequest: "request object is missing required field or any of the required fields is not an ID", }[c] } @@ -405,7 +406,7 @@ type ChangeOwnerResult struct { // UserId of the new owner of the group who is // an active member of the group OwnerID string `json:"owner_id"` - Status ChangeOwnerStatusCode `json:"status"` + Status changeOwnerStatusCode `json:"status"` } func (r ChangeOwnerResult) String() string { diff --git a/groups_api_test.go b/groups_api_test.go index 7a201c1..2879622 100755 --- a/groups_api_test.go +++ b/groups_api_test.go @@ -1,6 +1,8 @@ +// Package groupme defines a client capable of executing API commands for the GroupMe chat service package groupme import ( + "context" "fmt" "net/http" "testing" @@ -17,11 +19,14 @@ func (s *GroupsAPISuite) SetupSuite() { } func (s *GroupsAPISuite) TestGroupsIndex() { - groups, err := s.client.IndexGroups(&GroupsQuery{ - Page: 5, - PerPage: 20, - Omit: "memberships", - }) + groups, err := s.client.IndexGroups( + context.Background(), + &GroupsQuery{ + Page: 5, + PerPage: 20, + Omit: "memberships", + }, + ) s.Require().NoError(err) s.Require().NotZero(groups) for _, group := range groups { @@ -30,7 +35,7 @@ func (s *GroupsAPISuite) TestGroupsIndex() { } func (s *GroupsAPISuite) TestGroupsFormer() { - groups, err := s.client.FormerGroups() + groups, err := s.client.FormerGroups(context.Background()) s.Require().NoError(err) s.Require().NotZero(groups) for _, group := range groups { @@ -39,25 +44,28 @@ func (s *GroupsAPISuite) TestGroupsFormer() { } func (s *GroupsAPISuite) TestGroupsShow() { - group, err := s.client.ShowGroup("1") + group, err := s.client.ShowGroup(context.Background(), "1") s.Require().NoError(err) s.Assert().NotZero(group) } func (s *GroupsAPISuite) TestGroupsCreate() { - group, err := s.client.CreateGroup(GroupSettings{ - "Test", - "This is a test group", - "www.blank.com/image", - false, - true, - }) + group, err := s.client.CreateGroup( + context.Background(), + GroupSettings{ + "Test", + "This is a test group", + "www.blank.com/image", + false, + true, + }, + ) s.Require().NoError(err) s.Assert().NotZero(group) } func (s *GroupsAPISuite) TestGroupsUpdate() { - group, err := s.client.UpdateGroup("1", GroupSettings{ + group, err := s.client.UpdateGroup(context.Background(), "1", GroupSettings{ "Test", "This is a test group", "www.blank.com/image", @@ -69,24 +77,25 @@ func (s *GroupsAPISuite) TestGroupsUpdate() { } func (s *GroupsAPISuite) TestGroupsDestroy() { - err := s.client.DestroyGroup("1") + err := s.client.DestroyGroup(context.Background(), "1") s.Require().NoError(err) } func (s *GroupsAPISuite) TestGroupsJoin() { - group, err := s.client.JoinGroup("1", "please") + group, err := s.client.JoinGroup(context.Background(), "1", "please") s.Require().NoError(err) s.Assert().NotZero(group) } func (s *GroupsAPISuite) TestGroupsRejoin() { - group, err := s.client.RejoinGroup("1") + group, err := s.client.RejoinGroup(context.Background(), "1") s.Require().NoError(err) s.Assert().NotZero(group) } func (s *GroupsAPISuite) TestGroupsChangeOwner() { result, err := s.client.ChangeGroupOwner( + context.Background(), ChangeOwnerRequest{ "1", "123", @@ -99,8 +108,9 @@ func TestGroupsAPISuite(t *testing.T) { suite.Run(t, new(GroupsAPISuite)) } -////////// Test Groups Router ////////// +/*//////// Test Groups Router ////////*/ +// nolint // not duplicate code func groupsTestRouter() *mux.Router { router := mux.NewRouter().Queries("token", "").Subrouter() diff --git a/json.go b/json.go index 82d8145..327c45f 100755 --- a/json.go +++ b/json.go @@ -1,3 +1,4 @@ +// Package groupme defines a client capable of executing API commands for the GroupMe chat service package groupme import ( @@ -53,7 +54,7 @@ type MessagePreview struct { // GetMemberByUserID gets the group member by their UserID, // nil if no member matches -func (g Group) GetMemberByUserID(userID ID) *Member { +func (g *Group) GetMemberByUserID(userID ID) *Member { for _, member := range g.Members { if member.UserID == userID { return member @@ -65,7 +66,7 @@ func (g Group) GetMemberByUserID(userID ID) *Member { // GetMemberByNickname gets the group member by their Nickname, // nil if no member matches -func (g Group) GetMemberByNickname(nickname string) *Member { +func (g *Group) GetMemberByNickname(nickname string) *Member { for _, member := range g.Members { if member.Nickname == nickname { return member @@ -75,8 +76,8 @@ func (g Group) GetMemberByNickname(nickname string) *Member { return nil } -func (g Group) String() string { - return marshal(&g) +func (g *Group) String() string { + return marshal(g) } // Member is a GroupMe group member, returned in JSON API responses @@ -93,8 +94,8 @@ type Member struct { Email string `json:"email,omitempty"` // Only used when searching for the member to add to a group. } -func (m Member) String() string { - return marshal(&m) +func (m *Member) String() string { + return marshal(m) } // Message is a GroupMe group message, returned in JSON API responses @@ -106,7 +107,7 @@ type Message struct { UserID ID `json:"user_id,omitempty"` BotID ID `json:"bot_id,omitempty"` SenderID ID `json:"sender_id,omitempty"` - SenderType SenderType `json:"sender_type,omitempty"` + SenderType senderType `json:"sender_type,omitempty"` System bool `json:"system,omitempty"` Name string `json:"name,omitempty"` RecipientID ID `json:"recipient_id,omitempty"` @@ -120,32 +121,32 @@ type Message struct { Attachments []*Attachment `json:"attachments,omitempty"` } -func (m Message) String() string { - return marshal(&m) +func (m *Message) String() string { + return marshal(m) } -type SenderType string +type senderType string // SenderType constants const ( - SenderType_User SenderType = "user" - SenderType_Bot SenderType = "bot" - SenderType_System SenderType = "system" + SenderTypeUser senderType = "user" + SenderTypeBot senderType = "bot" + SenderTypeSystem senderType = "system" ) -type AttachmentType string +type attachmentType string // AttachmentType constants const ( - Mentions AttachmentType = "mentions" - Image AttachmentType = "image" - Location AttachmentType = "location" - Emoji AttachmentType = "emoji" + Mentions attachmentType = "mentions" + Image attachmentType = "image" + Location attachmentType = "location" + Emoji attachmentType = "emoji" ) // Attachment is a GroupMe message attachment, returned in JSON API responses type Attachment struct { - Type AttachmentType `json:"type,omitempty"` + Type attachmentType `json:"type,omitempty"` Loci [][]int `json:"loci,omitempty"` UserIDs []ID `json:"user_ids,omitempty"` URL string `json:"url,omitempty"` @@ -156,8 +157,8 @@ type Attachment struct { Charmap [][]int `json:"charmap,omitempty"` } -func (a Attachment) String() string { - return marshal(&a) +func (a *Attachment) String() string { + return marshal(a) } // User is a GroupMe user, returned in JSON API responses @@ -173,8 +174,8 @@ type User struct { SMS bool `json:"sms,omitempty"` } -func (u User) String() string { - return marshal(&u) +func (u *User) String() string { + return marshal(u) } // Chat is a GroupMe direct message conversation between two users, @@ -187,10 +188,11 @@ type Chat struct { OtherUser User `json:"other_user,omitempty"` } -func (c Chat) String() string { - return marshal(&c) +func (c *Chat) String() string { + return marshal(c) } +// Bot is a GroupMe bot, it is connected to a specific group which it can send messages to type Bot struct { BotID ID `json:"bot_id,omitempty"` GroupID ID `json:"group_id,omitempty"` @@ -200,10 +202,11 @@ type Bot struct { DMNotification bool `json:"dm_notification,omitempty"` } -func (b Bot) String() string { - return marshal(&b) +func (b *Bot) String() string { + return marshal(b) } +// Block is a GroupMe block between two users, direct messages are not allowed type Block struct { UserID ID `json:"user_id,omitempty"` BlockedUserID ID `json:"blocked_user_id,omitempty"` diff --git a/json_test.go b/json_test.go index 841e596..7c9d7ae 100755 --- a/json_test.go +++ b/json_test.go @@ -1,3 +1,4 @@ +// Package groupme defines a client capable of executing API commands for the GroupMe chat service package groupme import ( diff --git a/leaderboard_api.go b/leaderboard_api.go index 0d5b14b..ab46031 100644 --- a/leaderboard_api.go +++ b/leaderboard_api.go @@ -1,13 +1,15 @@ +// Package groupme defines a client capable of executing API commands for the GroupMe chat service package groupme import ( + "context" "fmt" "net/http" ) // GroupMe documentation: https://dev.groupme.com/docs/v3#leaderboard -////////// Endpoints ////////// +/*//////// Endpoints ////////*/ const ( // Used to build other endpoints leaderboardEndpointRoot = groupEndpointRoot + "/likes" @@ -18,34 +20,22 @@ const ( myHitsLeaderboardEndpoint = leaderboardEndpointRoot + "/for_me" // GET ) -////////// API Requests ////////// +/*//////// API Requests ////////*/ // Index type period string -func (p period) String() string { - return string(p) -} - // Define acceptable period values const ( - Period_Day = "day" - Period_Week = "week" - Period_Month = "month" + PeriodDay = "day" + PeriodWeek = "week" + PeriodMonth = "month" ) -/* -IndexLeaderboard - - -A list of the liked messages in the group for a given period of -time. Messages are ranked in order of number of likes. - -Parameters: - groupID - required, ID(string) - p - required, period(string) -*/ -func (c *Client) IndexLeaderboard(groupID ID, p period) ([]*Message, error) { +// IndexLeaderboard - A list of the liked messages in the group for a given period of +// time. Messages are ranked in order of number of likes. +func (c *Client) IndexLeaderboard(ctx context.Context, groupID ID, p period) ([]*Message, error) { url := fmt.Sprintf(c.endpointBase+indexLeaderboardEndpoint, groupID) httpReq, err := http.NewRequest("GET", url, nil) if err != nil { @@ -54,13 +44,13 @@ func (c *Client) IndexLeaderboard(groupID ID, p period) ([]*Message, error) { URL := httpReq.URL query := URL.Query() - query.Set("period", p.String()) + query.Set("period", string(p)) URL.RawQuery = query.Encode() var resp struct { Messages []*Message `json:"messages"` } - err = c.doWithAuthToken(httpReq, &resp) + err = c.doWithAuthToken(ctx, httpReq, &resp) if err != nil { return nil, err } @@ -80,7 +70,7 @@ timestamp in ISO-8601 format. Parameters: groupID - required, ID(string) */ -func (c *Client) MyLikesLeaderboard(groupID ID) ([]*Message, error) { +func (c *Client) MyLikesLeaderboard(ctx context.Context, groupID ID) ([]*Message, error) { url := fmt.Sprintf(c.endpointBase+myLikesLeaderboardEndpoint, groupID) httpReq, err := http.NewRequest("GET", url, nil) if err != nil { @@ -90,7 +80,7 @@ func (c *Client) MyLikesLeaderboard(groupID ID) ([]*Message, error) { var resp struct { Messages []*Message `json:"messages"` } - err = c.doWithAuthToken(httpReq, &resp) + err = c.doWithAuthToken(ctx, httpReq, &resp) if err != nil { return nil, err } @@ -110,7 +100,7 @@ timestamp in ISO-8601 format. Parameters: groupID - required, ID(string) */ -func (c *Client) MyHitsLeaderboard(groupID ID) ([]*Message, error) { +func (c *Client) MyHitsLeaderboard(ctx context.Context, groupID ID) ([]*Message, error) { url := fmt.Sprintf(c.endpointBase+myHitsLeaderboardEndpoint, groupID) httpReq, err := http.NewRequest("GET", url, nil) if err != nil { @@ -120,7 +110,7 @@ func (c *Client) MyHitsLeaderboard(groupID ID) ([]*Message, error) { var resp struct { Messages []*Message `json:"messages"` } - err = c.doWithAuthToken(httpReq, &resp) + err = c.doWithAuthToken(ctx, httpReq, &resp) if err != nil { return nil, err } diff --git a/leaderboard_api_test.go b/leaderboard_api_test.go index 95ffa3b..3d2fc25 100644 --- a/leaderboard_api_test.go +++ b/leaderboard_api_test.go @@ -1,6 +1,8 @@ +// Package groupme defines a client capable of executing API commands for the GroupMe chat service package groupme import ( + "context" "fmt" "net/http" "testing" @@ -17,7 +19,7 @@ func (s *LeaderboardAPISuite) SetupSuite() { } func (s *LeaderboardAPISuite) TestLeaderboardIndex() { - messages, err := s.client.IndexLeaderboard("1", Period_Day) + messages, err := s.client.IndexLeaderboard(context.Background(), "1", PeriodDay) s.Require().NoError(err) s.Require().NotZero(messages) for _, message := range messages { @@ -26,7 +28,7 @@ func (s *LeaderboardAPISuite) TestLeaderboardIndex() { } func (s *LeaderboardAPISuite) TestLeaderboardMyLikes() { - messages, err := s.client.MyLikesLeaderboard("1") + messages, err := s.client.MyLikesLeaderboard(context.Background(), "1") s.Require().NoError(err) s.Require().NotZero(messages) for _, message := range messages { @@ -35,7 +37,7 @@ func (s *LeaderboardAPISuite) TestLeaderboardMyLikes() { } func (s *LeaderboardAPISuite) TestLeaderboardMyHits() { - messages, err := s.client.MyHitsLeaderboard("1") + messages, err := s.client.MyHitsLeaderboard(context.Background(), "1") s.Require().NoError(err) s.Require().NotZero(messages) for _, message := range messages { @@ -47,6 +49,7 @@ func TestLeaderboardAPISuite(t *testing.T) { suite.Run(t, new(LeaderboardAPISuite)) } +// nolint // not duplicate code func leaderboardTestRouter() *mux.Router { router := mux.NewRouter().Queries("token", "").Subrouter() diff --git a/likes_api.go b/likes_api.go index 4107053..107396c 100644 --- a/likes_api.go +++ b/likes_api.go @@ -1,13 +1,15 @@ +// Package groupme defines a client capable of executing API commands for the GroupMe chat service package groupme import ( + "context" "fmt" "net/http" ) // GroupMe documentation: https://dev.groupme.com/docs/v3#likes -////////// Endpoints ////////// +/*//////// Endpoints ////////*/ const ( // Used to build other endpoints likesEndpointRoot = "/messages/%s/%s" @@ -16,20 +18,12 @@ const ( destroyLikeEndpoint = likesEndpointRoot + "/unlike" // POST ) -////////// API Requests ///////// +/*//////// API Requests ////////*/ // Create -/* -CreateLike - - -Like a message. - -Parameters: - conversationID - required, ID(string) - messageID - required, ID(string) -*/ -func (c *Client) CreateLike(conversationID, messageID ID) error { +// CreateLike - Like a message. +func (c *Client) CreateLike(ctx context.Context, conversationID, messageID ID) error { url := fmt.Sprintf(c.endpointBase+createLikeEndpoint, conversationID, messageID) httpReq, err := http.NewRequest("POST", url, nil) @@ -37,21 +31,11 @@ func (c *Client) CreateLike(conversationID, messageID ID) error { return err } - return c.doWithAuthToken(httpReq, nil) + return c.doWithAuthToken(ctx, httpReq, nil) } -// Destroy - -/* -DestroyLike - - -Unlike a message. - -Parameters: - conversationID - required, ID(string) - messageID - required, ID(string) -*/ -func (c *Client) DestroyLike(conversationID, messageID ID) error { +// DestroyLike - Unlike a message. +func (c *Client) DestroyLike(ctx context.Context, conversationID, messageID ID) error { url := fmt.Sprintf(c.endpointBase+destroyLikeEndpoint, conversationID, messageID) httpReq, err := http.NewRequest("POST", url, nil) @@ -59,5 +43,5 @@ func (c *Client) DestroyLike(conversationID, messageID ID) error { return err } - return c.doWithAuthToken(httpReq, nil) + return c.doWithAuthToken(ctx, httpReq, nil) } diff --git a/likes_api_test.go b/likes_api_test.go index a9b88a3..cb10224 100644 --- a/likes_api_test.go +++ b/likes_api_test.go @@ -1,6 +1,8 @@ +// Package groupme defines a client capable of executing API commands for the GroupMe chat service package groupme import ( + "context" "net/http" "testing" @@ -16,18 +18,20 @@ func (s *LikesAPISuite) SetupSuite() { } func (s *LikesAPISuite) TestLikesCreate() { - err := s.client.CreateLike("1", "1") + err := s.client.CreateLike(context.Background(), "1", "1") s.Require().NoError(err) } func (s *LikesAPISuite) TestLikesDestroy() { - err := s.client.DestroyLike("1", "1") + err := s.client.DestroyLike(context.Background(), "1", "1") s.Require().NoError(err) } func TestLikesAPISuite(t *testing.T) { suite.Run(t, new(LikesAPISuite)) } + +// nolint // not duplicate code func likesTestRouter() *mux.Router { router := mux.NewRouter().Queries("token", "").Subrouter() diff --git a/main_test.go b/main_test.go index 6499827..bb928e2 100755 --- a/main_test.go +++ b/main_test.go @@ -1,3 +1,4 @@ +// Package groupme defines a client capable of executing API commands for the GroupMe chat service package groupme import ( @@ -14,7 +15,7 @@ import ( "github.com/stretchr/testify/suite" ) -////////// Base API Suite ////////// +/*//////// Base API Suite ////////*/ type APISuite struct { // Base attributes suite.Suite @@ -22,7 +23,7 @@ type APISuite struct { server *http.Server wg sync.WaitGroup - // Overriden by child Suite + // Overridden by child Suite addr string handler http.Handler } @@ -42,7 +43,7 @@ func (s *APISuite) TearDownSuite() { s.wg.Wait() } -///// Start Server ///// +/*/// Start Server ///*/ func (s *APISuite) startServer(addr string, handler http.Handler) *http.Server { server := &http.Server{ Addr: addr, @@ -60,6 +61,7 @@ func (s *APISuite) startServer(addr string, handler http.Handler) *http.Server { // Wait until server has started listening url := fmt.Sprintf("http://%s", addr) + // nolint // url is meant to be variable for _, err := http.Get(url); err != nil; _, err = http.Get(url) { continue } @@ -67,7 +69,7 @@ func (s *APISuite) startServer(addr string, handler http.Handler) *http.Server { return server } -///// Generate Ephemeral Port ///// +/*/// Generate Ephemeral Port ///*/ const ( portMin = 49152 portMax = 65535 @@ -76,10 +78,11 @@ const ( func (s *APISuite) generatePort() string { rand.Seed(time.Now().UnixNano()) + // nolint // weak random generator is ok for creating port number in a test return strconv.Itoa((rand.Intn(portRange) + portMin)) } -////////// Test Main ////////// +/*//////// Test Main ////////*/ func TestMain(m *testing.M) { os.Exit(m.Run()) } diff --git a/members_api.go b/members_api.go index 4ec156e..6a11eb0 100644 --- a/members_api.go +++ b/members_api.go @@ -1,7 +1,9 @@ +// Package groupme defines a client capable of executing API commands for the GroupMe chat service package groupme import ( "bytes" + "context" "encoding/json" "fmt" "net/http" @@ -9,7 +11,7 @@ import ( // GroupMe documentation: https://dev.groupme.com/docs/v3#members -////////// Endpoints ////////// +/*//////// Endpoints ////////*/ const ( // Used to build other endpoints membersEndpointRoot = groupEndpointRoot + "/members" @@ -21,7 +23,7 @@ const ( updateMemberEndpoint = groupEndpointRoot + "/memberships/update" // POST ) -///// Add ///// +/*/// Add ///*/ /* AddMembers - @@ -46,7 +48,7 @@ Parameters: PhoneNumber - PhoneNumber(string) Email - string */ -func (c *Client) AddMembers(groupID ID, members ...*Member) (string, error) { +func (c *Client) AddMembers(ctx context.Context, groupID ID, members ...*Member) (string, error) { URL := fmt.Sprintf(c.endpointBase+addMembersEndpoint, groupID) var data = struct { @@ -69,7 +71,7 @@ func (c *Client) AddMembers(groupID ID, members ...*Member) (string, error) { ResultsID string `json:"results_id"` } - err = c.doWithAuthToken(httpReq, &resp) + err = c.doWithAuthToken(ctx, httpReq, &resp) if err != nil { return "", err } @@ -77,7 +79,7 @@ func (c *Client) AddMembers(groupID ID, members ...*Member) (string, error) { return resp.ResultsID, nil } -///// Results ///// +/*/// Results ///*/ /* AddMembersResults - @@ -95,7 +97,7 @@ Parameters: groupID - required, ID(string) resultID - required, string */ -func (c *Client) AddMembersResults(groupID ID, resultID string) ([]*Member, error) { +func (c *Client) AddMembersResults(ctx context.Context, groupID ID, resultID string) ([]*Member, error) { URL := fmt.Sprintf(c.endpointBase+addMembersResultsEndpoint, groupID, resultID) httpReq, err := http.NewRequest("GET", URL, nil) @@ -107,7 +109,7 @@ func (c *Client) AddMembersResults(groupID ID, resultID string) ([]*Member, erro Members []*Member `json:"members"` } - err = c.doWithAuthToken(httpReq, &resp) + err = c.doWithAuthToken(ctx, httpReq, &resp) if err != nil { return nil, err } @@ -115,7 +117,7 @@ func (c *Client) AddMembersResults(groupID ID, resultID string) ([]*Member, erro return resp.Members, nil } -///// Remove ///// +/*/// Remove ///*/ /* RemoveMember - @@ -128,7 +130,7 @@ Parameters: groupID - required, ID(string) membershipID - required, ID(string). Not the same as userID */ -func (c *Client) RemoveMember(groupID, membershipID ID) error { +func (c *Client) RemoveMember(ctx context.Context, groupID, membershipID ID) error { URL := fmt.Sprintf(c.endpointBase+removeMemberEndpoint, groupID, membershipID) httpReq, err := http.NewRequest("POST", URL, nil) @@ -136,10 +138,10 @@ func (c *Client) RemoveMember(groupID, membershipID ID) error { return err } - return c.doWithAuthToken(httpReq, nil) + return c.doWithAuthToken(ctx, httpReq, nil) } -///// Update ///// +/*/// Update ///*/ /* UpdateMember - @@ -147,7 +149,7 @@ UpdateMember - Update your nickname in a group. The nickname must be between 1 and 50 characters. */ -func (c *Client) UpdateMember(groupID ID, nickname string) (*Member, error) { +func (c *Client) UpdateMember(ctx context.Context, groupID ID, nickname string) (*Member, error) { URL := fmt.Sprintf(c.endpointBase+updateMemberEndpoint, groupID) type Nickname struct { @@ -171,7 +173,7 @@ func (c *Client) UpdateMember(groupID ID, nickname string) (*Member, error) { var resp Member - err = c.doWithAuthToken(httpReq, &resp) + err = c.doWithAuthToken(ctx, httpReq, &resp) if err != nil { return nil, err } diff --git a/members_api_test.go b/members_api_test.go index 809f1ff..f9b82d1 100644 --- a/members_api_test.go +++ b/members_api_test.go @@ -1,6 +1,8 @@ +// Package groupme defines a client capable of executing API commands for the GroupMe chat service package groupme import ( + "context" "fmt" "net/http" "testing" @@ -18,6 +20,7 @@ func (s *MembersAPISuite) SetupSuite() { func (s *MembersAPISuite) TestMembersAdd() { _, err := s.client.AddMembers( + context.Background(), "1", &Member{Nickname: "test"}, ) @@ -25,17 +28,17 @@ func (s *MembersAPISuite) TestMembersAdd() { } func (s *MembersAPISuite) TestMembersResults() { - _, err := s.client.AddMembersResults("1", "123") + _, err := s.client.AddMembersResults(context.Background(), "1", "123") s.Require().NoError(err) } func (s *MembersAPISuite) TestMembersRemove() { - err := s.client.RemoveMember("1", "123") + err := s.client.RemoveMember(context.Background(), "1", "123") s.Require().NoError(err) } func (s *MembersAPISuite) TestMembersUpdate() { - _, err := s.client.UpdateMember("1", "nickname") + _, err := s.client.UpdateMember(context.Background(), "1", "nickname") s.Require().NoError(err) } diff --git a/messages_api.go b/messages_api.go index 73cf913..93223b2 100644 --- a/messages_api.go +++ b/messages_api.go @@ -1,7 +1,9 @@ +// Package groupme defines a client capable of executing API commands for the GroupMe chat service package groupme import ( "bytes" + "context" "encoding/json" "fmt" "net/http" @@ -12,7 +14,7 @@ import ( // GroupMe documentation: https://dev.groupme.com/docs/v3#messages -////////// Endpoints ////////// +/*//////// Endpoints ////////*/ const ( // Used to build other endpoints messagesEndpointRoot = groupEndpointRoot + "/messages" @@ -21,9 +23,7 @@ const ( createMessagesEndpoint = messagesEndpointRoot // POST ) -// Index - -// MessagesQuery defines the optional URL parameters for IndexMessages +// IndexMessagesQuery defines the optional URL parameters for IndexMessages type IndexMessagesQuery struct { // Returns messages created before the given message ID BeforeID ID @@ -39,7 +39,7 @@ func (q IndexMessagesQuery) String() string { return marshal(&q) } -// MessagesIndexResponse contains the count and set of +// IndexMessagesResponse contains the count and set of // messages returned by the IndexMessages API request type IndexMessagesResponse struct { Count int `json:"count"` @@ -51,41 +51,31 @@ func (r IndexMessagesResponse) String() string { } /* -IndexMessages - - -Retrieve messages for a group. - +IndexMessages - Retrieves messages for a group. By default, messages are returned in groups of 20, ordered by created_at descending. This can be raised or lowered by passing a limit parameter, up to a maximum of 100 messages. - Messages can be scanned by providing a message ID as either the before_id, since_id, or after_id parameter. If before_id is provided, then messages immediately preceding the given message will be returned, in descending order. This can be used to continually page back through a group's messages. - The after_id parameter will return messages that immediately follow a given message, this time in ascending order (which makes it easy to pick off the last result for continued pagination). - Finally, the since_id parameter also returns messages created after the given message, but it retrieves the most recent messages. For example, if more than twenty messages are created after the since_id message, using this parameter will omit the messages that immediately follow the given message. This is a bit counterintuitive, so take care. - If no messages are found (e.g. when filtering with before_id) we return code 304. - Note that for historical reasons, likes are returned as an array of user ids in the favorited_by key. - -Parameters: See MessageQuery */ -func (c *Client) IndexMessages(groupID ID, req *IndexMessagesQuery) (IndexMessagesResponse, error) { +func (c *Client) IndexMessages(ctx context.Context, groupID ID, req *IndexMessagesQuery) (IndexMessagesResponse, error) { url := fmt.Sprintf(c.endpointBase+indexMessagesEndpoint, groupID) httpReq, err := http.NewRequest("GET", url, nil) if err != nil { @@ -111,7 +101,7 @@ func (c *Client) IndexMessages(groupID ID, req *IndexMessagesQuery) (IndexMessag URL.RawQuery = query.Encode() var resp IndexMessagesResponse - err = c.doWithAuthToken(httpReq, &resp) + err = c.doWithAuthToken(ctx, httpReq, &resp) if err != nil { return IndexMessagesResponse{}, err } @@ -119,11 +109,8 @@ func (c *Client) IndexMessages(groupID ID, req *IndexMessagesQuery) (IndexMessag return resp, nil } -// Create - /* -CreateMessage - -Send a message to a group +CreateMessage - Send a message to a group If you want to attach an image, you must first process it through our image service. @@ -137,19 +124,8 @@ The character map is an array of arrays containing rune data ([[{pack_id,offset}],...]). The placeholder should be a high-point/invisible UTF-8 character. - -Parameters: - groupID - required, ID(String) - See Message. - text - required, string. Can be ommitted if at least one - attachment is present - attachments - a polymorphic list of attachments (locations, - images, etc). You may have You may have more than - one of any type of attachment, provided clients can - display it. - */ -func (c *Client) CreateMessage(groupID ID, m *Message) (*Message, error) { +func (c *Client) CreateMessage(ctx context.Context, groupID ID, m *Message) (*Message, error) { URL := fmt.Sprintf(c.endpointBase+createMessagesEndpoint, groupID) m.SourceGUID = uuid.New().String() @@ -172,7 +148,7 @@ func (c *Client) CreateMessage(groupID ID, m *Message) (*Message, error) { var resp struct { *Message `json:"message"` } - err = c.doWithAuthToken(httpReq, &resp) + err = c.doWithAuthToken(ctx, httpReq, &resp) if err != nil { return nil, err } diff --git a/messages_api_test.go b/messages_api_test.go index b8c8d36..ada7e28 100644 --- a/messages_api_test.go +++ b/messages_api_test.go @@ -1,6 +1,8 @@ +// Package groupme defines a client capable of executing API commands for the GroupMe chat service package groupme import ( + "context" "fmt" "net/http" "testing" @@ -18,6 +20,7 @@ func (s *MessagesAPISuite) SetupSuite() { func (s *MessagesAPISuite) TestMessagesIndex() { resp, err := s.client.IndexMessages( + context.Background(), ID("123"), &IndexMessagesQuery{ BeforeID: "0123456789", @@ -35,6 +38,7 @@ func (s *MessagesAPISuite) TestMessagesIndex() { func (s *MessagesAPISuite) TestMessagesCreate() { message, err := s.client.CreateMessage( + context.Background(), ID("123"), &Message{ Text: "Test", @@ -49,6 +53,7 @@ func TestMessagesAPISuite(t *testing.T) { suite.Run(t, new(MessagesAPISuite)) } +// nolint // not duplicate code func messagesTestRouter() *mux.Router { router := mux.NewRouter().Queries("token", "").Subrouter() diff --git a/sms_mode_api.go b/sms_mode_api.go index 3de6f01..5d1ccb5 100644 --- a/sms_mode_api.go +++ b/sms_mode_api.go @@ -1,7 +1,9 @@ +// Package groupme defines a client capable of executing API commands for the GroupMe chat service package groupme import ( "bytes" + "context" "encoding/json" "fmt" "net/http" @@ -9,7 +11,7 @@ import ( // GroupMe documentation: https://dev.groupme.com/docs/v3#sms_mode -////////// Endpoints ////////// +/*//////// Endpoints ////////*/ const ( // Used to build other endpoints smsModeEndpointRoot = usersEndpointRoot + "/sms_mode" @@ -19,7 +21,7 @@ const ( deleteSMSModeEndpoint = smsModeEndpointRoot + "/delete" // POST ) -////////// API Requests ////////// +/*//////// API Requests ////////*/ // Create @@ -35,7 +37,7 @@ Parameters: omitted, both SMS and push notifications will be delivered to the device. */ -func (c *Client) CreateSMSMode(duration int, registrationID *ID) error { +func (c *Client) CreateSMSMode(ctx context.Context, duration int, registrationID *ID) error { URL := fmt.Sprintf(c.endpointBase + createSMSModeEndpoint) var data = struct { @@ -56,7 +58,7 @@ func (c *Client) CreateSMSMode(duration int, registrationID *ID) error { return err } - err = c.doWithAuthToken(httpReq, nil) + err = c.doWithAuthToken(ctx, httpReq, nil) if err != nil { return err } @@ -71,7 +73,7 @@ DeleteSMSMode - Disables SMS mode */ -func (c *Client) DeleteSMSMode() error { +func (c *Client) DeleteSMSMode(ctx context.Context) error { url := fmt.Sprintf(c.endpointBase + deleteSMSModeEndpoint) httpReq, err := http.NewRequest("POST", url, nil) @@ -79,5 +81,5 @@ func (c *Client) DeleteSMSMode() error { return err } - return c.doWithAuthToken(httpReq, nil) + return c.doWithAuthToken(ctx, httpReq, nil) } diff --git a/sms_mode_api_test.go b/sms_mode_api_test.go index 3f6e673..3d6c4be 100644 --- a/sms_mode_api_test.go +++ b/sms_mode_api_test.go @@ -1,6 +1,8 @@ +// Package groupme defines a client capable of executing API commands for the GroupMe chat service package groupme import ( + "context" "net/http" "testing" @@ -16,16 +18,17 @@ func (s *SMSModeAPISuite) SetupSuite() { } func (s *SMSModeAPISuite) TestSMSModeCreate() { - s.Assert().NoError(s.client.CreateSMSMode(10, nil)) + s.Assert().NoError(s.client.CreateSMSMode(context.Background(), 10, nil)) } func (s *SMSModeAPISuite) TestSMSModeDelete() { - s.Assert().NoError(s.client.DeleteSMSMode()) + s.Assert().NoError(s.client.DeleteSMSMode(context.Background())) } func TestSMSModeAPISuite(t *testing.T) { suite.Run(t, new(SMSModeAPISuite)) } +// nolint // not duplicate code func smsModeTestRouter() *mux.Router { router := mux.NewRouter().Queries("token", "").Subrouter() diff --git a/users_api.go b/users_api.go index 1459db8..3e05f93 100644 --- a/users_api.go +++ b/users_api.go @@ -1,7 +1,9 @@ +// Package groupme defines a client capable of executing API commands for the GroupMe chat service package groupme import ( "bytes" + "context" "encoding/json" "fmt" "net/http" @@ -9,7 +11,7 @@ import ( // GroupMe documentation: https://dev.groupme.com/docs/v3#users -////////// Endpoints ////////// +/*//////// Endpoints ////////*/ const ( // Used to build other endpoints usersEndpointRoot = "/users" @@ -19,7 +21,7 @@ const ( updateMyUserEndpoint = usersEndpointRoot + "/update" // POST ) -////////// API Requests ////////// +/*//////// API Requests ////////*/ // Me @@ -31,7 +33,7 @@ Loads a specific group. Parameters: groupID - required, ID(string) */ -func (c *Client) MyUser() (*User, error) { +func (c *Client) MyUser(ctx context.Context) (*User, error) { URL := fmt.Sprintf(c.endpointBase + myUserEndpoint) httpReq, err := http.NewRequest("GET", URL, nil) @@ -40,7 +42,7 @@ func (c *Client) MyUser() (*User, error) { } var resp User - err = c.doWithAuthToken(httpReq, &resp) + err = c.doWithAuthToken(ctx, httpReq, &resp) if err != nil { return nil, err } @@ -48,8 +50,7 @@ func (c *Client) MyUser() (*User, error) { return &resp, nil } -// Update - +// UserSettings are the settings for a GroupMe user type UserSettings struct { // URL to valid JPG/PNG/GIF image. URL will be converted into // an image service link (https://i.groupme.com/....) @@ -68,7 +69,7 @@ Update attributes about your own account Parameters: See UserSettings */ -func (c *Client) UpdateMyUser(us UserSettings) (*User, error) { +func (c *Client) UpdateMyUser(ctx context.Context, us UserSettings) (*User, error) { URL := fmt.Sprintf(c.endpointBase + updateMyUserEndpoint) jsonBytes, err := json.Marshal(&us) @@ -82,7 +83,7 @@ func (c *Client) UpdateMyUser(us UserSettings) (*User, error) { } var resp User - err = c.doWithAuthToken(httpReq, &resp) + err = c.doWithAuthToken(ctx, httpReq, &resp) if err != nil { return nil, err } diff --git a/users_api_test.go b/users_api_test.go index b3c1015..0cac439 100644 --- a/users_api_test.go +++ b/users_api_test.go @@ -1,6 +1,8 @@ +// Package groupme defines a client capable of executing API commands for the GroupMe chat service package groupme import ( + "context" "fmt" "net/http" "testing" @@ -17,13 +19,13 @@ func (s *UsersAPISuite) SetupSuite() { } func (s *UsersAPISuite) TestUsersMe() { - user, err := s.client.MyUser() + user, err := s.client.MyUser(context.Background()) s.Require().NoError(err) s.Assert().NotZero(user) } func (s *UsersAPISuite) TestUsersUpdate() { - user, err := s.client.UpdateMyUser(UserSettings{}) + user, err := s.client.UpdateMyUser(context.Background(), UserSettings{}) s.Require().NoError(err) s.Assert().NotZero(user) } @@ -31,6 +33,8 @@ func (s *UsersAPISuite) TestUsersUpdate() { func TestUsersAPISuite(t *testing.T) { suite.Run(t, new(UsersAPISuite)) } + +// nolint // not duplicate code func usersTestRouter() *mux.Router { router := mux.NewRouter().Queries("token", "").Subrouter()