API / Библиотеки и примеры кода / Для С

API позволяет рассылать сообщения через ваши проекты и сервисы по протоколам HTTP/HTTPS, SMTP и SMPP. Готовые библиотеки на разных языках программирования подключаются к вашему проекту и помогают отправлять сообщения из любого места с помощью одной команды.



Для С

Скачать файл библиотеки: smsc_api.c

Исходный код библиотеки:
/*
UKR.SMSCAB.RU cLib smsc API v. 0.0.1
*/

#include <stdio.h>
#include <stdlib.h>
#include <curl/curl.h>
#include <string.h>

#ifndef SMSC_API_H
#define SMSC_API_H

#define UNICODE
// Константы с параметрами отправки

static char* const    SMSC_LOGIN = "login";// логин клиента
static char* const    SMSC_PASSWORD = "password";// пароль
static char const    SMSC_HTTPS = 1;// использовать протокол HTTPS
static char        SMSC_POST = 0;// использовать метод POST
static char* const    SMSC_CHARSET =
           
#if defined _UNICODE || defined UNICODE
               
"utf-8";
           
#else
               
"windows-1251";
           
#endif // кодировка сообщения (utf-8 или koi8-r), по умолчанию используется windows-1251
static char const SMSC_DEBUG = 1; // флаг отладки

// Константы для отправки SMS по SMTP
static char* const SMTP_FROM = "api@ukr.smscab.ru";        // e-mail адрес отправителя
static char* const SMTP_SERVER = "send.ukr.smscab.ru";    // адрес smtp сервера
static char* const SMTP_LOGIN = "";            // логин для smtp сервера
static char* const SMTP_PASSWORD = "";            // пароль для smtp сервера

typedef char* string_t;

// Функция отправки SMS
//
// обязательные параметры:
//
// phones - список телефонов через запятую или точку с запятой
// message - отправляемое сообщение
//
// необязательные параметры:
//
// translit - переводить или нет в транслит (1,2 или 0)
// 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)
// sender - имя отправителя (Sender ID).
// query - строка дополнительных параметров, добавляемая в URL-запрос ("valid=01:00&maxsms=3&tz=2")
// files - массив путей к файлам для отправки mms или e-mail сообщений
//
// возвращает <id>, <количество sms>, <стоимость>, <баланс> в случае успешной отправки
// либо <id>, -<код ошибки> в случае ошибки

string_t send_sms (string_t phones, string_t message, int translit, string_t time, int id, int format, string_t sender, string_t query, string_t files);

// SMTP версия метода отправки SMS
void send_sms_mail(string_t phones, string_t mes, int translit, string_t time, int id, int format, string_t sender);

// Получение стоимости 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)
// sender - имя отправителя (Sender ID)
// query - строка дополнительных параметров, добавляемая в URL-запрос ("list=79999999999:Ваш пароль: 123\n78888888888:Ваш пароль: 456")
//
// возвращает <стоимость>, <количество sms> либо 0, -<код ошибки> в случае ошибки

string_t get_sms_cost(string_t phones, string_t mes, int translit, int format, string_t sender, string_t query);

// Проверка статуса отправленного SMS или HLR-запроса
//
// id - ID cообщения или список ID через запятую
// phone - номер телефона или список номеров через запятую
// all - вернуть все данные отправленного SMS, включая текст сообщения (0,1 или 2)
//
//
// для одиночного SMS-сообщения:
// <статус>, <время изменения>, <код ошибки доставки>
//
// для HLR-запроса:
// <статус>, <время изменения>, <код ошибки sms>, <код IMSI SIM-карты>, <номер сервис-центра>, <код страны регистрации>, <код оператора>,
// <название страны регистрации>, <название оператора>, <название роуминговой страны>, <название роумингового оператора>
//
// при all = 1 дополнительно возвращаются элементы:
// <время отправки>, <номер телефона>, <стоимость>, <sender id>, <название статуса>, <текст сообщения>
//
// при all = 2 дополнительно возвращаются элементы <страна>, <оператор> и <регион>
//
// если all = 0, то для каждого сообщения или HLR-запроса дополнительно возвращается <ID сообщения> и <номер телефона>
//
// если all = 1 или all = 2, то в ответ добавляется <ID сообщения>
//
// либо 0, -<код ошибки> в случае ошибки

string_t get_status(string_t id, string_t phone, int all);

// Получение баланса
//
// без параметров
//
// возвращает баланс в виде строки или пустую строку в случае ошибки

string_t get_balance(void);

void _print_debug(string_t str);
string_t _urlencode(string_t str);
string_t _urldecode(string_t str);
string_t _smsc_send_cmd(string_t cmd, string_t arg, string_t files);

#endif /* SMSC_API_H */

string_t send_sms (string_t phones, string_t message, int translit, string_t time, int id, int format, string_t sender, string_t query, string_t files) {
   
string_t res=NULL, arg=NULL;
   
   
char formats[][10] = {"&flash=1", "&push=1", "&hlr=1", "&bin=1", "&bin=2", "&ping=1", "&mms=1", "&mail=1", "&call=1", "&viber=1"};
   
   
asprintf(&arg, "cost=3&phones=%s%s%s&translit=%d&id=%d%s%s%s%s%s%s%s", _urlencode(phones),
                   
message ? "&mes=" : "", message ? _urlencode(message) : "",
                   
translit, id,
                   
format > 0 ? formats[format - 1] : "",
                   
sender ? "&sender=" : "", sender ? _urlencode(sender) : "",
                   
time ? "&time=" : "", time ? _urlencode(time) : "",
                   
query ? "&" : "", query ? query : "");

    if (
SMSC_DEBUG)
       
printf("%s\n",arg);
   
res = _smsc_send_cmd("send", arg, files);
   
free(arg);
    return
res;
}

void send_sms_mail(string_t phones, string_t mes, int translit, string_t time, int id, int format, string_t sender) {
   
CURL *curl;
   
CURLcode res = CURLE_OK;
   
struct curl_slist *recipients = NULL;

   
curl = curl_easy_init();
   
string_t mail_body;
   
   
asprintf(&mail_body,"%s:%s:%d:%s:%d,%d,%s:%s:%s", SMSC_LOGIN, SMSC_PASSWORD, id, time, translit, format, sender, phones, mes);
    if (
SMSC_DEBUG)
       
printf("%s\n",mail_body);
   
    if (
curl) {
       
curl_easy_setopt(curl, CURLOPT_URL, SMTP_SERVER);
       
recipients = curl_slist_append(recipients, SMTP_FROM);
       
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);
       
res = curl_easy_perform(curl);
        if (
res != CURLE_OK)
           
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
       
       
curl_slist_free_all(recipients);
       
curl_easy_cleanup(curl);
    }
   
}

string_t get_sms_cost(string_t phones, string_t mes, int translit, int format, string_t sender, string_t query) {
   
string_t res, arg;
   
char formats[][10] = {"&flash=1", "&push=1", "&hlr=1", "&bin=1", "&bin=2", "&ping=1", "&mms=1", "&mail=1", "&call=1", "&viber=1"};

   
asprintf(&arg, "cost=1&phones=%s&mes=%s&translit=%d%s%s%s%s%s", _urlencode(phones), _urlencode(mes), translit,
                   
format>0 ? formats[format-1] : "",
                   
sender ? "&sender=" : "", sender ? _urlencode(sender) : "",
                   
query ? "&query=" : "", query ? _urlencode(query) : "");
    if (
SMSC_DEBUG)
       
printf("%s\n",arg);
   
res = _smsc_send_cmd("send", arg, NULL);
   
free(arg);
    return
res;
}

string_t get_balance(void) {
    return
_smsc_send_cmd("balance", "", NULL); // (balance) или (0, -error)
}

string_t get_status(string_t id, string_t phone, int all) {
   
string_t arg;
   
   
asprintf(&arg, "phone=%s&id=%s&all=%d", _urlencode(phone),_urlencode(id), all);

    return
_smsc_send_cmd("status", arg, NULL);
}


//==============================================================================
struct MemoryStruct {
   
char *memory;
   
size_t size;
};

static
size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) {
   
size_t realsize = size * nmemb;
   
struct MemoryStruct *mem = (struct MemoryStruct *) userp;
   
   
mem->memory = realloc(mem->memory, mem->size + realsize + 1);
//    printf("%d", mem->memory);
   
if (mem->memory == NULL) {
   
/* out of memory! */
   
printf("not enough memory (realloc returned NULL)\n");
    return
0;
    }

   
memcpy(&(mem->memory[mem->size]), contents, realsize);
   
mem->size += realsize;
   
mem->memory[mem->size] = 0;
    return
realsize;
}
//==============================================================================

string_t _smsc_send_cmd(string_t cmd, string_t arg, string_t files) {
   
CURL *curl;
   
CURLcode res;
   
struct curl_slist *list = NULL;
   
struct curl_httppost* cpost = NULL;
   
struct curl_httppost* clast = NULL;
   
   
string_t _arg, url, istr, dstr;
   
char post, i=0;

   
struct MemoryStruct chunk;
   
chunk.memory = malloc(1); // will be grown as needed by the realloc above
   
chunk.memory[0] = 0;
   
chunk.size = 0; // no data at this point 

   
curl_global_init(CURL_GLOBAL_ALL);
   
curl = curl_easy_init();
    if (
curl) {
       
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
       
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) &chunk);
       
asprintf(&_arg, "login=%s&psw=%s&fmt=1&charset=%s&%s", _urlencode(SMSC_LOGIN), _urlencode(SMSC_PASSWORD), SMSC_CHARSET, arg);
       
post = SMSC_POST || files || (strlen(_arg) > 2000);
        do {
           
asprintf(&url, "ukr.smscab.ru/sys/%s.php", cmd);
            if (
i++)
               
asprintf(&url, "%s://www%d.%s", SMSC_HTTPS ? "https" : "http", i, url);
            else
               
asprintf(&url, "%s://%s", SMSC_HTTPS ? "https" : "http", url);
            if (
post) {
               
// разбираем строку параметров
               
istr = strtok(_arg,"=&");
                while (
istr != NULL) {
                   
asprintf(&dstr,"%s", istr);
                   
istr = strtok (NULL, "=&");
//                    printf("%s=%s\n", dstr, istr);
                   
curl_formadd(&cpost, &clast, CURLFORM_COPYNAME, dstr, CURLFORM_COPYCONTENTS, _urldecode(istr), CURLFORM_END);
                   
istr = strtok (NULL, "=&");
                }
                if (
files) {               
                   
res = curl_formadd(&cpost, &clast, CURLFORM_COPYNAME, "pictures", CURLFORM_FILE, files, CURLFORM_END);
                    if (
res != CURLE_OK)
                       
fprintf(stderr, "curl_easy_formadd() formfile failed: %s\n", curl_easy_strerror(res));
                }
               
curl_easy_setopt(curl, CURLOPT_HTTPPOST, cpost);
            }
            else
               
asprintf(&url, "%s?%s",url, _arg);
       
            if (
SMSC_DEBUG)
               
printf("%s\n%s\n", url, _arg);

           
curl_easy_setopt(curl, CURLOPT_URL, url);
           
res = curl_easy_perform(curl);
            if (
res != CURLE_OK)
               
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
            else
                if (
SMSC_DEBUG)
                   
printf("%lu bytes retrieved\n%s\n", (long)chunk.size, chunk.memory);       
        } while ((
i < 5) && (res != CURLE_OK));
       
curl_easy_cleanup(curl);
       
free(_arg);
       
free(url);
       
free(dstr);
    }
    return(
chunk.memory);
}

// кодирование параметра в http-запросе

string_t _urlencode(string_t str) {
   
string_t output;
   
CURL *curl;
   
    if (
str) {
       
curl = curl_easy_init();
        if (
curl) {
           
string_t output = curl_easy_escape(curl, str, 0);
           
curl_easy_cleanup(curl);
            return (
output);
        }
    return(
NULL);
    }
    return(
NULL);
}

// декодирование параметра в http-запросе

string_t _urldecode(string_t str) {
   
string_t output;
   
CURL *curl;
   
    if (
str) {
       
curl = curl_easy_init();
        if (
curl) {
           
string_t output = curl_easy_unescape(curl, str, 0, NULL);
           
curl_easy_cleanup(curl);
            return (
output);
        }
    return(
NULL);
    }
    return(
NULL);
}
// вывод отладочной информации

void _print_debug(string_t str) {
   
printf("%s\n", str);
}

Пример использования библиотеки:
#include "smsc_api.c"

string_t ret, balance;

ret = send_sms("79999999999", "Ваш пароль: 123", 0, NULL, 0, 7, NULL, "subj=Privet", NULL);
...
ret = send_sms("79999999999", "http://ukr.smscab.ru\nUKR.SMSCAB.RU", 0, "", 0, 0, "", "maxsms=3", NULL);
...
ret = send_sms("79999999999", "0605040B8423F0DC0601AE02056A0045C60C036D79736974652E72750001036D7973697465000101", 0, "", 0, 5, NULL, NULL, NULL);
...
ret = get_sms_cost("79999999999", "Ваш пароль: 123", 0, 7, NULL, NULL);
...
ret = get_status("12345", "79999999999", 1);
...
balance = get_balance();
...