Merge pull request #19 from DmitryZagorulko/master
* sending text stub * translations * delete bot instead deactivate
This commit is contained in:
commit
d1054f7653
@ -1 +1 @@
|
|||||||
alter table mg_user rename to user;
|
alter table mg_user rename to users;
|
||||||
|
1
migrations/1530177124_app.down.sql
Normal file
1
migrations/1530177124_app.down.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
alter table bot add column active boolean;
|
1
migrations/1530177124_app.up.sql
Normal file
1
migrations/1530177124_app.up.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
alter table bot drop column active;
|
@ -25,7 +25,6 @@ type Bot struct {
|
|||||||
Name string `gorm:"name type:varchar(40)" json:"name,omitempty"`
|
Name string `gorm:"name type:varchar(40)" json:"name,omitempty"`
|
||||||
CreatedAt time.Time
|
CreatedAt time.Time
|
||||||
UpdatedAt time.Time
|
UpdatedAt time.Time
|
||||||
Active bool `json:"active,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// User model
|
// User model
|
||||||
|
@ -48,8 +48,8 @@ func getBotByToken(token string) (*Bot, error) {
|
|||||||
return &bot, nil
|
return &bot, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Bot) setBotActivity() error {
|
func (b *Bot) deleteBot() error {
|
||||||
return orm.DB.Model(b).Where("token = ?", b.Token).Update("Active", !b.Active).Error
|
return orm.DB.Delete(b, "token = ?", b.Token).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
func getBotChannelByToken(token string) uint64 {
|
func getBotChannelByToken(token string) uint64 {
|
||||||
@ -69,9 +69,9 @@ func (c Connection) getBotsByClientID() Bots {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
func getBotByChannelAndCID(connectionID int, ch uint64) *Bot {
|
func getBot(cid int, ch uint64) *Bot {
|
||||||
var bot Bot
|
var bot Bot
|
||||||
orm.DB.First(&bot, "connection_id = ? AND channel = ?", connectionID, ch)
|
orm.DB.First(&bot, "connection_id = ? AND channel = ?", cid, ch)
|
||||||
|
|
||||||
return &bot
|
return &bot
|
||||||
}
|
}
|
||||||
|
31
routing.go
31
routing.go
@ -61,7 +61,7 @@ func setWrapperRoutes() {
|
|||||||
http.HandleFunc("/create/", createHandler)
|
http.HandleFunc("/create/", createHandler)
|
||||||
http.HandleFunc("/actions/activity", activityHandler)
|
http.HandleFunc("/actions/activity", activityHandler)
|
||||||
http.HandleFunc("/add-bot/", addBotHandler)
|
http.HandleFunc("/add-bot/", addBotHandler)
|
||||||
http.HandleFunc("/activity-bot/", activityBotHandler)
|
http.HandleFunc("/delete-bot/", deleteBotHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderTemplate(w http.ResponseWriter, tmpl string, c interface{}) {
|
func renderTemplate(w http.ResponseWriter, tmpl string, c interface{}) {
|
||||||
@ -200,7 +200,6 @@ func addBotHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
b.Channel = data.ChannelID
|
b.Channel = data.ChannelID
|
||||||
b.Active = true
|
|
||||||
|
|
||||||
err = c.createBot(b)
|
err = c.createBot(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -222,7 +221,7 @@ func addBotHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
w.Write(jsonString)
|
w.Write(jsonString)
|
||||||
}
|
}
|
||||||
|
|
||||||
func activityBotHandler(w http.ResponseWriter, r *http.Request) {
|
func deleteBotHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
defer r.Body.Close()
|
defer r.Body.Close()
|
||||||
setLocale(r.Header.Get("Accept-Language"))
|
setLocale(r.Header.Get("Accept-Language"))
|
||||||
body, err := ioutil.ReadAll(r.Body)
|
body, err := ioutil.ReadAll(r.Body)
|
||||||
@ -250,36 +249,16 @@ func activityBotHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ch := v1.Channel{
|
|
||||||
ID: getBotChannelByToken(b.Token),
|
|
||||||
Type: "telegram",
|
|
||||||
Events: []string{
|
|
||||||
"message_sent",
|
|
||||||
"message_updated",
|
|
||||||
"message_deleted",
|
|
||||||
"message_read",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
var client = v1.New(c.MGURL, c.MGToken)
|
var client = v1.New(c.MGURL, c.MGToken)
|
||||||
|
|
||||||
if b.Active {
|
data, status, err := client.DeactivateTransportChannel(getBotChannelByToken(b.Token))
|
||||||
data, status, err := client.DeactivateTransportChannel(ch.ID)
|
|
||||||
if status > http.StatusOK {
|
if status > http.StatusOK {
|
||||||
http.Error(w, localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "error_deactivating_channel"}), http.StatusBadRequest)
|
http.Error(w, localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "error_deactivating_channel"}), http.StatusBadRequest)
|
||||||
logger.Error(b.ID, status, err.Error(), data)
|
logger.Error(b.ID, status, err.Error(), data)
|
||||||
return
|
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.ID, status, err.Error(), data)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = b.setBotActivity()
|
err = b.deleteBot()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
raven.CaptureErrorAndWait(err, nil)
|
raven.CaptureErrorAndWait(err, nil)
|
||||||
http.Error(w, localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "error_save"}), http.StatusInternalServerError)
|
http.Error(w, localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "error_save"}), http.StatusInternalServerError)
|
||||||
@ -316,7 +295,7 @@ func settingsHandler(w http.ResponseWriter, r *http.Request, uid string) {
|
|||||||
"TableName": localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "table_name"}),
|
"TableName": localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "table_name"}),
|
||||||
"TableToken": localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "table_token"}),
|
"TableToken": localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "table_token"}),
|
||||||
"AddBot": localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "add_bot"}),
|
"AddBot": localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "add_bot"}),
|
||||||
"TableActivity": localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "table_activity"}),
|
"TableDelete": localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "table_delete"}),
|
||||||
"Title": localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "title"}),
|
"Title": localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "title"}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,7 @@ func TestRouting_addBotHandler(t *testing.T) {
|
|||||||
assert.Equal(t, "123123:Qwerty", res["token"])
|
assert.Equal(t, "123123:Qwerty", res["token"])
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRouting_activityBotHandler(t *testing.T) {
|
func TestRouting_deleteBotHandler(t *testing.T) {
|
||||||
defer gock.Off()
|
defer gock.Off()
|
||||||
|
|
||||||
gock.New("https://test.retailcrm.pro").
|
gock.New("https://test.retailcrm.pro").
|
||||||
@ -114,13 +114,13 @@ func TestRouting_activityBotHandler(t *testing.T) {
|
|||||||
Reply(200).
|
Reply(200).
|
||||||
BodyString(`{"id": 1}`)
|
BodyString(`{"id": 1}`)
|
||||||
|
|
||||||
req, err := http.NewRequest("POST", "/activity-bot/", strings.NewReader(`{"token": "123123:Qwerty", "active": false, "connectionId": 1}`))
|
req, err := http.NewRequest("POST", "/delete-bot/", strings.NewReader(`{"token": "123123:Qwerty", "active": false, "connectionId": 1}`))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
rr := httptest.NewRecorder()
|
rr := httptest.NewRecorder()
|
||||||
handler := http.HandlerFunc(activityBotHandler)
|
handler := http.HandlerFunc(deleteBotHandler)
|
||||||
handler.ServeHTTP(rr, req)
|
handler.ServeHTTP(rr, req)
|
||||||
|
|
||||||
assert.Equal(t, http.StatusOK, rr.Code,
|
assert.Equal(t, http.StatusOK, rr.Code,
|
||||||
|
@ -39,21 +39,17 @@ $("#add-bot").on("submit", function(e) {
|
|||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
$(document).on("click", ".activity-bot", function(e) {
|
$(document).on("click", ".delete-bot", function(e) {
|
||||||
let but = $(this);
|
let but = $(this);
|
||||||
send("/activity-bot/",
|
send("/delete-bot/",
|
||||||
{
|
{
|
||||||
token: but.attr("data-token"),
|
token: but.attr("data-token"),
|
||||||
active: (but.attr("data-activity") === 'true'),
|
|
||||||
connectionId: parseInt($('input[name=connectionId]').val()),
|
connectionId: parseInt($('input[name=connectionId]').val()),
|
||||||
},
|
},
|
||||||
function () {
|
function () {
|
||||||
if (but.attr("data-activity") === 'true') {
|
but.parents("tr").remove();
|
||||||
but.find('i').replaceWith('<i class="material-icons">play_arrow</i>');
|
if ($("#bots tbody tr").length === 0) {
|
||||||
but.attr("data-activity", "false")
|
$("#bots").addClass("hide");
|
||||||
} else {
|
|
||||||
but.find('i').replaceWith('<i class="material-icons">pause</i>');
|
|
||||||
but.attr("data-activity", "true")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -89,9 +85,9 @@ function getBotTemplate(data) {
|
|||||||
<td>${bot.name}</td>
|
<td>${bot.name}</td>
|
||||||
<td>${bot.token}</td>
|
<td>${bot.token}</td>
|
||||||
<td>
|
<td>
|
||||||
<button class="activity-bot btn btn-small waves-effect waves-light light-blue darken-1" type="submit" name="action"
|
<button class="delete-bot btn btn-small waves-effect waves-light light-blue darken-1" type="submit" name="action"
|
||||||
data-activity="true" data-token="${bot.token}">
|
data-token="${bot.token}">
|
||||||
<i class="material-icons">pause</i>
|
<i class="material-icons">delete</i>
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>`;
|
</tr>`;
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
#bots .activity-bot{
|
#bots .delete-bot{
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
44
telegram.go
44
telegram.go
@ -15,6 +15,7 @@ import (
|
|||||||
"github.com/aws/aws-sdk-go/service/s3/s3manager"
|
"github.com/aws/aws-sdk-go/service/s3/s3manager"
|
||||||
"github.com/getsentry/raven-go"
|
"github.com/getsentry/raven-go"
|
||||||
"github.com/go-telegram-bot-api/telegram-bot-api"
|
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||||
|
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||||
"github.com/retailcrm/mg-transport-api-client-go/v1"
|
"github.com/retailcrm/mg-transport-api-client-go/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -38,7 +39,7 @@ func telegramWebhookHandler(w http.ResponseWriter, r *http.Request, token string
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.ID == 0 || !b.Active {
|
if b.ID == 0 {
|
||||||
logger.Error(token, "telegramWebhookHandler: missing or deactivated")
|
logger.Error(token, "telegramWebhookHandler: missing or deactivated")
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
return
|
return
|
||||||
@ -76,7 +77,11 @@ func telegramWebhookHandler(w http.ResponseWriter, r *http.Request, token string
|
|||||||
var client = v1.New(c.MGURL, c.MGToken)
|
var client = v1.New(c.MGURL, c.MGToken)
|
||||||
|
|
||||||
if update.Message != nil {
|
if update.Message != nil {
|
||||||
if update.Message.Text != "" {
|
if update.Message.Text == "" {
|
||||||
|
setLocale(update.Message.From.LanguageCode)
|
||||||
|
update.Message.Text = localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: getMessageID(update.Message)})
|
||||||
|
}
|
||||||
|
|
||||||
nickname := update.Message.From.UserName
|
nickname := update.Message.From.UserName
|
||||||
user := getUserByExternalID(update.Message.From.ID)
|
user := getUserByExternalID(update.Message.From.ID)
|
||||||
|
|
||||||
@ -156,10 +161,13 @@ func telegramWebhookHandler(w http.ResponseWriter, r *http.Request, token string
|
|||||||
logger.Debugf("telegramWebhookHandler Type: SendMessage, Bot: %v, Message: %v, Response: %v", b.ID, snd, data)
|
logger.Debugf("telegramWebhookHandler Type: SendMessage, Bot: %v, Message: %v, Response: %v", b.ID, snd, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if update.EditedMessage != nil {
|
if update.EditedMessage != nil {
|
||||||
if update.EditedMessage.Text != "" {
|
if update.EditedMessage.Text == "" {
|
||||||
|
setLocale(update.EditedMessage.From.LanguageCode)
|
||||||
|
update.EditedMessage.Text = localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: getMessageID(update.Message)})
|
||||||
|
}
|
||||||
|
|
||||||
snd := v1.UpdateData{
|
snd := v1.UpdateData{
|
||||||
Message: v1.UpdateMessage{
|
Message: v1.UpdateMessage{
|
||||||
Message: v1.Message{
|
Message: v1.Message{
|
||||||
@ -183,7 +191,6 @@ func telegramWebhookHandler(w http.ResponseWriter, r *http.Request, token string
|
|||||||
logger.Debugf("telegramWebhookHandler Type: UpdateMessage, Bot: %v, Message: %v, Response: %v", b.ID, snd, data)
|
logger.Debugf("telegramWebhookHandler Type: UpdateMessage, Bot: %v, Message: %v, Response: %v", b.ID, snd, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
}
|
}
|
||||||
@ -229,8 +236,8 @@ func mgWebhookHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
uid, _ := strconv.Atoi(msg.Data.ExternalMessageID)
|
uid, _ := strconv.Atoi(msg.Data.ExternalMessageID)
|
||||||
cid, _ := strconv.ParseInt(msg.Data.ExternalChatID, 10, 64)
|
cid, _ := strconv.ParseInt(msg.Data.ExternalChatID, 10, 64)
|
||||||
|
|
||||||
b := getBotByChannelAndCID(c.ID, msg.Data.ChannelID)
|
b := getBot(c.ID, msg.Data.ChannelID)
|
||||||
if b.ID == 0 || !b.Active {
|
if b.ID == 0 {
|
||||||
logger.Error(msg.Data.ChannelID, "mgWebhookHandler: missing or deactivated")
|
logger.Error(msg.Data.ChannelID, "mgWebhookHandler: missing or deactivated")
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
w.Write([]byte("missing or deactivated"))
|
w.Write([]byte("missing or deactivated"))
|
||||||
@ -377,3 +384,26 @@ func UploadUserAvatar(url string) (picURLs3 string, err error) {
|
|||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getMessageID(data *tgbotapi.Message) string {
|
||||||
|
switch {
|
||||||
|
case data.Sticker != nil:
|
||||||
|
return "sticker"
|
||||||
|
case data.Audio != nil:
|
||||||
|
return "audio"
|
||||||
|
case data.Contact != nil:
|
||||||
|
return "contact"
|
||||||
|
case data.Document != nil:
|
||||||
|
return "document"
|
||||||
|
case data.Location != nil:
|
||||||
|
return "location"
|
||||||
|
case data.Video != nil:
|
||||||
|
return "video"
|
||||||
|
case data.Voice != nil:
|
||||||
|
return "voice"
|
||||||
|
case data.Photo != nil:
|
||||||
|
return "photo"
|
||||||
|
default:
|
||||||
|
return "undefined"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -53,7 +53,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th>{{.Locale.TableName}}</th>
|
<th>{{.Locale.TableName}}</th>
|
||||||
<th>{{.Locale.TableToken}}</th>
|
<th>{{.Locale.TableToken}}</th>
|
||||||
<th class="text-left">{{.Locale.TableActivity}}</th>
|
<th class="text-left">{{.Locale.TableDelete}}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@ -62,9 +62,9 @@
|
|||||||
<td>{{.Name}}</td>
|
<td>{{.Name}}</td>
|
||||||
<td>{{.Token}}</td>
|
<td>{{.Token}}</td>
|
||||||
<td>
|
<td>
|
||||||
<button class="activity-bot btn btn-small waves-effect waves-light light-blue darken-1" type="submit" name="action"
|
<button class="delete-bot btn btn-small waves-effect waves-light light-blue darken-1" type="submit" name="action"
|
||||||
data-activity="{{.Active}}" data-token="{{.Token}}">
|
data-token="{{.Token}}">
|
||||||
<i class="material-icons">{{if .Active}}pause{{else}}play_arrow{{end}}</i>
|
<i class="material-icons">delete</i>
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -1,30 +1,40 @@
|
|||||||
button_save: Save
|
button_save: Save
|
||||||
tab_settings: Connection settings
|
tab_settings: CRM settings
|
||||||
tab_bots: Bots
|
tab_bots: Bots
|
||||||
table_name: Bot name
|
table_name: Name
|
||||||
table_token: Bot token
|
table_token: Token
|
||||||
table_activity: Activity
|
table_delete: Delete
|
||||||
api_key: API Key
|
api_key: API key
|
||||||
add_bot: Add bot
|
add_bot: Add a bot
|
||||||
title: Telegram transport for retailCRM
|
title: Module of connecting Telegram to retailCRM
|
||||||
successful: Data successfully updated
|
successful: Data was updated successfully
|
||||||
|
|
||||||
no_bot_token: Enter the bot token
|
no_bot_token: Enter a token
|
||||||
wrong_data: Incorrect data
|
wrong_data: Wrong data
|
||||||
set_method: Set POST method
|
set_method: Set POST method
|
||||||
bot_already_created: Bot already created
|
bot_already_created: Bot is already created
|
||||||
not_found_account: The account could not be found, contact technical support
|
not_found_account: Account is not found, contact technical support
|
||||||
error_activating_channel: Error while activating the channel
|
error_activating_channel: Error when activating a channel
|
||||||
error_deactivating_channel: Error while deactivating the channel
|
error_deactivating_channel: Error when deactivating a channel
|
||||||
incorrect_url_key: Enter the correct CRM url or apiKey
|
incorrect_url_key: Enter the correct URL or API key
|
||||||
error_creating_integration: Error while creating integration
|
error_creating_integration: Error when integrating
|
||||||
error_creating_connection: Error while creating connection
|
error_creating_connection: Error when establishing a connection
|
||||||
connection_already_created: Connection already created
|
connection_already_created: Connection is already established
|
||||||
missing_url_key: Missing crm url or apiKey
|
missing_url_key: URL and API key are missing
|
||||||
incorrect_url: Enter the correct CRM url
|
incorrect_url: Enter the correct URL of CRM
|
||||||
incorrect_token: Set correct bot token
|
incorrect_token: Create the correct token
|
||||||
error_creating_webhook: Error while creating webhook
|
error_creating_webhook: Error when creating a webhook
|
||||||
error_adding_bot: Error while adding bot
|
error_adding_bot: Error when adding a bot
|
||||||
error_save: An error occurred while saving, contact technical support
|
error_save: Error while saving, contact technical support
|
||||||
missing_credentials: "Necessary credentials: {{.Credentials}}"
|
missing_credentials: "Required methods: {{.Credentials}}"
|
||||||
error_activity_mg: Check the activity with MessageGateway in CRM settings
|
error_activity_mg: Check if the integration with MessageGateway is enabled in CRM settings
|
||||||
|
|
||||||
|
sticker: "[sticker]"
|
||||||
|
audio: "[audio file]"
|
||||||
|
contact: "[contact]"
|
||||||
|
document: "[document]"
|
||||||
|
location: "[location]"
|
||||||
|
video: "[video]"
|
||||||
|
voice: "[voice message]"
|
||||||
|
photo: "[photo]"
|
||||||
|
undefined: "[undefined format of a message]"
|
||||||
|
@ -3,7 +3,7 @@ tab_settings: Настройки CRM
|
|||||||
tab_bots: Боты
|
tab_bots: Боты
|
||||||
table_name: Имя
|
table_name: Имя
|
||||||
table_token: Токен
|
table_token: Токен
|
||||||
table_activity: Активность
|
table_delete: Удалить
|
||||||
api_key: API Ключ
|
api_key: API Ключ
|
||||||
add_bot: Добавить бота
|
add_bot: Добавить бота
|
||||||
title: Модуль подключения Telegram к retailCRM
|
title: Модуль подключения Telegram к retailCRM
|
||||||
@ -28,3 +28,13 @@ error_adding_bot: Ошибка при добавлении бота
|
|||||||
error_save: Ошибка при сохранении, обратитесь в службу технической поддержки
|
error_save: Ошибка при сохранении, обратитесь в службу технической поддержки
|
||||||
missing_credentials: "Необходимые методы: {{.Credentials}}"
|
missing_credentials: "Необходимые методы: {{.Credentials}}"
|
||||||
error_activity_mg: Проверьте активность интеграции с MessageGateway в настройках CRM
|
error_activity_mg: Проверьте активность интеграции с MessageGateway в настройках CRM
|
||||||
|
|
||||||
|
sticker: "[стикер]"
|
||||||
|
audio: "[аудио файл]"
|
||||||
|
contact: "[контакт]"
|
||||||
|
document: "[документ]"
|
||||||
|
location: "[местонахождение]"
|
||||||
|
video: "[видео]"
|
||||||
|
voice: "[голосовое сообщение]"
|
||||||
|
photo: "[изображение]"
|
||||||
|
undefined: "[неопределенный формат сообщения]"
|
||||||
|
Loading…
Reference in New Issue
Block a user