Skip to content

Commit

Permalink
Add WithContext() methods to the API (#92)
Browse files Browse the repository at this point in the history
Co-authored-by: Neil Garb <[email protected]>
  • Loading branch information
neilgarb and NeilLuno authored Oct 28, 2021
1 parent e00bda2 commit d8d6378
Show file tree
Hide file tree
Showing 13 changed files with 258 additions and 59 deletions.
7 changes: 5 additions & 2 deletions common.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package gotwilio

import (
"context"
"encoding/json"
"io/ioutil"
"net/http"
Expand All @@ -20,11 +21,13 @@ type ListResources struct {
Messages []*SmsResponse `json:"messages"`

t *Twilio
ctx context.Context
}

func (t *Twilio) newListResources() *ListResources {
func (t *Twilio) newListResources(ctx context.Context) *ListResources {
lr := new(ListResources)
lr.t = t
lr.ctx = ctx
return lr
}

Expand All @@ -33,7 +36,7 @@ func (l *ListResources) hasNext() bool {
}

func (l *ListResources) next() (*Exception, error) {
resp, err := l.t.get(l.NextPageUri)
resp, err := l.t.get(l.ctx, l.NextPageUri)
if err != nil {
return nil, err
}
Expand Down
43 changes: 36 additions & 7 deletions conference.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package gotwilio

import (
"context"
"encoding/json"
"fmt"
"net/http"
Expand Down Expand Up @@ -79,7 +80,11 @@ type ConferenceParticipantOptions struct {
// GetConference fetches details for a single conference instance
// https://www.twilio.com/docs/voice/api/conference-resource#fetch-a-conference-resource
func (twilio *Twilio) GetConference(conferenceSid string) (*Conference, *Exception, error) {
res, err := twilio.get(twilio.buildUrl(fmt.Sprintf("Conferences/%s.json", conferenceSid)))
return twilio.GetConferenceWithContext(context.Background(), conferenceSid)
}

func (twilio *Twilio) GetConferenceWithContext(ctx context.Context, conferenceSid string) (*Conference, *Exception, error) {
res, err := twilio.get(ctx, twilio.buildUrl(fmt.Sprintf("Conferences/%s.json", conferenceSid)))
if err != nil {
return nil, nil, err
}
Expand All @@ -101,12 +106,16 @@ func (twilio *Twilio) GetConference(conferenceSid string) (*Conference, *Excepti
// UpdateConference to end it or play an announcement
// https://www.twilio.com/docs/voice/api/conference-resource#update-a-conference-resource
func (twilio *Twilio) UpdateConference(conferenceSid string, options *ConferenceOptions) (*Conference, *Exception, error) {
return twilio.UpdateConferenceWithContext(context.Background(), conferenceSid, options)
}

func (twilio *Twilio) UpdateConferenceWithContext(ctx context.Context, conferenceSid string, options *ConferenceOptions) (*Conference, *Exception, error) {
form, err := query.Values(options)
if err != nil {
return nil, nil, err
}

res, err := twilio.post(form, twilio.buildUrl(fmt.Sprintf("Conferences/%s.json", conferenceSid)))
res, err := twilio.post(ctx, form, twilio.buildUrl(fmt.Sprintf("Conferences/%s.json", conferenceSid)))
if err != nil {
return nil, nil, err
}
Expand All @@ -131,7 +140,11 @@ type getParticipantsResponse struct {
// GetConferenceParticipants fetches details for all conference participants resource
// https://www.twilio.com/docs/voice/api/conference-participant-resource#read-multiple-participant-resources
func (twilio *Twilio) GetConferenceParticipants(conferenceSid string) ([]*ConferenceParticipant, *Exception, error) {
res, err := twilio.get(twilio.buildUrl(fmt.Sprintf("Conferences/%s/Participants.json", conferenceSid)))
return twilio.GetConferenceParticipantsWithContext(context.Background(), conferenceSid)
}

func (twilio *Twilio) GetConferenceParticipantsWithContext(ctx context.Context, conferenceSid string) ([]*ConferenceParticipant, *Exception, error) {
res, err := twilio.get(ctx, twilio.buildUrl(fmt.Sprintf("Conferences/%s/Participants.json", conferenceSid)))
if err != nil {
return nil, nil, err
}
Expand All @@ -154,7 +167,11 @@ func (twilio *Twilio) GetConferenceParticipants(conferenceSid string) ([]*Confer
// GetConferenceParticipant fetches details for a conference participant resource
// https://www.twilio.com/docs/voice/api/conference-participant-resource#fetch-a-participant-resource
func (twilio *Twilio) GetConferenceParticipant(conferenceSid, callSid string) (*ConferenceParticipant, *Exception, error) {
res, err := twilio.get(twilio.buildUrl(fmt.Sprintf("Conferences/%s/Participants/%s.json", conferenceSid, callSid)))
return twilio.GetConferenceParticipantWithContext(context.Background(), conferenceSid, callSid)
}

func (twilio *Twilio) GetConferenceParticipantWithContext(ctx context.Context, conferenceSid, callSid string) (*ConferenceParticipant, *Exception, error) {
res, err := twilio.get(ctx, twilio.buildUrl(fmt.Sprintf("Conferences/%s/Participants/%s.json", conferenceSid, callSid)))
if err != nil {
return nil, nil, err
}
Expand All @@ -176,12 +193,16 @@ func (twilio *Twilio) GetConferenceParticipant(conferenceSid, callSid string) (*
// AddConferenceParticipant adds a Participant to a conference by dialing out a new call
// https://www.twilio.com/docs/voice/api/conference-participant-resource#create-a-participant-agent-conference-only
func (twilio *Twilio) AddConferenceParticipant(conferenceSid string, participant *ConferenceParticipantOptions) (*ConferenceParticipant, *Exception, error) {
return twilio.AddConferenceParticipantWithContext(context.Background(), conferenceSid, participant)
}

func (twilio *Twilio) AddConferenceParticipantWithContext(ctx context.Context, conferenceSid string, participant *ConferenceParticipantOptions) (*ConferenceParticipant, *Exception, error) {
form, err := query.Values(participant)
if err != nil {
return nil, nil, err
}

res, err := twilio.post(form, twilio.buildUrl(fmt.Sprintf("Conferences/%s/Participants.json", conferenceSid)))
res, err := twilio.post(ctx, form, twilio.buildUrl(fmt.Sprintf("Conferences/%s/Participants.json", conferenceSid)))
if err != nil {
return nil, nil, err
}
Expand All @@ -202,12 +223,16 @@ func (twilio *Twilio) AddConferenceParticipant(conferenceSid string, participant
// UpdateConferenceParticipant
// https://www.twilio.com/docs/voice/api/conference-participant-resource#create-a-participant-agent-conference-only
func (twilio *Twilio) UpdateConferenceParticipant(conferenceSid string, callSid string, participant *ConferenceParticipantOptions) (*ConferenceParticipant, *Exception, error) {
return twilio.UpdateConferenceParticipantWithContext(context.Background(), conferenceSid, callSid, participant)
}

func (twilio *Twilio) UpdateConferenceParticipantWithContext(ctx context.Context, conferenceSid string, callSid string, participant *ConferenceParticipantOptions) (*ConferenceParticipant, *Exception, error) {
form, err := query.Values(participant)
if err != nil {
return nil, nil, err
}

res, err := twilio.post(form, twilio.buildUrl(fmt.Sprintf("Conferences/%s/Participants/%s.json", conferenceSid, callSid)))
res, err := twilio.post(ctx, form, twilio.buildUrl(fmt.Sprintf("Conferences/%s/Participants/%s.json", conferenceSid, callSid)))
if err != nil {
return nil, nil, err
}
Expand All @@ -227,7 +252,11 @@ func (twilio *Twilio) UpdateConferenceParticipant(conferenceSid string, callSid

// DeleteConferenceParticipant
func (twilio *Twilio) DeleteConferenceParticipant(conferenceSid string, callSid string) (*Exception, error) {
res, err := twilio.delete(twilio.buildUrl(fmt.Sprintf("Conferences/%s/Participants/%s.json", conferenceSid, callSid)))
return twilio.DeleteConferenceParticipantWithContext(context.Background(), conferenceSid, callSid)
}

func (twilio *Twilio) DeleteConferenceParticipantWithContext(ctx context.Context, conferenceSid string, callSid string) (*Exception, error) {
res, err := twilio.delete(ctx, twilio.buildUrl(fmt.Sprintf("Conferences/%s/Participants/%s.json", conferenceSid, callSid)))
if err != nil {
return nil, err
}
Expand Down
33 changes: 27 additions & 6 deletions fax.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package gotwilio

import (
"context"
"encoding/json"
"io/ioutil"
"net/http"
Expand Down Expand Up @@ -56,7 +57,11 @@ type FaxResourcesList struct {
}

func (t *Twilio) CancelFax(faxSid string) (*Exception, error) {
resp, err := t.post(url.Values{"Status": []string{"cancelled"}}, "https://fax.twilio.com/v1/Faxes/"+faxSid)
return t.CancelFaxWithContext(context.Background(), faxSid)
}

func (t *Twilio) CancelFaxWithContext(ctx context.Context, faxSid string) (*Exception, error) {
resp, err := t.post(ctx, url.Values{"Status": []string{"cancelled"}}, "https://fax.twilio.com/v1/Faxes/"+faxSid)
if err != nil {
return nil, err
}
Expand All @@ -73,7 +78,11 @@ func (t *Twilio) CancelFax(faxSid string) (*Exception, error) {
}

func (t *Twilio) DeleteFax(faxSid string) (*Exception, error) {
resp, err := t.delete("https://fax.twilio.com/v1/Faxes/" + faxSid)
return t.DeleteFaxWithContext(context.Background(), faxSid)
}

func (t *Twilio) DeleteFaxWithContext(ctx context.Context, faxSid string) (*Exception, error) {
resp, err := t.delete(ctx, "https://fax.twilio.com/v1/Faxes/" + faxSid)
if err != nil {
return nil, err
}
Expand All @@ -90,7 +99,11 @@ func (t *Twilio) DeleteFax(faxSid string) (*Exception, error) {
}

func (t *Twilio) GetFax(faxSid string) (*FaxResource, *Exception, error) {
resp, err := t.get("https://fax.twilio.com/v1/Faxes/" + faxSid)
return t.GetFaxWithContext(context.Background(), faxSid)
}

func (t *Twilio) GetFaxWithContext(ctx context.Context, faxSid string) (*FaxResource, *Exception, error) {
resp, err := t.get(ctx, "https://fax.twilio.com/v1/Faxes/" + faxSid)
if err != nil {
return nil, nil, err
}
Expand All @@ -116,6 +129,10 @@ func (t *Twilio) GetFax(faxSid string) (*FaxResource, *Exception, error) {
// GetFaxes gets faxes for a Twilio account.
// See https://www.twilio.com/docs/fax/api/faxes#fax-list-resource
func (t *Twilio) GetFaxes(to, from, createdOnOrBefore, createdAfter string) ([]*FaxResource, *Exception, error) {
return t.GetFaxesWithContext(context.Background(), to, from, createdOnOrBefore, createdAfter)
}

func (t *Twilio) GetFaxesWithContext(ctx context.Context, to, from, createdOnOrBefore, createdAfter string) ([]*FaxResource, *Exception, error) {
values := url.Values{}
if to != "" {
values.Set("To", to)
Expand All @@ -130,7 +147,7 @@ func (t *Twilio) GetFaxes(to, from, createdOnOrBefore, createdAfter string) ([]*
values.Set("DateCreatedAfter", createdAfter)
}

resp, err := t.get("https://fax.twilio.com/v1/Faxes")
resp, err := t.get(ctx, "https://fax.twilio.com/v1/Faxes")
if err != nil {
return nil, nil, err
}
Expand All @@ -144,7 +161,7 @@ func (t *Twilio) GetFaxes(to, from, createdOnOrBefore, createdAfter string) ([]*
return nil, exc, err
}

lr := t.newListResources()
lr := t.newListResources(ctx)
if err := json.Unmarshal(respBody, lr); err != nil {
return nil, nil, err
}
Expand All @@ -161,6 +178,10 @@ func (t *Twilio) GetFaxes(to, from, createdOnOrBefore, createdAfter string) ([]*
// SendFax uses Twilio to send a fax.
// See https://www.twilio.com/docs/fax/api/faxes#list-post for more information.
func (t *Twilio) SendFax(to, from, mediaUrl, quality, statusCallback string, storeMedia bool) (*FaxResource, *Exception, error) {
return t.SendFaxWithContext(context.Background(), to, from, mediaUrl, quality, statusCallback, storeMedia)
}

func (t *Twilio) SendFaxWithContext(ctx context.Context, to, from, mediaUrl, quality, statusCallback string, storeMedia bool) (*FaxResource, *Exception, error) {
values := url.Values{}
values.Set("To", to)
values.Set("From", from)
Expand All @@ -175,7 +196,7 @@ func (t *Twilio) SendFax(to, from, mediaUrl, quality, statusCallback string, sto
values.Set("StoreMedia", "true")
}

resp, err := t.post(values, "https://fax.twilio.com/v1/Faxes")
resp, err := t.post(ctx, values, "https://fax.twilio.com/v1/Faxes")
if err != nil {
return nil, nil, err
}
Expand Down
13 changes: 7 additions & 6 deletions gotwilio.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package gotwilio
import (
"encoding/json"
"fmt"
"context"
"net/http"
"net/url"
"path"
Expand Down Expand Up @@ -111,8 +112,8 @@ func (twilio *Twilio) getBasicAuthCredentials() (string, string) {
return twilio.AccountSid, twilio.AuthToken
}

func (twilio *Twilio) post(formValues url.Values, twilioUrl string) (*http.Response, error) {
req, err := http.NewRequest("POST", twilioUrl, strings.NewReader(formValues.Encode()))
func (twilio *Twilio) post(ctx context.Context, formValues url.Values, twilioUrl string) (*http.Response, error) {
req, err := http.NewRequestWithContext(ctx, "POST", twilioUrl, strings.NewReader(formValues.Encode()))
if err != nil {
return nil, err
}
Expand All @@ -122,8 +123,8 @@ func (twilio *Twilio) post(formValues url.Values, twilioUrl string) (*http.Respo
return twilio.do(req)
}

func (twilio *Twilio) get(twilioUrl string) (*http.Response, error) {
req, err := http.NewRequest("GET", twilioUrl, nil)
func (twilio *Twilio) get(ctx context.Context, twilioUrl string) (*http.Response, error) {
req, err := http.NewRequestWithContext(ctx, "GET", twilioUrl, nil)
if err != nil {
return nil, err
}
Expand All @@ -132,8 +133,8 @@ func (twilio *Twilio) get(twilioUrl string) (*http.Response, error) {
return twilio.do(req)
}

func (twilio *Twilio) delete(twilioUrl string) (*http.Response, error) {
req, err := http.NewRequest("DELETE", twilioUrl, nil)
func (twilio *Twilio) delete(ctx context.Context, twilioUrl string) (*http.Response, error) {
req, err := http.NewRequestWithContext(ctx, "DELETE", twilioUrl, nil)
if err != nil {
return nil, err
}
Expand Down
25 changes: 21 additions & 4 deletions phonenumbers.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package gotwilio

import (
"context"
"encoding/json"
"net/http"
"net/url"
Expand Down Expand Up @@ -164,6 +165,10 @@ type getIncomingPhoneNumbersResponse struct {
// GetIncomingPhoneNumbers reads multiple IncomingPhoneNumbers from the Twilio REST API, with optional filtering
// https://www.twilio.com/docs/phone-numbers/api/incomingphonenumber-resource#read-multiple-incomingphonenumber-resources
func (twilio *Twilio) GetIncomingPhoneNumbers(request GetIncomingPhoneNumbersRequest) ([]*IncomingPhoneNumber, *Exception, error) {
return twilio.GetIncomingPhoneNumbersWithContext(context.Background(), request)
}

func (twilio *Twilio) GetIncomingPhoneNumbersWithContext(ctx context.Context, request GetIncomingPhoneNumbersRequest) ([]*IncomingPhoneNumber, *Exception, error) {
// convert request to url.Values for encoding into querystring
form, err := query.Values(request)
if err != nil {
Expand All @@ -178,7 +183,7 @@ func (twilio *Twilio) GetIncomingPhoneNumbers(request GetIncomingPhoneNumbersReq
}
reqURL.RawQuery = form.Encode()

res, err := twilio.get(reqURL.String())
res, err := twilio.get(ctx, reqURL.String())
if err != nil {
return nil, nil, err
}
Expand All @@ -200,13 +205,17 @@ func (twilio *Twilio) GetIncomingPhoneNumbers(request GetIncomingPhoneNumbersReq
// CreateIncomingPhoneNumber creates an IncomingPhoneNumber resource via the Twilio REST API.
// https://www.twilio.com/docs/phone-numbers/api/incomingphonenumber-resource#create-an-incomingphonenumber-resource
func (twilio *Twilio) CreateIncomingPhoneNumber(options IncomingPhoneNumber) (*IncomingPhoneNumber, *Exception, error) {
return twilio.CreateIncomingPhoneNumberWithContext(context.Background(), options)
}

func (twilio *Twilio) CreateIncomingPhoneNumberWithContext(ctx context.Context, options IncomingPhoneNumber) (*IncomingPhoneNumber, *Exception, error) {
// convert options to HTTP form
form, err := query.Values(options)
if err != nil {
return nil, nil, err
}

res, err := twilio.post(form, twilio.buildUrl("IncomingPhoneNumbers.json"))
res, err := twilio.post(ctx, form, twilio.buildUrl("IncomingPhoneNumbers.json"))
if err != nil {
return nil, nil, err
}
Expand All @@ -228,13 +237,17 @@ func (twilio *Twilio) CreateIncomingPhoneNumber(options IncomingPhoneNumber) (*I
// UpdateIncomingPhoneNumber updates an IncomingPhoneNumber resource via the Twilio REST API.
// https://www.twilio.com/docs/phone-numbers/api/incomingphonenumber-resource#update-an-incomingphonenumber-resource
func (twilio *Twilio) UpdateIncomingPhoneNumber(sid string, options IncomingPhoneNumber) (*IncomingPhoneNumber, *Exception, error) {
return twilio.UpdateIncomingPhoneNumberWithContext(context.Background(), sid, options)
}

func (twilio *Twilio) UpdateIncomingPhoneNumberWithContext(ctx context.Context, sid string, options IncomingPhoneNumber) (*IncomingPhoneNumber, *Exception, error) {
// convert options to HTTP form
form, err := query.Values(options)
if err != nil {
return nil, nil, err
}

res, err := twilio.post(form, twilio.buildUrl("IncomingPhoneNumbers/"+sid+".json"))
res, err := twilio.post(ctx, form, twilio.buildUrl("IncomingPhoneNumbers/"+sid+".json"))
if err != nil {
return nil, nil, err
}
Expand All @@ -256,8 +269,12 @@ func (twilio *Twilio) UpdateIncomingPhoneNumber(sid string, options IncomingPhon
// DeleteIncomingPhoneNumber deletes an IncomingPhoneNumber resource via the Twilio REST API.
// https://www.twilio.com/docs/phone-numbers/api/incomingphonenumber-resource#delete-an-incomingphonenumber-resource
func (twilio *Twilio) DeleteIncomingPhoneNumber(sid string) (*Exception, error) {
return twilio.DeleteIncomingPhoneNumberWithContext(context.Background(), sid)
}

func (twilio *Twilio) DeleteIncomingPhoneNumberWithContext(ctx context.Context, sid string) (*Exception, error) {
resourceName := sid + ".json"
res, err := twilio.delete(twilio.buildUrl("IncomingPhoneNumbers/" + resourceName))
res, err := twilio.delete(ctx, twilio.buildUrl("IncomingPhoneNumbers/" + resourceName))
if err != nil {
return nil, err
}
Expand Down
Loading

0 comments on commit d8d6378

Please sign in to comment.