Обработка страницы Salesforce VisualForce как внешнего виджета

#screen-scraping #salesforce #apex-code #visualforce

#очистка экрана #salesforce #apex-код #visualforce

Вопрос:

Я хочу превратить страницу Salesforce VisualForce в виджет для моего корпоративного веб-сайта. Я хочу получить доступ к виджету, используя код на стороне сервера и учетную запись службы. Я буду кэшировать, стилизовать и выводить HTML-код виджета на своей веб-странице. Я знаю, что мог бы просто воспроизвести виджет с помощью кода на стороне сервера и нескольких вызовов API, но мне нравится идея иметь возможность управлять виджетом в Salesforce и иметь виджет, доступный для повторного использования в другом месте в Salesforce.

В этом случае виджет будет сообщать о текущих лидерах конкурса, который мы отслеживаем в Salesforce. Я планирую повторно использовать этот подход для других «виджетов мини-отчетов». Это очень полезный шаблон. Я уверен, что кто-то там уже элегантно решил эту проблему. Пока мои поиски оказались пустыми.

Я пытался избегать сайтов, потому что пользователь, посещающий наш корпоративный веб-сайт, не имеет учетной записи пользователя в Salesforce (теперь я думаю о сайте, который разрешает анонимный доступ).

Моя первая попытка выглядела так (вдохновленная SSO для портала самообслуживания):

 var ws = new sfapi.SforceService();
var lr = ws.login(Secrets.salesforce_user_name, Secrets.salesforce_password);
string url = "https://na6.salesforce.com/apex/mywidget?sessionId="   lr.sessionId;
  

Я пробовал?sid и ?csssid тоже, но подобные URL-адреса просто перенаправляют меня на страницу входа в систему Salesforce:

 https://na6.salesforce.com/apex/mywidget?sessionId=00D3000000myorg!my-session-id-from-logging-in-with-the-api-8_i2fX_9wnYdwnwatGVuX6jGjmVmnv50j78yfGF1aKHdoDFtIx_J9
  

Вероятно, я мог бы использовать стандартные методы очистки экрана для публикации в стандартной форме входа в систему Salesforce с именем пользователя и паролем, а затем перейти на страницу / apex / mywidget. Но это кажется неуклюжим и неподдерживаемым.

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

Любая помощь приветствуется. Пока я собираюсь поиграть с подходом анонимных сайтов.

Ответ №1:

Рендеринг данных на странице Visualforce, а затем их удаление с экрана кажется немного хрупким, не говоря уже о неэффективности — есть лучший способ…

Определите веб-службу Apex REST, после чего вы сможете легко вызвать эту веб-службу из кода на стороне сервера и при необходимости по-прежнему отображать ее в Visualforce — вы можете вызвать метод Apex REST, как и любой другой метод Apex.

Вот пример веб-службы REST. Я просто возвращаю Map<String,String> здесь, но вы можете вернуть любой примитивный тип, любой объект sObject или список или карту примитивов или объектов sObjects (если на карте есть строковые ключи) — см. Документы Apex REST Web Services

 @RestResource(urlMapping='/MyResource/*')
global with sharing class MyRestResource {
    @HttpGet
    global static Map<String,String> getResource() {
        Map<String,String> result = new Map<String,String>();

        result.put('key1', 'value1');
        result.put('key2', 'value2');

        return resu<
    }
}
  

Вот некоторый PHP, который его вызывает (я предполагаю, что у вас есть токен доступа (он же идентификатор сеанса) и URL-адрес экземпляра):

 $url = "$instance_url/services/apexrest/MyResource";
$curl = curl_init($url);

curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER,
  array("Authorization: OAuth $access_token",
    "Content-type: application/json"));

$json_response = curl_exec($curl);

$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);

if ( $status != 200 ) {
    die("Error: call to URL $url failed with status $status, ".
      "response $json_responsen");
}

$response = json_decode($json_response, true);

echo "The service says ".$response['key1'].' '.$response['key2']."n";

curl_close($curl);
  

А вот страница Visualforce, если вы хотите отобразить те же данные

 <apex:page controller="TestRestController">
  <p>Controller says {!result}</p>
</apex:page>
  

Контроллер страницы:

 public class TestRestController {
    public String getResult() {
        Map<String, String> result = MyRestResource.getResource();

        return result.get('key1')   ' '   result.get('key2');
    }
}
  

Комментарии:

1. Отличный ответ; это лучший способ сделать что-то.

2. Теперь это выглядит первоклассно. Я попробую это в эти выходные. Спасибо!

3. Добро пожаловать! Если все получится, пожалуйста, установите флажок на этот ответ, чтобы мы могли продвигать лучшие практики 🙂

4. Вау! Это действительно открыло мне глаза на возможности, выходящие далеко за рамки простого виджета. Но это отлично работало и для виджета. Прямо сейчас я возвращаю список <Contact> в XML (я устанавливаю HTTP Accept в application/ xml, потому что мне проще анализировать серверную часть на C #). Я думаю, что в конечном итоге я верну одну строку слегка отформатированного html. Таким образом, я могу управлять уровнем представления из Salesforce (желательно в моем случае, потому что я нахожусь в dll, предоставляемой вызываемой оболочкой для старой школы ASP — отлично подходит для общения с API, но не для презентации). Спасибо за урок metadaddy!

5. Несколько советов для тех, кто впервые знакомится с этой очень полезной функцией Salesforce. Вы получаете только один метод @HttpGet, и его имя на самом деле не имеет значения. Ваш класс APEX должен быть как минимум версии 22 (я боролся с этим, но в конечном итоге обновился Force.com IDE до последней версии и открыл MyClassName.cls-meta.xml в Eclipse изменение элемента apiVersion на 23). На C # это очень просто с помощью WebRequest. var req = WebRequest. Создать (url); запрос. Headers.Add(«Авторизация: OAuth » sid); запрос. Принять = «application /xml»; запрос. GetResponse() и вы в ударе.

Ответ №2:

Я не уверен, что это сработает для ваших целей, но есть URL-адрес, который вы могли бы попробовать:

 https://<endpoint host>/secur/frontdoor.jsp?sid=<session id>
  

После загрузки этой страницы вы можете перенаправить ее на URL-адрес виджета.

Комментарии:

1. Спасибо, Мэтью. Я заставил его работать с этим URL. Мне пришлось разделить CookieContainer между первым и вторым запросом, чтобы аутентификация была перенесена — но это сработало! Я не думаю, что вы знаете, принимает ли frontdoor.jsp параметр перенаправления, где я мог бы сделать это в одном запросе вместо двух?

2. Я попробовал параметр Returnl и получил сообщение об ошибке, что у меня должен быть включен javascript (я использую c # и HttpWebRequest). Сбор CookieCollection и два запроса работают достаточно хорошо. Еще раз спасибо.

3. Добро пожаловать! К сожалению, я попробовал параметры retURN и startURL, но и с ними я не смог заставить его работать.

4. Пожалуйста, не удаляйте Visualforce с экрана — есть гораздо лучший способ сделать это — см. Мой ответ…

5. @BhavikPatel ваш комментарий, вероятно, лучше всего было бы сформулировать как новый вопрос; таким образом, вы получите больше ответов.

Ответ №3:

Это звучит как Force.com Сайты — это именно то, что вам нужно.

Идея сайтов заключается в том, что они позволяют получать доступ к страницам Visualforce без необходимости входа в систему.

Комментарии:

1. Я думаю, вы правы, когда я готов откусить больший кусок сайтов Salesforce. Но в данном случае мне нужен «виджет». Если хотите, делайте небольшие шаги. Чтобы удалить виджет с сайтов, я могу создать его в IFrame или удалить его с экрана — оба они кажутся неуклюжими. Я собираюсь настроить пользовательский веб-сервис REST, как предложено metadaddy. Тем не менее, спасибо.