Показаны сообщения с ярлыком Рабочие процессы. Показать все сообщения
Показаны сообщения с ярлыком Рабочие процессы. Показать все сообщения

вторник, 30 июня 2015 г.

SharePoint. Как послать email используя JavaScript


У меня возникла необходимость послать email сообщение c формы элемента, сделав это асинхронно из JavaScript. В JSOM я не нашел такой возможности.

Способ № 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 функцию:

CreateEmailListItem('emailList', 'Ulmaskulov_ar@Borets.ru', 'subject', 'body')

После выполнения функции в списке можно увидеть созданный элемент:
После создания выполнится рабочий процесс и отправит письмо. Это решает проблему.

P. S. Не забудьте разобраться с правами на список, иначе пользователи смогут читать сообщения отправленные не им.
Рекомендую перейти в настройки списка: Параметры -> Дополнительные параметры -> Разрешения на уровне элементов -> Доступ на чтение и отметить "Чтение элементов, созданных пользователем". Выглядит это так:


Способ № 3
После публикации ссылки на пост в фейсбуке, в комментариях, мне подсказали еще один способ. Вероятно, это самый удобный из всех возможных. Спасибо Denis Molodtsov и Иван Горбадей.
Суть способа заключается в отправке запроса к SharePoint REST API.
Код выглядит так:

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);
        }
    });
};

среда, 18 марта 2015 г.

SharePoint 2013. Workflow error: System.ArgumentException: ContentTypeId at Microsoft.Activities.Hosting.Runtime.Subroutine.SubroutineChild...

Рабочий процесс перешел в состояние Приостановлено.

Так же выдает ошибку:
Details: An unhandled exception occurred during the execution of the workflow instance. Exception details: System.ArgumentException: ContentTypeId at Microsoft.Activities.Hosting.Runtime.Subroutine.SubroutineChild.Execute(CodeActivityContext context) at System.Activities.CodeActivity.InternalExecute(ActivityInstance instance, ActivityExecutor executor, BookmarkManager bookmarkManager) at System.Activities.Runtime.ActivityExecutor.ExecuteActivityWorkItem.ExecuteBody(ActivityExecutor executor, BookmarkManager bookmarkManager, Location resultLocation)



Ошибка может быть связана с тем, что при создании элемента указывается пользовательский тип контента, который не добавлен в список. В общем то SharePoint Designer об этом заранее сообщает:
При редактировании поля "Типа содержимого задачи:" чуть ниже, если попытаетесь выбрать иной тип контента, появится надпись:
Проверьте, применяется ли этот тип содержимого к списку задач рабочего процесса.

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

пятница, 30 января 2015 г.

Sharepoint designer. Рабочий процесс не обновляется после публикации

Создавая рабочий процесс для SharePoint 2010 и используя SharePoint Designer 2010 я столкнулся с проблемой, новый процесс не начинал работать с новой логикой. Причем ошибка появилась после решения такой ошибки.
SharePoint "видел", что процесс именно новый, т.к. к отработанным в прошлом добавлялось время публикации, в скобках. Но работать продолжал по старой логике.
Как выяснилось, причина на стороне клиента, а именно в SharePoint Designer. Причем ошибка появилась в 2010 и 2013 версиях.
Что бы побороть проблему надо почистить кэш, для этого необходимо удалить все данные по следующим путям:

%USERPROFILE%\AppData\Local\Microsoft\WebsiteCache
%APPDATA%\Microsoft\Web Server Extensions\Cache

Для SharePoint Designer 2010 еще надо сделать несколько движений:
Файл->Параметры->Общие->Кэшировать данные сайта во время сеансов в SharePoint Designer(Снять галочку)

Это решило проблему.

SharePoint Ошибка рабочего процесса: An IfElseActivity must have at least...


Сделав совсем маленький рабочий процесс я попытался опубликовать его.
Ферма 2013 версии, а рабочий процесс 2010.
Часть процесса, из-за которой возникла ошибка выглядит так:

Публикация рабочего процесса прошла неудачно:


Текст ошибки:
При компиляции рабочего процесса были обнаружены ошибки. Файлы рабочего процесса сохранены, но не могут быть выполнены.
Дополнительно:
(0,0) Activity 'ID38' validation failed: An ifElseActivity must have at least one child of type ifElseBranchActivity.)

Пытаясь найти решение, я обнаружил невидимый элемент, который все же можно сделать доступным для просмотра, если выполнить клик по нему:

Каким именно образом мне удалось сотворить такое "Действие рабочего процесса" мне не удалось выяснить. После его удаления процесс нормально опубликовался.

пятница, 6 июня 2014 г.

Как возвращаться на форму элемента после старта рабочего процесса

После старта рабочего процесса из формы элемента - Вас вернет на представление списка.
Поменять такое поведение можно, если добавить немного JavaScript кода на страницу с представлением списка. Код будет читать referrer, брать ID и делать редирект на форму элемента списка. В нашем случае на форму просмотра. При это важно, что бы код отработал только если Вы перешли на страницу после старта рабочего процесса. Это мы сможем понять по присутствию "Workflow.aspx" в referrer.

Код выглядит так:
// Функция позволяет взять параметр из referrer
function getParameterByName(name, url) {
    name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
    var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
results = regex.exec(url);
    return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}

// Получаем referrer
var ref = document.referrer
// Получаем ID из referrer
var ID = getParameterByName("ID", ref)
if (ref.indexOf("Workflow.aspx") > -1){
// Делаем редирект
    window.location = "/office/Lists/Contractors/DispForm.aspx?ID=" + ID
}

Теперь надо добавить это все в представление списка, воспользуемся SharePoint Designer 2013:
В моем случая я имею только одно представление, откроем его в расширенном режиме и добавим код, как на картинке:
Сохраните изменение и проверьте работу.

вторник, 29 апреля 2014 г.

Отправить ссылку на элемент из рабочего процесса

В ходе выполнения рабочего процесса может возникнуть необходимость уведомить определенного пользователя о необходимости изменить поля в элементе списка.
Для уведомления можно использовать электронную почту.

Сформировать письмо и отправить пользователю ссылку:

К сожалению, если использовать способ как картинке выше, то мы получим следующую ссылку:
http://server/Lists/ListName/81_.000

Где 81 - это Id текущего элемента. Такая ссылка на элемент работать не будет.
Что бы создать рабочую ссылку нужно использовать встроенный в SharePoint Designer 2013 построитель строк и сформировать такое:
[%Контекст рабочего процесса:URL адрес текущего сайта %]/Lists/listname/Dispform.aspx?ID=[%Текущий элемент:ID%]




Для этого получаем URL текущего сайта:



И Id текущего элемента:


Теперь у нас есть рабочая ссылка на элемент.

Стоить отметить, что в приведенном примере мы указываем ссылку на форму просмотра.
У нас остается возможность формировать ссылку сразу на форму изменения элемента.


UPD:
Можно использовать контекст рабочего процесса и получить ссылку на документ:
Но при этом нельзя будет сформировать ссылку сразу на форму редактирования.
Создается ссылка на форму просмотра, чего почти всегда достаточно.