#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. Тем не менее, спасибо.