1

Тема: JScript: Работаем с Google Calendar API (отправка sms-напоминаний)

Данный скрипт позволяет отправлять sms-напоминания через Google Calendar API.

Для того чтобы данный пример заработал нужно:

1. Создать аккаунт гугл
2. Настроить его (установить sms-напоминание о событии, указать номер мобильного телефона (свой) на который будут приходить sms-уведомления)
3. В коде скрипта найти и заменить %your_google_email%, %your_google_password% на значения вашего аккаунта

Ограничения:

1. Лимит на кол-во sms-ок (у меня не более 50 за раз, потом какое-то время вообще не отправляет)


/* Google Calendar. Добавление SMS-напоминаний */



/*

    Описание:
    
            Посылает запрос на удаленный сервер
    
    Параметры:
    
            methodType  - Тип запроса [POST | GET]
            
            sourceURL   - URL сервера
            
            requestType - Режим работы с сервером [true=асинхронный | false=синхронный]
            
            sendValue   - Тело запроса
            
            reqTime     - Время ожидания ответа (в миллисекундах)
            
            headers     - Заголовки запроса
            
            okcode      - Код ответа сервера, который считается успешным
    
*/


function sendRequestToServer(methodType, sourceURL, requestType, sendValue, reqTime, headers, okcode)
{
    
    try
    {
        
        //Определение доступной версии системного объекта "XMLHttpRequest"
        //****************************************************************************
        
        var reqObj;
        
        var progIDs = [
                                                                    
                                                                    "Msxml2.XMLHTTP.6.0",
                                                                    
                                                                    "Msxml2.XMLHTTP.3.0",
                                                                    
                                                                    "Microsoft.XMLHTTP"
                                                                    
                                                                    ];
        
        
        
        for (var i = 0; i < progIDs.length; i++)
        {
            
            try
            {
                
                reqObj = new ActiveXObject(progIDs[i]);
                
                break;
                
            }
            catch (e)
            {
            }
            
        }
        
        //****************************************************************************
        
        
        //Открываем соединение с удаленным хостом
        
        reqObj.open(methodType, sourceURL, requestType);
        
        
        //Устанавливаем параметры в зависимости от типа запроса
        
        if (methodType == "POST")
        {
            
            var hDefault = [
                                                                            
                                                                            ["Content-type",   "application/x-www-form-urlencoded"],
                                                                            
                                                                            ["Content-length", sendValue.length],
                                                                            
                                                                            ["Connection",     "close"]
                                                                            
                                                                        ];
            
            
            if (headers)
            {
                headers = headers.concat(hDefault);
            }
            else
            {
                headers = hDefault;
            }
            
        }
        else
        {
            
            //Добавляем к URL случайную последовательность цифр для предотвращения кэширования запросов
            
            sourceURL += "&id=" + retRndNumber(1, 10000000);
            
        }
        
        
        //Устанавливаем заголовки запроса (если есть)
        
        for (var i = 0; i < headers.length; i++)
        {
            reqObj.setRequestHeader(headers[i][0], headers[i][1]);
        }
        
        
        //Посылаем тело запроса
        
        reqObj.send(sendValue);
        
        
        
        /* Получаем ответ от сервера */
        
        
        var timer = 100;
        
        //Если запрос синхронный или время ожидания равно нулю, то отменить задержку выполнения
        
        if (!requestType || !reqTime) {timer = 0;}
        
        
        //Ожидаем ответ от сервера
        
        while (true)
        {
            
            if (reqObj.readyState == 4)
            {
                
                if (reqObj.status != okcode) {WScript.Echo("Wrong status: " + reqObj.status); return false;}
                
                //Данные успешно получены с сервера, разбираем полученный ответ
            
                return reqObj.responseText;
                
            }
            
            
            if (reqTime <= 0)
            {
                
                //Превышен интервал ожидания, соединение было сброшено
                
                WScript.Echo("Превышен интервал ожидания, соединение было сброшено");
                
                //Прерываем запрос
                
                reqObj.abort();
                
                //Выходим из цикла
                
                return false;
                
            }
            
            
            //Уменьшаем значение времени ожидания на величину "timer"
            
            reqTime -= timer;
            
            //Приостанавливаем выполнение скрипта на время = timer
            
            WScript.Sleep(timer);
            
        }
        
    }
    catch (e)
    {
        
        //Сообщаем пользователю о неудачной попытке запроса
        
        WScript.Echo("Не удалось отправить запрос");
        
    }
    
}





//Возвращает случайное число

function retRndNumber(nMin, nMax)
{
    return Math.floor(nMin + (nMax - nMin) * Math.random());
}





function getStrDate(msec)
{
    
    var dateObj = new Date(msec);
    
    var year    = dateObj.getFullYear();
    
    var month   = dateObj.getMonth() + 1;
    
    
    if (month < 10) {month = "0" + month;}
    
    var day     = dateObj.getDate();
    
    if (day < 10) {day = "0" + day;}
    
    
    var hour    = dateObj.getHours();
    
    if (hour < 10) {hour = "0" + hour;}
    
    
    var minute  = dateObj.getMinutes();
    
    if (minute < 10) {minute = "0" + minute;}
    
    
    var second  = dateObj.getSeconds();
    
    if (second < 10) {second = "0" + second;}
    
    
    
    return (year + "-" + month + "-" + day + "T" + hour + ":" + minute + ":" + second);
    
}





try
{
    
    //Авторизация
    //************************************************************************************************************
    
    var methodType  = "POST";
    
    var sourceURL   = "https://www.google.com/accounts/ClientLogin";
    
    var requestType = false;
    
    var sendValue   = "accountType=GOOGLE&Email=%your_google_email%&Passwd=%your_google_password%&service=cl&source=test-user-1";
    
    var reqTime     = 0;
    
    var headers     = false;
    
    var okcode      = 200;
    
    
    
    //Отправляем запрос
    
    var authResponse = sendRequestToServer(methodType, sourceURL, requestType, sendValue, reqTime, headers, okcode);
    
    //Выдергиваем из ответа строку аутентификации
    
    var authCode = authResponse.match(/auth=(.+)/i);
    
    
    if (authCode == null) {WScript.Quit(); /* Не удалось получить строку аутентификации */}
    
    authCode = authCode[1];
    
    //************************************************************************************************************
    
    
    
    
    
    //Добавляем одиночное событие
    //************************************************************************************************************
    
    //Время в формате yyyy-mm-ddThh:mm:ss
    
    var time = getStrDate(new Date().getTime() + 60000);
    
    
    methodType  = "POST";
    
    sourceURL   = "https://www.google.com/calendar/feeds/default/private/full";
    
    requestType = false;
    
    sendValue   = "<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gd='http://schemas.google.com/g/2005'>";
    
    sendValue   += "<title type='text'>" + retRndNumber(1, 1000) + "</title>";
    
    sendValue   += "<gd:when startTime='" + time + "' endTime='" + time + "'>";
    
    sendValue   += "<gd:reminder minutes='1' method='sms' />";
    
    sendValue   += "</gd:when>";
    
    sendValue   += "</entry>";

    
    reqTime     = 0;
    
    headers     = [["Authorization", "GoogleLogin auth=" + authCode], ["Content-Type", "application/atom+xml"]];
    
    okcode      = 201;
    
    
    
    //Отправляем запрос
    
    sendRequestToServer(methodType, sourceURL, requestType, sendValue, reqTime, headers, okcode);

    //************************************************************************************************************
    
}
catch (e)
{
    
    //Произошла ошибка
    
    WScript.Echo(e.message);
    
}

2

Re: JScript: Работаем с Google Calendar API (отправка sms-напоминаний)

is5157 пишет:

Добавляем к URL случайную последовательность цифр для предотвращения кэширования запросов

Лучше использовать посылку дополнительного заголовка

reqObj.setRequestHeader('If-Modified-Since', (new Date(0)).toUTCString());
( 2 * b ) || ! ( 2 * b )

3

Re: JScript: Работаем с Google Calendar API (отправка sms-напоминаний)

Rumata пишет:
is5157 пишет:

Добавляем к URL случайную последовательность цифр для предотвращения кэширования запросов

Лучше использовать посылку дополнительного заголовка

reqObj.setRequestHeader('If-Modified-Since', (new Date(0)).toUTCString());

Не спорю )

4

Re: JScript: Работаем с Google Calendar API (отправка sms-напоминаний)

Как код будет полностью работоспособен, то обязательно опубликуйте в Коллекции :-)

5

Re: JScript: Работаем с Google Calendar API (отправка sms-напоминаний)

is5157 пишет:

Добавляем к URL случайную последовательность цифр для предотвращения кэширования запросов

Во избежание кэширования следует использовать WinHttpRequest.

6

Re: JScript: Работаем с Google Calendar API (отправка sms-напоминаний)

is5157 пишет:

Данный скрипт позволяет отправлять sms-напоминания через Google Calendar API.
...

is5157,

отличный пример работы с Google Calendar.
Спасибо.

Но у меня работает не полностью.
1. Запускаю скрипт, смотрю в Google Calendar - все нормально, запланированное событие появилось.
Смотрю в его свойства - есть "Напоминание СМС 1 мин."
2. Никакого напоминания на СМС не приходит. Пробовал вручную добавить оповещение на экран и по почте - срабатывает только оповещение на экран.
3. Если в свойствах события изменить время мероприятия - хотя бы на минуту, неважно плюс или минус - и сделать СОХРАНИТЬ, то все отлично работает. СМС приходит.
Если добавить оповещение по почте - то и оно тоже срабатывает.
4. Просто СОХРАНИТЬ  - без изменения времени мероприятия - эффекта не дает.

Т.е. Ваш скрипт все формирует вроде правильно, но оповещение на СМС и по почте не срабатывает - во всяком случае у меня.
Если вручную изменить время мероприятия в уже сформированной записи календаря - все начинает работать.

Тестировал на Win XP SP3 + IE 8.

7

Re: JScript: Работаем с Google Calendar API (отправка sms-напоминаний)

Slav пишет:
is5157 пишет:

Данный скрипт позволяет отправлять sms-напоминания через Google Calendar API.
...

is5157,

отличный пример работы с Google Calendar.
Спасибо.

Но у меня работает не полностью.
1. Запускаю скрипт, смотрю в Google Calendar - все нормально, запланированное событие появилось.
Смотрю в его свойства - есть "Напоминание СМС 1 мин."
2. Никакого напоминания на СМС не приходит. Пробовал вручную добавить оповещение на экран и по почте - срабатывает только оповещение на экран.
3. Если в свойствах события изменить время мероприятия - хотя бы на минуту, неважно плюс или минус - и сделать СОХРАНИТЬ, то все отлично работает. СМС приходит.
Если добавить оповещение по почте - то и оно тоже срабатывает.
4. Просто СОХРАНИТЬ  - без изменения времени мероприятия - эффекта не дает.

Т.е. Ваш скрипт все формирует вроде правильно, но оповещение на СМС и по почте не срабатывает - во всяком случае у меня.
Если вручную изменить время мероприятия в уже сформированной записи календаря - все начинает работать.

Тестировал на Win XP SP3 + IE 8.

Проверял на своем компе и у знакомого, sms-ки приходят (хотя 2 компа мало для полноценной проверки). Вы написали: "Если в свойствах события изменить время мероприятия - хотя бы на минуту, неважно плюс или минус - и сделать СОХРАНИТЬ, то все отлично работает. СМС приходит", возможно,  это связано с тем, что событие наступает до того как срабатывает напоминание о событии и google решает что нет смысла слать sms-напоминание, раз уж событие наступило. Для решения данной проблемы можно попробовать установить время события позже чем установлено сейчас в скрипте. Найти строчку "var time = getStrDate(new Date().getTime() + 60000);" и изменить на "var time = getStrDate(new Date().getTime() + 120000);", а может даже и больше если все равно не приходит.

8

Re: JScript: Работаем с Google Calendar API (отправка sms-напоминаний)

is5157 пишет:

... а может даже и больше если все равно не приходит.

is5157,

время самого мероприятия я сразу увеличил - плюс 5 минут от текущего.
Предупреждение оставил как было - за 1 минуту до начала.

Причину глюка пока не понял.
Как я и говорил - сразу после работы скрипта задание в Google появляется, но СМС не отсылается.
Если я вручную в задании изменю время мероприятия - неважно плюс или минус 1 минута - и сделаю "сохранить", то все работает.

Видимо глюк уникален - если разберусь в чем причина сообщу.