Salesforce – Notify external API (or create activity event) on custom object change - salesforce

I need a fairly trivial thing: every time a user changes a salesoforce custom object field, I need to notify the external service about the change.
Either push the notification or somehow log the object change event somewhere in salesforce. (and make the external service regularly check those latest events for any new activity)
Is either of those options possible?
The only info I could find on this issue is this somewhat relevant SO thread, but it's 3 years old and doesn't answer anything.

This can be done by creating a PushTopic and subscribing to it via Streaming API.

Related

Triggering an apex class when a field is created/modified in an Object

I am new to salesforce and I am trying working on an integration, where I need to send object schema to a third party system. I was able to create a simple apex class to create a JSON message and send it to an end point.
I am trying to figure out how to automate this, meaning.. I want to trigger this apex class when an new field is created or an existing field is modified in a specific custom object.
Created an apex class to generate a JSON with the list of custom fields in the object and their properties. I want to be able to trigger this automatically when object is updated
There's a "you're doing it wrong" element to it. It's metadata, not data, not so easy to trigger from inside Apex. Salesforce has mechanisms for easy pulling of this info, not pushing. External system can call "describes" with If-Modified-Since, querying EntityDefinition, FieldDefinition with Tooling API...
Even if you pull it off - technically it'll be useless to external system. When you created new field but didn't modify Profiles/Permission Sets yet - attempts to query it will fail. Same error is thrown for genuine syntax errors in SOQL and for "yes, we do have such field but you're not authorised to see it".
If you really want to continue down this path you can look into scheduling Apex (say run every 5 minutes, will that be good enough? Class to check EntityDefinition or Setup Audit Trail and send the message if needed)

Raise an event notification to a specific client when a user is registered/created on Identity Server

I am creating an AdminUI for my users where I set all the permission. As part of the requirements, every time that a user logins on my IdentityServer I need to set some default permissions, but those are handle on my Admin application. Which is the best way to raise an event to let that application that a user was created on the IdentityServer?
The simplest is i think to create a simple WebApi in IdentityServer that returns the latest users and then let the other application poll this API every X seconds. In that way the system is cleanly decoupled. Perhaps expose the data as a a RSS XML document or a JSON list of items.
There is a built in eventing model in IdentityServer that you could use and push notifications to the Admin application. But push is a bit more complicated to get right, especially how to deal with all the failre/error cases.
I's suggest to add a custom event sink to process UserLoginSuccessEvent or any other event you need, here is list of all builtin events. Find their code here.
In the custom sink as suggested in the other answer you can call an API on admin app to inform it about changes.
Here is a sample for custom sink.
I think to keep two applications decoupled you better to setup a service-bus for simple implementation a sub/pub mechanism. when any user complete registration(or any other actions),then as mentioned in another answer handle the events and add message. admin UI should subscribed before to receive these messages with some information to create a user related data.

Creating and modifying calendar subscriptions using the google API

I want the ability to create a calendar using the calendar API and issue one-way syncs to this calendar when changes happen on my end. I do not want the user to be able to make changes, i.e., it should work like a subscription but instead of google pulling changes, I want to push changes. This way users can get the changes in real time as opposed to having to wait for a long time to see updates.
I looked through the APIs and I could find no way to a) create subscription b) force subscribed calendar refresh. I also tried creating a secondary calendar and setting ACLs on it for the current user but this also doesn't work, I get the following error:
"reason": "cannotChangeOwnAcl",
"message": "Cannot change your own access level."
Is there a way to accomplish this with the API?

AngularJS: combine REST with Socket.IO

In the single page webapp I've recently built I'm getting data for my models using Restangular module. I'd like to add real-time updates to the app so whenever any model has been changed or added on the server I can update my model list.
I've seen this working very well in webapps like Trello where you can see the updates without refreshing the web page. I'm sure Trello webclient uses REST API.
What is a proper way to architect both server and client to archive this?
First of all, your question is too general and can have a lot of solutions that depend
on your needs and conditions.
I'll give you a brief overview for a single case when you want to leave REST APIs
and add some realtime with web sockets.
Get all data from the REST -- Sokets for notifications only.
Pros: Easy to implement both server side and client side. You only need to emit events on the server with
info about modified resource (like resource name and ID), and catch these events on the client side and fetch
data with REST APIs.
Cons: One more request to the server on every notification. That can increase traffic dramaticaly when you have a lot of active clients for a single resource (they will generate a lot of reverse requests to the server).
Get initial load from the REST -- Sockets for notifications with data payload.
Pros: All info comes with the notification and will not cause new requests to the server, so we have less traffic.
Cons: Harder to implement both server side and client side. You will need to add data to all the events on the server. You will need to fetch data from all the events on the client side.
Updated according to the comment
As for handling different types of models (just a way to go).
Client side.
Keep a factory for each model.
Keep in mind that you need realtime updates only for displayed data (in most cases), so you can easily
use memory caching (so you can find any entity by its ID).
Add listener for every type of changes (Created, Updated, Deleted).
In any listener you should call some initObject function, that will find entity in the cache by ID and extend it, if there is no entity with such ID, just create a new one and add it to cache.
Any Delete just removes an entity from the cache.
Any time you need this resource, you should return the link to cache object in order to keep two way databinding (that is why I use extend and not =). Of course, you need to handle the cases like: "User is editing the resource while notification about deleting comes".
Server side.
It is easier to send all the model then just modified fields (in both cases you must send the ID of resource).
For any Create, Update, Delete event push event to all engaged users.
Event name should contain action name (like New, Update, Delete) and the name of resource (like User, Task etc.). So, you will have NewTask, UpdateTask events.
Event payload should contain the model or just modified fields with the ID.
Collection changes can be handled in two ways: with add/update/remove items in collection or changing all the collection as a whole.
All modifications like PUT, POST, DELETE are made with REST of course.
I've made a super simple pseudo gist for the case 1). https://gist.github.com/gpstmp/9868760 but it can be updated for case 2) like so https://gist.github.com/gpstmp/9900454
Hope this helps.

Listening to changes in sling's users and groups

I want to be notified of changes to users or groups in sling's userManager as they happen. For example, when a new group is created, I need to create a new node with the same name under /content. When a new user is created, I want to give them write-permissions for /content/foo. And similar tearDown steps when objects are deleted.
I tried registering a EventHandler (org.osgi.service.event.EventHandler), with event.topics set to "*" (all topics), but this captured only resource changes and not userManager changes because users and groups are synthetic resources (I think)
I tried using a org.apache.sling.api.request.SlingRequestListener, but the SlingRequestEvent did not come with any info that would help me distinguish the request (or I didn't know how). Also, I am not sure if this is can even be used for callbacks that need to be called AFTER the request is processed.
I have used Filters for a different issue and I tried applying them for this purpose too. But they have their limitations - My filter is called BEFORE the request, so it's not possible to know if the request will result in SUCCESS before deciding to take action.
Any suggestions on how to listen and respond to changes in sling's user and group models?
In https://issues.apache.org/jira/browse/SLING-977 Ian Boston suggests using a SlingPostProcessor service to be informed of calls to the user management's POST servlets.
I haven't tried it myself, and if you do it you might anyway miss changes that are done via Sling's user management APIs - but that might be good enough depending on your use case.
Apart from that I don't think there's currently a surefire way of being notified of such changes. To implement that in Sling we'd need to wrap the org.apache.jackrabbit.api.security.user.* objects (Group, User, UserManager) to send events when they're changed. Certainly doable but would require changes to that Sling bundle.

Resources