utwil

package module
v0.0.0-...-a2d49e9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 11, 2016 License: BSD-2-Clause Imports: 9 Imported by: 1

README

# utwil: Go Utilities for Twilio
#
**utwil is currently under heavy development, so expect breakage.**

Documentation can be found at:
[https://godoc.org/github.com/wyc/utwil](https://godoc.org/github.com/wyc/utwil)

Made with [gojson](https://github.com/ChimeraCoder/gojson).

## Installation
In your terminal:
``` bash
$ go get github.com/wyc/utwil
```

In your code:
``` go
import "github.com/wyc/utwil"
```

## Features

##### Make a utwil.Client
``` go
client := utwil.NewClient(AccoutSID, AuthToken)
```

##### Send an SMS

``` go
// type client.SendSMS func(from, to, msg string) (utwil.Message, error)
msg, err := client.SendSMS("+15551231234", "+15553214321", "Hello, world!")
```

##### Send an MMS

``` go
// type client.SendMMS func(from, to, msg, mediaURL string) (utwil.Message, error)
mediaURL := "http://i.imgur.com/sZPem77.png"
body := "Hello, world!"
msg, err := client.SendMMS("+15551231234", "+15553214321", body, mediaURL)
```

##### Make a Call

``` go
callbackPostURL := fmt.Sprintf(
        "http://twimlets.com/forward?PhoneNumber=%s",
        "+15559871234",
)
// type client.Call func(from, to, callbackPostURL string) (utwil.Call, error)
call, err := client.Call("+15551231234", "+15553214321", callbackPostURL)
```

##### Make a Recorded Call

``` go
// type client.RecordedCall func(from, to, callbackURL string) (utwil.Call, error)
call, err := client.RecordedCall("+15551231234", "+15553214321", callbackPostURL)
```

##### Lookups
``` go
// type client.Lookup func(phoneNumber string) (utwil.Lookup, error)
lookup, err := client.Lookup("+15551231234")
// handle err
fmt.Println(lookup.Carrier.Type) // "mobile", "landline", or "voip"
```

##### Custom requests
For more complicated requests, populate the respective XxxxxReq struct
and call the `client.SubmitXxxxx(XxxxxReq) (Xxxxx, error)` method:
``` go
msgReq := utwil.MessageReq{
        From:           "+15559871234",
        To:             "+15551231234",
        Body:           "Hello, world!",
        StatusCallback: "https://post.here.com/when/msg/status/changes.twiml",
}
msg, err := client.SubmitMessage(msgReq)
```

##### Query Messages (SMS/MMS)

``` go
weekAgo := time.Now().Add(-7 * 24 * time.Hour)
iter := client.Messages(
                utwil.SentBeforeYMD(weekAgo),
                utwil.To("+15551231234")).Iter()
var msg utwil.Message
for iter.Next(&msg) {
        // do something with utwil.Message
}
if iter.Err() != nil {
        // handle err
}
```

##### Query Calls
``` go
iter := client.Calls(
                utwil.From("+15551231234"),
                utwil.StartedAfter("2015-04-01")).Iter()
var call utwil.Call
for iter.Next(&call) {
        // do something with utwil.Call
}
if iter.Err() != nil {
        // handle err
}
```

## Testing
First, populate env vars `TWILIO_ACCOUNT_SID`, `TWILIO_AUTH_TOKEN`,
                         `TWILIO_DEFAULT_TO`, `TWILIO_DEFAULT_FROM`.
Then run `go test` and expect many annoyances to `TWILIO_DEFAULT_TO`:
- Phone call and second forwarded phone call to the same number
- One SMS message

Run `go test -test.v` instead if you want more details to the console.

## To do
- Better testing harness...maybe we can borrow a testing AccountSID/AuthToken
  pair and *commit them to the repo* >:)
- Fetching additional resources from a call/msg such as recording or MMS
- Tools for responding with TwiML, including changing live call state
- CRUD for managerial records such as accounts, addresses, phone numbers,
  queues, SIP, etc
- More comments in src
- Investigate STUN, TURN, and ICE offerings

Feel free to request features by opening an issue.

## Alternatives
- https://github.com/sfreiberg/gotwilio (No lookup or call/msg listing)
- https://bitbucket.org/ckvist/twilio (Has tools for generating TwiML, but no lookup or call/msg listing)

Documentation

Overview

Package utwil contains Go utilities for dealing with the Twilio API

The most-used data structure is the Client, which stores credentials and has useful methods for interacing with Twilio. The current supported feature set includes the sending of Calls and Messages, retrieval of Calls and Messages, and the lookup of phone numbers.

These actions will incur the appropriate costs on your Twilio account.

Before go test, populate env vars TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, TWILIO_DEFAULT_TO, and TWILIO_DEFAULT_FROM.

Start with:

client := utwil.NewClient(AccoutSID, AuthToken)

Commonly used actions have convenience functions:

msg, err := client.SendSMS("+15551231234", "+15559879876", "Hello, world!")

For more complicated requests, populate the respective XxxxxReq struct and call the SubmitXxxxx() method:

	msgReq := utwil.MessageReq{
       	From:           "+15559871234",
       	To:             "+15551231234",
       	Body:           "Hello, world!",
       	StatusCallback: "https://post.here.com/when/msg/status/changes.twiml",
	}
	msg, err := client.SubmitMessage(msgReq)

Index

Constants

View Source
const (
	BaseURL   = "https://api.twilio.com"
	LookupURL = "https://lookups.twilio.com/v1"

	APIVersion = "2010-04-01"
)

At the time of writing, the current API version was released on Apr. 1, 2010

View Source
const YMD = "2006-01-02"

YMD is used to format time.Time for querying the Twilio REST API

Variables

This section is empty.

Functions

This section is empty.

Types

type Call

type Call struct {
	AccountSID      string `json:"account_sid"`
	Annotation      string `json:"annotation"`
	AnsweredBy      string `json:"answered_by"`
	ApiVersion      string `json:"api_version"`
	CallerName      string `json:"caller_name"`
	DateCreated     *Time  `json:"date_created"`
	DateUpdated     *Time  `json:"date_updated"`
	Direction       string `json:"direction"`
	Duration        string `json:"duration"`
	ForwardedFrom   string `json:"forwarded_from"`
	From            string `json:"from"`
	FromFormatted   string `json:"from_formatted"`
	GroupSID        string `json:"group_sid"`
	ParentCallSID   string `json:"parent_call_sid"`
	PhoneNumberSID  string `json:"phone_number_sid"`
	Price           string `json:"price"`
	PriceUnit       string `json:"price_unit"`
	SID             string `json:"sid"`
	StartTime       *Time  `json:"start_time"`
	EndTime         *Time  `json:"end_time"`
	Status          string `json:"status"`
	SubresourceURIs struct {
		Notifications string `json:"notifications"`
		Recordings    string `json:"recordings"`
	} `json:"subresource_uris"`
	To          string `json:"to"`
	ToFormatted string `json:"to_formatted"`
	URI         string `json:"uri"`
}

Call is the Go-representation of Twilio REST API's call.

Details:

https://www.twilio.com/docs/api/rest/call

type CallIter

type CallIter struct {
	// contains filtered or unexported fields
}

CallIter iterates through Twilio calls.

func (CallIter) Err

func (iter CallIter) Err() error

Err returns the latest error a MessageIter or CallIter encounters or nil if there was no error.

func (*CallIter) Next

func (iter *CallIter) Next(call *Call) bool

Next attempts to populate call with the next utwil.Call, returning false if it could not due to out of messages or an error. It is therefore recommended to check for errors with CallIter.Err() after use:

Example:

var call utwil.Call
for callIter.Next(&call) {
	// use msg
}
if callIter.Err() != nil {
	// handle err
}

type CallListQuery

type CallListQuery struct{ *ListQuery }

CallListQuery is a struct that contains an embedded utwil.ListQuery. The typing allows the correctly-typed iterator/list to be returned.

func (*CallListQuery) Iter

func (q *CallListQuery) Iter() *CallIter

Iter creates an iterator that iterates utwil.Call results

type CallReq

type CallReq struct {
	From                 string
	To                   string
	URL                  string
	ApplicationSID       string
	Method               string
	FallbackURL          string
	FallbackMethod       string
	StatusCallback       string
	StatusCallbackMethod string
	SendDigits           string
	IfMachine            string
	Timeout              int
	Record               bool
}

CallReq is the Go-representation of the Twilio REST API's call request.

Details:

https://www.twilio.com/docs/api/rest/making-calls

type Client

type Client struct {
	AccountSID string
	AuthToken  string
	HTTPClient *http.Client
}

Client stores Twilio API credentials

func NewClient

func NewClient(accountSID, authToken string) Client

NewClient exists as a stable interface to create a new utwil.Client.

func (*Client) Call

func (c *Client) Call(from, to, callbackPostURL string) (*Call, error)

Call requests the Twilio API to call a number and send a POST request to the given URL to report what happened:

https://www.twilio.com/docs/api/twiml/twilio_request

Example:

callbackPostURL := fmt.Sprintf(
        "http://twimlets.com/forward?PhoneNumber=%s",
        "+15559871234",
)
call, err := client.Call("+15551231234", "+15553214321", callbackPostURL)

func (*Client) Calls

func (c *Client) Calls(confs ...ListQueryConf) *CallListQuery

Calls takes a vargs of utwil.ListQueryConf functions to configure the query to be sent to the Twilio API:

Example:

iter := client.Calls(
	utwil.StartedBefore("2014-01-01"),
	utwil.To("+15551231234")).Iter()

func (*Client) Lookup

func (c *Client) Lookup(phoneNumber string) (Lookup, error)

Lookup looks up a phone number's details including the carrier (Type=carrier)

Example:

	lookup, err := client.Lookup("+15551231234")
     // handle err
     fmt.Println(lookup.Carrier.Type) // "mobile", "landline", or "voip"

func (*Client) LookupNoCarrier

func (c *Client) LookupNoCarrier(phoneNumber string) (Lookup, error)

LookupNoCarrier looks up a phone number's details without the carrier

func (*Client) Messages

func (c *Client) Messages(confs ...ListQueryConf) *MessageListQuery

Messages takes a vargs of utwil.ListQueryConf functions to configure the query to be sent to the Twilio API:

iter := client.Messages(
        utwil.SentAfter("2014-01-01"),
        utwil.From("+15551231234")).Iter()

func (*Client) RecordedCall

func (c *Client) RecordedCall(from, to, callbackPostURL string) (*Call, error)

RecordedCall is the same as Client.Call, but recorded

func (*Client) SendMMS

func (c *Client) SendMMS(from, to, body, mediaURL string) (Message, error)

SendMMS sends body and mediaURL from/to the specified number.

Example:

	mediaURL := "http://i.imgur.com/sZPem77.png"
     body := "Hello, world!"
     msg, err := client.SendMMS("+15551231234", "+15553214321", body, mediaURL)

func (*Client) SendSMS

func (c *Client) SendSMS(from, to, body string) (Message, error)

SendSMS sends body from/to the specified number.

Example:

msg, err := client.SendSMS("+15551231234", "+15553214321", "Hello, world!")

func (*Client) SubmitCall

func (c *Client) SubmitCall(req CallReq) (*Call, error)

SubmitCall sends a call request populating form fields only if they contain a non-zero value.

func (*Client) SubmitLookup

func (c *Client) SubmitLookup(req LookupReq) (Lookup, error)

SubmitLookup sends a lookup request populating form fields only if they contain a non-zero value.

func (*Client) SubmitMessage

func (c *Client) SubmitMessage(req MessageReq) (Message, error)

SubmitMessage sends a message request populating form fields only if they contain a non-zero value.

type ListQuery

type ListQuery struct {
	url.Values
	*Client
}

ListQuery stores query filter configuration and a *utwil.Client, and is used by MessageListQuery and CallListQuery.

type ListQueryConf

type ListQueryConf func(*ListQuery)

ListQueryConf configures a passed *utwil.ListQuery

func From

func From(phoneNumber string) ListQueryConf

From filters calls and messages sent from a phone number.

func SentAfter

func SentAfter(ymd string) ListQueryConf

SentAfter filters messages sent after a given date string "YYYY-MM-DD"

func SentAfterYMD

func SentAfterYMD(t time.Time) ListQueryConf

SentAfterYMD filters messages sent after a given date (YMD considered only)

func SentBefore

func SentBefore(ymd string) ListQueryConf

SentBefore filters messages sent before a given date string "YYYY-MM-DD"

func SentBeforeYMD

func SentBeforeYMD(t time.Time) ListQueryConf

SentBeforeYMD filters messages sent before a given date (YMD considered only)

func StartedAfter

func StartedAfter(ymd string) ListQueryConf

StartedAfter filters calls started after a given date string "YYYY-MM-DD"

func StartedAfterYMD

func StartedAfterYMD(t time.Time) ListQueryConf

StartedAfterYMD filters calls started after a given date (YMD considered only)

func StartedBefore

func StartedBefore(ymd string) ListQueryConf

StartedBefore filters calls started before a given date string "YYYY-MM-DD"

func StartedBeforeYMD

func StartedBeforeYMD(t time.Time) ListQueryConf

StartedBeforeYMD filters calls started before a given date (YMD considered only)

func To

func To(phoneNumber string) ListQueryConf

To filters calls and messages sent to a phone number.

type Lookup

type Lookup struct {
	Carrier *struct {
		ErrorCode         *int   `json:"error_code"`
		MobileCountryCode string `json:"mobile_country_code"`
		MobileNetworkCode string `json:"mobile_network_code"`
		Name              string `json:"name"`
		Type              string `json:"type"`
	} `json:"carrier"`
	CountryCode    string `json:"country_code"`
	NationalFormat string `json:"national_format"`
	PhoneNumber    string `json:"phone_number"`
	URL            string `json:"url"`
}

Lookup is the Go-representation of Twilio REST API's lookup.

Details:

https://www.twilio.com/docs/api/rest/lookups

type LookupReq

type LookupReq struct {
	PhoneNumber string
	Type        string
	CountryCode string
}

LookupReq is the Go-representation of Twilio REST API's lookup request.

Details:

https://www.twilio.com/docs/api/rest/lookups#lookups-query-parameters

type Message

type Message struct {
	AccountSID      string  `json:"account_sid"`
	APIVersion      string  `json:"api_version"`
	Body            string  `json:"body"`
	DateCreated     *Time   `json:"date_created"`
	DateSent        *Time   `json:"date_sent"`
	DateUpdated     *Time   `json:"date_updated"`
	Direction       string  `json:"direction"`
	ErrorCode       *int    `json:"error_code"`
	ErrorMessage    *string `json:"error_message"`
	From            string  `json:"from"`
	NumMedia        string  `json:"num_media"`
	NumSegments     string  `json:"num_segments"`
	Price           string  `json:"price"`
	PriceUnit       string  `json:"price_unit"`
	SID             string  `json:"sid"`
	Status          string  `json:"status"`
	SubresourceURIs struct {
		Media string `json:"media"`
	} `json:"subresource_uris"`
	To  string `json:"to"`
	URI string `json:"uri"`
}

Message is the Go-representation of Twilio REST API's message.

Details:

https://www.twilio.com/docs/api/rest/message

type MessageIter

type MessageIter struct {
	// contains filtered or unexported fields
}

MessageIter iterates through Twilio messages.

func (MessageIter) Err

func (iter MessageIter) Err() error

Err returns the latest error a MessageIter or CallIter encounters or nil if there was no error.

func (*MessageIter) Next

func (iter *MessageIter) Next(msg *Message) bool

Next attempts to populate msg with the next utwil.Message, returning false if it could not due to out of messages or an error. It is therefore recommended to check for errors with MessageIter.Err() after use:

Example:

var msg utwil.Message
for messageIter.Next(&msg) {
	// use msg
}
if messageIter.Err() != nil {
	// handle err
}

type MessageListQuery

type MessageListQuery struct{ *ListQuery }

MessageListQuery is a struct that contains an embedded utwil.ListQuery. The typing allows the correctly-typed iterator/list to be returned.

func (*MessageListQuery) Iter

func (q *MessageListQuery) Iter() *MessageIter

Iter creates an iterator that iterates utwil.Message results

type MessageReq

type MessageReq struct {
	From           string
	To             string
	Body           string
	MediaURL       string
	StatusCallback string
	ApplicationSID string
}

MessageReq is the Go-representation of Twilio REST API's message request.

Details:

https://www.twilio.com/docs/api/rest/sending-messages

type RESTException

type RESTException struct {
	Code     *int        `json:"code"`
	Message  string      `json:"message"`
	MoreInfo string      `json:"more_info"`
	Status   interface{} `json:"status"`
}

RESTException represents an error returned by the Twilio API

Details:

https://www.twilio.com/docs/errors

func (RESTException) Error

func (r RESTException) Error() string

Print the RESTException in a human-readable form.

type Time

type Time struct {
	time.Time
}

Time is a wrapper around time.Time to support JSON marshalling to/from the Twilio REST API, which uses RFC1123Z.

func (*Time) MarshalJSON

func (t *Time) MarshalJSON() ([]byte, error)

MarshalJSON marshals time.Time into the time.RFC1123Z format

func (*Time) UnmarshalJSON

func (t *Time) UnmarshalJSON(data []byte) error

UnmarshalJSON unmarshals time.Time from the time.RFC1123Z format

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL