Страница 1 из 3

E-mail рассылка в Галактике

Добавлено: 16 ноя 2009, 15:43
sim
Просьба поделиться знаниями и опытом - какие возможности имеет встроенный функционал e-mail рассылки в Галактике? Только ли для рассылки уведомлений о надвигающемся ДР? Или еще для чего-то пригоден?

Добавлено: 16 ноя 2009, 16:31
edward_K
В приведеном фейсе прописаны 2 способа 'MAPI','send direct', 3 вызов внешней утилиты зависит от той что используете. Я так давно писал свою собственную для отправки почты - и она вроде как до сих пор успешно трудися на рассылке отчетов по отгрузке. Отчеты были самопальные, при запуске рассылки пробегался список настроек с запомненным фильтром, вывод списка отчетов гасился, как и вывод на экран(нужные файлы для отправки тоже были прописаны в настройке). В результате каждый получал в том виде что нужно, и только то что ему положенно и только если есть данные для него.
Кнопка "почта" в редакторе это наследие той доработки - в какой то момент я не смог ее добавить в редактор и тому клиенту пришлось теребить разработчика. Правда не в том виде как хотелось бы - у меня например список адресатов был общий для всех, был журнал отправки (работа с ним шла наподобие таблы events - практически не рос). Ну и было еще несколько вкусностей типа нарезка по ширине под факс и убирание спецсиволов по настройке.

Код: Выделить всё

/* =======================================

для отправки письма стандартными средствами

======================================*/
#component ""
vipinterface SELECTRECIPIENT licensed(free)
parameters (RECLIST :longint) 
 ;
#component "F_USERREPORT"

vipinterface EmailRun licensed(free)
parameters
( email_type : word ;
  email_addr :string ;
  email_subject :string ;
  email_text :string ;
  email_attach1 :string ;
  email_attach2 :string ;
  email_attach3 :string ;
  email_addr_copy :string 
);

Interface EmailRun 'Проверка отправки почты',EscClose ;
var 
  email_type : word ;
  email_addr :string ;
  email_addr_temp :string ;
  email_subject :string ;
  email_text :string ;
  email_attach1 : string ;
  email_attach2 : string ;
  email_attach3 : string ;
  email_addr_copy :string ;
  email_body :string ;
  MAPIMessage:longint ;
  Marker: longint ;
  
create view vEmailRun
as select katpodr.name from katpodr,X$RESOURCES
where (( userId == x$users.atl_nrec 
and userid == X$RESOURCES.XR$CODE
and 58 == X$RESOURCES.XR$TYPE
))

 ;
parameters
   email_type
  ,email_addr 
  ,email_subject 
  ,email_text 
  ,email_attach1 
  ,email_attach2 
  ,email_attach3 
  ,email_addr_copy 
 ;  
file EmailMemo;        // Файл для копирования мемо-поля контакта в EMail-письмо
File WinBody;

Function MyOem2Ansi(w:string) :string ;
{ MyOem2Ansi:=w ;
} 
Function MySendMail :boolean ;
{ MySendMail:=false ;
email_addr:=trim(email_addr)
email_addr_copy:=trim(email_addr_copy)
var email_addr_from:string;
email_addr_from:=username+'@mail.ru'

case email_type of
0:
{
  MAPIMessage := InitMAPIMessage;

  AddRecipientToMail(DocBasFn866to1251(email_addr),
                     DocBasFn866to1251('SMTP:' + email_addr), MAPIMessage);
  if email_addr_copy<>''
   AddRecipientToMail(DocBasFn866to1251(email_addr_copy),
                     DocBasFn866to1251('SMTP:' + email_addr_copy), MAPIMessage);
  // Тема письма
  SetMAPIMessageSubject(DocBasFn866to1251(email_subject), MAPIMessage);
  AddStringToMailBody(DocBasFn866to1251(
      'Здравствуйте!' + ''#13#10), MAPIMessage);
  AddStringToMailBody(DocBasFn866to1251(
      email_text), MAPIMessage);
  if fileexist(email_attach1)    
    AddAttachedFileToMail(email_attach1, email_attach1, MAPIMessage);
  if fileexist(email_attach2)    
    AddAttachedFileToMail(email_attach2, email_attach2, MAPIMessage);
  if fileexist(email_attach3)    
    AddAttachedFileToMail(email_attach3, email_attach3, MAPIMessage);
  SendGalMail(MAPIMessage);
}
1:
{
//  message('NEW MAIL')
  email_body:=GetStringParameter('Files','OutputFilesDirectory',0)+
    '\!email'+username+'.txt'
  if fileexist(email_body) deletefile(email_body)
  logstrtofile(email_body,email_addr+'/'+email_addr_from)
  logstrtofile(email_body,Oem2Ansi('Привет'))
  logstrtofile(email_body,Oem2Ansi(email_text))
  logstrtofile(email_body,Oem2Ansi(email_attach1))
  logstrtofile(email_body,Oem2Ansi(email_attach2))
  logstrtofile(email_body,Oem2Ansi(email_attach3))
  WinBody.openfile(GetStringParameter('Files','OutputFilesDirectory',0)+
    '\!emailbody.txt',stCreate)
  WinBody.WriteLn('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">');
  WinBody.WriteLn('<HTML>');
  WinBody.WriteLn('<HEAD>'); 
  WinBody.WriteLn('<TITLE>Atlantis e-mail.</TITLE>');
  WinBody.WriteLn('<META charset="windows-1251">');
  WinBody.WriteLn('</HEAD>');
  WinBody.WriteLn('<BODY BGCOLOR="#EEEFE0"> <FONT SIZE="+2">');
  WinBody.WriteLn(' ');
  WinBody.WriteLn(MyOem2Ansi(' этот файл HTML - в WIN-кодировке<br>'));
  WinBody.WriteLn(' <FONT SIZE="0" COLOR="#0000FF">');
  WinBody.WriteLn(MyOem2Ansi(' Если сообщение отображается некорректно, откройте'));
  WinBody.WriteLn(MyOem2Ansi(' его отдельно в браузере.<br>'));
  WinBody.WriteLn(MyOem2Ansi('Привет<br>'))
  WinBody.WriteLn(MyOem2Ansi(email_text)+'<br>')
  WinBody.WriteLn(MyOem2Ansi(email_attach1)+'<br>')
  WinBody.WriteLn(MyOem2Ansi(email_attach2)+'<br>')
  WinBody.WriteLn(MyOem2Ansi(email_attach3)+'<br>')

  WinBody.WriteLn(' </BODY>');
  WinBody.WriteLn(' </HTML>');

  if not SetCurMailEncodingTable(AMAIL_1251)
  { message(' '+GetMailErrorString)
    exit ;
  }
  if not CreateMail(email_addr, email_addr_copy, email_subject)
  { message(' '+GetMailErrorString)
    exit ;
  }
   if true
   { if not SetBody(WinBody.Handle, 3)
     {
      logstrtofile(email_body,GetMailErrorString)
     }
   } 
   else 
   { if not AddPartHtmlBinary(WINBody.Handle, 'part 1.html', '1')
     {
     logstrtofile(email_body,GetMailErrorString)
     }
   }  
  WinBody.close
  if fileexist(email_attach1)    
  { if not  AddAttachFrom(email_attach1)
    { message(' '+GetMailErrorString)
      exit ;
    }  
    else
      logstrtofile(email_body,Oem2Ansi('Вложили '+email_attach1))
  }

  if fileexist(email_attach2)    
  { if not  AddAttachFrom(email_attach2)
    { message(' '+GetMailErrorString)
      exit ;
    }  
    else
      logstrtofile(email_body,Oem2Ansi('Вложили '+email_attach2))
  }
  if fileexist(email_attach3)    
  { if not  AddAttachFrom(email_attach3)
    { message('AddAttachFrom '+GetMailErrorString)
      exit ;
    }  
    else
      logstrtofile(email_body,Oem2Ansi('Вложили '+email_attach3))
  }

  if not SendMail
  { message('SendMail '+GetMailErrorString)
    exit ;
  }
/*
  // не пашет вложение 
  if not SendMailFrom(email_addr,  email_addr_copy, email_subject, email_body, false)
  { message('SendMailFrom '+GetMailErrorString)
    exit ;
  }
*/  
}  
else
{ message('Режим еще не обрабатывается!')
}
end ;
  MySendMail:=true ;
} 

screen scrMain ;
table katpodr ;
fields
   email_type : [list 0 'MAPI','send direct','send sendmail'],protect ;
   email_addr : pickbutton,noprotect ;
   email_addr_copy : pickbutton,noprotect ;
   email_subject   : noprotect ;
   email_text      : noprotect ;
   email_attach1   : pickbutton,noprotect ;
   email_attach2   : pickbutton,noprotect ;
   email_attach3   : pickbutton,noprotect ;
buttons
   cmOk,default,,'Отправить',hcObVedTimParam,sci1Esc;
   cmCancel,,,'Выход',hcObVedTimParam,sci1Esc;
<<
 ТИП        .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 Кому       .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 Копия      .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 Тема       .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 Содержание .@@@@@@@@@@@@@@@@@@@@@@@@@@
 Вложение 1 .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 Вложение 2 .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 Вложение 3 .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 

   <. Отправить .>       <. ~О~тмена .> 
>>
end;

Function GetAddr :string ;
var i,k :word ;
    witem :comp ;
    wstr:string;
{ GetAddr:='' ;
  wstr:=''
//  message(GetMarkerCount(Marker))
  for(i:=0;i<GetMarkerCount(Marker);i:=i+1)
  { GetMarker(Marker, i, witem)
    message(string(i)+' '+string(witem) )
    // НЕ ПРАВИЛЬНО конечно
    /*
    if getfirst X$RESOURCES where (( witem ==  X$RESOURCES.atl_nrec ))=0 //  58== X$RESOURCES.XR$TYPE
     GetAddr:=GetAddr+X$RESOURCES.XR$NAME+','
    */
    k:=0
    _loop X$RESOURCES
    { inc(k)
      if k=witem
      { wstr:=wstr+if(wstr<>'',',','')+X$RESOURCES.XR$NAME
        break;
      }
    } //_loop X$RESOURCES
  } //for(i:=0;i<GetMarkerCount(Marker);i:=i+1)
  GetAddr:=wstr ;
} // Function GetAddr :string ;
HandleEvent
cmPick:
{ case curfield of
  #email_addr :
  { RunInterFace(SELECTRECIPIENT,Marker) ;
    email_addr:=GetAddr ;
//    message(Marker)
  }
  #email_addr_copy :
  { RunInterFace(SELECTRECIPIENT,Marker) ;
    email_addr_copy:=GetAddr ;
  }
  #email_attach1 : email_attach1:= GetFileName('*.*','Выбор файла 1') ;
  #email_attach2 : email_attach2:= GetFileName('*.*','Выбор файла 2') ;
  #email_attach3 : email_attach3:= GetFileName('*.*','Выбор файла 3') ;
  end ;
  rescanpanel(#katpodr) ;  
}
cmInit :
{ if email_addr<>''
  { MySendMail ;
    closeinterface(cmDone) ;
    abort ;
  }
  Marker:=InitMarker('marker_mail', 8, 200, 10) 
}
cmOk:
{ MySendMail  ;
  CloseInterface(cmDefault)
}
cmDone:
{ DoneMarker(Marker,'marker_mail')
}
end;
end.

Добавлено: 16 ноя 2009, 16:43
m0p3e
Есть еще один, более вкусный способ через MailManager.dll. Все параметры (smtp-сервер, smpt-порт, e-mail) задаются программно.

Добавлено: 17 ноя 2009, 13:41
sim
Все это здОрово, но вопрос был - какие возможности имеет ВСТРОЕННЫЙ ФУНКЦИОНАЛ e-mail рассылки?

Добавлено: 19 ноя 2009, 03:06
LaaLaa
Фрагмент из документации vip_5.4.23.chm

Код: Выделить всё

Функции для работы с почтой    

В Атлантис реализованы возможности отправления сообщений на электронную почту, доступные как для прикладного программиста, так и для пользователя. Функции работают при наличии прав для отправления сообщений, настраиваемых в Support. Физически отправление сообщений происходит с компьютера, на котором запущена клиентская часть. Настройки сервера исходящих сообщений задаются также в Support.

Прикладной программист имеет возможность реализовывать в прикладном коде создание и отправление писем, отображая или не отображая диалоги задания адреса получателя, темы сообщения и т.д.

Пользователь имеет возможность отправлять письма, задавая в качестве тела письма (и в качестве вложения) содержимое редактируемого файла, отчета или мемо-поля.

Оглавление раздела
Функция AddAttach 
Функция AddAttachFrom 
Функция AddPartHTMLBinary 
Функция AddPartHTMLBinaryFrom 
Функция CreateMail 
Функция GetCurMailEncodingTable 
Функция GetIthRecipient 
Функция GetMailErrorCode 
Функция GetMailErrorString 
Функция GetMyFromAddr 
Функция GetRecipientsCount 
Функция SendMail 
Функция SendMailFrom 
Функция SetBody 
Функция SetBodyFrom 
Функция SetCurMailEncodingTable 
Пример исходного кода, демонстрирующего возможности API 
Таблица кодов ошибок и соответствующих сообщений 

Добавлено: 19 ноя 2009, 03:12
LaaLaa
С помощью данного API реализована функция отправки по почте отчетов в формате Бизнес-текст. В коне просмотра текста есть кнопка "отправить по E-Mail".

Еще с помошью данного API реализована функция рассылки расчетных листков в модуле "Заработная плата". Детали см. в документации по модулю зарплата.

Добавлено: 30 ноя 2009, 20:23
sim
Спасибо!
Проверили: отправка отчетов Бизнес-текст работает.
С рассылкой расчетных листков пока не разбирались, но надеемся что тоже будет функционировать.

Добавлено: 16 дек 2009, 13:10
Алексей
Модераторам: может выложить в опыт?

Добавлено: 16 дек 2009, 13:38
m0p3e
Функции описанные в доке (CreateMail и так далее) имеют существенный недостаток - отсутствие гибкости.
1. Параметры smtp сервера читаются из настроек в протекте и задать программно их нельзя.
2. e-mail-ом получателя может являться только адрес внесенный в протекте и задать программно его нельзя.
3. Если у пользователя под которым формируется письмо не стоит галка "Пользователь может отсылать почтовые сообщения", то и письмо не уйдет. Опять же программно обойти данное ограничение нельзя.
Программиста зажали в рамки по полной программе. В той же 1С шлешь куда хочешь и через любой сервер.
ДТП пытался убедить что, данная ситуация дискриминация программистов, но услышан не был.

Добавлено: 16 дек 2009, 15:37
LaaLaa
Да действительно, этот набор функций специфичен. Перечисленные ограничения действительно были заложены изначально в требованиях на разработку этих функций.

На счет пункта
m0p3e писал(а): 2. e-mail-ом получателя может являться только адрес внесенный в протекте и задать программно его нельзя.
не совсем так. Если в проекте оставить пуспой список допустимых адресов получателей. То отправлять можно будет на любой адрес.

Добавлено: 16 дек 2009, 16:33
m0p3e
Хм. Да со вторым что-то напутал. :)
Адрес можно указать. Но с адресами тоже какие-то ограничения меня расстроили. Подзабылось уже... :)

Добавлено: 16 дек 2009, 16:48
Seybukan
В модуле Взаимоотношения с клиентами \ Работа с клиентами \ Контакты.
В самом контакте есть локальная функция "Сформировать e-mail по контакту".
В результате его создается стандартное письмо в почтовом клиенте по умолчанию.

Поройте мож какие там хитрые функции используются.

Добавлено: 16 дек 2009, 17:22
m0p3e
Seybukan
Работа через MAPI неудобна тем, что при отправке письма появляется запрос "Кто-то пытается письмо от вашего имени послать! Разрешить?". Понятно что можно уровень безопасности понизить, но есть понятие корпоративной политики.

Всех вышеназванных недостатков лишена MailManager.dll, но непонятен ее статус в Галактике. Документации тоже никакой нет.

Добавлено: 16 дек 2009, 17:33
Seybukan
m0p3e

А я разве сказал что функционал который я указал реализован на MAPI?
Там письмо создается именно в почтовом клиенте по умолчанию(оутлук, бат что стоит по умолчанию там и создается), а не в фоновом режиме.
Единственное что надо нажимать кнопку отправить.
Та функция живет очень давно и галктический MAPI появился позже.
Или я не прав?

Добавлено: 16 дек 2009, 18:09
m0p3e
Посмотрел.
Там вызывается процедура SendEMailForContact;
В ней:
.......
MAPIMessage := InitMAPIMessage
.......