I have experience in Salesforce administration, but not in Salesforce development.
My task is to push a Order in Salesforce to an external REST API, if the order is in the custom status "Processing" and the Order Start Date (EffectiveDate) is in 10 days.
The order will be than processed in the down-stream system.
If the order was successfully pushed to the REST API the status should be changed to "Activated".
Can anybody give me some example code to get started?
There's very cool guide for picking right mechanism, I've been studying from this PDF for one of SF certifications: https://developer.salesforce.com/docs/atlas.en-us.integration_patterns_and_practices.meta/integration_patterns_and_practices/integ_pat_intro_overview.htm
A lot depends on whether the endpoint is accessible from Salesforce (if it isn't - you might have to pull data instead of pushing), what authentication it needs.
For push out of Salesforce you could use
Outbound Message - it'd be an XML document sent when (time-based in your case?) workflow fires, not REST but it's just clicks, no code. The downside is that it's just 1 object in message. So you can send Order header but no line items.
External Service would be code-free and you could build a flow with it.
You could always push data with Apex code (something like this). We'd split the solution into 2 bits.
The part that gets actual work done: At high level you'd write function that takes list of Order ids as parameter, queries them, calls req.setBody(JSON.serialize([SELECT Id, OrderNumber FROM Order WHERE Id IN :ids]));... If the API needs some special authentication - you'd look into "Named Credentials". Hard to say what you'll need without knowing more about your target.
And the part that would call this Apex when the time comes. Could be more code (a nightly scheduled job that makes these callouts 1 minute after midnight?) https://salesforce.stackexchange.com/questions/226403/how-to-schedule-an-apex-batch-with-callout
Could be a flow / process builder (again, you probably want time-based flows) that calls this piece of Apex. The "worker" code would have to "implement interface" (a fancy way of saying that the code promises there will be function "suchAndSuchName" that takes "suchAndSuch" parameters). Check Process.Plugin out.
For pulling data... well, target application could login to SF (SOAP, REST) and query the table of orders once a day. Lots of integration tools have Salesforce plugins, do you already use Azure Data Factory? Informatica? BizTalk? Mulesoft?
There's also something called "long polling" where client app subscribes to notifications and SF pushes info to them. You might have heard about CometD? In SF-speak read up about Platform Events, Streaming API, Change Data Capture (although that last one fires on change and sends only the changed fields, not great for pushing a complete order + line items). You can send platform events from flows too.
So... don't dive straight to coding the solution. Plan a bit, the maintenance will be easier. This is untested, written in Notepad, I don't have org with orders handy... But in theory you should be able to schedule it to run at 1 AM for example. Or from dev console you can trigger it with Database.executeBatch(new OrderSyncBatch(), 1);
public class OrderSyncBatch implements Database.Batchable, Database.AllowsCallouts {
public Database.QueryLocator start(Database.BatchableContext bc) {
Date cutoff = System.today().addDays(10);
return Database.getQueryLocator([SELECT Id, Name, Account.Name, GrandTotalAmount, OrderNumber, OrderReferenceNumber,
(SELECT Id, UnitPrice, Quantity, OrderId FROM OrderItems)
FROM Order
WHERE Status = 'Processing' AND EffectiveDate = :cutoff]);
}
public void execute(Database.BatchableContext bc, List<sObject> scope) {
Http h = new Http();
List<Order> toUpdate = new List<Order>();
// Assuming you want 1 order at a time, not a list of orders?
for (Order o : (List<Order>)scope) {
HttpRequest req = new HttpRequest();
HttpResponse res;
req.setEndpoint('https://example.com'); // your API endpoint here, or maybe something that starts with "callout:" if you'd be using Named Credentials
req.setMethod('POST');
req.setHeader('Content-Type', 'application/json');
req.setBody(JSON.serializePretty(o));
res = h.send(req);
if (res.getStatusCode() == 200) {
o.Status = 'Activated';
toUpdate.add(o);
}
else {
// Error handling? Maybe just debug it, maybe make a Task for the user or look into
// Database.RaisesPlatformEvents
System.debug(res);
}
}
update toUpdate;
}
public void finish(Database.BatchableContext bc) {}
public void execute(SchedulableContext sc){
Database.executeBatch(new OrderSyncBatch(), Limits.getLimitCallouts()); // there's limit of 10 callouts per single transaction
// and by default batches process 200 records at a time so we want smaller chunks
// https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_methods_system_limits.htm
// You might want to tweak the parameter even down to 1 order at a time if processing takes a while at the other end.
}
}
Related
We need to use a single instace of VRS to support concurrent request.
We have a requirement where multiple different users should be able to create a route plan for different vehicles and locations same time. However, looking at VRS functionality, I am not able to understand how applications supports it. For demo, when I create a different route using different browser, it always merges first and second request and give one single result.
Just a little more elobration on the question:
We are aiming to convert requests as REST API endpoints which will be invoked by different uses same time for their usecase.
Eg. Request 1: Vehicle 1&2 with 50 locations. VRS can calculate route & give one message with all detailed calculations for request1.
Request 2: Vehicle 3 & 4 with 40 locations. So VRS can calculate route which later we can get as one message with all detailed calculations limited to request 2.
Both requests can be submitted same time & application should considered as separate requests without getting merged.
Is there a way to add request ID or any other paramaters to achive this?
For multi-tenant solving, the SolverManager API is ideal:
public class TimeTableService {
// tenantId is Long, but it can also be String or UUID
private SolverManager<TimeTable, Long> solverManager;
// Returns immediately, call it for every dataset
public void solveBatch(Long tenantId) {
solverManager.solve(tenantId,
// Called once, when solving starts
this::findById,
// Called once, when solving ends
this::save);
}
public TimeTable findById(Long tenantId) {...}
public void save(TimeTable timeTable) {...}
}
I have researched high and low through multiple websites and have not found a single fully documented solution for round-robin call forwarding with-in the Twilio stack; let alone within Twilio Studio. The last time this question was asked in detail was in 2013 so your help is greatly appreciated. I am looking to find a solution to the following to educate myself and others:
[Round Robin Scenario]
Mentioned by Phil Krnjeu on Aug 1 '13 at 23:04, "I'm trying to create a website that has a phone number on it (say, a phone number for a school). When you call that number, it has different secretary offices (A,B,C, D). I want to create something where the main number is called, and then it goes and calls phone number A the first time, the second time someone calls the main number, number B is called, C, then D. Once D is called (which would be the 4th call), the 5th call goes back to A."
The response to the above question was to use an IVR Screening & Recording application which requires the caller to pick an agent which is not a true Round Robin solution. The solution I am looking for and many others require the system to know which agent is in a group and which agent is next to receive a call.
[Key Features Needed]
Ability to add forwarding numbers as identified above A, B, C, D as a group or IVR extensions such as 1 = Management, 2 = Sales and etc...
Set a subsequent calling rule that notates in a DB of some sort. Caller A through D, for example, equals 1 unsuccessful. When caller A has been forwarded a call it now equals 0 successful then the script stops and allows the call to be answered by the user or its voicemail. Then the next call comes in and is forwarded to user B and assigned a 0 successful value, then the script stops.
After the caller finishes the call or finishes leaving a voicemail the script needs to end the call.
[Final Destination]
The round-robin should finalize its call with the forwarded phone numbers voicemail.
[Known Issues]
Forwarding a call to multiple numbers not stopping when someone answers
[Options]
Once this question is posted I am sure someone will ask in the near future what if I wanted the call to be forwarded to a Twilio voicemail instead of using the forwarded phone number's voicemail which could be let's say a cell phone. I do not necessarily need this feature, however, making an additional comment would be very helpful to the community. Thank you for your time.
I have limited knowledge of programming besides having the ability to review articles posted by other users. One article I researched in detail that did not work for me was, "IVR: Screening & Recording with PHP and Laravel."
The solution I am looking for first would be to make this code through the new Twilio Studio interface if that is not possible then any other solution would be helpful to all.
Sam here from the Twilio Support Team. You can build what you've described using Twilio's Runtime suite, Studio, and Functions.
I wrote a blog post with detailed instructions and screenshots here, and I've included a summarized version below as well.
CREATE YOUR VARIABLE
First, you need to create a serverless Variable which will be used as the round robin counter. The variable must be inside an Environment, which is inside a Service. This is the only part of the application where you will need your own laptop. You can see how to create these with any of the SDKs or using curl in the docs.
Create a Service
Create an Environment
Create a Variable
Be sure to copy the SIDs of your Service, Environment, and Variable since you will need that for your function.
For convenience, this is how you create the Variable in NodeJS.
const accountSid = 'your_account_sid';
const authToken = 'your_auth_token';
const client = require('twilio')(accountSid, authToken);
client.serverless.services('ZSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
.environments('ZEXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
.variables
.create({key: 'key', value: 'value'})
.then(variable => console.log(variable.sid));
CREATE YOUR FUNCTION
Create the following Environment Variables here in the console and save set them equal to their respective SID that you saved earlier.
RR_SERVICE_SID
RR_ENV_SID
RR_VAR_SID_CTR
Next, make sure you check the Enable ACCOUNT_SID and AUTH_TOKEN checkbox above the Environment Variables section under Credentials.
Be sure your Twilio Client version in the Dependencies section is set to the latest, so we can be sure it includes the Serverless resources. At the time of writing (March 2020), the default Client version does not include them, so we upgraded to 3.41.1, which was the latest.
Go here in the console and create a blank Function.
Copy and paste the following code and replace the numbers with the ones you would like to include in your Round Robin (make sure the environment variables you just created match what's in the code).
exports.handler = function(context, event, callback) {
// Number List
let numbers = [
"+18652142345", //Sam
"+18651092837", //Tina
"+19193271892", //Matt
// Copy and paste line above to add another number.
];
// Initialize Twilio Client
let client = context.getTwilioClient();
// Fetch Round Robin Ctr
client.serverless.services(context.RR_SERVICE_SID)
.environments(context.RR_ENV_SID)
.variables(context.RR_VAR_SID_CTR)
.fetch()
.then(variable => {
// Use counter value to determine number to call
let number = numbers[variable.value];
// Create var with new ctr value
let ctr = variable.value;
// Check if current counter value is less than RR length (i.e. the number of numbers in round robin)
// If so, increment
if(ctr == numbers.length-1) {
ctr = 0;
}
// Otherwise reset ctr
else ctr++;
// Update counter value
client.serverless.services(context.RR_SERVICE_SID)
.environments(context.RR_ENV_SID)
.variables(context.RR_VAR_SID_CTR)
.update({value: ctr})
.then(resp => {
// Return number to call
let response = {number};
// Return our counter value and a null error value
callback(null, response);
});
});
};
CREATE YOUR STUDIO FLOW
Click the red plus sign to create a new Flow here.
Give the Flow a name and click Next.
Scroll to the bottom of the templates and click 'Import from JSON' and click Next.
Paste the Flow JSON shown here and click Next.
Click the RoundRobin function widget and select the Function you just created under the Default service.
Click the FunctionError widget, click MESSAGING & CHAT CONFIG, and change the SEND MESSAGE TO number to a number that you would like to notify by text in the event of a Function failure.
Click the DefaultNumber widget and change the default number that will be forwarded to in the event of a Function failure.
Click the Publish button at the top of your Flow.
CONFIGURE YOUR TWILIO NUMBER
Go here in the console.
Click the Twilio number you would like to configure.
Scroll down to the A CALL COMES IN dropdown in the Voice section and select Studio Flow.
Select your new Flow in the Select a Flow dropdown to the right.
Click Save at the bottom.
And that's it. You're now all set to test!
I have to implement MVC .Net Web api (say "Main" api) which includes two parts.
1) Database call to fetch the record.
2) And more than 1000s of another web api call(response time 100 ms on avg. for each) which will use records returned by above db call.
Also, the Main api will be called in every 3 seconds continuously. I tried implementing using async/await method but didn't find much progress and when trying to test it using Apache Benchmark tool, it throws timeout specified has expired error.
Is there any way to achieve this? Please suggest.
Code snippet
[HttpGet]
public async Task<string> doTaskasync()
{
TripDetails obj = new TripDetails();
GPSCoordinates objGPS = new GPSCoordinates();
try
{
/* uriArray Contains more than 1000 APIs which needs to be exectued. */
string[] uriArray = await dolongrunningtaskasync();
IEnumerable<Task<GPSCoordinates>> allTasks = uriArray .Select(u => GetLocationsAsync(u));
IEnumerable<GPSCoordinates> allResults = await Task.WhenAll(allTasks);
}
catch (Exception ex)
{
return ex.Message ;
}
return "success";
}
Ab.exe test
There is nothing wrong programmatically with your code - except that this is practically a DOS attack on the second (location) API. You should definitely add caching to avoid at least part of the 1000 api calls, especially if you call the main api often (as you wrote).
What I would do is to make the inner api calls a centralized operation instead of making these calls individually inside your web api method. For example you could use a central list for location api calls (tasks) that have been started (but not finished), and another list for results that have been already finished. Both list could be a concurrent dictionary by the unique urls you use for the location api calls.
We are developing using VS2010 and MVC4, deploying our web app on an IIS 7.5 on Windows7.
Our project has a long running process for which we want to display status and progress.
In order to accomplish this we have a small serializable class with properties that describe the current status. The long operation pseudo code goes like this:
int curentPercentComplete = 0;
EngineStatus status = new EngineStatus();
while (!done) {
status.PercentComplete = curentPercentComplete;
Session['status'] = status;
// do lengthy operation
curentPercentComplete = compute();
done = isJobFinished();
}
We also have an other controller action that tries to retrieve the current status from the session
which then encodes to json and returns it to the browser via an Ajax request.
Our problem is that we always seem to get the last saved data from the previous request, in other words the session object does not seem to update the Session['status'] field during the execution of the while block.
We have tried the session state mode both InProc and StateServer with exactly the same behavior.
Thanks in advance.
It turns out that the MVC framework performs a single update of the session data at the end of the request which means that only the last value is saved.
Since the "lengthy" operation is performed in a single request-response cycle, the idea of storing intermediate status information in the session is plain wrong.
I am fairly new to Scala and I'm working on an application (library) which is a client to a 3rd-party service (I'm not able to modify the server side and it uses custom binary protocol). I use Netty for networking.
I want to design an API which should allow users to:
Send requests to the server
Send requests to the server and get the response asynchronously
Subscribe to events triggered by the server (having multiple asynchronous event handlers which should be able to send requests as well)
I am not sure how should I design it. Exploring Scala, I stumble upon a bunch of information about Actor model, but I am not sure if it can be applied there and if it can, how.
I'd like to get some recommendations on the way I should take.
In general, the Scala-ish way to expose asynchronous functionality to user code is to return a scala.concurrent.Future[T].
If you're going the actor route, you might consider encapsulating the binary communication within the context of a single actor class. You can scale the instances of this proxy actor using Akka's router support, and you could produce response futures easily using the ask pattern. There are a few nice libraries (Spray, Play Framework) that make wrapping e.g. a RESTful or even WebSocket layer over Akka almost trivial.
A nice model for the pub-sub functionality might be to define a Publisher trait that you can mix in to some actor subclasses. This could define some state to keep track of subscribers, handle Subscribe and Unsubscribe messages, and provide some sort of convenient method for broadcasting messages:
/**
* Sends a copy of the supplied event object to every subscriber of
* the event object class and superclasses.
*/
protected[this] def publish[T](event: T) {
for (subscriber <- subscribersFor(event)) subscriber ! event
}
These are just some ideas based on doing something similar in some recent projects. Feel free to elaborate on your use case if you need more specific direction. Also, the Akka user list is a great resource for general questions like this, if indeed you're interested in exploring actors in Scala.
Observables
This looks like a good example for the Obesrvable pattern. This pattern comes from the Reactive Extensions of .NET, but is also available for Java and Scala. The library is provided by Netflix and has a really good quality.
This pattern has a good theoretical foundation --- it is the dual to the iterator in the category theoretical sense. But more important, it has a lot of practical ideas in it. Especially it handles time very good, e.g. you can limit the event rate you want to get.
With an observable you can process events on avery high level. In .NET it looks a lot like an SQL query. You can register for certain events ("FROM"), filter them ("WHERE") and finally process them ("SELECT"). In Scala you can use standard monadic API (map, filter, flatMap) and of course "for expressions".
An example can look like
stackoverflowQuestions.filter(_.tag == "Scala").map(_.subject).throttleLast(1 second).subscribe(println _)
Obeservables take away a lot of problems you will have with event based systems
Handling subsrcriptions
Handling errors
Filtering and pre-processing events
Buffering events
Structuring the API
Your API should provide an obesrvable for each event source you have. For procedure calls you provide a function that will map the function call to an obesrvable. This function will call the remote procedure and provide the result through the obeservable.
Implementation details
Add the following dependency to your build.sbt:
libraryDependencies += "com.netflix.rxjava" % "rxjava-scala" % "0.15.0"
You can then use the following pattern to convert a callback to an obeservable (given your remote API has some way to register and unregister a callback):
private val callbackFunc : (rx.lang.scala.Observer[String]) => rx.lang.scala.Subscription = { o =>
val listener = {
case Value(s) => o.onNext(s)
case Error(e) => o.onError(o)
}
remote.subscribe(listener)
// Return an interface to cancel the subscription
new Subscription {
val unsubscribed = new AtomicBoolean(false)
def isUnsubscribed: Boolean = unsubscribed.get()
val asJavaSubscription: rx.Subscription = new rx.Subscription {
def unsubscribe() {
remote.unsubscribe(listener)
unsubscribed.set(true)
}
}
}
If you have some specific questions, just ask and I can refine the answer
Additional ressources
There is a very nice course from Martin Odersky et al. at coursera, covering Observables and other reactive techniques.
Take a look at the spray-client library. This provides HTTP request functionality (I'm assuming the server you want to talk to is a web service?). It gives you a pretty nice DSL for building requests and is all about being asynchronous. It does use the akka Actor model behind the scenes, but you do not have to build your own Actors to use it. Instead the you can just use scala's Future model for handling things asynchronously. A good introduction to the Future model is here.
The basic building block of spray-client is a "pipeline" which maps an HttpRequest to a Future containing an HttpResponse:
// this is from the spray-client docs
val pipeline: HttpRequest => Future[HttpResponse] = sendReceive
val response: Future[HttpResponse] = pipeline(Get("http://spray.io/"))
You can take this basic building block and build it up into a client API in a couple of steps. First, make a class that sets up a pipeline and defines some intermediate helpers demonstrating ResponseTransformation techniques:
import scala.concurrent._
import spray.can.client.HttpClient
import spray.client.HttpConduit
import spray.client.HttpConduit._
import spray.http.{HttpRequest, HttpResponse, FormData}
import spray.httpx.unmarshalling.Unmarshaller
import spray.io.IOExtension
type Pipeline = (HttpRequest) => Future[HttpResponse]
// this is basically spray-client boilerplate
def createPipeline(system: ActorSystem, host: String, port: Int): Pipeline = {
val httpClient = system.actorOf(Props(new HttpClient(IOExtension(system).ioBridge())))
val conduit = system.actorOf(props = Props(new HttpConduit(httpClient, host, port)))
sendReceive(conduit)
}
private var pipeline: Pipeline = _
// unmarshalls to a specific type, e.g. a case class representing a datamodel
private def unmarshallingPipeline[T](implicit ec:ExecutionContext, um:Unmarshaller[T]) = (pipeline ~> unmarshal[T])
// for requests that don't return any content. If you get a successful Future it worked; if there's an error you'll get a failed future from the errorFilter below.
private def unitPipeline(implicit ec:ExecutionContext) = (pipeline ~> { _:HttpResponse => () })
// similar to unitPipeline, but where you care about the specific response code.
private def statusPipeline(implicit ec:ExecutionContext) = (pipeline -> {r:HttpResponse => r.status})
// if you want standard error handling create a filter like this
// RemoteServerError and RemoteClientError are custom exception classes
// not shown here.
val errorFilter = { response:HttpResponse =>
if(response.status.isSuccess) response
else if(response.status.value >= 500) throw RemoteServerError(response)
else throw RemoteClientError(response)
}
pipeline = (createPipeline(system, "yourHost", 8080) ~> errorFilter)
Then you can use wrap these up in methods tied to specific requests/responses that becomes the public API. For example, suppose the service has a "ping" GET endpoint that returns a string ("pong") and a "form" POST endpoint where you post form data and receive a DataModel in return:
def ping()(implicit ec:ExecutionContext, um:Unmarshaller[String]): Future[String] =
unmarshallingPipeline(Get("/ping"))
def form(formData: Map[String, String])(implicit ec:ExecutionContext, um:Unmarshaller[DataModel]): Future[DataModel] =
unmarshallingPipeline(Post("/form"), FormData(formData))
And then someone could use the API like this:
import scala.util.{Failure, Success}
API.ping() foreach(println) // will print out "pong" when response comes back
API.form(Map("a" -> "b") onComplete {
case Success(dataModel) => println("Form accepted. Server returned DataModel: " + dataModel)
case Failure(e) => println("Oh noes, the form didn't go through! " + e)
}
I'm not sure if you will find direct support in spray-client for your third bullet point about subscribing to events. Are these events being generated by the server and somehow sent to your client outside the scope of a specific HTTP request? If so, then spray-client will probably not be able to help directly (though your event handlers could still use it to send requests). Are the events occurring on the client side, e.g. the completion of deferred processing initially triggered by a response from the server? If so, you could actually probably get pretty far just by using the functionality in Future, but depending on your use cases, using Actors might make sense.