| Для Microsoft Visual C++
Завантажити файл бібліотеки:
smsc_api_vc.cpp
Вихідний код бібліотеки:
// SMSC.UA API для Microsoft Visual C++ (smsc.ua) версия 1.3 (03.07.2019)
#define _AFXDLL
#include <afxinet.h>
#include <vector>
#include <Shlwapi.h>
#include <Strsafe.h>
using namespace std;
// Константы с параметрами отправки
const CString SMSC_LOGIN = ""; // логин клиента
const CString SMSC_PASSWORD = ""; // пароль клиента. Если передан пустой логин, то SMSC_PASSWORD используется, как API ключ, вместо логина и пароля
const bool SMSC_HTTPS = false; // использовать протокол HTTPS
const bool SMSC_POST = false; // использовать метод POST
const CString SMSC_CHARSET =
#if defined _UNICODE || defined UNICODE
"utf-8";
#else
"windows-1251";
#endif // кодировка сообщения (utf-8 или koi8-r), по умолчанию используется windows-1251
const bool SMSC_DEBUG = false; // флаг отладки
class SMSC {
public:
// Общедоступные методы класса SMSС
//
// Метод отправки SMS
//
// обязательные параметры:
//
// phones - список телефонов через запятую или точку с запятой
// message - отправляемое сообщение
//
// необязательные параметры:
//
// translit - переводить или нет в транслит
// time - необходимое время доставки в виде строки (DDMMYYhhmm, h1-h2, 0ts, +m)
// id - идентификатор сообщения. Представляет собой 32-битное число в диапазоне от 1 до 2147483647.
// format - формат сообщения (0 - обычное sms, 1 - flash-sms, 2 - wap-push, 3 - hlr, 4 - bin, 5 - bin-hex, 6 - ping-sms, 7 - mms, 8 - mail, 9 - call, 10 - viber, 11 - soc, 13 - telegram)
// sender - имя отправителя (Sender ID).
// query - строка дополнительных параметров, добавляемая в URL-запрос ("valid=01:00&maxsms=3")
//
// возвращает массив (<id>, <количество sms>, <стоимость>, <баланс>) в случае успешной отправки
// либо (<id>, -<код ошибки>) в случае ошибки
vector<CString> send_sms(CString phones, CString message, int translit = 0, CString time = "", int id = 0, int format = 0, CString sender = "", CString query = "")
{
CString tt, ir;
CString formats[13] = {"flash=1", "push=1", "hlr=1", "bin=1", "bin=2", "ping=1", "mms=1", "mail=1", "call=1", "viber=1", "soc=1", "", "tg=1"};
ir.Format((CString)"%i", id);
tt.Format((CString)"%i", translit);
vector<CString> m = _smsc_send_cmd("send", "cost=3&phones=" + (CString)_urlencode(phones) +
"&mes=" + (CString)_urlencode(message) + "&id=" + ir + "&translit=" + tt + (format > 0 ? "&" + formats[format - 1] : "") +
(sender != "" ? "&sender=" + (CString)_urlencode(sender) : "") + (time != "" ? "&time=" + (CString)_urlencode(time) : "") +
(query != "" ? "&" + query : ""));
// (id, cnt, cost, balance) или (id, -error)
if (SMSC_DEBUG)
if (m[1] > "0")
_print_debug("Сообщение отправлено успешно. ID: " + m[0] + ", всего SMS: " + m[1] +
", стоимость: " + m[2] + ", баланс: " + m[3]);
else
_print_debug("Ошибка №" + m[1].Mid(1, 1) + ", ID: " + m[0]);
return m;
};
// Метод получения стоимости SMS
//
// обязательные параметры:
//
// phones - список телефонов через запятую или точку с запятой
// message - отправляемое сообщение
//
// необязательные параметры:
//
// translit - переводить или нет в транслит
// format - формат сообщения (0 - обычное sms, 1 - flash-sms, 2 - wap-push, 3 - hlr, 4 - bin, 5 - bin-hex, 6 - ping-sms, 7 - mms, 8 - mail, 9 - call, 10 - viber, 11 - soc, 13 - telegram)
// sender - имя отправителя (Sender ID)
// query - строка дополнительных параметров, добавляемая в URL-запрос ("list=79999999999:Ваш пароль: 123\n78888888888:Ваш пароль: 456")
//
// возвращает массив (<стоимость>, <количество sms>) либо (0, -<код ошибки>) в случае ошибки
vector<CString> get_sms_cost(CString phones, CString message, int translit = 0, int format = 0, CString sender = "", CString query = "")
{
CString tt;
CString formats[13] = {"flash=1", "push=1", "hlr=1", "bin=1", "bin=2", "ping=1", "mms=1", "mail=1", "call=1", "viber=1", "soc=1", "", "tg=1"};
tt.Format((CString)"%i", translit);
vector<CString> m = _smsc_send_cmd("send", "cost=1&phones=" + (CString)_urlencode(phones) +
"&mes=" + (CString)_urlencode(message) + "&translit=" + tt + (format > 0 ? "&" + formats[format-1] : "") +
(sender != "" ? "&sender=" + (CString)_urlencode(sender) : "") + (query != "" ? "&" + query : ""));
// (cost, cnt) или (0, -error)
if (SMSC_DEBUG)
if (m[1] > "0")
_print_debug("Стоимость рассылки: " + m[0] + ". Всего SMS: " + m[1]);
else
_print_debug("Ошибка №" + m[1].Mid(1, 1));
return m;
};
// Метод проверки статуса отправленного SMS или HLR-запроса
//
// id - ID cообщения
// phone - номер телефона
//
// возвращает массив:
// для отправленного SMS (<статус>, <время изменения>, <код ошибки sms>)
// для HLR-запроса (<статус>, <время изменения>, <код ошибки sms>, <код IMSI SIM-карты>, <номер сервис-центра>, <код страны регистрации>,
// <код оператора абонента>, <название страны регистрации>, <название оператора абонента>, <название роуминговой страны>,
// <название роумингового оператора>)
//
// При all = 1 дополнительно возвращаются элементы в конце массива:
// (<время отправки>, <номер телефона>, <стоимость>, <sender id>, <название статуса>, <текст сообщения>)
//
// либо (0, -<код ошибки>) в случае ошибки
vector<CString> get_status(int id, CString phone, int all = 0)
{
CString ans, ir, tr;
int i;
ir.Format((CString)"%i", id);
tr.Format((CString)"%i", all);
vector<CString> m = _smsc_send_cmd("status", "phone=" + (CString)_urlencode(phone) + "&id=" + ir + (all > 0 ? "&all=" + tr : ""));
// (status, time, err) или (0, -error)
if (SMSC_DEBUG)
if ((m[1] != "") && (m[1] >= "0"))
{
time_t tm = _ttoi(m[1]);
struct tm ltm;
TCHAR st[100] = {0};
localtime_s(<m, &tm);
_stprintf_s(st, 100, (CString)"%2d.%2d.%d %2d:%2d:%2d", ltm.tm_mday, (ltm.tm_mon) + 1, (ltm.tm_year) + 1900, ltm.tm_hour, ltm.tm_min, ltm.tm_sec);
_print_debug( "Статус SMS = " + m[0] + ", время изменения статуса - " + st);
}
else
_print_debug("Ошибка №" + m[1].Mid(1, 1));
if (all == 1 && m.size() > 9 && (m.size() < 14 || m[14] != "HLR"))
{
ans = m[0];
for (i = 1; i < (int)m.size(); i++)
ans += "," + m[i];
m.clear();
int cp = 0;
for (i = 0; i < 8; i++)
m.push_back(ans.Tokenize((CString)",", cp));
m.push_back(ans.Mid(cp));
}
return m;
};
// Метод получения баланса
//
// без параметров
//
// возвращает баланс в виде строки или пустую строку в случае ошибки
CString get_balance(void)
{
vector<CString> m = _smsc_send_cmd("balance", ""); // (balance) или (0, -error)
if (SMSC_DEBUG)
if (m.size() == 1)
_print_debug("Сумма на счете: " + m[0]);
else
_print_debug("Ошибка №" + m[1].Mid(1, 1));
return m.size() == 1 ? m[0] : "";
};
private:
// Приватные методы класса SMSС
//
// Метод вызова запроса. Формирует URL и делает 3 попытки чтения
vector<CString> _smsc_send_cmd(CString cmd, CString arg)
{
vector<CString> m;
int cnt = 0;
CString url, _url;
arg = (SMSC_LOGIN != "" ? "login=" + (CString)_urlencode(SMSC_LOGIN) + "&psw=" : "apikey=") + (CString)_urlencode(SMSC_PASSWORD) + "&fmt=1&charset=" + SMSC_CHARSET + "&" + arg;
url = _url = (SMSC_HTTPS ? "https" : "http") + (CString)"://smsc.ua/sys/" + cmd + ".php";
CString sr, ot, res, strcnt;
INTERNET_PORT pt;
DWORD st;
char sz[1024] = {0};
CInternetSession ses((CString)"Visual C++", PRE_CONFIG_INTERNET_ACCESS);
CHttpConnection *ds;
AfxParseURL(url + '?' + arg, st, sr, ot, pt);
ds = ses.GetHttpConnection(sr, NULL, pt);
do
{
if (cnt++) {
strcnt.Format((CString)"%i", cnt);
url = _url;
url.Replace((CString)"smsc.ua/", (CString)"www" + strcnt + ".smsc.ua/");
AfxParseURL(url + '?' + arg, st, sr, ot, pt);
ds = ses.GetHttpConnection(sr, NULL, pt);
}
CHttpFile *pc;
try {
if (SMSC_POST || arg.GetLength() > 2000)
{
pc = ds->OpenRequest(0, "/sys/" + cmd + ".php", NULL, 1, NULL, NULL, SMSC_HTTPS ? INTERNET_FLAG_SECURE : INTERNET_FLAG_EXISTING_CONNECT);
pc->SendRequest((CString)"Content-Type: application/x-www-form-urlencoded", (LPVOID)(LPCSTR)(CStringA)arg, arg.GetLength());
}
else
{
pc = ds->OpenRequest(1, ot, NULL, 1, NULL, NULL, SMSC_HTTPS ? INTERNET_FLAG_SECURE : INTERNET_FLAG_EXISTING_CONNECT);
pc->SendRequest();
}
pc->Read(sz, 1024);
}
catch (CInternetException* e) {
}
res = sz;
pc->Close();
}
while ((res == "") && (cnt < 5));
if (res == "")
{
if (SMSC_DEBUG)
_print_debug("Ошибка чтения адреса: " + url + "?" + arg);
res = ","; // фиктивный ответ
}
ds->Close();
ses.Close();
return _explode(res);
};
// кодирование параметра в http-запросе
CStringA _urlencode(CString s_in)
{
#if defined _UNICODE || defined UNICODE
const WCHAR *pt_utf16 = s_in;
const size_t cch_utf16m = INT_MAX - 1;
size_t cch_utf16;
::StringCchLengthW(pt_utf16, cch_utf16m, &cch_utf16);
++cch_utf16;
int cb_utf8 = ::WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, pt_utf16, static_cast<int>(cch_utf16), NULL, 0, NULL, NULL);
CStringA s_utf8;
CHAR *pt_utf8 = s_utf8.GetBuffer(cb_utf8);
::WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, pt_utf16, static_cast<int>(cch_utf16), pt_utf8, cb_utf8, NULL, NULL);
s_utf8.ReleaseBuffer();
return _encode(s_utf8);
#else
return _encode(s_in);
#endif
};
CStringA _encode(CStringA s_in)
{
CStringA s_out;
for (int i = 0; i < s_in.GetLength(); i++)
{
CHAR ch = s_in[i];
if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'))
s_out.AppendChar(ch);
else
{
BYTE ccv = static_cast<BYTE>(ch);
CHAR eb[4];
sprintf_s(eb, sizeof(eb), "%%%02X", ccv);
s_out.Append(eb);
}
}
return s_out;
};
// вывод отладочной информации
void _print_debug(CString str)
{
MessageBox(NULL, str, NULL, MB_OK);
};
// разделение строки, возвращаемой сервером, на массив строк
vector<CString> _explode(CString str)
{
int cp = 0;
vector<CString> m;
do
{
m.push_back(str.Tokenize((CString)",", cp));
}
while (m.back() != "");
m.pop_back();
return m;
};
};
// Examples:
// SMSC *sms = new SMSC();
// СString balance;
// vector<CString> ret;
//
// ret = sms->send_sms("79999999999", "Ваш пароль: 123", 1);
// ret = sms->send_sms("79999999999", "http://smsc.ua\nSMSC.UA", 0, "", 0, 0, "", "maxsms=3");
// ret = sms->send_sms("79999999999", "0605040B8423F0DC0601AE02056A0045C60C036D79736974652E72750001036D7973697465000101", 0, "", 0, 5);
// ret = sms->send_sms("79999999999", "", 0, "", 0, 3);
// ret = sms->get_sms_cost("79999999999", "Вы успешно зарегистрированы!");
// ret = sms->get_status(12345, "79999999999");
// balance = sms->get_balance();
//
// delete sms;
Приклад використання бібліотеки:
#include "smsc_api_vc.cpp" ... SMSC *sms = new SMSC(); СString balance; vector<CString> ret; ... ret = sms->send_sms("79999999999", "Ваш пароль: 123", 1); ... ret = sms->send_sms("79999999999", "http://smsc.ua\nSMSC.UA", 0, "", 0, 0, "", "maxsms=3"); ... ret = sms->send_sms("79999999999", "0605040B8423F0DC0601AE02056A0045C60C036D79736974652E72750001036D7973697465000101", 0, "", 0, 5); ... ret = sms->send_sms("79999999999", "", 0, "", 0, 3); ... ret = sms->get_sms_cost("79999999999", "Вы успешно зарегистрированы!"); ... ret = sms->get_status(12345, "79999999999"); ... balance = sms->get_balance(); ... delete sms;
|