github.com/twilio/twilio-go@v1.20.1/README.md (about) 1 # twilio-go 2 3 [](https://github.com/twilio/twilio-go/actions/workflows/test-and-deploy.yml) 4 [](https://pkg.go.dev/github.com/twilio/twilio-go) 5 [](https://github.com/twilio/twilio-go/releases/latest) 6 7 All the code [here](./rest) was generated by [twilio-oai-generator](https://github.com/twilio/twilio-oai-generator) by 8 leveraging [openapi-generator](https://github.com/OpenAPITools/openapi-generator) 9 and [twilio-oai](https://github.com/twilio/twilio-oai). If you find an issue with the generation or the OpenAPI specs, 10 please go ahead and open an issue or a PR against the relevant repositories. 11 12 ## 🚀 Feature Update 13 Twilio Go Helper Library's version 1.20.0 adds support for the application/json content type in the request body. See example [here](#messaging-bulk). 14 Behind the scenes Go Helper is now auto-generated via OpenAPI with this release. 15 This enables us to rapidly add new features and enhance consistency across versions and languages. 16 17 ## Documentation 18 19 The documentation for the Twilio API can be found [here][apidocs]. 20 21 The Go library documentation can be found [here][libdocs]. 22 23 ### Supported Go Versions 24 25 This library supports the following Go implementations: 26 27 - Go 1.15 28 - Go 1.16 29 - Go 1.17 30 - Go 1.18 31 - Go 1.19 32 - Go 1.20 33 34 ## Installation 35 36 The recommended way to install `twilio-go` is by using [Go modules](https://go.dev/ref/mod#go-get). 37 38 If you already have an initialized project, you can run the command below from your terminal in the project directory to install the library: 39 40 ```shell 41 go get github.com/twilio/twilio-go 42 ``` 43 44 If you are starting from scratch in a new directory, you will first need to create a go.mod file for tracking dependencies such as twilio-go. This is similar to using package.json in a Node.js project or requirements.txt in a Python project. [You can read more about mod files in the Go documentation](https://golang.org/doc/modules/managing-dependencies). To create the file, run the following command in your terminal: 45 46 ```shell 47 go mod init twilio-example 48 ``` 49 50 Once the module is initialized, you may run the installation command from above, which will update your go.mod file to include twilio-go. 51 52 ### Test your installation 53 54 Try sending yourself an SMS message by pasting the following code example into a sendsms.go file in the same directory where you installed twilio-go. Be sure to update the accountSid, authToken, and from phone number with values from your Twilio account. The to phone number can be your own mobile phone number. 55 56 ```go 57 package main 58 59 import ( 60 "encoding/json" 61 "fmt" 62 63 "github.com/twilio/twilio-go" 64 twilioApi "github.com/twilio/twilio-go/rest/api/v2010" 65 ) 66 67 func main() { 68 accountSid := "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" 69 authToken := "f2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 70 71 client := twilio.NewRestClientWithParams(twilio.ClientParams{ 72 Username: accountSid, 73 Password: authToken, 74 }) 75 76 params := &twilioApi.CreateMessageParams{} 77 params.SetTo("+15558675309") 78 params.SetFrom("+15017250604") 79 params.SetBody("Hello from Go!") 80 81 resp, err := client.Api.CreateMessage(params) 82 if err != nil { 83 fmt.Println("Error sending SMS message: " + err.Error()) 84 } else { 85 response, _ := json.Marshal(*resp) 86 fmt.Println("Response: " + string(response)) 87 } 88 } 89 ``` 90 91 Save `sendsms.go`. In your terminal from the same directory, run: 92 93 ```shell 94 go run sendsms.go 95 ``` 96 97 After a brief delay, you will receive the text message on your phone. 98 99 > **Warning** 100 > It's okay to hardcode your credentials when testing locally, but you should use environment variables to keep them secret before committing any code or deploying to production. Check out [How to Set Environment Variables](https://www.twilio.com/blog/2017/01/how-to-set-environment-variables.html) for more information. 101 102 ## Use the helper library 103 104 ### API credentials 105 106 The Twilio `RestClient` needs your Twilio credentials. We recommend storing them as environment variables, so that you don't have to worry about committing and accidentally posting them somewhere public. See http://twil.io/secure for more details on how to store environment variables. 107 108 ```go 109 package main 110 111 import "github.com/twilio/twilio-go" 112 113 func main() { 114 // This will look for `TWILIO_ACCOUNT_SID` and `TWILIO_AUTH_TOKEN` variables inside the current environment to initialize the constructor 115 // You can find your Account SID and Auth Token at twilio.com/console 116 // `TWILIO_ACCOUNT_SID` should be in format "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" 117 client := twilio.NewRestClient() 118 } 119 ``` 120 121 If you don't want to use environment variables, you can also pass the credentials directly to the constructor as below. 122 123 ```go 124 package main 125 126 import "github.com/twilio/twilio-go" 127 128 func main() { 129 accountSid := "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" 130 authToken := "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY" 131 client := twilio.NewRestClientWithParams(twilio.ClientParams{ 132 Username: accountSid, 133 Password: authToken, 134 }) 135 } 136 ``` 137 138 ### Use a Subaccount 139 140 Subaccounts in Twilio are just accounts that are "owned" by your account. Twilio users can create subaccounts to help separate Twilio account usage into different buckets. 141 142 If you wish to make API calls with a Subaccount, you can do so by setting the `AccountSid` field in the `twilio.ClientParams`: 143 144 ```go 145 package main 146 147 import "github.com/twilio/twilio-go" 148 149 func main() { 150 // subaccountSid should also be in format "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" 151 subaccountSid := os.Getenv("TWILIO_SUBACCOUNT_SID") 152 client := twilio.NewRestClientWithParams(twilio.ClientParams{ 153 AccountSid: subaccountSid, 154 }) 155 } 156 ``` 157 158 ### Use API Keys 159 160 Lastly, if you want to follow best practices and initialize your client using an [API Key and Secret](https://www.twilio.com/docs/iam/keys/api-key), instead of potentially exposing your account's AuthToken, use the following pattern: 161 162 ```go 163 package main 164 165 import ( 166 "os" 167 168 "github.com/twilio/twilio-go" 169 ) 170 171 func main() { 172 accountSid := os.Getenv("TWILIO_ACCOUNT_SID") 173 apiKey := os.Getenv("TWILIO_API_KEY") 174 apiSecret := os.Getenv("TWILIO_API_SECRET") 175 176 client := twilio.NewRestClientWithParams(twilio.ClientParams{ 177 Username: apiKey, 178 Password: apiSecret, 179 AccountSid: accountSid, 180 }) 181 } 182 183 ``` 184 185 ### Specify a Region and/or Edge 186 187 ```go 188 package main 189 190 import ( 191 "github.com/twilio/twilio-go" 192 ) 193 194 func main() { 195 client := twilio.NewRestClient() 196 client.SetRegion("au1") 197 client.SetEdge("sydney") 198 } 199 ``` 200 201 This will result in the `hostname` transforming from `api.twilio.com` to `api.sydney.au1.twilio.com`. 202 203 A Twilio client constructed without these parameters will also look for `TWILIO_REGION` and `TWILIO_EDGE` variables inside the current environment. 204 205 ### Buy a phone number 206 207 ```go 208 package main 209 210 import ( 211 "fmt" 212 "github.com/twilio/twilio-go" 213 twilioApi "github.com/twilio/twilio-go/rest/api/v2010" 214 ) 215 216 func main() { 217 phoneNumber := "AVAILABLE_TWILIO_PHONE_NUMBER" 218 219 client := twilio.NewRestClient() 220 221 params := &twilioApi.CreateIncomingPhoneNumberParams{} 222 params.SetPhoneNumber(phoneNumber) 223 224 resp, err := client.Api.CreateIncomingPhoneNumber(params) 225 if err != nil { 226 fmt.Println(err.Error()) 227 } else { 228 fmt.Println("Phone Number Status: " + *resp.Status) 229 } 230 } 231 ``` 232 233 ### Make a call 234 235 ```go 236 package main 237 238 import ( 239 "fmt" 240 "github.com/twilio/twilio-go" 241 twilioApi "github.com/twilio/twilio-go/rest/api/v2010" 242 "os" 243 ) 244 245 func main() { 246 from := os.Getenv("TWILIO_FROM_PHONE_NUMBER") 247 to := os.Getenv("TWILIO_TO_PHONE_NUMBER") 248 249 client := twilio.NewRestClient() 250 251 params := &twilioApi.CreateCallParams{} 252 params.SetTo(to) 253 params.SetFrom(from) 254 params.SetUrl("http://twimlets.com/holdmusic?Bucket=com.twilio.music.ambient") 255 256 resp, err := client.Api.CreateCall(params) 257 if err != nil { 258 fmt.Println(err.Error()) 259 } else { 260 fmt.Println("Call Status: " + *resp.Status) 261 fmt.Println("Call Sid: " + *resp.Sid) 262 fmt.Println("Call Direction: " + *resp.Direction) 263 } 264 } 265 ``` 266 267 ### Get data about an existing Call 268 269 ```go 270 package main 271 272 import ( 273 "fmt" 274 "os" 275 276 "github.com/twilio/twilio-go" 277 twilioApi "github.com/twilio/twilio-go/rest/api/v2010" 278 ) 279 280 func main() { 281 accountSid := os.Getenv("TWILIO_ACCOUNT_SID") 282 apiKey := os.Getenv("TWILIO_API_KEY") 283 apiSecret := os.Getenv("TWILIO_API_SECRET") 284 285 client := twilio.NewRestClientWithParams(twilio.ClientParams{ 286 Username: apiKey, 287 Password: apiSecret, 288 AccountSid: accountSid, 289 }) 290 291 params := &twilioApi.FetchCallParams{} 292 293 resp, err := client.Api.FetchCall("CA42ed11f93dc08b952027ffbc406d0868", params) 294 if err != nil { 295 fmt.Println(err.Error()) 296 } else { 297 fmt.Println("Call Status: " + *resp.Status) 298 fmt.Println("Call Sid: " + *resp.Sid) 299 fmt.Println("Call Direction: " + *resp.Direction) 300 } 301 } 302 ``` 303 304 ### Send Bulk Message <a id="messaging-bulk"></a> 305 306 Try sending a message to multiple recipients with JSON request body support. 307 308 ```go 309 package main 310 311 import ( 312 "encoding/json" 313 "fmt" 314 315 "github.com/twilio/twilio-go" 316 previewMessaging "github.com/twilio/twilio-go/rest/preview_messaging/v1" 317 ) 318 319 func main() { 320 accountSid := "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" 321 authToken := "f2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 322 323 client := twilio.NewRestClientWithParams(twilio.ClientParams{ 324 Username: accountSid, 325 Password: authToken, 326 }) 327 328 // create multiple recipients 329 msg1 := previewMessaging.MessagingV1Message{To: "+XXXXXXXXXX"} 330 msg2 := previewMessaging.MessagingV1Message{To: "+XXXXXXXXXX"} 331 332 // create message request object 333 req := &previewMessaging.CreateMessagesRequest{Messages: []previewMessaging.MessagingV1Message{msg1, msg2}, Body: "Hello from Go!", From: "+XXXXXXXXXX"} 334 params := &previewMessaging.CreateMessagesParams{CreateMessagesRequest: req} 335 336 resp, err := client.PreviewMessagingV1.CreateMessages(params) 337 if err != nil { 338 fmt.Println("Error sending SMS message: " + err.Error()) 339 } else { 340 response, _ := json.Marshal(*resp) 341 fmt.Println("Response: " + string(response)) 342 } 343 } 344 ``` 345 346 ### Iterate through records 347 348 This library also offers paging functionality. Collections such as calls and messages have `ListXxx` and `StreamXxx` 349 functions that page under the hood. With both list and stream, you can specify the number of records you want to 350 receive (limit) and the maximum size you want each page fetch to be (pageSize). The library will then handle the task 351 for you. 352 353 `List` eagerly fetches all records and returns them as a list, whereas `Stream` streams the records and lazily retrieves 354 the pages as you iterate over the collection. Also, `List` returns no records if any errors are encountered while paging, 355 whereas `Stream` returns all records up until encountering an error. You can also page manually using the `PageXxx` 356 function in each of the apis. 357 358 #### Use `ListXxx` or `StreamXxx` 359 360 ```go 361 package main 362 363 import ( 364 "fmt" 365 "github.com/twilio/twilio-go" 366 twilioApi "github.com/twilio/twilio-go/rest/api/v2010" 367 "os" 368 ) 369 370 func main() { 371 from := os.Getenv("TWILIO_FROM_PHONE_NUMBER") 372 373 client := twilio.NewRestClient() 374 375 params := &twilioApi.ListMessageParams{} 376 params.SetFrom(from) 377 params.SetPageSize(20) 378 params.SetLimit(100) 379 380 resp, _ := client.Api.ListMessage(params) 381 for record := range resp { 382 fmt.Println("Body: ", *resp[record].Body) 383 } 384 385 channel, _ := client.Api.StreamMessage(params) 386 for record := range channel { 387 fmt.Println("Body: ", *record.Body) 388 } 389 } 390 ``` 391 392 #### Use `PageXxx` 393 394 ```go 395 package main 396 397 import ( 398 "fmt" 399 "github.com/twilio/twilio-go" 400 twilioApi "github.com/twilio/twilio-go/rest/api/v2010" 401 "net/url" 402 "os" 403 ) 404 405 func main() { 406 from := os.Getenv("TWILIO_FROM_PHONE_NUMBER") 407 408 client := twilio.NewRestClient() 409 410 params := &twilioApi.ListMessageParams{} 411 params.SetFrom(from) 412 params.SetPageSize(20) 413 414 var pageToken string 415 var pageNumber string 416 resp, err = client.Api.PageMessage(params, "", "") 417 if err != nil { 418 fmt.Println(err) 419 } else { 420 fmt.Println(resp.NextPageUri) 421 u, _ := url.Parse(resp.NextPageUri) 422 q := u.Query() 423 pageToken = q.Get("PageToken") 424 pageNumber = q.Get("Page") 425 } 426 427 resp, err := client.Api.PageMessage(params, pageToken, pageNumber) 428 if err != nil { 429 fmt.Println(err) 430 } else { 431 if resp != nil { 432 fmt.Println(*resp.Messages[0].Body) 433 } 434 } 435 } 436 ``` 437 438 ### Handle Exceptions 439 440 If the Twilio API returns a 400 or a 500 level HTTP response, the twilio-go library will include information in the returned err value. 400-level errors are [normal during API operation](https://www.twilio.com/docs/usage/requests-to-twilio) ("Invalid number", "Cannot deliver SMS to that number", for example) and should be handled appropriately. 441 442 ```go 443 package main 444 445 import ( 446 "fmt" 447 "os" 448 449 "github.com/twilio/twilio-go" 450 twilioclient "github.com/twilio/twilio-go/client" 451 twilioApi "github.com/twilio/twilio-go/rest/api/v2010" 452 ) 453 454 func main() { 455 phoneNumber := os.Getenv("TWILIO_PHONE_NUMBER") 456 457 client := twilio.NewRestClient() 458 459 params := &twilioApi.CreateIncomingPhoneNumberParams{} 460 params.SetPhoneNumber(phoneNumber) 461 462 resp, err := client.Api.CreateIncomingPhoneNumber(params) 463 if err != nil { 464 twilioError := err.(*twilioclient.TwilioRestError) 465 fmt.Println(twilioError.Error()) 466 } 467 } 468 ``` 469 470 ### Generate TwiML 471 472 To control phone calls, your application needs to output [TwiML](https://www.twilio.com/docs/voice/twiml). 473 474 Use the `twiml` package to easily create such responses. 475 476 ```go 477 package main 478 479 import ( 480 "fmt" 481 "github.com/twilio/twilio-go/twiml" 482 ) 483 484 func main() { 485 //Construct Verbs 486 dial := &twiml.VoiceDial{} 487 say := &twiml.VoiceSay{ 488 Message: "Welcome to Twilio!", 489 Voice: "woman", 490 Language: "en-gb", 491 OptionalAttributes: map[string]string{"input": "test"}, 492 } 493 pause := &twiml.VoicePause{ 494 Length: "10", 495 } 496 //Construct Noun 497 queue := &twiml.VoiceQueue{ 498 Url: "www.twilio.com", 499 } 500 //Adding Queue to Dial 501 dial.InnerElements = []twiml.Element{queue} 502 503 //Adding all Verbs to twiml.Voice 504 verbList := []twiml.Element{dial, say, pause} 505 twimlResult, err := twiml.Voice(verbList) 506 if err == nil { 507 fmt.Println(twimlResult) 508 } else { 509 fmt.Println(err) 510 } 511 } 512 ``` 513 514 This will print the following: 515 516 ```xml 517 <?xml version="1.0" encoding="UTF-8"?> 518 <Response> 519 <Dial> 520 <Queue url="www.twilio.com"/> 521 </Dial> 522 <Say voice="woman" language="en-gb" input="test">Welcome to Twilio!</Say> 523 <Pause length="10"/> 524 </Response> 525 ``` 526 527 ## Advanced Usage 528 529 ### Use the request validator 530 531 Validate that GET/POST Requests are coming from Twilio: 532 533 ```go 534 package main 535 536 import ( 537 "fmt" 538 "os" 539 540 "github.com/twilio/twilio-go/client" 541 ) 542 543 func main() { 544 // You can find your Auth Token at twilio.com/console 545 // For this example: authToken := "12345" 546 authToken := os.Getenv("TWILIO_AUTH_TOKEN") 547 548 requestValidator := client.NewRequestValidator(authToken) 549 550 // Twilio's request URL 551 url := "https://mycompany.com/myapp.php?foo=1&bar=2" 552 553 // Post variables in Twilio's request 554 params := map[string]string{ 555 "CallSid": "CA1234567890ABCDE", 556 "Caller": "+12349013030", 557 "Digits": "1234", 558 "From": "+12349013030", 559 "To": "+18005551212", 560 } 561 562 // X-Twilio-Signature header attached to the request 563 signature := "0/KCTR6DLpKmkAf8muzZqo1nDgQ=" 564 565 // Validate GET request 566 fmt.Println(requestValidator.Validate(url, params, signature)) 567 568 // Example of the POST request 569 Body := []byte(`{"property": "value", "boolean": true}`) 570 theUrl := "https://mycompany.com/myapp.php?bodySHA256=0a1ff7634d9ab3b95db5c9a2dfe9416e41502b283a80c7cf19632632f96e6620" 571 theSignature := "y77kIzt2vzLz71DgmJGsen2scGs=" 572 573 // Validate POST request 574 fmt.Println(requestValidator.ValidateBody(theUrl, Body, theSignature)) 575 } 576 ``` 577 578 ### Use standalone products 579 580 Don't want to import the top-level Twilio RestClient with access to the full suite of Twilio products? Use standalone product services instead: 581 582 ```go 583 package main 584 585 import ( 586 "github.com/twilio/twilio-go/client" 587 twilioApi "github.com/twilio/twilio-go/rest/api/v2010" 588 serverless "github.com/twilio/twilio-go/rest/serverless/v1" 589 "os" 590 ) 591 592 func main() { 593 accountSid := os.Getenv("TWILIO_ACCOUNT_SID") 594 authToken := os.Getenv("TWILIO_AUTH_TOKEN") 595 596 // Create an instance of our default BaseClient implementation 597 // You will need to provide your API credentials to the Client manually 598 defaultClient := &client.Client{ 599 Credentials: client.NewCredentials(accountSid, authToken), 600 } 601 defaultClient.SetAccountSid(accountSid) 602 603 coreApiService := twilioApi.NewApiServiceWithClient(defaultClient) 604 serverlessApiService := serverless.NewApiServiceWithClient(defaultClient) 605 } 606 ``` 607 608 ### Other advanced examples 609 610 - [Learn how to create your own custom HTTP client](./advanced-examples/custom-http-client.md) 611 612 ## Build Access Tokens 613 614 This library supports [access token](https://www.twilio.com/docs/iam/access-tokens) generation for use in the Twilio Client SDKs. 615 616 Here's how you would generate a token for the Voice SDK: 617 618 ```go 619 package main 620 621 import ( 622 "os" 623 "github.com/twilio/twilio-go/client/jwt" 624 ) 625 626 accountSid := os.Getenv("TWILIO_ACCOUNT_SID") 627 applicationSid := os.Getenv("TWILIO_TWIML_APP_SID") 628 apiKey := os.Getenv("TWILIO_API_KEY") 629 apiSecret := os.Getenv("TWILIO_API_SECRET") 630 identity := "fake123" 631 632 params := jwt.AccessTokenParams{ 633 AccountSid: accountSid, 634 SigningKeySid: apiKey, 635 Secret: apiSecret, 636 Identity: identity, 637 } 638 639 jwtToken := jwt.CreateAccessToken(params) 640 voiceGrant := &jwt.VoiceGrant{ 641 Incoming: jwt.Incoming{Allow: true}, 642 Outgoing: jwt.Outgoing{ 643 ApplicationSid: applicationSid, 644 }, 645 } 646 647 jwtToken.AddGrant(voiceGrant) 648 token, err := jwtToken.ToJwt() 649 ``` 650 651 Create Capability Tokens for TaskRouter v1: 652 653 ```go 654 package main 655 656 import ( 657 "os" 658 "github.com/twilio/twilio-go/client/jwt/taskrouter" 659 ) 660 661 AccountSid := os.Getenv("TWILIO_ACCOUNT_SID") 662 AuthToken := os.Getenv("TWILIO_AUTH_TOKEN") 663 WorkspaceSid := os.Getenv("TWILIO_WORKSPACE_SID") 664 ChannelID := os.Getenv("TWILIO_CHANNEL_ID") 665 666 Params = taskrouter.CapabilityTokenParams{ 667 AccountSid: AccountSid, 668 AuthToken: AuthToken, 669 WorkspaceSid: WorkspaceSid, 670 ChannelID: ChannelID, 671 } 672 673 capabilityToken := taskrouter.CreateCapabilityToken(Params) 674 token, err := capabilityToken.ToJwt() 675 ``` 676 677 ## Local Usage 678 679 ### Building 680 681 To build _twilio-go_ run: 682 683 ```shell 684 go build ./... 685 ``` 686 687 ### Testing 688 689 To execute the test suite run: 690 691 ```shell 692 go test ./... 693 ``` 694 695 ### Generating Local Documentation 696 697 To generate documentation, from the root directory: 698 699 ```shell 700 godoc -http=localhost:{port number} 701 ``` 702 703 Then, navigate to `http://localhost:{port number}/pkg/github.com/twilio/twilio-go` in your local browser. 704 705 Example: 706 707 ```shell 708 godoc -http=localhost:6060 709 ``` 710 711 http://localhost:6060/pkg/github.com/twilio/twilio-go 712 713 ## Docker Image 714 715 The `Dockerfile` present in this repository and its respective `twilio/twilio-go` Docker image are currently used by Twilio for testing purposes only. 716 717 ## Getting help 718 719 If you need help installing or using the library, please check the [Twilio Support Help Center](https://support.twilio.com) first, and [file a support ticket](https://twilio.com/help/contact) if you don't find an answer to your question. 720 721 If you've instead found a bug in the library or would like new features added, go ahead and open issues or pull requests against this repo! 722 723 [apidocs]: https://www.twilio.com/docs/api 724 [libdocs]: https://pkg.go.dev/github.com/twilio/twilio-go?tab=versions