1
0
mirror of synced 2024-11-25 13:16:02 +03:00

improve struct, template, routing

This commit is contained in:
DmitryZagorulko 2018-05-28 18:16:13 +03:00
parent 5c6cab9fbf
commit 45a6b478d7
18 changed files with 121 additions and 63 deletions

View File

@ -16,6 +16,7 @@ services:
user: ${UID:-1000}:${GID:-1000}
volumes:
- ./:/mg_telegram/
- ./static:/static/
links:
- postgres
ports:

View File

@ -5,23 +5,24 @@ import "time"
// Connection model
type Connection struct {
ID int `gorm:"primary_key"`
ClientID string `gorm:"client_id" json:"clientId,omitempty"`
APIKEY string `gorm:"api_key" json:"api_key,omitempty"`
APIURL string `gorm:"api_url" json:"api_url,omitempty"`
MGURL string `gorm:"mg_url" json:"mg_url,omitempty"`
MGToken string `gorm:"mg_token" json:"mg_token,omitempty"`
ClientID string `gorm:"client_id type:varchar(70);not null;unique" json:"clientId,omitempty"`
APIKEY string `gorm:"api_key type:varchar(100);not null;unique" json:"api_key,omitempty"`
APIURL string `gorm:"api_url type:varchar(100);not null;unique" json:"api_url,omitempty"`
MGURL string `gorm:"mg_url type:varchar(100);unique" json:"mg_url,omitempty"`
MGToken string `gorm:"mg_token type:varchar(100)" json:"mg_token,omitempty"`
CreatedAt time.Time
UpdatedAt time.Time
Active bool `json:"active,omitempty"`
Bots []Bot `gorm:"foreignkey:ConnectionID"`
}
// Bot model
type Bot struct {
ID int `gorm:"primary_key"`
ClientID string `gorm:"client_id" json:"clientId,omitempty"`
ConnectionID int `gorm:"connection_id" json:"connectionId,omitempty"`
Channel uint64 `json:"channel,omitempty"`
Token string `json:"token,omitempty"`
Name string `json:"name,omitempty"`
Token string `gorm:"token type:varchar(100);not null;unique" json:"token,omitempty"`
Name string `gorm:"name type:varchar(40)" json:"name,omitempty"`
CreatedAt time.Time
UpdatedAt time.Time
Active bool `json:"active,omitempty"`

View File

@ -26,6 +26,10 @@ func (c *Connection) saveConnection() error {
return orm.DB.Model(c).Where("client_id = ?", c.ClientID).Update(c).Error
}
func (c *Connection) createBot(b Bot) error {
return orm.DB.Model(c).Association("Bots").Append(&b).Error
}
func getBotByToken(token string) *Bot {
var bot Bot
orm.DB.First(&bot, "token = ?", token)
@ -33,10 +37,6 @@ func getBotByToken(token string) *Bot {
return &bot
}
func (b *Bot) createBot() error {
return orm.DB.Create(b).Error
}
func (b *Bot) setBotActivity() error {
return orm.DB.Model(b).Where("token = ?", b.Token).Update("Active", !b.Active).Error
}
@ -49,5 +49,13 @@ func getBotChannelByToken(token string) uint64 {
}
func (b *Bots) getBotsByClientID(uid string) error {
return orm.DB.Where("client_id = ?", uid).Find(b).Error
var c Connection
return orm.DB.First(&c, "client_id = ?", uid).Association("Bots").Find(b).Error
}
func getConnectionById(id int) *Connection {
var connection Connection
orm.DB.First(&connection, "id = ?", id)
return &connection
}

View File

@ -8,6 +8,7 @@ import (
"io/ioutil"
"net/http"
"regexp"
"strings"
"github.com/getsentry/raven-go"
"github.com/go-telegram-bot-api/telegram-bot-api"
@ -19,7 +20,6 @@ import (
)
var (
templates = template.Must(template.ParseFiles("templates/layout.html", "templates/form.html", "templates/home.html"))
validPath = regexp.MustCompile(`^/(save|settings|telegram)/([a-zA-Z0-9-:_+]+)$`)
localizer *i18n.Localizer
bundle = &i18n.Bundle{DefaultLanguage: language.English}
@ -114,6 +114,7 @@ func addBotHandler(w http.ResponseWriter, r *http.Request) {
if err != nil {
raven.CaptureErrorAndWait(err, nil)
http.Error(w, localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "error_adding_bot"}), http.StatusInternalServerError)
logger.Error(err.Error())
return
}
@ -123,6 +124,7 @@ func addBotHandler(w http.ResponseWriter, r *http.Request) {
if err != nil {
raven.CaptureErrorAndWait(err, nil)
http.Error(w, localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "error_adding_bot"}), http.StatusInternalServerError)
logger.Error(err.Error())
return
}
@ -131,10 +133,10 @@ func addBotHandler(w http.ResponseWriter, r *http.Request) {
return
}
c := getConnection(b.ClientID)
c := getConnectionById(b.ConnectionID)
if c.MGURL == "" || c.MGToken == "" {
http.Error(w, localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "not_found_account"}), http.StatusBadRequest)
logger.Error(b.ClientID, "MGURL or MGToken is empty")
logger.Error(b.Token, "MGURL or MGToken is empty")
return
}
@ -166,13 +168,6 @@ func addBotHandler(w http.ResponseWriter, r *http.Request) {
return
}
_, err = bot.GetWebhookInfo()
if err != nil {
logger.Error(b.Token, err.Error())
http.Error(w, localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "error_creating_webhook"}), http.StatusBadRequest)
return
}
b.Name = GetBotName(bot)
ch := v1.Channel{
@ -196,7 +191,7 @@ func addBotHandler(w http.ResponseWriter, r *http.Request) {
b.Channel = data.ChannelID
b.Active = true
err = b.createBot()
err = c.createBot(b)
if err != nil {
raven.CaptureErrorAndWait(err, nil)
http.Error(w, localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "error_adding_bot"}), http.StatusInternalServerError)
@ -221,6 +216,7 @@ func activityBotHandler(w http.ResponseWriter, r *http.Request) {
if err != nil {
raven.CaptureErrorAndWait(err, nil)
http.Error(w, localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "error_save"}), http.StatusInternalServerError)
logger.Error(err.Error())
return
}
@ -230,13 +226,14 @@ func activityBotHandler(w http.ResponseWriter, r *http.Request) {
if err != nil {
raven.CaptureErrorAndWait(err, nil)
http.Error(w, localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "error_save"}), http.StatusInternalServerError)
logger.Error(err.Error())
return
}
c := getConnection(b.ClientID)
c := getConnectionById(b.ConnectionID)
if c.MGURL == "" || c.MGToken == "" {
http.Error(w, localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "not_found_account"}), http.StatusBadRequest)
logger.Error(b.ClientID, "MGURL or MGToken is empty")
logger.Error(b.ID, "MGURL or MGToken is empty")
return
}
@ -257,14 +254,14 @@ func activityBotHandler(w http.ResponseWriter, r *http.Request) {
data, status, err := client.DeactivateTransportChannel(ch.ID)
if status > http.StatusOK {
http.Error(w, localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "error_deactivating_channel"}), http.StatusBadRequest)
logger.Error(b.ClientID, status, err.Error(), data)
logger.Error(b.ID, status, err.Error(), data)
return
}
} else {
data, status, err := client.ActivateTransportChannel(ch)
if status > http.StatusCreated {
http.Error(w, localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "error_activating_channel"}), http.StatusBadRequest)
logger.Error(b.ClientID, status, err.Error(), data)
logger.Error(b.ID, status, err.Error(), data)
return
}
}
@ -272,7 +269,7 @@ func activityBotHandler(w http.ResponseWriter, r *http.Request) {
err = b.setBotActivity()
if err != nil {
raven.CaptureErrorAndWait(err, nil)
logger.Error(b.ClientID, err.Error())
logger.Error(b.ID, err.Error())
http.Error(w, localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "error_save"}), http.StatusInternalServerError)
return
}
@ -345,6 +342,12 @@ func saveHandler(w http.ResponseWriter, r *http.Request) {
return
}
_, err, code := getAPIClient(c.APIURL, c.APIKEY)
if err != nil {
http.Error(w, err.Error(), code)
return
}
err = c.saveConnection()
if err != nil {
raven.CaptureErrorAndWait(err, nil)
@ -391,24 +394,12 @@ func createHandler(w http.ResponseWriter, r *http.Request) {
return
}
client := v5.New(c.APIURL, c.APIKEY)
cr, status, errr := client.APICredentials()
if errr.RuntimeErr != nil {
raven.CaptureErrorAndWait(errr.RuntimeErr, nil)
http.Error(w, localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "not_found_account"}), http.StatusInternalServerError)
logger.Error(c.APIURL, status, errr.RuntimeErr, cr)
client, err, code := getAPIClient(c.APIURL, c.APIKEY)
if err != nil {
http.Error(w, err.Error(), code)
return
}
if !cr.Success {
http.Error(w, localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "incorrect_url_key"}), http.StatusBadRequest)
logger.Error(c.APIURL, status, errr.ApiErr, cr)
return
}
//TODO: проверка на необходимые методы cr.Credentials
integration := v5.IntegrationModule{
Code: transport,
IntegrationCode: transport,
@ -416,7 +407,7 @@ func createHandler(w http.ResponseWriter, r *http.Request) {
Name: "Telegram",
ClientID: c.ClientID,
Logo: fmt.Sprintf(
"https://%s/web/telegram_logo.svg",
"https://%s/static/telegram_logo.svg",
config.HTTPServer.Host,
),
BaseURL: fmt.Sprintf(
@ -564,3 +555,55 @@ func validateCrmSettings(c Connection) error {
return nil
}
func getAPIClient(url, key string) (*v5.Client, error, int) {
client := v5.New(url, key)
cr, status, errr := client.APICredentials()
if errr.RuntimeErr != nil {
raven.CaptureErrorAndWait(errr.RuntimeErr, nil)
logger.Error(url, status, errr.RuntimeErr, cr)
return nil, errors.New(localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "not_found_account"})), http.StatusInternalServerError
}
if !cr.Success {
logger.Error(url, status, errr.ApiErr, cr)
return nil, errors.New(localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "incorrect_url_key"})), http.StatusBadRequest
}
if res := checkCredentials(cr.Credentials); len(res) != 0 {
logger.Error(url, status, res)
return nil,
errors.New(localizer.MustLocalize(&i18n.LocalizeConfig{
MessageID: "missing_credentials",
TemplateData: map[string]interface{}{
"Credentials": strings.Join(res, ", "),
},
})),
http.StatusBadRequest
}
return client, nil, 0
}
func checkCredentials(credential []string) []string {
rc := []string{
"/api/integration-modules/{code}",
"/api/integration-modules/{code}/edit",
}
for kn, vn := range rc {
for _, vc := range credential {
if vn == vc {
if len(rc) == 1 {
rc = rc[:0]
break
}
rc = append(rc[:kn], rc[kn+1:]...)
}
}
}
return rc
}

2
run.go
View File

@ -49,6 +49,6 @@ func (x *RunCommand) Execute(args []string) error {
func start() {
setWrapperRoutes()
setTransportRoutes()
http.Handle("/web/", http.StripPrefix("/web/", http.FileServer(http.Dir("web"))))
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
http.ListenAndServe(config.HTTPServer.Listen, nil)
}

View File

@ -24,7 +24,10 @@ $("#add-bot").on("submit", function(e) {
e.preventDefault();
send(
$(this).attr('action'),
formDataToObj($(this).serializeArray()),
{
connectionId: parseInt($(this).find('input[name=connectionId]').val()),
token: $(this).find('input[name=token]').val(),
},
function (data) {
let bots = $("#bots");
if (bots.hasClass("hide")) {
@ -42,7 +45,7 @@ $(document).on("click", ".activity-bot", function(e) {
{
token: but.attr("data-token"),
active: (but.attr("data-activity") === 'true'),
clientId: $('input[name=clientId]').val(),
connectionId: parseInt($('input[name=connectionId]').val()),
},
function () {
if (but.attr("data-activity") === 'true') {

View File

Before

Width:  |  Height:  |  Size: 999 B

After

Width:  |  Height:  |  Size: 999 B

View File

@ -45,7 +45,7 @@ func telegramWebhookHandler(w http.ResponseWriter, r *http.Request, token string
return
}
c := getConnection(b.ClientID)
c := getConnectionById(b.ConnectionID)
if c.MGURL == "" || c.MGToken == "" {
logger.Error(token, "MGURL or MGToken is empty")
w.WriteHeader(http.StatusBadRequest)

View File

@ -9,7 +9,7 @@
<div id="tab1" class="col s12">
<div class="row indent-top">
<form id="save" class="tab-el-center" action="/save/" method="POST">
<input name="clientId" type="hidden" value="{{.Conn.ClientID}}">
<input name="connectionId" type="hidden" value="{{.Conn.ID}}">
<div class="row">
<div class="input-field col s12">
<input placeholder="API Url" id="api_url" name="api_url" type="text" class="validate" value="{{.Conn.APIURL}}">
@ -34,7 +34,7 @@
<div id="tab2" class="col s12">
<div class="row indent-top">
<form id="add-bot" class="tab-el-center" action="/add-bot/" method="POST">
<input name="clientId" type="hidden" value="{{.Conn.ClientID}}">
<input name="connectionId" type="hidden" value="{{.Conn.ID}}">
<div class="row">
<div class="input-field col s12">
<input placeholder="{{.Locale.TableToken}}" id="token" name="token" type="text" class="validate">

View File

@ -3,9 +3,9 @@
<meta title="Telegram transport">
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>{{.Locale.Title}}</title>
<link rel="stylesheet" href="../web/materialize.min.css">
<link rel="stylesheet" href="../web/font.css" >
<link rel="stylesheet" href="../web/style.css" >
<link rel="stylesheet" href="/static/materialize.min.css">
<link rel="stylesheet" href="/static/font.css" >
<link rel="stylesheet" href="/static/style.css" >
</head>
<body>
<div class="container">
@ -14,8 +14,8 @@
</div>
{{template "body" .}}
</div>
<script src="../web/materialize.min.js"></script>
<script src="../web/jquery-3.3.1.min.js"></script>
<script src="../web/script.js"></script>
<script src="/static/materialize.min.js"></script>
<script src="/static/jquery-3.3.1.min.js"></script>
<script src="/static/script.js"></script>
</body>
</html>

View File

@ -26,3 +26,4 @@ incorrect_token: Set correct bot token
error_creating_webhook: Error while creating webhook
error_adding_bot: Error while adding bot
error_save: An error occurred while saving, contact technical support
missing_credentials: "Necessary credentials: {{.Credentials}}"

View File

@ -26,3 +26,4 @@ incorrect_token: Установите корректный токен
error_creating_webhook: Ошибка при создании webhook
error_adding_bot: Ошибка при добавлении бота
error_save: Ошибка при сохранении, обратитесь в службу технической поддержки
missing_credentials: "Необходимые методы: {{.Credentials}}"