diff --git a/cmd/sachet/config.go b/cmd/sachet/config.go index 747702af..87e62684 100644 --- a/cmd/sachet/config.go +++ b/cmd/sachet/config.go @@ -29,6 +29,7 @@ import ( "github.com/messagebird/sachet/provider/sipgate" "github.com/messagebird/sachet/provider/sms77" "github.com/messagebird/sachet/provider/smsc" + "github.com/messagebird/sachet/provider/smstools" "github.com/messagebird/sachet/provider/telegram" "github.com/messagebird/sachet/provider/tencentcloud" "github.com/messagebird/sachet/provider/textmagic" @@ -75,6 +76,7 @@ var config struct { Ghasedak ghasedak.Config Sfr sfr.Config TextMagic textmagic.Config + SmsTools smstools.Config } Receivers []ReceiverConf diff --git a/cmd/sachet/main.go b/cmd/sachet/main.go index 60d9b9f8..80ea684c 100644 --- a/cmd/sachet/main.go +++ b/cmd/sachet/main.go @@ -37,6 +37,7 @@ import ( "github.com/messagebird/sachet/provider/sipgate" "github.com/messagebird/sachet/provider/sms77" "github.com/messagebird/sachet/provider/smsc" + "github.com/messagebird/sachet/provider/smstools" "github.com/messagebird/sachet/provider/telegram" "github.com/messagebird/sachet/provider/tencentcloud" "github.com/messagebird/sachet/provider/textmagic" @@ -147,6 +148,8 @@ func providerByName(name string) (sachet.Provider, error) { return sfr.NewSfr(config.Providers.Sfr), nil case "textmagic": return textmagic.NewTextMagic(config.Providers.TextMagic), nil + case "smstools": + return smstools.NewSmsTools(config.Providers.SmsTools), nil } return nil, fmt.Errorf("%s: Unknown provider", name) diff --git a/provider/smstools/smstools.go b/provider/smstools/smstools.go new file mode 100644 index 00000000..e692f3f1 --- /dev/null +++ b/provider/smstools/smstools.go @@ -0,0 +1,73 @@ +package smstools + +import ( + "encoding/binary" + "fmt" + "hash/fnv" + "io" + "os" + "path/filepath" + "time" + + "github.com/messagebird/sachet" +) + +type Config struct { + OutgoingDir string `yaml:"outgoing_dir"` +} + +var _ (sachet.Provider) = (*SmsTools)(nil) + +type SmsTools struct { + Config +} + +func NewSmsTools(config Config) *SmsTools { + SmsTools := &SmsTools{Config: config} + return SmsTools +} + +func (smst *SmsTools) createFile(recipient, message string) (*os.File, error) { + h := fnv.New32() + if _, err := io.WriteString(h, recipient+message); err != nil { + return nil, err + } + if err := binary.Write(h, binary.LittleEndian, time.Now().UnixNano()); err != nil { + return nil, err + } + + hsum := h.Sum32() + prefix := filepath.Join(smst.OutgoingDir, "sachet-") + + try := 0 + for { + name := fmt.Sprintf("%s%d", prefix, hsum) + f, err := os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0o666) + if os.IsExist(err) { + if try++; try < 10000 { + hsum++ + continue + } + return nil, fmt.Errorf("unable to create conflict-free filename") + } + return f, err + } +} + +func (smst *SmsTools) Send(message sachet.Message) error { + for _, recipient := range message.To { + outfile, err := smst.createFile(recipient, message.Text) + if err != nil { + return err + } + defer outfile.Close() + outfile.WriteString("To: " + recipient + "\n") + outfile.WriteString("Alphabet: UTF-8\n") + outfile.WriteString("\n") + _, err = outfile.WriteString(message.Text) + if err != nil { + return err + } + } + return nil +}