Skip to content

Commit

Permalink
Initial implementation of Wireless API
Browse files Browse the repository at this point in the history
Lots of resources missing still - rate plans, usage records.

Updates #10
  • Loading branch information
kevinburke committed Jun 23, 2017
1 parent 1ec9298 commit 7e96c07
Show file tree
Hide file tree
Showing 4 changed files with 202 additions and 29 deletions.
74 changes: 45 additions & 29 deletions http.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,29 @@ const MonitorVersion = "v1"
// The base URL for Twilio Pricing.
var PricingBaseURL = "https://pricing.twilio.com"

// Version of the Twilio Pricing API.
const PricingVersion = "v1"

var FaxBaseURL = "https://fax.twilio.com"

const FaxVersion = "v1"

// Version of the Twilio Pricing API.
const PricingVersion = "v1"
// The base URL for Twilio Wireless.
var WirelessBaseURL = "https://wireless.twilio.com"

// Version of the Twilio Wireless API.
const WirelessVersion = "v1"

// The APIVersion to use. Your mileage may vary using other values for the
// APIVersion; the resource representations may not match.
const APIVersion = "2010-04-01"

type Client struct {
*rest.Client
Monitor *Client
Pricing *Client
Fax *Client
Monitor *Client
Pricing *Client
Fax *Client
Wireless *Client

// FullPath takes a path part (e.g. "Messages") and
// returns the full API path, including the version (e.g.
Expand Down Expand Up @@ -83,6 +90,9 @@ type Client struct {

// NewFaxClient initializes these services
Faxes *FaxService

// NewWirelessClient initializes these services
Sims *SimService
}

const defaultTimeout = 30*time.Second + 500*time.Millisecond
Expand Down Expand Up @@ -152,46 +162,45 @@ func NewFaxClient(accountSid string, authToken string, httpClient *http.Client)
return c
}

// NewMonitorClient returns a Client for use with the Twilio Monitor API.
func NewMonitorClient(accountSid string, authToken string, httpClient *http.Client) *Client {
if httpClient == nil {
httpClient = defaultHttpClient
func newNewClient(sid, token, baseURL string, client *http.Client) *Client {
if client == nil {
client = defaultHttpClient
}
restClient := rest.NewClient(accountSid, authToken, MonitorBaseURL)
restClient.Client = httpClient
restClient := rest.NewClient(sid, token, baseURL)
restClient.Client = client
restClient.UploadType = rest.FormURLEncoded
restClient.ErrorParser = parseTwilioError
c := &Client{
Client: restClient,
AccountSid: accountSid,
AuthToken: authToken,
AccountSid: sid,
AuthToken: token,
}
c.FullPath = func(pathPart string) string {
return "/" + c.APIVersion + "/" + pathPart
}
return c
}

// NewWirelessClient returns a Client for use with the Twilio Wireless API.
func NewWirelessClient(accountSid string, authToken string, httpClient *http.Client) *Client {
c := newNewClient(accountSid, authToken, WirelessBaseURL, httpClient)
c.APIVersion = WirelessVersion
c.Sims = &SimService{client: c}
return c
}

// NewMonitorClient returns a Client for use with the Twilio Monitor API.
func NewMonitorClient(accountSid string, authToken string, httpClient *http.Client) *Client {
c := newNewClient(accountSid, authToken, MonitorBaseURL, httpClient)
c.APIVersion = MonitorVersion
c.Alerts = &AlertService{client: c}
return c
}

// returns a new Client to use the pricing API
// NewPricingClient returns a new Client to use the pricing API
func NewPricingClient(accountSid string, authToken string, httpClient *http.Client) *Client {
if httpClient == nil {
httpClient = defaultHttpClient
}
restClient := rest.NewClient(accountSid, authToken, PricingBaseURL)
restClient.Client = httpClient
restClient.UploadType = rest.FormURLEncoded
restClient.ErrorParser = parseTwilioError
c := &Client{
Client: restClient,
AccountSid: accountSid,
AuthToken: authToken,
}
c := newNewClient(accountSid, authToken, PricingBaseURL, httpClient)
c.APIVersion = PricingVersion
c.FullPath = func(pathPart string) string {
return "/" + c.APIVersion + "/" + pathPart
}
c.Voice = &VoicePriceService{
Countries: &CountryVoicePriceService{client: c},
Numbers: &NumberVoicePriceService{client: c},
Expand Down Expand Up @@ -226,6 +235,7 @@ func NewClient(accountSid string, authToken string, httpClient *http.Client) *Cl
c.Monitor = NewMonitorClient(accountSid, authToken, httpClient)
c.Pricing = NewPricingClient(accountSid, authToken, httpClient)
c.Fax = NewFaxClient(accountSid, authToken, httpClient)
c.Wireless = NewWirelessClient(accountSid, authToken, httpClient)

c.Accounts = &AccountService{client: c}
c.Applications = &ApplicationService{client: c}
Expand Down Expand Up @@ -307,6 +317,12 @@ func (c *Client) UseSecretKey(key string) {
if c.Pricing != nil {
c.Pricing.UseSecretKey(key)
}
if c.Fax != nil {
c.Fax.UseSecretKey(key)
}
if c.Wireless != nil {
c.Wireless.UseSecretKey(key)
}
}

// GetResource retrieves an instance resource with the given path part (e.g.
Expand Down
33 changes: 33 additions & 0 deletions responses_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,18 @@ func getServer(response []byte) (*Client, *Server) {
client.Monitor.Base = s.URL
client.Pricing.Base = s.URL
client.Fax.Base = s.URL
client.Wireless.Base = s.URL
return client, s
}

func getServerCode(response []byte, code int) (*Client, *Server) {
s := newServer(response, code)
client := NewClient("AC123", "456", nil)
client.Base = s.URL
client.Fax.Base = s.URL
client.Monitor.Base = s.URL
client.Pricing.Base = s.URL
client.Wireless.Base = s.URL
return client, s
}

Expand Down Expand Up @@ -2610,5 +2613,35 @@ var availablePhoneNumbers = []byte(`
}
`)

var simGetResponse = []byte(`
{
"account_sid": "AC58f1e8f2b1c6b88ca90a012a4be0c279",
"commands_callback_method": "POST",
"commands_callback_url": null,
"date_created": "2017-06-22T21:44:48Z",
"date_updated": "2017-06-22T21:45:45Z",
"e_id": null,
"friendly_name": null,
"iccid": "8901260852290182427",
"links": {
"rate_plan": "https://wireless.twilio.com/v1/RatePlans/WPfaf4062b7697612c807c1d5e9316ffbc",
"usage_records": "https://wireless.twilio.com/v1/Sims/DEe10f758e920e43318ad80677505fcf90/UsageRecords"
},
"rate_plan_sid": "WPfaf4062b7697612c807c1d5e9316ffbc",
"sid": "DEe10f758e920e43318ad80677505fcf90",
"sms_fallback_method": null,
"sms_fallback_url": null,
"sms_method": null,
"sms_url": null,
"status": "active",
"unique_name": "iPhone v13",
"url": "https://wireless.twilio.com/v1/Sims/DEe10f758e920e43318ad80677505fcf90",
"voice_fallback_method": null,
"voice_fallback_url": null,
"voice_method": null,
"voice_url": null
}
`)

const from = "+19253920364"
const to = "+19253920364"
102 changes: 102 additions & 0 deletions wireless.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package twilio

import (
"context"
"net/url"

types "github.com/kevinburke/go-types"
)

const simPathPart = "Sims"

type SimService struct {
client *Client
}

// Sim represents a Sim resource.
type Sim struct {
Sid string `json:"sid"`
UniqueName string `json:"unique_name"`
Status Status `json:"status"`
FriendlyName types.NullString `json:"friendly_name"`
ICCID string `json:"iccid"`

CommandsCallbackMethod string `json:"commands_callback_method"`
CommandsCallbackURL types.NullString `json:"commands_callback_url"`
DateCreated TwilioTime `json:"date_created"`
DateUpdated TwilioTime `json:"date_updated"`
RatePlanSid string `json:"rate_plan_sid"`
SMSURL types.NullString `json:"sms_url"`
SMSMethod types.NullString `json:"sms_method"`
SMSFallbackMethod types.NullString `json:"sms_fallback_method"`
SMSFallbackURL types.NullString `json:"sms_fallback_url"`
VoiceURL types.NullString `json:"voice_url"`
VoiceMethod types.NullString `json:"voice_method"`
VoiceFallbackMethod types.NullString `json:"voice_fallback_method"`
VoiceFallbackURL types.NullString `json:"voice_fallback_url"`

URL string `json:"url"`
AccountSid string `json:"account_sid"`
Links map[string]string `json:"links"`
}

// SimPage represents a page of Sims.
type SimPage struct {
Meta Meta `json:"meta"`
Sims []*Sim `json:"sims"`
}

// Get finds a single Sim resource by its sid, or returns an error.
func (s *SimService) Get(ctx context.Context, sid string) (*Sim, error) {
sim := new(Sim)
err := s.client.GetResource(ctx, simPathPart, sid, sim)
return sim, err
}

// Update the sim with the given data. Valid parameters may be found here:
// https://www.twilio.com/docs/api/wireless/rest-api/sim#instance-post
func (c *SimService) Update(ctx context.Context, sid string, data url.Values) (*Sim, error) {
sim := new(Sim)
err := c.client.UpdateResource(ctx, simPathPart, sid, data, sim)
return sim, err
}

// SimPageIterator lets you retrieve consecutive pages of resources.
type SimPageIterator interface {
// Next returns the next page of resources. If there are no more resources,
// NoMoreResults is returned.
Next(context.Context) (*SimPage, error)
}

type simPageIterator struct {
p *PageIterator
}

// GetPage returns a single Page of resources, filtered by data.
//
// See https://www.twilio.com/docs/api/wireless/rest-api/sim#list-get.
func (f *SimService) GetPage(ctx context.Context, data url.Values) (*SimPage, error) {
return f.GetPageIterator(data).Next(ctx)
}

// GetPageIterator returns a SimPageIterator with the given page
// filters. Call iterator.Next() to get the first page of resources (and again
// to retrieve subsequent pages).
func (f *SimService) GetPageIterator(data url.Values) SimPageIterator {
iter := NewPageIterator(f.client, data, simPathPart)
return &simPageIterator{
p: iter,
}
}

// Next returns the next page of resources. If there are no more resources,
// NoMoreResults is returned.
func (f *simPageIterator) Next(ctx context.Context) (*SimPage, error) {
ap := new(SimPage)
err := f.p.Next(ctx, ap)
if err != nil {
return nil, err
}
f.p.SetNextPageURI(ap.Meta.NextPageURL)
return ap, nil
}
22 changes: 22 additions & 0 deletions wireless_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package twilio

import (
"context"
"testing"
)

func TestGetSim(t *testing.T) {
t.Parallel()
client, server := getServer(simGetResponse)
defer server.Close()
sim, err := client.Wireless.Sims.Get(context.Background(), "DEe10f758e920e43318ad80677505fcf90")
if err != nil {
t.Fatal(err)
}
if sim.Sid != "DEe10f758e920e43318ad80677505fcf90" {
t.Errorf("sim: got sid %q, want %q", sim.Sid, "DEe10f758e920e43318ad80677505fcf90")
}
if sim.Status != StatusActive {
t.Errorf("sim: got status %q, want %q", sim.Status, StatusActive)
}
}

0 comments on commit 7e96c07

Please sign in to comment.