Мы возвращаемся на Хабр после долгого отсутствия. И сегодня хотим рассказать как быстро и просто создать свой дополнительный модуль для BILLmanager'a. Эта задача существенно упростилась, потому что теперь доступен исходный код уже реализованных нами плагинов.
Возможность получения дополнительного модуля для BILLmanager существовала и ранее, причём несколькими способами.
Первый вариант — заказать модуль у нас, в ISPsystem. Получившийся продукт будет поддерживаться во всех последующих версиях BILLmanager, а также будет доступен для подключения другим пользователям. Однако порой наш плотный roadmap может надолго отсрочить релиз желаемого плагина.
Второй вариант — обратиться к нашим технологическим партнёрам, но в этом случае вопрос с поддержкой продукта нужно будет решать с партнёрами дополнительно.
И, наконец, третий вариант — написать модуль самостоятельно. Начиная с версии 5.58 вам больше не потребуется внушительный опыт программирования, т.к. теперь набор разработчика BILLmanager включает в себя примеры исходного кода 8 существующих плагинов, а именно:
- cpanel – обеспечивает интеграцию с одноимённой панелью управления;
- epp – универсальный обработчик для взаимодействия с поддерживающими протокол EPP регистраторами доменных имён;
- webnames – взаимодействует с этим доменным регистратором;
- thesslstore – модуль для покупки SSL-сертификатов;
- paypal – плагин для приёма платежей через данную платёжную систему;
- privatbank – для взаимодействия с биллингом банка;
- remotemail – почтовый шлюз;
- smsc – СМС-шлюз для компании СМС-центр;
Для получения пакета с примерами требуется установить BILLmanager (инструкция как это сделать находится здесь). В процессе инсталляции выберите желаемую версию продукта (Standard, Advanced или Corporate), а затем установите пакет billmanager-[выбранный_вариант]-devel (например, yum install billmanager-corporate-devel).
После установки пакета devel примеры будут находиться здесь:
/usr/local/mgr5/src/examples
Вооружившись образцами и имеющейся документацией, можно разработать модуль практически для любой платёжной системы, доменного регистратора, СМС-шлюза и т.д.
Рассмотрим процесс написания СМС-шлюза для взаимодействия с сотовым оператором Q-telecom; исходники — под катами чуть ниже.
При переделке модуля использовалось описание API Q-telecom; оно лежит здесь.
Из документации к API видно, что взаимодействие выполняется по протоколу http, так же как и в СМС-шлюзе из примеров. Воспользуемся этим.
Создадим копию директории /usr/local/mgr5/src/examples/smsc и назовём её gwqtc.
Внутри лежит 3 файла: xml отвечает за то, как плагин выглядит в BILLmanager; cpp описывает backend; в makefile лежат инструкции для компилятора как собрать всю эту прелесть в бинарник.
Начнём с самого сложного, — с переделки gwsmsc.cpp. Переименуем его в gwqtc.cpp, затем откроем файл в текстовом редакторе. Меняем в отвечающем за создание post-запроса куске кода названия переменных на описанные ребятами из Q-telecom. Добавляем параметр gzip=none, чтобы в случае сбоев текст ошибки приходил читаемым. Те строки, которые QTC не поймёт — удаляем.
Где и что поменяли
Затем в файле ищем и меняем “smsc” на “qtc” (в итоге изменения будут в двух строках). Всё, файл gwqtc.cpp готов. Самое сложное мы сделали.
Займёмся xml: меняем его имя на billmgr_mod_gwqtc; внутри “SMS-center” перепиcываем на “Q-telecom”, а “smsc” на “qtc”. С внешним видом закончили.
В makefile всё совсем просто: всюду меняем “smsc” на “qtc”.
Теперь скомпилируем и установим модуль командой make install, не забыв перед этим установить пакет gcc-c++, если его в системе нет.
После всех этих действий в BILLmanager, в меню “Интеграция” → “Модули сообщений” → “Создать” вы увидите новый модуль, Q-telecom.
Как это выглядит в BILLmanager
Осталось внести полученные при заключении договора с Q-telecom настройки — и можно пользоваться!
Вот обещанные исходники в конечном их виде.
gwqtc.cpp
#include <gate/gatemodule.h>
#include <defines.h>
#include <mgr/mgrlog.h>
#include <mgr/mgrrpc.h>
#include <sstream>
#define BINARY_NAME "gwqtc"
MODULE("notify");
namespace gate {
class QTC : public Module {
public:
QTC()
: Module(BINARY_NAME)
{
}
virtual mgr_xml::Xml Features() const
{
mgr_xml::Xml out;
mgr_xml::XmlNode features = out.GetRoot().AppendChild("features");
features.AppendChild("feature").SetProp("name", GATE_CMD_OUTGOING);
out.GetRoot().AppendChild("notify_module", "ntsms");
return out;
}
virtual mgr_xml::Xml Ingoing(mgr_xml::Xml& msg) const
{
mgr_xml::Xml out;
return out;
}
virtual void Outgoing(mgr_xml::Xml& msg) const
{
string message = msg.GetRoot().FindNode("message");
string project_id = msg.GetRoot().FindNode("project").FindNode("id");
string phone = msg.GetRoot().FindNode("user").FindNode("phone");
str::inpl::RemoveNonDigit(phone);
string sender = GateParam("originator_" + project_id);
if (sender.empty())
sender = GateParam("originator");
mgr_rpc::HttpQuery http;
http.EnableCookie();
http.AcceptAnyResponse();
std::stringstream out;
http.Post("http://service.qtelecom.ru/public/http/", "user=" +
str::url::Encode(GateParam("login")) +
"&pass=" + str::url::Encode(GateParam("psw")) +
"&target=" + str::url::Encode(phone) +
"&message=" + str::url::Encode(message) +
"&gzip=none"
"&sender=" + str::url::Encode(sender) +
"&action=post_sms", out);
Debug("response: %s", out.str().c_str());
mgr_xml::XmlString result(out.str());
string result_str = result.GetNode("//result/error");
if (!result_str.empty())
throw mgr_err::Error(result_str);
}
};
} // END NAMESPACE GATE
RUN_MODULE(gate::QTC)
billmgr_mod_gwqtc.xml
<?xml version="1.0" encoding="UTF-8"?>
<mgrdata>
<plugin name="gwqtc">
<group>gateway</group>
<author>BILLmanager team</author>
</plugin>
<metadata name="gateway.gwqtc">
<form>
<field name="login">
<input type="text" name="login" required="yes" identifier="yes"/>
</field>
<field name="psw">
<input type="password" name="psw" required="yes"/>
</field>
<field name="originator" project="yes">
<input type="text" name="originator"/>
</field>
</form>
</metadata>
<lang name="ru">
<messages name="plugin">
<msg name="desc_short_gwqtc">Q-telecom</msg>
<msg name="desc_full_gwqtc">Сервер Q-telecom</msg>
<msg name="price_gwqtc">Бесплатно</msg>
</messages>
<messages name="gateway.gwqtc">
<msg name="login">Логин</msg>
<msg name="psw">Пароль</msg>
<msg name="translit">Транслитерация</msg>
<msg name="originator">Отправитель</msg>
<msg name="hint_login">Логин в личный кабинет Q-telecomа</msg>
<msg name="hint_psw">Пароль от личного кабинета</msg>
<msg name="hint_translit">Транслитерация СМС сообщений при отправке</msg>
<msg name="hint_originator">Подпись отправителя в СМС</msg>
</messages>
<messages name="gateway_include">
<msg name="module_gwqtc">Сервер Q-telecom</msg>
<msg name="gwqtc">Q-telecom</msg>
<msg name="desc_gwqtc">СМС шлюз</msg>
</messages>
</lang>
<lang name="en">
<messages name="plugin">
<msg name="desc_short_gwqtc">SMS-center</msg>
<msg name="desc_full_gwqtc">Server SMS-center</msg>
<msg name="price_gwqtc">Free</msg>
</messages>
</lang>
</mgrdata>
Makefile
MGR = billmgr
PLUGIN = gwqtc
CFLAGS += -I/usr/local/mgr5/include/billmgr
CXXFLAGS += -I/usr/local/mgr5/include/billmgr
WRAPPER += gwqtc
gwqtc_SOURCES = gwqtc.cpp
gwqtc_FOLDER = gate
gwqtc_LDADD = -lmgr -lmgrdb
gwqtc_DLIBS = gatemodule
BASE ?= /usr/local/mgr5
include $(BASE)/src/isp.mk
Как мы с вами только что выяснили, относительно примеров изменены всего несколько строк. То есть теперь для написания плагинов хватит и небольшого опыта программирования, а партнёры смогут повысить качество выпускаемых продуктов на основе образцов.
К слову сказать, нами запланирован запуск магазина модулей, в котором разработанные вами дополнения можно будет бесплатно или за определённые деньги разместить для других компаний.
Надеемся, эта статья окажется полезной пользователям BILLmanager. Будем очень рады услышать о ваших успехах в описанном процессе.