Роботы, плагины и скрипты к чату MyChat. Разработка альтернативных клиентов и различных утилит. Технические вопросы по программированию, замечания и предложения по развитию API
Аватара пользователя
Alexandr
Обновлен скрипт для автоматического размещения объявления о дне рождения сотрудника.

Код: Выделить всё
//////////////////////////////////////////////////////////////
//                                                          //
// MyChat Server Script Language                            //
//                                                          //
// Скрипт автоматических поздравлений с днями рождений      //
// версия 1.1 от 13.05.2019                                 //
//                                                          //
// Copyright(c) Alexandr                           //
//                                              //   
// Проверяется весь список пользователей               //
// Если необходимо ограничить список пользователей        //   
// Можно изменить функцию получения списка пользователей    //   
// на mGetUsersListByParams                           //   
// Выполнять каждый час                                     //
// Вопросы, пожелания, комментарии:                         //
// http://www.nsoft-s.com/forum/viewforum.php?f=35          //
//                                              //
// История версий:                                 //
//   - изменен скрипт в соответствии с новыми функциями      //
//                                            //
//////////////////////////////////////////////////////////////
var
  s, sUserFullName, sMsg, s2, sToday, sOld, date, ddmm : string;
  iUIN, iSex, i, y, d, m: integer;
  sPol: string;
begin
  sToday := Copy(FormatDateTime('dd.mm.yyyy', Now),1,5); // получаем текущую дату

  // читаем из реестра запись о прошлом запуске
  RegGetString(HKEY_CURRENT_USER, 'Software\MyChatServerScripts\BirthdayReminder', sOld);

    // если мы ужа работали сегодня, то ничего не делаем, чтобч
    // не поздравить одних и тех же людей по второму кругу
    if sToday<>sOld then begin
      // записываем в реестр текущую дату
      RegSetString(HKEY_CURRENT_USER, 'Software\MyChatServerScripts\BirthdayReminder', sToday);
     
                                 
          // и перебираем их всех по одному

        for i := 1 to mGetMaxRegisteredUIN() do begin
         date := mGetUserAttribute(i, 'Home_Birthday');
            ddmm := Copy(date,1,5);
            if ((ddmm=sToday) and (date<>'01.01.1900.00.00.00')) then begin
            sPol := mGetUserAttribute(iUIN, 'Sex');
            sUserFullName := mGetUserFullNameByPreset(i, 0); // ... и полного имени
            
                case iSex of
               0, 1: s2 := 'его';
               2: s2 := 'её';
            end;

            // формируем строку для поздравления
            sMsg := 'Сегодня ' + sUserFullName + ' празднует день рождения!' +
            CRLF +
            'Подравляем ' + s2 + ' с этим праздником и желаем всего самого ' +
            'светлого и доброго!';

            // ...и размещаем её на доске объяалений, чтобы было видно всем пользователям,
            // а дату окончания объявления выставляем до конца текущего дня   
            mAddNewBBSMessage(false, sMsg, EndOfTheDay(Now));
         end;
      end;
   end;
end.
Аватара пользователя
Алексей Пикуров
Добрый день. Попробуйте заменить функции работы с реестром на DBStorageGetData и DBStorageSetData. Это будет правильнее и быстрее, в старых версиях MyChat этих функций не было.
Аватара пользователя
Alexandr
Изменено.
Код: Выделить всё
//////////////////////////////////////////////////////////////
//                                                          //
// MyChat Server Script Language                            //
//                                                          //
// Скрипт автоматических поздравлений с днями рождений      //
// версия 1.1 от 13.05.2019                                 //
//                                                          //
// Copyright(c) Alexandr                           //
//                                              //   
// Проверяется весь список пользователей               //
// Если необходимо ограничить список пользователей        //   
// Можно изменить функцию получения списка пользователей    //   
// на mGetUsersListByParams                           //   
// Выполнять каждый час                                     //
// Вопросы, пожелания, комментарии:                         //
// http://www.nsoft-s.com/forum/viewforum.php?f=35          //
//                                              //
// История версий:                                 //
//   - изменен скрипт в соответствии с новыми функциями      //
//                                            //
//////////////////////////////////////////////////////////////
var
  s, sUserFullName, sMsg, s2, sToday, sTodayFull, sOld, date, ddmm : string;
  iUIN, iSex, i, y, d, m: integer;
  sPol: string;
begin
  sToday := Copy(FormatDateTime('dd.mm.yyyy', Now),1,5); // получаем текущую дату
  sTodayFull := FormatDateTime('dd.mm.yyyy', Now);

  // читаем из базы запись о прошлом запуске
  sOld = DBStorageGetData('RunBirthday');
 
    // если мы ужа работали сегодня, то ничего не делаем, чтобч
    // не поздравить одних и тех же людей по второму кругу
    if sTodayFull<>sOld then begin
      // записываем в реестр текущую дату
      mDBStorageSetData('RunBirthday', sTodayFull);
                                 
        // и перебираем их всех по одному
        for i := 1 to mGetMaxRegisteredUIN() do begin
         date := mGetUserAttribute(i, 'Home_Birthday');
            ddmm := Copy(date,1,5);
            if ((ddmm=sToday) and (date<>'01.01.1900.00.00.00')) then begin
            sPol := mGetUserAttribute(iUIN, 'Sex');
            sUserFullName := mGetUserFullNameByPreset(i, 0); // ... и полного имени
            
                case iSex of
               0, 1: s2 := 'его';
               2: s2 := 'её';
            end;

            // формируем строку для поздравления
            sMsg := 'Сегодня ' + sUserFullName + ' празднует день рождения!' +
            CRLF +
            'Поздравляем '+' с днем рождения! ' +
                CRLF +
                'Пусть жизнь дарит Вам побольше ярких моментов и сбудутся все самые смелые и заветные желания!'+
                CRLF +
                'Желаем чтобы в Вашем доме всегда царили счастье и понимание.'+
                CRLF +
                'И пусть Вас окружают только искренние, верные, надежные друзья и добрые люди. ' +
                CRLF +
                'С уважение, администрация!';

            // ...и размещаем её на доске объяалений, чтобы было видно всем пользователям,
            // а дату окончания объявления выставляем до конца текущего дня   
            mAddNewBBSMessage(false, sMsg, EndOfTheDay(Now));
         end;
      end;
   end;
end.
Аватара пользователя
Alexandr
Изменено но не верно (забыл про : и m), а можно удалить предыдущие посты и оставить один.
Это верный вариант.
Код: Выделить всё
//////////////////////////////////////////////////////////////
//                                                          //
// MyChat Server Script Language                            //
//                                                          //
// Скрипт автоматических поздравлений с днями рождений      //
// версия 1.1 от 13.05.2019                                 //
//                                                          //
// Copyright(c) Alexandr                           //
//                                              //   
// Проверяется весь список пользователей               //
// Если необходимо ограничить список пользователей        //   
// Можно изменить функцию получения списка пользователей    //   
// на mGetUsersListByParams                           //   
// Выполнять каждый час                                     //
// Вопросы, пожелания, комментарии:                         //
// http://www.nsoft-s.com/forum/viewforum.php?f=35          //
//                                              //
// История версий:                                 //
//   - изменен скрипт в соответствии с новыми функциями      //
//                                            //
//////////////////////////////////////////////////////////////
var
  s, sUserFullName, sMsg, s2, sToday, sTodayFull, sOld, date, ddmm : string;
  iUIN, iSex, i, y, d, m: integer;
  sPol: string;
begin
  sToday := Copy(FormatDateTime('dd.mm.yyyy', Now),1,5); // получаем текущую дату
  sTodayFull := FormatDateTime('dd.mm.yyyy', Now);

  // читаем из базы запись о прошлом запуске
  sOld = DBStorageGetData('RunBirthday');
 
    // если мы ужа работали сегодня, то ничего не делаем, чтобч
    // не поздравить одних и тех же людей по второму кругу
    if sTodayFull<>sOld then begin
      // записываем в реестр текущую дату
      mDBStorageSetData('RunBirthday', sTodayFull);
                                 
        // и перебираем их всех по одному
        for i := 1 to mGetMaxRegisteredUIN() do begin
         date := mGetUserAttribute(i, 'Home_Birthday');
            ddmm := Copy(date,1,5);
            if ((ddmm=sToday) and (date<>'01.01.1900.00.00.00')) then begin
            sPol := mGetUserAttribute(iUIN, 'Sex');
            sUserFullName := mGetUserFullNameByPreset(i, 0); // ... и полного имени
           
                case iSex of
               0, 1: s2 := 'его';
               2: s2 := 'её';
            end;

            // формируем строку для поздравления
            sMsg := 'Сегодня ' + sUserFullName + ' празднует день рождения!' +
            CRLF +
            'Поздравляем '+' с днем рождения! ' +
                CRLF +
                'Пусть жизнь дарит Вам побольше ярких моментов и сбудутся все самые смелые и заветные желания!'+
                CRLF +
                'Желаем чтобы в Вашем доме всегда царили счастье и понимание.'+
                CRLF +
                'И пусть Вас окружают только искренние, верные, надежные друзья и добрые люди. ' +
                CRLF +
                'С уважение, администрация!';

            // ...и размещаем её на доске объяалений, чтобы было видно всем пользователям,
            // а дату окончания объявления выставляем до конца текущего дня   
            mAddNewBBSMessage(false, sMsg, EndOfTheDay(Now));
         end;
      end;
   end;
end.
Аватара пользователя
Алексей Пикуров
Пусть будет, процесс тоже важен :)
WhiteNord
Добрый день!
Возможно ли доработать скрипт, чтобы он брал список лиц, которых сегодня нужно поздравить, из внешнего файла, а не только из числа пользователей чата? Т.к. не все члены коллектива используют чат, но напомнить остальным про их ДР будет не лишним)))
WhiteNord
...да и как напоминалку о памятных датах можно было бы использовать.
Аватара пользователя
Алексей Пикуров
Да, возможно. Делаете сами или заказываете у нас.
Аватара пользователя
AlexaS
1. Скопировал текст скрипта из темы создал скрипт в every hour активировал итог каждый час на доске объявлений добавляется дубль поздравления.
2. Отключил скрипт в every hour, создал в скрипт в every day итог утром сервер чата висел в логах ничего.

Что неправильно в скрипте ?

Код: Выделить всё
// ---------------------------------------
// Script created by admin (UIN 1)
// 07.11.2019 11:54:34
// ---------------------------------------
var
  s, sUserFullName, sMsg, s2, sToday, sTodayFull, sOld, date, ddmm : string;
  iUIN, iSex, i, y, d, m: integer;
  sPol: string;
begin
  sToday := Copy(FormatDateTime('dd.mm.yyyy', Now),1,5); // получаем текущую дату
  sTodayFull := FormatDateTime('dd.mm.yyyy', Now);

   // читаем из реестра запись о прошлом запуске
  RegGetString(HKEY_CURRENT_USER, 'Software\MyChatServerScripts\BirthdayReminder', sOld);
 
    // если мы ужа работали сегодня, то ничего не делаем, чтобы
    // не поздравить одних и тех же людей по второму кругу
    if sTodayFull<>sOld then begin
      // записываем в реестр текущую дату
      mDBStorageSetData('RunBirthday', sTodayFull);
                                 
        // и перебираем их всех по одному
        for i := 1 to mGetMaxRegisteredUIN() do begin
         date := mGetUserAttribute(i, 'Home_Birthday');
            ddmm := Copy(date,1,5);
            if ((ddmm=sToday) and (date<>'01.01.1900.00.00.00')) then begin
            sPol := mGetUserAttribute(iUIN, 'Sex');
            sUserFullName := mGetUserFullNameByPreset(i, 0); // ... и полного имени
           
                case iSex of
               0, 1: s2 := 'его';
               2: s2 := 'её';
            end;

            // формируем строку для поздравления
            sMsg := 'Сегодня ' + sUserFullName + ' празднует день рождения!' +
            CRLF +
            'Поздравляем '+' с днем рождения! ' +
                CRLF +
                'Пусть жизнь дарит Вам побольше ярких моментов и сбудутся все самые смелые и заветные желания!'+
                CRLF +
                'Желаем чтобы в Вашем доме всегда царили счастье и понимание.'+
                CRLF +
                'И пусть Вас окружают только искренние, верные, надежные друзья и добрые люди. ' +
                CRLF +
                'С уважением, администрация!';

            // ...и размещаем её на доске объявлений, чтобы было видно всем пользователям,
            // а дату окончания объявления выставляем до конца текущего дня   
            mAddNewBBSMessage(false, sMsg, EndOfTheDay(Now));
         end;
      end;
   end;
end.

поставил
Аватара пользователя
Алексей Пикуров
Используйте тег code для оформления исходников на форуме, удобнее читать форматированный текст.

Я не знаю, откуда вы копировали скрипт, но у вас внутри каша, перемешана логика.

Код: Выделить всё
RegGetString(HKEY_CURRENT_USER, 'Software\MyChatServerScripts\BirthdayReminder', sOld);

и параллельно с ним

Код: Выделить всё
mDBStorageSetData('RunBirthday', sTodayFull);

Проверьте исходник, который вы копировали и прочитайте внимательно, что и как вы делаете.
Аватара пользователя
AlexaS
Спасибо исправил. Скрипт брал выше из темы но он с 2 ошибками. Поэтому заменил обращение к базе на обращение к реестру для проверки выполнения упустив что запись в базу а чтение из реестра получилось.
Как проверю отпишусь указав итоговый текст скрипта (для истории).
Надеюсь в новых версии работать тоже будет .
WhiteNord
Доброго дня!
А если скрипт в разделе "Every Day" он по какому принципу запускается? Разово? В какое время?
WhiteNord
Ясно,, спасибо. Еще вопрос. Как проверить наличие или отсутствие в БД значения, создаваемого в БД функцией mDBStorageSetData ? Просто в скрипте в первых сообщениях темы я вижу mDBStorageGetData, но нет проверки на существование и предполагаю что первый запуск скрипта вызовет ошибку. Или нет?
Аватара пользователя
Алексей Пикуров
Пожалуйста.

Во-первых, есть справка по всем скриптовым функциям, с примерами. Есть функция mDBStorageKeyExists для проверки существования ключа.

Во-вторых, в справке по функции mDBStorageGetData чётко написано:
Если данных с указанным ключом нет или ключ не существует, функция вернет пустую строку.


Пользуйтесь справкой. Она для этого и сделана :) Ну, а если в ней чего-то нет, то, конечно, спрашивайте на форуме, дополним.
WhiteNord
[smilie=blush.gif] Сорри! Действительно, не дочитал. Буду внимательней.)
Подскажите, как на Ваш взгляд лучше реализовать запуск скрипта-оповещения о событиях (в том числе днях рождения)? Вот есть раздел EveryDay, в нем скрипт срабатывает в 00:00 (раз в сутки), при этом нужно, чтобы пользователи прийдя с утра на работу получили сообщение о том, какие сегодня знаменательные события. Так вот, если сделать рассылку в приваты от встроенного робота, получат ли пользователи сообщения после включения компов? Или лучше как-то запускать скрипт в определенное время и сообщение отправлять в общий канал?
WhiteNord
Вот для оповещения о ДР (других событиях) набросал вот такой простенький скрипт, который выводит в консоль строки событий с текущей датой:
Код: Выделить всё
// ---------------------------------------
// Script created by admin (UIN 1)
// 12.12.2019 11:25:39
// ---------------------------------------
const
myfile = 'C:\ProgramData\MyChat Server\db\Birthday.txt';
var
sTodayFull, TextLine, TODAY : string;
iCount, i : integer;
begin
TODAY:=(FormatDateTime('ddddd', now)); //  в переменную TODAY кидаем текущую дату
 begin
  if FileExists(myfile) then
    begin
    icount := GetTextFileLinesCount(myfile,0); //
    for i:=1 to iCount+1 do //Проходим по файлу до последней строки (правда
       begin
           LoadLineFromFile(myfile,i,TextLine);
              if pos(TODAY, TextLine) = 1 // Нашли в строке есть дата, совпадающая с текущей
             then begin                  
                   // delete(TextLine,1,11); //удалить дату
                    mLogScript(TextLine,''); //И выводим на экран (в консоль) строку с текстом события
                   end
       end
    end 
  else mSendPrivateMessage(0, 3, 'Файл c датами событий не существует!', 21, false); //сообщение на UIN3 о том, что файла нет
 end
end.

В консоли он вполне работает. Теперь думаю, как лучше сделать его запуск, чтобы это было разово и не в 00 часов, а часов в 8:00.
(Файл для скрипта прилагаю)
Вложения
(519 байт) Скачиваний: 142
WhiteNord
Еще простите один вопрос сейчас возник:
почему при отправке в канал "Главный" сообщения с помощью функции "mSendChannelMessage, например:
Код: Выделить всё
mSendChannelMessage(1,'test');

приходит следующее:

Откуда "L$" ?
Аватара пользователя
Георгий Лысенко
Вы используете устаревшую функцию для отправки сообщения.
Вот актуальный способ. В этой функции, для отправки текста используйте тип сообщения MSG_TYPE_TEXT.
Аватара пользователя
Алексей Пикуров
Так вот, если сделать рассылку в приваты от встроенного робота, получат ли пользователи сообщения после включения компов?

Да.
Или лучше как-то запускать скрипт в определенное время и сообщение отправлять в общий канал?

Тут вам решать, как людям будет удобнее. Технически быстрее будет отправить в конференцию сообщение, а не в 100500 разных приватов, без разбора. Но если вашим пользователей не будет это "в напряг", то можно и в приваты отправлять.
WhiteNord
Спасибо! Благодаря подсказке Георгия, проверил функцию mSendConfMessage для отправки в общий канал и все отлично работает. Думаю ей и воспользуюсь, а скрипт повешу на закладку EveryDay. Таким образом пользователи просмотрят сообщения в общем канале после включения ПК. Не буду заморачиваться на запуск по времени)).
WhiteNord
епрст, теперь после использования устаревшей функции "mSendChannelMessage в общем канале остались записи "L$test", которые никак не удаляются из базы ((
Аватара пользователя
Георгий Лысенко
Вы можете удалить эти сообщения поштучно в адмике, в просмотре протоколов или прямо из клиента, в контекстном меню.
WhiteNord
Обычно да, но в данном случае ни один способ не помог
WhiteNord
Хм, интересно, я сперва попытался удалить их из контекстного меню в окне канала (ПКМ->Удалить сообщение у всех пользователей), но они не удаляются [smilie=shok.gif] , а в Админке в протоколировании их нет.
Аватара пользователя
Георгий Лысенко
Да, вы правы, используя старую функцию, удалить сообщения нельзя, в новой таких проблем нет.
WhiteNord
Теперь наверное только 'history.db' сносить?
WhiteNord
Сам не хочу))) Но и не хотелось бы, чтобы это: L$test, L$tes, L$test навсегда теперь в общем канале застряло(
Аватара пользователя
Алексей Пикуров
Тогда откатывайте полный бекап всех баз сервера.
WhiteNord
Хм, создал короче себе проблем [smilie=biggrin.gif]
Ладно, спасибо. Главное, цель все равно достигнута)
Аватара пользователя
Stepan_Shock
привет, а все таки есть актуальный работающий скрипт уведомления о днях рождениях и событиях?
Аватара пользователя
Алексей Пикуров
Чем вас не устраивает этот скрипт?

https://nsoft-s.com/mcserverhelp/index.html?scripts.htm
viewtopic.php?f=35&t=1963
Аватара пользователя
Алексей Пикуров
UPD (18.01.2021)
Скрипт устарел, свежая версия для версии MyChat 8.4.0 и старше.