4 Commits

19 changed files with 439 additions and 205 deletions

View File

@ -40,7 +40,7 @@ tidy:
go mod tidy
watch:
modd
go run github.com/cortesi/modd/cmd/modd
lint:
golangci-lint run --enable-all

View File

@ -40,23 +40,8 @@ powow:
# Clé d'API à utiliser par les clients Powow utilisant le mock
apiKey: powow
# Modèles de SMS transactionnels
# Voir https://powow4.iroquois.fr/user/docs/api/#create-transactional-sms
# et https://powow4.iroquois.fr/user/docs/api/#update-transactional-sms
#
# L'identifiant (SmsID) de chaque modèle est son index dans le tableau.
sms:
- name: Powow SMS
from: FakeSMS
# Modèle de contenu pour le SMS avec patrons d'insertion
# Voir https://powow4.iroquois.fr/user/docs/api/#send-transactional-sms, "About the CustomData parameter"
content: |
Bonjour %Subscriber:Firstname%,
Lorem ipsum dolor sit amet...
# Cet attribut n'est pas utilisé dans le cadre du mock
shortLink: false
# La création/mise à jour de modèles de SMS s'effectue via les méthodes TransactionalSMS.Create et TransactionalSMS.Update.
# Voir le fichier ./misc/powow.http pour un exemple de requête.
```
### Variables d'environnement

View File

@ -8,6 +8,8 @@ import (
"forge.cadoles.com/Cadoles/fake-sms/internal/command"
"forge.cadoles.com/Cadoles/fake-sms/internal/config"
"forge.cadoles.com/Cadoles/fake-sms/internal/model"
"forge.cadoles.com/Cadoles/fake-sms/internal/model/powow"
"forge.cadoles.com/Cadoles/fake-sms/internal/query"
"forge.cadoles.com/Cadoles/fake-sms/internal/storm"
"gitlab.com/wpetit/goweb/cqrs"
@ -40,6 +42,10 @@ func getServiceContainer(conf *config.Config) (*service.Container, error) {
ctn.Provide(storm.ServiceName, storm.ServiceProvider(
storm.WithPath(conf.Data.Path),
storm.WithObjects(
&model.SMS{},
&powow.SMSTemplate{},
),
))
ctn.Provide(cqrs.ServiceName, cqrs.ServiceProvider())

View File

@ -2,7 +2,7 @@
<div class="columns is-mobile">
<div class="column is-narrow">
<h1 class="is-size-3 title">
<a href="{{ .BaseURL }}" rel="Inbox" class="has-text-grey-dark">
<a href="{{ .BaseURL }}/" rel="Inbox" class="has-text-grey-dark">
{{if or .Messages .SMS}}
📳
{{else}}

View File

@ -23,10 +23,11 @@
</tr>
</thead>
<tbody>
{{ $baseURL := .BaseURL }}
{{range .Messages}}
<tr data-controller="inbox-entry"
data-action="click->outbox-entry#onClick"
data-inbox-entry-link="{{ .BaseURL }}/sms/{{ .ID }}">
data-inbox-entry-link="{{ $baseURL }}/sms/{{ .ID }}">
<td class="sms-from">
<span class="is-size-7">{{ .From }}</span>
</td>
@ -38,7 +39,7 @@
</td>
<td class="sms-actions">
<div class="buttons is-right">
<a href="{{ .BaseURL }}/sms/{{ .ID }}" class="button is-small is-link">👁️ See</a>
<a href="{{ $baseURL }}/sms/{{ .ID }}" class="button is-small is-link">👁️ See</a>
</div>
</td>
</tr>

View File

@ -2,9 +2,9 @@
{{define "header_buttons"}}
<button class="button is-danger"
data-controller="restful"
data-restful-endpoint="{{ .BaseURL }}/{{ .SMS.ID }}"
data-restful-endpoint="{{ .BaseURL }}/sms/{{ .SMS.ID }}"
data-restful-method="DELETE"
data-restful-redirect="{{ .BaseURL }}">
data-restful-redirect="{{ .BaseURL }}/">
🗑️ Delete
</button>
{{end}}

1
debian/compat vendored
View File

@ -1 +0,0 @@
9

14
debian/control vendored
View File

@ -1,14 +0,0 @@
Source: fake-sms
Section: unknown
Priority: optional
Maintainer: Cadoles <contact@cadoles.com>
Build-Depends: debhelper (>= 8.0.0), wget, ca-certificates, tar, curl
Standards-Version: 3.9.4
Homepage: http://forge.cadoles.com/Cadoles/fake-sms
Vcs-Git: http://forge.cadoles.com/Cadoles/fake-sms.git
Vcs-Browser: http://forge.cadoles.com/Cadoles/fake-sms
Package: fake-sms
Architecture: amd64
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: Serveur d'envoi de SMS factice pour le développement avec interface web

View File

@ -1 +0,0 @@
var/lib/fake-sms

View File

@ -1,11 +0,0 @@
[Unit]
Description=Serveur d'envoi de SMS factice pour le développement avec interface web
After=network-online.target
[Service]
Type=simple
ExecStart=/usr/bin/fake-sms -workdir /usr/share/fake-sms -config /etc/fake-sms/config.yml
Restart=on-failure
[Install]
WantedBy=multi-user.target

54
debian/rules vendored
View File

@ -1,54 +0,0 @@
#!/usr/bin/make -f
# -*- makefile -*-
# Uncomment this to turn on verbose mode.
export DH_VERBOSE=1
GO_VERSION := 1.15.6
OS := linux
ARCH := amd64
GOPATH=$(HOME)/go
ifeq (, $(shell which go 2>/dev/null))
override_dh_auto_build: install-go
endif
ifeq (, $(shell which node 2>/dev/null))
override_dh_auto_build: install-nodejs
endif
%:
dh $@ --with systemd
override_dh_auto_build: $(GOPATH)
GOPATH=$(GOPATH) PATH="$(PATH):/usr/local/go/bin:$(GOPATH)/bin" make tooling
npm install
GOPATH=$(GOPATH) PATH="$(PATH):/usr/local/go/bin:$(GOPATH)/bin" go mod vendor
GOPATH=$(GOPATH) PATH="$(PATH):/usr/local/go/bin:$(GOPATH)/bin" ARCH_TARGETS=$(ARCH) make release
$(GOPATH):
mkdir -p $(GOPATH)
install-go:
wget https://dl.google.com/go/go$(GO_VERSION).$(OS)-$(ARCH).tar.gz
tar -C /usr/local -xzf go$(GO_VERSION).$(OS)-$(ARCH).tar.gz
install-nodejs:
curl -sL https://deb.nodesource.com/setup_14.x | bash -
apt-get install -y nodejs
override_dh_auto_install:
mkdir -p debian/fake-sms/usr/share/fake-sms
mkdir -p debian/fake-sms/etc/fake-sms
mkdir -p debian/fake-sms/usr/bin
cp -r release/fake-sms-$(OS)-$(ARCH)/* debian/fake-sms/usr/share/fake-sms/
mv debian/fake-sms/usr/share/fake-sms/bin/fake-sms debian/fake-sms/usr/bin/fake-sms
mv debian/fake-sms/usr/share/fake-sms/config.yml debian/fake-sms/etc/fake-sms/config.yml
install -d debian/fake-sms
override_dh_strip:
override_dh_auto_test:

View File

@ -1 +0,0 @@
3.0 (native)

14
go.mod
View File

@ -5,10 +5,22 @@ go 1.14
require (
github.com/asdine/storm/v3 v3.1.1
github.com/caarlos0/env/v6 v6.2.1
github.com/cortesi/modd v0.0.0-20210222043654-cbdcc23af7d5 // indirect
github.com/davecgh/go-spew v1.1.1
github.com/elliotchance/phpserialize v1.3.0
github.com/fatih/color v1.10.0 // indirect
github.com/go-chi/chi v4.1.1+incompatible
github.com/google/go-cmp v0.5.4 // indirect
github.com/kovetskiy/go-php-serialize v0.0.0-20141101074437-71ef41a548d8 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/pkg/errors v0.9.1
github.com/stretchr/testify v1.7.0 // indirect
gitlab.com/wpetit/goweb v0.0.0-20200707070104-985ce3eba3c2
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e // indirect
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 // indirect
golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d // indirect
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43 // indirect
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v2 v2.2.8
)

86
go.sum
View File

@ -34,12 +34,26 @@ github.com/alecthomas/kong v0.2.1-0.20190708041108-0548c6b1afae/go.mod h1:+inYUS
github.com/alecthomas/kong-hcl v0.1.8-0.20190615233001-b21fea9723c8/go.mod h1:MRgZdU3vrFd05IQ89AxUZ0aYdF39BYoNFa324SodPCA=
github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897 h1:p9Sln00KOTlrYkxI1zYWl1QLnEqAqEARBEYa8FQnQcY=
github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20210208195552-ff826a37aa15 h1:AUNCr9CiJuwrRYS3XieqF+Z9B9gNxo/eANAJCF2eiN4=
github.com/alecthomas/units v0.0.0-20210208195552-ff826a37aa15/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=
github.com/asdine/storm/v3 v3.1.1 h1:5ESJvmcNhQQOFcvpxkIHcZs7mp8Z6XGdBqEoAgf+11g=
github.com/asdine/storm/v3 v3.1.1/go.mod h1:LEpXwGt4pIqrE/XcTvCnZHT5MgZCV6Ub9q7yQzOFWr0=
github.com/bmatcuk/doublestar v1.3.4 h1:gPypJ5xD31uhX6Tf54sDPUOBXTqKH4c9aPY66CyQrS0=
github.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE=
github.com/caarlos0/env/v6 v6.2.1 h1:/bFpX1dg4TNioJjg7mrQaSrBoQvRfLUHNfXivdFbbEo=
github.com/caarlos0/env/v6 v6.2.1/go.mod h1:3LpmfcAYCG6gCiSgDLaFR5Km1FRpPwFvBbRcjHar6Sw=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cortesi/modd v0.0.0-20210222043654-cbdcc23af7d5 h1:R2McxbAMq4aEHYUzQ8DGxWPXHSr33LdWS1C2qWCS554=
github.com/cortesi/modd v0.0.0-20210222043654-cbdcc23af7d5/go.mod h1:5XXIj61uad0c9FWBHCA1M+pP+xvO0+/OI10xL4Hg68w=
github.com/cortesi/moddwatch v0.0.0-20210222043437-a6aaad86a36e h1:vNbhR09qtq9ELJgvhAWng4zl/4CVTPBPVev3R8MlUYc=
github.com/cortesi/moddwatch v0.0.0-20210222043437-a6aaad86a36e/go.mod h1:MUkYRZrwFTHATqCI5tDJRPqmBt9xf3q4+Avfut7kCCE=
github.com/cortesi/termlog v0.0.0-20210222042314-a1eec763abec h1:v7D8uHsIKsyjfyhhNdY4qivqN558Ejiq+CDXiUljZ+4=
github.com/cortesi/termlog v0.0.0-20210222042314-a1eec763abec/go.mod h1:10Fm2kasJmcKf1FSMQGSWb976sfR29hejNtfS9AydB4=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E=
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ=
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964/go.mod h1:Xd9hchkHSWYkEqJwUGisez3G1QY8Ryz0sdWrLPMGjLk=
@ -49,10 +63,13 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/dlclark/regexp2 v1.1.6/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk=
github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/elliotchance/phpserialize v1.3.0 h1:yQ9t2spsOBp95V9qo4vPYIC2bXFaYOraRb8hpWd5E38=
github.com/elliotchance/phpserialize v1.3.0/go.mod h1:gt7XX9+ETUcLXbtTKEuyrqW3lcLUAeS/AnGZ2e49TZs=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg=
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
github.com/go-chi/chi v4.1.1+incompatible h1:MmTgB0R8Bt/jccxp+t6S/1VGIKdJw5J74CK/c9tTfA4=
github.com/go-chi/chi v4.1.1+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
@ -79,8 +96,9 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.2-0.20191216170541-340f1ebe299e h1:4WfjkTUTsO6siF8ghDQQk6t7x/FPsv3w6MXkc47do7Q=
github.com/google/go-cmp v0.3.2-0.20191216170541-340f1ebe299e/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
@ -92,9 +110,7 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m
github.com/gorilla/csrf v1.6.0/go.mod h1:7tSf8kmjNYr7IWDCYhd3U8Ck34iQ/Yw5CJu7bAkHEGI=
github.com/gorilla/handlers v1.4.1/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
github.com/gorilla/sessions v1.2.0 h1:S7P+1Hm5V/AT9cjEcUD5uDaQSX0OE577aCXgoaKpYbQ=
github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
@ -102,24 +118,31 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kovetskiy/go-php-serialize v0.0.0-20141101074437-71ef41a548d8 h1:5SuynDl9zQBugAPyvRjca4mClezQH954P4fBxdUB7GA=
github.com/kovetskiy/go-php-serialize v0.0.0-20141101074437-71ef41a548d8/go.mod h1:vbjtdVbbitDdc7FZj0ojJf+O/fEqf6Io1OmvIf9sWVg=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.1.0 h1:Sm1gr51B1kKyfD2BlRcLSiEkffoG96g6TPv6eRoEiB8=
github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E=
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw=
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0=
github.com/pkg/diff v0.0.0-20200914180035-5b29258ca4f7/go.mod h1:zO8QMzTeZd5cpnIkz/Gn6iK0jDfGicM1nynOkkPIl28=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@ -127,16 +150,19 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rjeczalik/notify v0.0.0-20181126183243-629144ba06a1 h1:FLWDC+iIP9BWgYKvWKKtOUZux35LIQNAuIzp/63RQJU=
github.com/rjeczalik/notify v0.0.0-20181126183243-629144ba06a1/go.mod h1:aErll2f0sUX9PXZnVNyeiObbmTlk5jnMoCa4QEjJeqM=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI=
@ -152,8 +178,9 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vKV/xzVTO7XPAwm8xbf4w2g=
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -183,10 +210,9 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191105084925-a882066a44e0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d h1:1aflnvSoWWLI2k/dMUAl5lvU1YO4Mb4hz0gh+1rjcxU=
golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -195,7 +221,11 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -207,14 +237,23 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 h1:LfCXLvNmTYH9kEmVgqbnsWfruoXZIrh4YBgqVHtDvw0=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201029080932-201ba4db2418/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43 h1:SgQ6LNaYJU0JIuEHv9+s6EbhSCwYeAf5Yvj6lpYlqAE=
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20191110171634-ad39bd3f0407/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@ -264,11 +303,13 @@ google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ij
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1 h1:wdKvqQk7IttEw92GoRyKG2IDrUIpgpj6H6m81yfeMW0=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
@ -277,9 +318,14 @@ gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWd
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
mvdan.cc/editorconfig v0.1.1-0.20200121172147-e40951bde157/go.mod h1:Ge4atmRUYqueGppvJ7JNrtqpqokoJEFxYbP0Z+WeKS8=
mvdan.cc/sh/v3 v3.2.2 h1:UpH3jtOUEXBWXZg35bnRukUjsB6UR+nNhhXCi2dGKOs=
mvdan.cc/sh/v3 v3.2.2/go.mod h1:fPQmabBpREM/XQ9YXSU5ZFZ/Sm+PmKP9/vkFHgYKJEI=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=

View File

@ -28,8 +28,7 @@ type DataConfig struct {
}
type PowowConfig struct {
APIKey string `yaml:"apiKey" env:"FAKESMS_POWOW_API_KEY"`
SMS []PowowSMS `yaml:"sms"`
APIKey string `yaml:"apiKey" env:"FAKESMS_POWOW_API_KEY"`
}
type PowowSMS struct {
@ -80,17 +79,6 @@ func NewDefault() *Config {
},
Powow: PowowConfig{
APIKey: "powow",
SMS: []PowowSMS{
{
Name: "Powow SMS",
From: "FakeSMS",
ShortLink: false,
Content: `Bonjour %Subscriber:Firstname%,
Lorem ipsum dolor sit amet...
`,
},
},
},
}
}

View File

@ -0,0 +1,10 @@
package powow
type SMSTemplate struct {
ID int `storm:"id,increment"`
SmsName string
FromName string
Content string
ShortLink int
Language string
}

View File

@ -4,12 +4,16 @@ import (
"context"
"encoding/base64"
"encoding/json"
"io/ioutil"
"net/http"
"strconv"
"strings"
"forge.cadoles.com/Cadoles/fake-sms/internal/command"
"forge.cadoles.com/Cadoles/fake-sms/internal/config"
"forge.cadoles.com/Cadoles/fake-sms/internal/model/powow"
"forge.cadoles.com/Cadoles/fake-sms/internal/storm"
"github.com/davecgh/go-spew/spew"
php "github.com/kovetskiy/go-php-serialize"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/cqrs"
"gitlab.com/wpetit/goweb/logger"
@ -20,25 +24,32 @@ import (
type ErrorCode int
const (
ErrorCodeInvalidCommand ErrorCode = 99997
ErrorCodeAuthenticationFailure ErrorCode = 99998
ErrorCodeNotEnoughPrivileges ErrorCode = 99999
ErrorCodeMissingSMSID ErrorCode = 1
ErrorCodeMissingMobilePhoneNumber ErrorCode = 2
ErrorCodeInvalidSMSID ErrorCode = 3
ErrorCodeInvalidMobilePhoneNumber ErrorCode = 4
ErrorCodeInvalidCustomData ErrorCode = 5
ErrorCodeInvalidTimeToSend ErrorCode = 6
ErrorCodeAccountSubscribersLimitExceeded ErrorCode = 7
ErrorCodeMobilePhoneNumberCannotBeSaved ErrorCode = 7
ErrorCodeTransactionalIDCannotBeCreated ErrorCode = 9
ErrorCodeSMSSentLimitExceeded ErrorCode = 10
ErrorCodeInvalidCommand ErrorCode = 99997
ErrorCodeAuthenticationFailure ErrorCode = 99998
ErrorCodeNotEnoughPrivileges ErrorCode = 99999
ErrorCodeTransactionSMSSendMissingSMSID ErrorCode = 1
ErrorCodeTransactionSMSSendMissingMobilePhoneNumber ErrorCode = 2
ErrorCodeTransactionSMSSendInvalidSMSID ErrorCode = 3
ErrorCodeTransactionSMSSendInvalidMobilePhoneNumber ErrorCode = 4
ErrorCodeTransactionSMSSendInvalidCustomData ErrorCode = 5
ErrorCodeTransactionSMSSendInvalidTimeToSend ErrorCode = 6
ErrorCodeTransactionSMSSendAccountSubscribersLimitExceeded ErrorCode = 7
ErrorCodeTransactionSMSSendMobilePhoneNumberCannotBeSaved ErrorCode = 7
ErrorCodeTransactionSMSSendTransactionalIDCannotBeCreated ErrorCode = 9
ErrorCodeTransactionSMSSendSMSSentLimitExceeded ErrorCode = 10
ErrorCodeTransactionSMSUpdateMissingSMSID ErrorCode = 1
ErrorCodeTransactionSMSUpdateInvalidSMSID ErrorCode = 3
ErrorCodeTransactionSMSUpdateInvalidFromName ErrorCode = 4
ErrorCodeTransactionSMSUpdateInvalidLanguage ErrorCode = 7
)
type Command string
const (
CommandTransactionalSMSSend = "TransactionalSms.Send"
CommandTransactionalSMSSend = "TransactionalSms.Send"
CommandTransactionalSMSCreate = "TransactionalSms.Create"
CommandTransactionalSMSUpdate = "TransactionalSms.Update"
)
type PowowRequest struct {
@ -49,6 +60,11 @@ type PowowRequest struct {
}
type PowowResponse struct {
Success bool
ErrorCode map[int]ErrorCode
}
type PowowResponseSuccess struct {
Success bool
ErrorCode ErrorCode
}
@ -59,38 +75,87 @@ func handlePowowEntrypoint(w http.ResponseWriter, r *http.Request) {
ctn := container.Must(ctx)
conf := config.Must(ctn)
data, err := ioutil.ReadAll(r.Body)
err := r.ParseForm()
if err != nil {
logger.Error(ctx, "could not read body", logger.E(errors.WithStack(err)))
logger.Error(ctx, "could not parse form", logger.E(errors.WithStack(err)))
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
defer r.Body.Close()
//data, err := ioutil.ReadAll(r.Body)
//if err != nil {
// logger.Error(ctx, "could not read body", logger.E(errors.WithStack(err)))
// http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
// return
//}
//defer r.Body.Close()
pr := &PowowRequest{
Payload: make(map[string]interface{}),
}
if err := json.Unmarshal(data, pr); err != nil {
logger.Error(ctx, "could not parse request", logger.E(errors.WithStack(err)))
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
pr.APIKey = r.FormValue("APIKey")
pr.Command = Command(r.FormValue("Command"))
pr.ResponseFormat = r.FormValue("ResponseFormat")
return
if pr.Command == CommandTransactionalSMSUpdate {
smsid, err := strconv.ParseFloat(r.FormValue("SmsID"), 64)
if err != nil {
logger.Error(ctx, "could not convert SmsID to float", logger.E(errors.WithStack(err)))
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
}
pr.Payload = map[string]interface{}{
"SmsID": smsid,
"Content": r.FormValue("Content"),
"ShortLink": r.FormValue("ShortLink"),
"Language": r.FormValue("Language"),
"FromName": r.FormValue("FromName"),
"SmsName": r.FormValue("SmsName"),
}
}
if err := json.Unmarshal(data, &pr.Payload); err != nil {
logger.Error(ctx, "could not parse request payload", logger.E(errors.WithStack(err)))
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
if pr.Command == CommandTransactionalSMSSend {
customData, err := php.Decode(r.FormValue("CustomData"))
if err != nil {
logger.Error(ctx, "could not cunserialized custom data", logger.E(errors.WithStack(err)))
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
}
var smsid float64
if r.FormValue("SmsID") != "" {
smsid, err = strconv.ParseFloat(r.FormValue("SmsID"), 64)
if err != nil {
logger.Error(ctx, "could not convert SmsID to float", logger.E(errors.WithStack(err)))
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
}
}
pr.Payload = map[string]interface{}{
"SmsID": smsid,
"MobilePhoneNumber": r.FormValue("MobilePhoneNumber"),
"TimeToSend": r.FormValue("TimeToSend"),
"CustomData": customData,
}
}
//if err := json.Unmarshal(data, pr); err != nil {
// logger.Error(ctx, "could not parse request", logger.E(errors.WithStack(err)))
// http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
// return
//}
//if err := json.Unmarshal(data, &pr.Payload); err != nil {
// logger.Error(ctx, "could not parse request payload", logger.E(errors.WithStack(err)))
// http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
// return
//}
// Authenticate user
if conf.Powow.APIKey != pr.APIKey {
res := &PowowResponse{
Success: false,
ErrorCode: ErrorCodeAuthenticationFailure,
ErrorCode: map[int]ErrorCode{0: ErrorCodeAuthenticationFailure},
}
sendPowowResponse(w, res)
@ -103,11 +168,19 @@ func handlePowowEntrypoint(w http.ResponseWriter, r *http.Request) {
case CommandTransactionalSMSSend:
handleTransactionalSMSSend(ctx, ctn, w, pr)
return
case CommandTransactionalSMSCreate:
handleTransactionalSMSCreate(ctx, ctn, w, pr)
return
case CommandTransactionalSMSUpdate:
handleTransactionalSMSUpdate(ctx, ctn, w, pr)
return
default:
res := &PowowResponse{
Success: false,
ErrorCode: ErrorCodeInvalidCommand,
ErrorCode: map[int]ErrorCode{0: ErrorCodeInvalidCommand},
}
sendPowowResponse(w, res)
@ -119,63 +192,70 @@ func handlePowowEntrypoint(w http.ResponseWriter, r *http.Request) {
// Mock https://powow4.iroquois.fr/user/docs/api/#send-transactional-sms
func handleTransactionalSMSSend(ctx context.Context, ctn *service.Container, w http.ResponseWriter, req *PowowRequest) {
bus := cqrs.Must(ctn)
conf := config.Must(ctn)
db := storm.Must(ctn)
rawSMSID, exists := req.Payload["SmsID"]
smsID, exists, valid := getPowowSMSID(req)
if !exists {
sendPowowResponse(w, &PowowResponse{
ErrorCode: ErrorCodeMissingSMSID,
ErrorCode: map[int]ErrorCode{0: ErrorCodeTransactionSMSSendMissingSMSID},
Success: false,
})
return
}
smsID, ok := rawSMSID.(float64)
if !ok {
if !valid {
sendPowowResponse(w, &PowowResponse{
ErrorCode: ErrorCodeInvalidSMSID,
ErrorCode: map[int]ErrorCode{0: ErrorCodeTransactionSMSSendInvalidSMSID},
Success: false,
})
return
}
if smsID < 0 || int(smsID) > len(conf.Powow.SMS)-1 {
sendPowowResponse(w, &PowowResponse{
ErrorCode: ErrorCodeInvalidSMSID,
Success: false,
})
smsTmpl := &powow.SMSTemplate{}
return
if err := db.One("ID", smsID, smsTmpl); err != nil {
if errors.Is(err, storm.ErrNotFound) {
sendPowowResponse(w, &PowowResponse{
ErrorCode: map[int]ErrorCode{0: ErrorCodeTransactionSMSSendInvalidSMSID},
Success: false,
})
return
}
panic(errors.Wrap(err, "could not retrieve sms template"))
}
customData := make(map[string]interface{})
rawCustomData, exists := req.Payload["CustomData"]
if exists {
customData, ok = rawCustomData.(map[string]interface{})
cData, ok := rawCustomData.(map[interface{}]interface{})
if !ok {
sendPowowResponse(w, &PowowResponse{
ErrorCode: ErrorCodeInvalidCustomData,
ErrorCode: map[int]ErrorCode{0: ErrorCodeTransactionSMSSendInvalidCustomData},
Success: false,
})
return
}
for k, v := range cData {
customData[k.(string)] = v
}
req.Payload["CustomData"] = customData
}
sms := conf.Powow.SMS[int(smsID)]
body, err := createSMSBody(sms.Content, customData)
body, err := createSMSBody(smsTmpl.Content, customData)
if err != nil {
panic(errors.Wrap(err, "could not generate sms body"))
}
req.Payload["_Template"] = sms
req.Payload["_Template"] = smsTmpl
storeSMS := &command.StoreSMSRequest{
From: sms.From,
From: smsTmpl.FromName,
Body: body,
Recipient: req.Payload["MobilePhoneNumber"].(string),
Metadata: req.Payload,
@ -187,10 +267,10 @@ func handleTransactionalSMSSend(ctx context.Context, ctn *service.Container, w h
}
res := &struct {
PowowResponse
PowowResponseSuccess
TransactionalID int
}{
PowowResponse: PowowResponse{
PowowResponseSuccess: PowowResponseSuccess{
Success: true,
ErrorCode: 0,
},
@ -202,7 +282,7 @@ func handleTransactionalSMSSend(ctx context.Context, ctn *service.Container, w h
func createSMSBody(template string, customData map[string]interface{}) (string, error) {
content := template
spew.Dump(customData)
for k, v := range customData {
decoded, err := base64.StdEncoding.DecodeString(v.(string))
if err != nil {
@ -217,6 +297,143 @@ func createSMSBody(template string, customData map[string]interface{}) (string,
return content, nil
}
// Mock https://powow4.iroquois.fr/user/docs/api/#create-transactional-sms
func handleTransactionalSMSCreate(ctx context.Context, ctn *service.Container, w http.ResponseWriter, req *PowowRequest) {
db := storm.Must(ctn)
smsTemplate := &powow.SMSTemplate{}
if err := db.Save(smsTemplate); err != nil {
panic(errors.Wrap(err, "could not save sms template"))
}
res := &struct {
PowowResponseSuccess
SmsID int
}{
PowowResponseSuccess: PowowResponseSuccess{
Success: true,
ErrorCode: 0,
},
SmsID: smsTemplate.ID,
}
sendPowowResponse(w, res)
}
// Mock https://powow4.iroquois.fr/user/docs/api/#update-transactional-sms
func handleTransactionalSMSUpdate(ctx context.Context, ctn *service.Container, w http.ResponseWriter, req *PowowRequest) {
smsID, exists, valid := getPowowSMSID(req)
if !exists {
sendPowowResponse(w, &PowowResponse{
ErrorCode: map[int]ErrorCode{0: ErrorCodeTransactionSMSUpdateMissingSMSID},
Success: false,
})
return
}
if !valid {
sendPowowResponse(w, &PowowResponse{
ErrorCode: map[int]ErrorCode{0: ErrorCodeTransactionSMSUpdateInvalidSMSID},
Success: false,
})
return
}
db := storm.Must(ctn)
smsTmpl := &powow.SMSTemplate{}
if err := db.One("ID", smsID, smsTmpl); err != nil {
if errors.Is(err, storm.ErrNotFound) {
sendPowowResponse(w, &PowowResponse{
ErrorCode: map[int]ErrorCode{0: ErrorCodeTransactionSMSUpdateInvalidSMSID},
Success: false,
})
return
}
panic(errors.Wrap(err, "could not retrieve sms template"))
}
rawContent, exists := req.Payload["Content"]
if exists {
content, ok := rawContent.(string)
if ok {
smsTmpl.Content = content
}
}
rawLanguage, exists := req.Payload["Language"]
if exists {
language, ok := rawLanguage.(string)
if ok {
if !contains(language, "en", "fr", "it", "es", "de", "pt", "pl", "zh") {
sendPowowResponse(w, &PowowResponse{
ErrorCode: map[int]ErrorCode{0: ErrorCodeTransactionSMSUpdateInvalidLanguage},
Success: false,
})
return
}
smsTmpl.Language = language
}
}
rawFromName, exists := req.Payload["FromName"]
if exists {
fromName, ok := rawFromName.(string)
if ok {
smsTmpl.FromName = fromName
}
}
rawShortLink, exists := req.Payload["ShortLink"]
if exists {
shortLink, ok := rawShortLink.(float64)
if ok {
if shortLink == 1.0 {
smsTmpl.ShortLink = 1
} else {
smsTmpl.ShortLink = 0
}
}
}
rawSMSName, exists := req.Payload["SmsName"]
if exists {
smsName, ok := rawSMSName.(string)
if ok {
smsTmpl.SmsName = smsName
}
}
rawShortLink, exists = req.Payload["ShortLink"]
if exists {
shortLink, ok := rawShortLink.(float64)
if ok {
if shortLink == 1.0 {
smsTmpl.ShortLink = 1
} else {
smsTmpl.ShortLink = 0
}
}
}
if err := db.Save(smsTmpl); err != nil {
panic(errors.Wrap(err, "could not save sms template"))
}
sendPowowResponse(w, &PowowResponseSuccess{
ErrorCode: 0,
Success: true,
})
}
func sendPowowResponse(w http.ResponseWriter, res interface{}) {
w.Header().Add("Content-Type", "application/json")
@ -227,3 +444,17 @@ func sendPowowResponse(w http.ResponseWriter, res interface{}) {
panic(errors.WithStack(err))
}
}
func getPowowSMSID(req *PowowRequest) (smsID int, exists bool, valid bool) {
rawSMSID, exists := req.Payload["SmsID"]
if !exists {
return -1, false, false
}
smsIDFloat, ok := rawSMSID.(float64)
if !ok {
return -1, true, false
}
return int(smsIDFloat), true, true
}

11
internal/route/util.go Normal file
View File

@ -0,0 +1,11 @@
package route
func contains(search string, items ...string) bool {
for _, item := range items {
if item == search {
return true
}
}
return false
}

View File

@ -1,14 +1,40 @@
POST http://localhost:3000/api/v1/mock/powow
Content-Type: application/json
### Create transactional SMS template
{
"APIKey": "powow",
"Command": "TransactionalSms.Send",
"ResponseFormat": "JSON",
"SmsID": 0,
"MobilePhoneNumber": "+33699999999",
"TimeToSend": "2017-01-01 10:00:00",
"CustomData": {
"Firstname": "Rm9v"
}
}
# @name createSms
POST http://localhost:3000/api/v1/mock/powow
Content-Type: application/x-www-form-urlencoded
APIKey=powow
&Command=TransactionalSms.Create
### Update transactional SMS template
@SmsID = {{createSms.response.body.$.SmsID}}
POST http://localhost:3000/api/v1/mock/powow
Content-Type: application/x-www-form-urlencoded
APIKey=powow
&Command=TransactionalSms.Update
&SmsID={{SmsID}}
&SmsName=Defaut SMS
&FromName=FakeSMS
&Content=Bonjour%20%25Subscriber%3AFirstname%25%2C%5CnLorem%20ipsum%20dolor%20sit%20amet...
&ShortLink=0
&Language=fr
### Send transactional SMS
POST http://localhost:3000/api/v1/mock/powow
Content-Type: application/x-www-form-urlencoded
APIKey=powow
&Command=TransactionalSms.Send
&ResponseFormat=JSON
&SmsID={{SmsID}}
&MobilePhoneNumber=+33699999999
&TimeToSend=2017-01-01 10:00:00
&CustomData=a%3A1%3A%7Bs%3A9%3A%22Firstname%22%3Bs%3A8%3A%22am9obg%3D%3D%22%3B%7D
# custom data [Firstname => "john"] = a:1:{s:9:"Firstname";s:8:"am9obg==";}