У меня возникла необходимость послать email сообщение c формы элемента, сделав это асинхронно из JavaScript. В JSOM я не нашел такой возможности.
Способ № 1
Первое что пришло в голову - сделать на C# веб-часть, которая будет брать данные из url и отсылать почту, код выглядит достаточно коротким:
Теперь нам необходимо вызвать серверной код GET запросом, код на JavaScript & jQuery будет выглядеть так:
Недостаток этого решения в самом решении. Нужно создавать и разворачивать веб-часть, SPUtility недоступен в Sandbox решениях. Возможны прочие причины не использовать серверный код.
Способ № 2
Есть другой пусть. Как известно, мы можем слать письма используя рабочий процесс, так же мы знаем о возможности создавать элементы списка используя JSOM. Т.е. можем создать JavaScript'ом элемент списка, на создании которого запуститься рабочий процесс и отошлет письмо. Чтобы у рабочего процесса была информация куда, с какой темой и что слать - создадим соответствующие поля в списке. Наш элемент списка должен иметь 3 столбца:
Суть способа заключается в отправке запроса к SharePoint REST API.Способ № 1
Первое что пришло в голову - сделать на C# веб-часть, которая будет брать данные из url и отсылать почту, код выглядит достаточно коротким:
using (var oSite = new SPSite(SPContext.Current.Web.Url))
using (var oWeb = oSite.OpenWeb(SPContext.Current.Web.ServerRelativeUrl))
{
string to, subject, body;
to = Page.Request.QueryString["to"];
subject = Page.Request.QueryString["subject"];
body = Page.Request.QueryString["body"];
var headers = new StringDictionary
{
{"to", to},
{"subject", subject},
{"content-type", "text/html"}
};
SPUtility.SendEmail(oWeb, headers, body);
}
Теперь нам необходимо вызвать серверной код GET запросом, код на JavaScript & jQuery будет выглядеть так:
// Отсылаем уведомление
function SendMail(to, subject, body) {
$.ajax({
url: '/SitePages/SendMail.aspx',
type: 'GET',
data: { to: to, subject: subject, body: body },
contentType: 'application/json; charset=utf-8',
success: function (response) {
console.log("success send email to secretary");
},
error: function () {
console.log("error");
}
});
}
Недостаток этого решения в самом решении. Нужно создавать и разворачивать веб-часть, SPUtility недоступен в Sandbox решениях. Возможны прочие причины не использовать серверный код.
Способ № 2
Есть другой пусть. Как известно, мы можем слать письма используя рабочий процесс, так же мы знаем о возможности создавать элементы списка используя JSOM. Т.е. можем создать JavaScript'ом элемент списка, на создании которого запуститься рабочий процесс и отошлет письмо. Чтобы у рабочего процесса была информация куда, с какой темой и что слать - создадим соответствующие поля в списке. Наш элемент списка должен иметь 3 столбца:
- Кому
- Тема
- Тело
Итак, у нас будет функция которая будет написана на JavaScript и использовать JSOM для создания элемента в списке:
// Создаем элемент списка
function CreateEmailListItem(emailListTitle, to, subject, body) {
var clientContext = new SP.ClientContext.get_current();
var oList = clientContext.get_web().get_lists().getByTitle(emailListTitle);
var itemCreateInfo = new SP.ListItemCreationInformation();
this.oListItem = oList.addItem(itemCreateInfo);
oListItem.set_item('To', to);
oListItem.set_item('Subject', subject);
oListItem.set_item('Body', body);
oListItem.update();
clientContext.load(oListItem);
clientContext.executeQueryAsync(function.createDelegate(this, this.onQuerySucceededEmailListItem), function.createDelegate(this, this.onQueryFailedEmailListItem));
}
function onQuerySucceededEmailListItem() {
console.log('(Успех. Элемент списка создан.)Item created: ' + oListItem.get_id());
}
function onQueryFailedEmailListItem(sender, args) {
console.log('Request failed. (Ошибка. Элемент списка не создан.)' + args.get_message() + '\n' + args.get_stackTrace());
}
После создания элемента будет срабатывать рабочий процесс отсылающий письмо. Для этого нам нужно одно действие рабочего процесса:
В редакторе необходимо настроить действие:
Для начала заполним отправителя:
Аналогично необходимо заполнить поля "Тема" и "Тело":
Необходимо опубликовать рабочий процесс и обязательно отметить пункт "Автоматически запускать рабочий процесс при создании элемента":
Теперь попробуем вызвать нашу JavaScript функцию:
P. S. Не забудьте разобраться с правами на список, иначе пользователи смогут читать сообщения отправленные не им.
Рекомендую перейти в настройки списка: Параметры -> Дополнительные параметры -> Разрешения на уровне элементов -> Доступ на чтение и отметить "Чтение элементов, созданных пользователем". Выглядит это так:
Способ № 3
Для начала заполним отправителя:
Аналогично необходимо заполнить поля "Тема" и "Тело":
Теперь действие рабочего процесса заполнено:
Теперь попробуем вызвать нашу JavaScript функцию:
CreateEmailListItem('emailList', 'Ulmaskulov_ar@Borets.ru', 'subject', 'body')
После выполнения функции в списке можно увидеть созданный элемент:
После создания выполнится рабочий процесс и отправит письмо. Это решает проблему.
Рекомендую перейти в настройки списка: Параметры -> Дополнительные параметры -> Разрешения на уровне элементов -> Доступ на чтение и отметить "Чтение элементов, созданных пользователем". Выглядит это так:
После публикации ссылки на пост в фейсбуке, в комментариях, мне подсказали еще один способ. Вероятно, это самый удобный из всех возможных. Спасибо Denis Molodtsov и Иван Горбадей.
Код выглядит так:
function SendEmail(from, to, body, subject) {
var siteurl = _spPageContextInfo.webServerRelativeUrl;
var urlTemplate = siteurl + "/_api/SP.Utilities.Utility.SendEmail";
$.ajax({
contentType: 'application/json',
url: urlTemplate,
type: "POST",
data: JSON.stringify({
'properties': {
'__metadata': { 'type': 'SP.Utilities.EmailProperties' },
'From': from,
'To': { 'results': [to] },
'Body': body,
'Subject': subject
}
}
),
headers: {
"Accept": "application/json;odata=verbose",
"content-type": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val()
},
success: function(data) {
alert("Email sent");
},
error: function(err) {
alert(err.responseText);
}
});
};