Skip to content
  •  
  •  
  •  
3 changes: 3 additions & 0 deletions client/base_client.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package client

import (
"context"
"net/http"
"net/url"
"time"
Expand All @@ -13,4 +14,6 @@ type BaseClient interface {
headers map[string]interface{}, body ...byte) (*http.Response, error)
SetOauth(auth OAuth)
OAuth() OAuth
SendRequestWithContext(ctx context.Context, method string, rawURL string, data url.Values,
headers map[string]interface{}, body ...byte) (*http.Response, error)
}
12 changes: 9 additions & 3 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,12 @@ var userAgentOnce sync.Once
func (c *Client) SendRequest(method string, rawURL string, data url.Values,
headers map[string]interface{}, body ...byte) (*http.Response, error) {

return c.SendRequestWithContext(context.TODO(), method, rawURL, data, headers, body...)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return c.SendRequestWithContext(context.TODO(), method, rawURL, data, headers, body...)
return c.SendRequestWithContext(context.Background(), method, rawURL, data, headers, body...)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For all of these - TODO is "we plan to add context later" but there's no way for us to do that.

}

func (c *Client) SendRequestWithContext(ctx context.Context, method string, rawURL string, data url.Values,
headers map[string]interface{}, body ...byte) (*http.Response, error) {

contentType := extractContentTypeHeader(headers)

u, err := url.Parse(rawURL)
Expand Down Expand Up @@ -167,7 +173,7 @@ func (c *Client) SendRequest(method string, rawURL string, data url.Values,
//data is already processed and information will be added to u(the url) in the
//previous step. Now body will solely contain json payload
if contentType == jsonContentType {
req, err = http.NewRequest(method, u.String(), bytes.NewBuffer(body))
req, err = http.NewRequestWithContext(ctx, method, u.String(), bytes.NewBuffer(body))
if err != nil {
return nil, err
}
Expand All @@ -177,7 +183,7 @@ func (c *Client) SendRequest(method string, rawURL string, data url.Values,
if method == http.MethodPost || method == http.MethodPut || method == http.MethodPatch {
valueReader = strings.NewReader(data.Encode())
}
req, err = http.NewRequestWithContext(context.Background(), method, u.String(), valueReader)
req, err = http.NewRequestWithContext(ctx, method, u.String(), valueReader)
if err != nil {
return nil, err
}
Expand All @@ -203,7 +209,7 @@ func (c *Client) SendRequest(method string, rawURL string, data url.Values,
}
if c.OAuth() != nil {
oauth := c.OAuth()
token, _ := c.OAuth().GetAccessToken(context.TODO())
token, _ := c.OAuth().GetAccessToken(ctx)
if token != "" {
req.Header.Add("Authorization", "Bearer "+token)
}
Expand Down
9 changes: 7 additions & 2 deletions client/page_util.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package client

import (
"context"
"encoding/json"
"fmt"
"strings"
Expand All @@ -25,13 +26,17 @@ func ReadLimits(pageSize *int, limit *int) int {
}
}

func GetNext(baseUrl string, response interface{}, getNextPage func(nextPageUri string) (interface{}, error)) (interface{}, error) {
func GetNext(baseUrl string, response interface{}, getNextPage func(ctx context.Context, nextPageUri string) (interface{}, error)) (interface{}, error) {
return GetNextWithContext(context.TODO(), baseUrl, response, getNextPage)
}

func GetNextWithContext(ctx context.Context, baseUrl string, response interface{}, getNextPage func(ctx context.Context, nextPageUri string) (interface{}, error)) (interface{}, error) {
nextPageUrl, err := getNextPageUrl(baseUrl, response)
if err != nil {
return nil, err
}

return getNextPage(nextPageUrl)
return getNextPage(ctx, nextPageUrl)
}

func toMap(s interface{}) (map[string]interface{}, error) {
Expand Down
7 changes: 4 additions & 3 deletions client/page_util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package client

import (
"bytes"
"context"
"encoding/json"
"io"
"net/http"
Expand Down Expand Up @@ -140,7 +141,7 @@ type testMessage struct {
To *string `json:"to,omitempty"`
}

func getSomething(nextPageUrl string) (interface{}, error) {
func getSomething(ctx context.Context, nextPageUrl string) (interface{}, error) {
return nextPageUrl, nil
}

Expand All @@ -151,11 +152,11 @@ func TestPageUtil_GetNext(t *testing.T) {
ps := &testResponse{}
_ = json.NewDecoder(response.Body).Decode(ps)

nextPageUrl, err := GetNext(baseUrl, ps, getSomething)
nextPageUrl, err := GetNextWithContext(context.TODO(), baseUrl, ps, getSomething)
assert.Equal(t, "https://api.twilio.com/2010-04-01/Accounts/ACXX/Messages.json?From=9999999999&PageNumber=&To=4444444444&PageSize=2&Page=1&PageToken=PASMXX", nextPageUrl)
assert.Nil(t, err)

nextPageUrl, err = GetNext(baseUrl, nil, getSomething)
nextPageUrl, err = GetNextWithContext(context.TODO(), baseUrl, nil, getSomething)
assert.Empty(t, nextPageUrl)
assert.Nil(t, err)
}
Expand Down
32 changes: 13 additions & 19 deletions client/request_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package client

import (
"context"
"net/http"
"net/url"
"os"
Expand All @@ -12,25 +13,18 @@ type RequestHandler struct {
Client BaseClient
Edge string
Region string
ctx context.Context
}

func NewRequestHandler(client BaseClient) *RequestHandler {
return &RequestHandler{
Client: client,
Edge: os.Getenv("TWILIO_EDGE"),
Region: os.Getenv("TWILIO_REGION"),
ctx: context.TODO(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see where we use this, it makes me nervous that we're using this here

}
}

func (c *RequestHandler) sendRequest(method string, rawURL string, data url.Values,
headers map[string]interface{}, body ...byte) (*http.Response, error) {
parsedURL, err := c.BuildUrl(rawURL)
if err != nil {
return nil, err
}
return c.Client.SendRequest(method, parsedURL, data, headers, body...)
}

// BuildUrl builds the target host string taking into account region and edge configurations.
func (c *RequestHandler) BuildUrl(rawURL string) (string, error) {
u, err := url.Parse(rawURL)
Expand Down Expand Up @@ -82,22 +76,22 @@ func (c *RequestHandler) BuildUrl(rawURL string) (string, error) {
return u.String(), nil
}

func (c *RequestHandler) Post(path string, bodyData url.Values, headers map[string]interface{}, body ...byte) (*http.Response, error) {
return c.sendRequest(http.MethodPost, path, bodyData, headers, body...)
func (c *RequestHandler) PostWithContext(ctx context.Context, path string, bodyData url.Values, headers map[string]interface{}, body ...byte) (*http.Response, error) {
return c.Client.SendRequestWithContext(ctx, http.MethodPost, path, bodyData, headers, body...)
}

func (c *RequestHandler) Put(path string, bodyData url.Values, headers map[string]interface{}, body ...byte) (*http.Response, error) {
return c.sendRequest(http.MethodPut, path, bodyData, headers, body...)
func (c *RequestHandler) PutWithContext(ctx context.Context, path string, bodyData url.Values, headers map[string]interface{}, body ...byte) (*http.Response, error) {
return c.Client.SendRequestWithContext(ctx, http.MethodPut, path, bodyData, headers, body...)
}

func (c *RequestHandler) Patch(path string, bodyData url.Values, headers map[string]interface{}, body ...byte) (*http.Response, error) {
return c.sendRequest(http.MethodPatch, path, bodyData, headers, body...)
func (c *RequestHandler) PatchWithContext(ctx context.Context, path string, bodyData url.Values, headers map[string]interface{}, body ...byte) (*http.Response, error) {
return c.Client.SendRequestWithContext(ctx, http.MethodPatch, path, bodyData, headers, body...)
}

func (c *RequestHandler) Get(path string, queryData url.Values, headers map[string]interface{}) (*http.Response, error) {
return c.sendRequest(http.MethodGet, path, queryData, headers)
func (c *RequestHandler) GetWithContext(ctx context.Context, path string, queryData url.Values, headers map[string]interface{}) (*http.Response, error) {
return c.Client.SendRequestWithContext(ctx, http.MethodGet, path, queryData, headers)
}

func (c *RequestHandler) Delete(path string, queryData url.Values, headers map[string]interface{}) (*http.Response, error) {
return c.sendRequest(http.MethodDelete, path, queryData, headers)
func (c *RequestHandler) DeleteWithContext(ctx context.Context, path string, queryData url.Values, headers map[string]interface{}) (*http.Response, error) {
return c.Client.SendRequestWithContext(ctx, http.MethodDelete, path, queryData, headers)
}
5 changes: 3 additions & 2 deletions client/request_handler_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package client_test

import (
"context"
"errors"
"net/http"
"net/http/httptest"
Expand Down Expand Up @@ -83,7 +84,7 @@ func TestRequestHandler_SendGetRequest(t *testing.T) {
defer errorServer.Close()

requestHandler := NewRequestHandler("user", "pass")
resp, err := requestHandler.Get(errorServer.URL, nil, nil) //nolint:bodyclose
resp, err := requestHandler.GetWithContext(context.TODO(), errorServer.URL, nil, nil) //nolint:bodyclose
twilioError := err.(*client.TwilioRestError)
assert.Nil(t, resp)
assert.Equal(t, 400, twilioError.Status)
Expand All @@ -108,7 +109,7 @@ func TestRequestHandler_SendPostRequest(t *testing.T) {
defer errorServer.Close()

requestHandler := NewRequestHandler("user", "pass")
resp, err := requestHandler.Post(errorServer.URL, nil, nil) //nolint:bodyclose
resp, err := requestHandler.PostWithContext(context.TODO(), errorServer.URL, nil, nil) //nolint:bodyclose
twilioError := err.(*client.TwilioRestError)
assert.Nil(t, resp)
assert.Equal(t, 400, twilioError.Status)
Expand Down
24 changes: 24 additions & 0 deletions cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package twilio

import (
"context"
"os"
"testing"

Expand Down Expand Up @@ -268,3 +269,26 @@ func TestOrgsScimUerList(t *testing.T) {
assert.Nil(t, err)
assert.NotNil(t, users)
}

func TestSendingATextWithContext(t *testing.T) {
params := &Api.CreateMessageParams{}
params.SetTo(to)
params.SetFrom(from)
params.SetBody("Hello there")

resp, err := testClient.Api.CreateMessageWithContext(context.TODO(), params)
assert.Nil(t, err)
assert.NotNil(t, resp)
assert.Equal(t, "Hello there", *resp.Body)
assert.Equal(t, from, *resp.From)
assert.Equal(t, to, *resp.To)
}

func TestOrgsAccountsListWithContext(t *testing.T) {
listAccounts, err := orgsClient.PreviewIamOrganization.ListOrganizationAccountsWithContext(context.TODO(), orgSid, &PreviewIam.ListOrganizationAccountsParams{})
assert.Nil(t, err)
assert.NotNil(t, listAccounts)
accounts, err := orgsClient.PreviewIamOrganization.FetchOrganizationAccountWithContext(context.TODO(), orgSid, &PreviewIam.FetchOrganizationAccountParams{PathAccountSid: &accountSidOrgs})
assert.Nil(t, err)
assert.NotNil(t, accounts)
}
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ require (
)

retract (
v1.25.0 // Contains build issue
v1.22.0 // Contains known bug
v1.25.0 // Contains build issue
v1.22.0 // Contains known bug
)
7 changes: 7 additions & 0 deletions rest/accounts/v1/api_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,10 @@ func NewApiService(requestHandler *twilio.RequestHandler) *ApiService {
func NewApiServiceWithClient(client twilio.BaseClient) *ApiService {
return NewApiService(twilio.NewRequestHandler(client))
}

func NewApiServiceWithCtx(requestHandler *twilio.RequestHandler) *ApiService {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure we need this method

return &ApiService{
requestHandler: requestHandler,
baseURL: "https://accounts.twilio.com",
}
}
6 changes: 5 additions & 1 deletion rest/accounts/v1/auth_tokens_promote.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,24 @@
package openapi

import (
"context"
"encoding/json"
"net/url"
)

// Promote the secondary Auth Token to primary. After promoting the new token, all requests to Twilio using your old primary Auth Token will result in an error.
func (c *ApiService) UpdateAuthTokenPromotion() (*AccountsV1AuthTokenPromotion, error) {
return c.UpdateAuthTokenPromotionWithContext(context.TODO())
}
func (c *ApiService) UpdateAuthTokenPromotionWithContext(ctx context.Context) (*AccountsV1AuthTokenPromotion, error) {
path := "/v1/AuthTokens/Promote"

data := url.Values{}
headers := map[string]interface{}{
"Content-Type": "application/x-www-form-urlencoded",
}

resp, err := c.requestHandler.Post(c.baseURL+path, data, headers)
resp, err := c.requestHandler.PostWithContext(ctx, c.baseURL+path, data, headers)
if err != nil {
return nil, err
}
Expand Down
11 changes: 9 additions & 2 deletions rest/accounts/v1/auth_tokens_secondary.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,24 @@
package openapi

import (
"context"
"encoding/json"
"net/url"
)

// Create a new secondary Auth Token
func (c *ApiService) CreateSecondaryAuthToken() (*AccountsV1SecondaryAuthToken, error) {
return c.CreateSecondaryAuthTokenWithContext(context.TODO())
}
func (c *ApiService) CreateSecondaryAuthTokenWithContext(ctx context.Context) (*AccountsV1SecondaryAuthToken, error) {
path := "/v1/AuthTokens/Secondary"

data := url.Values{}
headers := map[string]interface{}{
"Content-Type": "application/x-www-form-urlencoded",
}

resp, err := c.requestHandler.Post(c.baseURL+path, data, headers)
resp, err := c.requestHandler.PostWithContext(ctx, c.baseURL+path, data, headers)
if err != nil {
return nil, err
}
Expand All @@ -45,14 +49,17 @@ func (c *ApiService) CreateSecondaryAuthToken() (*AccountsV1SecondaryAuthToken,

// Delete the secondary Auth Token from your account
func (c *ApiService) DeleteSecondaryAuthToken() error {
return c.DeleteSecondaryAuthTokenWithContext(context.TODO())
}
func (c *ApiService) DeleteSecondaryAuthTokenWithContext(ctx context.Context) error {
path := "/v1/AuthTokens/Secondary"

data := url.Values{}
headers := map[string]interface{}{
"Content-Type": "application/x-www-form-urlencoded",
}

resp, err := c.requestHandler.Delete(c.baseURL+path, data, headers)
resp, err := c.requestHandler.DeleteWithContext(ctx, c.baseURL+path, data, headers)
if err != nil {
return err
}
Expand Down
7 changes: 5 additions & 2 deletions rest/accounts/v1/consents_bulk.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package openapi

import (
"context"
"encoding/json"
"net/url"
)
Expand All @@ -30,8 +31,10 @@ func (params *CreateBulkConsentsParams) SetItems(Items []map[string]interface{})
return params
}

//
func (c *ApiService) CreateBulkConsents(params *CreateBulkConsentsParams) (*AccountsV1BulkConsents, error) {
return c.CreateBulkConsentsWithContext(context.TODO(), params)
}
func (c *ApiService) CreateBulkConsentsWithContext(ctx context.Context, params *CreateBulkConsentsParams) (*AccountsV1BulkConsents, error) {
path := "/v1/Consents/Bulk"

data := url.Values{}
Expand All @@ -51,7 +54,7 @@ func (c *ApiService) CreateBulkConsents(params *CreateBulkConsentsParams) (*Acco
}
}

resp, err := c.requestHandler.Post(c.baseURL+path, data, headers)
resp, err := c.requestHandler.PostWithContext(ctx, c.baseURL+path, data, headers)
if err != nil {
return nil, err
}
Expand Down
7 changes: 5 additions & 2 deletions rest/accounts/v1/contacts_bulk.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package openapi

import (
"context"
"encoding/json"
"net/url"
)
Expand All @@ -30,8 +31,10 @@ func (params *CreateBulkContactsParams) SetItems(Items []map[string]interface{})
return params
}

//
func (c *ApiService) CreateBulkContacts(params *CreateBulkContactsParams) (*AccountsV1BulkContacts, error) {
return c.CreateBulkContactsWithContext(context.TODO(), params)
}
func (c *ApiService) CreateBulkContactsWithContext(ctx context.Context, params *CreateBulkContactsParams) (*AccountsV1BulkContacts, error) {
path := "/v1/Contacts/Bulk"

data := url.Values{}
Expand All @@ -51,7 +54,7 @@ func (c *ApiService) CreateBulkContacts(params *CreateBulkContactsParams) (*Acco
}
}

resp, err := c.requestHandler.Post(c.baseURL+path, data, headers)
resp, err := c.requestHandler.PostWithContext(ctx, c.baseURL+path, data, headers)
if err != nil {
return nil, err
}
Expand Down
Loading
Loading