Skip to main content

We want to be able to send custom notifications when a case is re-assigned to another user. The built in SecOps notification leaves a little to be desired. Can I pull case wall, or some other status change info  from a job? I have tried get_case_comments, get_case_tasks, get_case_by_Id, and none seem to have the status change info I am looking for. 

Hey @pfinocch ,


Before going into the details of Case Wall extraction, I would like to focus on the use case itself. If the goal is to create a notification, when a case assignee has changed then I have an alternative proposal that will work better and be more lightweight. 


I would suggest for you to store inside the job context the following object:


[
{
"caseId": "1",
"assignee": "user1@example"
},
{
"caseId": "2",
"assignee": "user2@example"
}
]

When the job iteration is going to fetch the details of the case, you will compare, if the assignee is the same as it's stored in the context of the job. If there is match -> no notification, if there is no match -> create notification. If the case was closed, then the entry will be removed from the list. This way you will ensure that the context will not grow infinitely. 


To solve this use case you can use the "get_case_by_Id" method and to understand how to store context, you can refer to the code of any other job in the Marketplace. As an example, "ServiceNow Sync Incidents Job" also stores data in the context, so you can use it as a reference.


Let me know, if this makes sense.


Hey @pfinocch ,


Before going into the details of Case Wall extraction, I would like to focus on the use case itself. If the goal is to create a notification, when a case assignee has changed then I have an alternative proposal that will work better and be more lightweight. 


I would suggest for you to store inside the job context the following object:


[
{
"caseId": "1",
"assignee": "user1@example"
},
{
"caseId": "2",
"assignee": "user2@example"
}
]

When the job iteration is going to fetch the details of the case, you will compare, if the assignee is the same as it's stored in the context of the job. If there is match -> no notification, if there is no match -> create notification. If the case was closed, then the entry will be removed from the list. This way you will ensure that the context will not grow infinitely. 


To solve this use case you can use the "get_case_by_Id" method and to understand how to store context, you can refer to the code of any other job in the Marketplace. As an example, "ServiceNow Sync Incidents Job" also stores data in the context, so you can use it as a reference.


Let me know, if this makes sense.


Is there more documentation on how to store context? Its not very clear from looking at the sync incidents job. 


Is there more documentation on how to store context? Its not very clear from looking at the sync incidents job. 


There are 2 methods that are responsible for this: "get_job_context_property" and "set_job_context_property". 


The structure for the methods is like this:


self.soar_job.set_job_context_property(
identifier=self.name_id, // this is always the same
property_key="string that represents the the entry in the database, where the JSON will be stored",
property_value=json.dumps({json object that you want to set}),
)
self.soar_job.get_job_context_property(
identifier=self.name_id,
property_key="string that represents the the entry in the database, where the JSON will be stored"
)

So, if you want to create a DB entry in the context of the job called "case_state", then you would do something like this:


self.soar_job.set_job_context_property(
identifier=self.name_id,
property_key="case_state",
property_value=json.dumps([
{
"caseId": "1",
"assignee": "user1@example"
},
{
"caseId": "2",
"assignee": "user2@example"
}
]),
)

And if you want to get back the data, you would do this:


self.soar_job.get_job_context_property(
identifier=self.name_id,
property_key="case_state",
)

We are working on proper dev guides for different integration components and when will have it ready, there will be more elaborate explanation for the Jobs, but hopefully this will push you in the right direction.


Eventually, you are not bound only to the DB context. You can build the same workflow using the file system or bucket, which will be used to store information about case state.


There are 2 methods that are responsible for this: "get_job_context_property" and "set_job_context_property". 


The structure for the methods is like this:


self.soar_job.set_job_context_property(
identifier=self.name_id, // this is always the same
property_key="string that represents the the entry in the database, where the JSON will be stored",
property_value=json.dumps({json object that you want to set}),
)
self.soar_job.get_job_context_property(
identifier=self.name_id,
property_key="string that represents the the entry in the database, where the JSON will be stored"
)

So, if you want to create a DB entry in the context of the job called "case_state", then you would do something like this:


self.soar_job.set_job_context_property(
identifier=self.name_id,
property_key="case_state",
property_value=json.dumps([
{
"caseId": "1",
"assignee": "user1@example"
},
{
"caseId": "2",
"assignee": "user2@example"
}
]),
)

And if you want to get back the data, you would do this:


self.soar_job.get_job_context_property(
identifier=self.name_id,
property_key="case_state",
)

We are working on proper dev guides for different integration components and when will have it ready, there will be more elaborate explanation for the Jobs, but hopefully this will push you in the right direction.


Eventually, you are not bound only to the DB context. You can build the same workflow using the file system or bucket, which will be used to store information about case state.


Thank you for your help so far! I am new to coding in secops, and there is a slight learning curve.

Here is what I have now, I am just testing to see if i can set the value 4777:

 

    siemplify.set_job_context_property(
        identifier=name_id,
        property_key="case_state",
        property_value=('4777')
    )
siemplify.get_job_context_property(
        identifier=name_id,
        property_key="case_state",
        )
Which works. Debug output is 4777. But when I comment out the set in order to only get:
INFO] No data found for property key: case_state

There are 2 methods that are responsible for this: "get_job_context_property" and "set_job_context_property". 


The structure for the methods is like this:


self.soar_job.set_job_context_property(
identifier=self.name_id, // this is always the same
property_key="string that represents the the entry in the database, where the JSON will be stored",
property_value=json.dumps({json object that you want to set}),
)
self.soar_job.get_job_context_property(
identifier=self.name_id,
property_key="string that represents the the entry in the database, where the JSON will be stored"
)

So, if you want to create a DB entry in the context of the job called "case_state", then you would do something like this:


self.soar_job.set_job_context_property(
identifier=self.name_id,
property_key="case_state",
property_value=json.dumps([
{
"caseId": "1",
"assignee": "user1@example"
},
{
"caseId": "2",
"assignee": "user2@example"
}
]),
)

And if you want to get back the data, you would do this:


self.soar_job.get_job_context_property(
identifier=self.name_id,
property_key="case_state",
)

We are working on proper dev guides for different integration components and when will have it ready, there will be more elaborate explanation for the Jobs, but hopefully this will push you in the right direction.


Eventually, you are not bound only to the DB context. You can build the same workflow using the file system or bucket, which will be used to store information about case state.


I think this was something I was missing. I had 

        self.name_id = (
            f'{self.soar_job.script_name}_{self.soar_job.unique_identifier}'
        )
But once I edited to 
        self.name_id = (
            f'{self.soar_job.script_name}'
        )
It worked.

Reply