├── .gitignore ├── Makefile ├── go.mod ├── carriers_test.go ├── .editorconfig ├── .travis.yml ├── options.go ├── .gitattributes ├── carriers.go ├── tinysms_test.go ├── go.sum ├── LICENSE ├── tinysms.go └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | coverage.txt 2 | .DS_Store 3 | .vscode 4 | .idea 5 | *.sw[op] 6 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | all: fmt test 3 | 4 | .PHONY: fmt 5 | 6 | fmt: 7 | @go fmt . 8 | 9 | 10 | .PHONY: test 11 | 12 | test: 13 | go test . 14 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/ajm113/go-tinysms 2 | 3 | go 1.14 4 | 5 | require ( 6 | github.com/stretchr/testify v1.5.1 7 | gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0 8 | ) 9 | -------------------------------------------------------------------------------- /carriers_test.go: -------------------------------------------------------------------------------- 1 | package tinysms 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestCarriers(t *testing.T) { 10 | assert.NotNil(t, Carriers) 11 | assert.NotEmpty(t, Carriers) 12 | } 13 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.go] 12 | indent_style = tab 13 | 14 | 15 | [*.md] 16 | indent_style = tab 17 | trim_trailing_whitespace = false 18 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - 1.12.x 4 | - 1.13.x 5 | - tip 6 | env: 7 | - GO111MODULE=on 8 | install: 9 | - go get -v golang.org/x/lint/golint 10 | script: 11 | - golint -set_exit_status ./... 12 | - go test -race -coverprofile=coverage.txt -covermode=atomic ./... 13 | after_success: 14 | - bash <(curl -s https://codecov.io/bash) 15 | matrix: 16 | allow_failures: 17 | - go: tip 18 | -------------------------------------------------------------------------------- /options.go: -------------------------------------------------------------------------------- 1 | package tinysms 2 | 3 | // Options SMTP Connection strings. 4 | type Options struct { 5 | // Addr we are connecting to. e.g: "smtp.gmail.com:587" 6 | Addr string 7 | 8 | // Username Sometimes email address or username used to login 9 | Username string 10 | Password string 11 | 12 | // FromAddress Use custom from address if service supports it. Sometimes they will ignore this. 13 | FromAddress string 14 | } 15 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Automatically normalize line endings for all text-based files 2 | # http://git-scm.com/docs/gitattributes#_end_of_line_conversion 3 | * text=auto 4 | 5 | # For the following file types, normalize line endings to LF on checking and 6 | # prevent conversion to CRLF when they are checked out (this is required in 7 | # order to prevent newline related issues) 8 | .* text eol=lf 9 | *.go text eol=lf 10 | LICENSE text eol=lf 11 | -------------------------------------------------------------------------------- /carriers.go: -------------------------------------------------------------------------------- 1 | package tinysms 2 | 3 | // Carriers List of carriers and their email domains. 4 | var Carriers = map[string]string{ 5 | "alltel": "message.alltel.com", 6 | "cricket": "sms.mycricket.com", 7 | "at&t": "txt.att.net", 8 | "bell-atlantic": "message.bam.com", 9 | "comcast": "comcastpcs.textmsg.com", 10 | "boost": "myboostmobile.com", 11 | "sprint": "messaging.sprintpcs.com", 12 | "t-mobile": "tmomail.net", 13 | "verizon": "vtext.com", 14 | "virgin": "vmobl.net", 15 | "qwest": "qwestmp.com", 16 | "nextel": "messaging.nextel.com", 17 | "vodacom": "voda.co.za", 18 | } 19 | -------------------------------------------------------------------------------- /tinysms_test.go: -------------------------------------------------------------------------------- 1 | package tinysms 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | var options = &Options{ 10 | Addr: "smtp.gmail.com:587", 11 | Username: "tester@gmail.com", 12 | Password: "testing", 13 | FromAddress: "andrew@test.com", 14 | } 15 | 16 | func TestTinySMS(t *testing.T) { 17 | c := NewClient(options) 18 | 19 | assert.NotNil(t, c) 20 | assert.NotNil(t, c.Options) 21 | } 22 | 23 | func TestSend(t *testing.T) { 24 | c := NewClient(options) 25 | 26 | err := c.Send("5555555555", "AT&T", "tinysms Golang Library is 1337!") 27 | 28 | assert.NotNil(t, err) 29 | } 30 | 31 | func TestSendErrors(t *testing.T) { 32 | c := NewClient(options) 33 | 34 | err := c.Send("5555555555", "error", "failed message!") 35 | 36 | assert.NotNil(t, err) 37 | 38 | c.Options.Addr = ":123" 39 | err = c.Send("5555555555", "AT&T", "failed message!") 40 | 41 | assert.NotNil(t, err) 42 | } 43 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= 2 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 6 | github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= 7 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 8 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 9 | gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0 h1:POO/ycCATvegFmVuPpQzZFJ+pGZeX22Ufu6fibxDVjU= 10 | gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg= 11 | gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= 12 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2020-present Andrew McRobb 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /tinysms.go: -------------------------------------------------------------------------------- 1 | package tinysms 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "net" 7 | "net/smtp" 8 | "strings" 9 | ) 10 | 11 | type ( 12 | // SMSClient Client object used to send SMS messages. 13 | SMSClient struct { 14 | Options *Options 15 | stmpClient *smtp.Client 16 | } 17 | ) 18 | 19 | // NewClient Creates new client instant to send SMS. 20 | func NewClient(options *Options) (c *SMSClient) { 21 | c = &SMSClient{Options: options} 22 | return 23 | } 24 | 25 | // Send Sends SMS message to target number supplied with message string. 26 | func (c *SMSClient) Send(number, carrier, message string) (err error) { 27 | carrierEmailDomain, ok := Carriers[strings.ToLower(carrier)] 28 | 29 | if !ok { 30 | err = errors.New("unsupported carrier " + carrier + "! Please check available carriers list!") 31 | return 32 | } 33 | 34 | to := []string{fmt.Sprintf("%s@%s", number, carrierEmailDomain)} 35 | 36 | // Now split the host/port for smtp.PlainAuth 37 | host, _, err := net.SplitHostPort(c.Options.Addr) 38 | 39 | if err != nil { 40 | return 41 | } 42 | 43 | auth := smtp.PlainAuth("", c.Options.Username, c.Options.Password, host) 44 | 45 | // Now send the request! 46 | err = smtp.SendMail(c.Options.Addr, auth, c.Options.FromAddress, to, []byte(message)) 47 | 48 | return 49 | } 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tinysms 2 | **Simple free SMS client using SMTP** 3 | 4 | [![codecov](https://codecov.io/gh/ajm113/go-tinysms/branch/master/graph/badge.svg)](https://codecov.io/gh/ajm113/go-tinysms) 5 | [![Build Status](https://travis-ci.org/ajm113/go-tinysms.svg?branch=master)](https://travis-ci.org/ajm113/go-tinysms) 6 | [![Go Report Card](https://goreportcard.com/badge/github.com/ajm113/go-tinysms)](https://goreportcard.com/report/github.com/ajm113/go-tinysms) 7 | 8 | This is a library is perfect for small projects you are only sending a small amount of SMS to a single phone or a few you know of. Unfortunately, you need to know the user's carrier to send SMS. If you don't want to have to ask your users that. Then this project is not for you. I recommend using [Twilio](https://www.twilio.com/) for this if you plan on high volumn SMS messages. 9 | 10 | ## Requirements 11 | 12 | You are required to have an SMTP server to send SMS. Google provides this for free including few other major email providers. You will need to look up or ask your provider to give you SMTP access to send messages. **This library currently only supports major US wireless carriers**. If you would like to add one. Please make a PR request or open an issue! 13 | 14 | ## Install 15 | 16 | `go get github.com/ajm113/go-tinysms` 17 | 18 | ## Usuage 19 | 20 | ``` 21 | import "github.com/ajm113/go-tinysms" 22 | 23 | func main() { 24 | c := tinysms.NewClient(&tinysms.Options{ 25 | // SMTP Server and login settings. 26 | Addr: "smtp.gmail.com:587", 27 | Username: "tester@gmail.com", 28 | Password: "testing", 29 | 30 | // How you want the from address to show on text messages. 31 | FromAddress: "andrew@test.com", 32 | }) 33 | 34 | // Send a text message to a phone using AT&T. 35 | err := c.Send("5555555555", "AT&T", "tinysms Golang library is 1337!") 36 | } 37 | ``` 38 | 39 | ## This project wants help! 40 | Few things you can help improve the project! 41 | 42 | - Better carrier support of international carriers. 43 | - Improved documentation. 44 | - Better code coverage and unit tests. 45 | 46 | ## License 47 | 48 | MIT 49 | 50 | ## Authors 51 | 52 | - Andrew McRobb 53 | --------------------------------------------------------------------------------