'Get JSON data from APEX class using php
So I have this APEX class that is triggered every time I create a contact in salesforce. The class then sends the data for the created contact to webservice that I've set. Here is the class
@isTest
public class testWebhookTriggerTest {
static SObject mock(String sobjectName) {
SObjectType t = Schema.getGlobalDescribe().get(sobjectName);
SObject o = t.newSobject();
Map<String, Schema.SObjectField> m = t.getDescribe().fields.getMap();
for (String fieldName : m.keySet()) {
DescribeFieldResult f = m.get(fieldName).getDescribe();
if (!f.isNillable() && f.isCreateable() && !f.isDefaultedOnCreate()) {
if (f.getType() == DisplayType.Boolean) {
o.put(f.getName(), false);
}
else if (f.getType() == DisplayType.Currency) {
o.put(f.getName(), 0);
}
else if (f.getType() == DisplayType.Date) {
o.put(f.getName(), Date.today());
}
else if (f.getType() == DisplayType.DateTime) {
o.put(f.getName(), System.now());
}
else if (f.getType() == DisplayType.Double) {
o.put(f.getName(), 0.0);
}
else if (f.getType() == DisplayType.Email) {
o.put(f.getName(), '[email protected]');
}
else if (f.getType() == DisplayType.Integer) {
o.put(f.getName(), 0);
}
else if (f.getType() == DisplayType.Percent) {
o.put(f.getName(), 0);
}
else if (f.getType() == DisplayType.Phone) {
o.put(f.getName(), '555-555-1212');
}
else if (f.getType() == DisplayType.String) {
o.put(f.getName(), 'TEST');
}
else if (f.getType() == DisplayType.TextArea) {
o.put(f.getName(), 'TEST');
}
else if (f.getType() == DisplayType.Time) {
o.put(f.getName(), System.now().time());
}
else if (f.getType() == DisplayType.URL) {
o.put(f.getName(), 'http://example.com');
}
else if (f.getType() == DisplayType.PickList) {
o.put(f.getName(), f.getPicklistValues()[0].getValue());
}
}
}
return o;
}
@isTest static void testTrigger() {
SObject o = mock('Contact');
Test.startTest();
insert o;
update o;
delete o;
Test.stopTest();
System.assertEquals(200, Webhook.response.getStatusCode());
System.assertEquals('https://alpahs.com/software/whatconverts/1/salesforceWebhook.php', Webhook.request.getEndpoint());
if (Webhook.request != null) {
Map<String, Object> jsonResponse = (Map<String, Object>) JSON.deserializeUntyped(Webhook.request.getBody());
System.assertNotEquals(null, jsonResponse.get('userId'));
}
}
}
My problem is that im not able to read the JSON data. This is my script that is listening for the data from salesforce
<?php
require_once './salesforceAuth.php';
// $headers = getallheaders();
$salesForce = new SalesForce();
$data = file_get_contents('php://input');
$dataFile = fopen("datasf.txt", "w");
try {
var_dump($data);
fwrite($dataFile,$data);
} catch (\Throwable $th) {
echo "Error / " . $th->getMessage();
}
?>
But I keep getting string(0) "".
Can someone please show me what I'm doing wrong here?
Solution 1:[1]
Capture some logs when creating contacts (open Developer Console from upper right corner, cog/gear icon or look into Setup -> Debug logs). When I tried that code generated by heroku app and endpoint generated with https://requestbin.net/ I could see
CALLOUT_REQUEST|[45]|System.HttpRequest[Endpoint=https://ok89nqo55upgs7r6.b.requestbin.net, Method=POST]
CALLOUT_REQUEST|[45]|System.HttpRequest retrying request in response to handshake failure: Received fatal alert: unrecognized_name
EXCEPTION_THROWN|[45]|System.CalloutException: Received fatal alert: unrecognized_name
HEAP_ALLOCATE|[45]|Bytes:43
FATAL_ERROR|System.CalloutException: Received fatal alert: unrecognized_name
Class.Webhook.callout: line 45, column 1
It seems to be some HTTPS / SSL problem. There's not much info on the net about it, you might be unlucky with the SF instance you're using (sandbox?) or maybe the certificate you used on the php app is suspicious (self signed maybe?)
- https://developer.salesforce.com/forums/?id=906F000000093nlIAA
- https://salesforce.stackexchange.com/questions/33275/error-system-calloutexception-received-fatal-alert-bad-record-mac
- https://blog.bergin.io/system-calloutexception-received-fatal-alert-handshake-failure-7d370be2d49b
It's stupid but try to change the Contact trigger to use HTTP instead of HTTPS. And change the Setup -> Remote Site Setting to "disable protocol security". And try again. If it works - you'll know it's something with SSL and you'll have something you can take to SF support.
trigger ContactHookWebhookTrigger on Contact (after insert) {
String url = 'http://ok89nqo55upgs7r6.b.requestbin.net';
String content = Webhook.jsonContent(Trigger.new, Trigger.old);
Webhook.callout(url, content);
}
After I made these changes and created new contact - that request bin captured some payload properly
https://requestbin.net/bins/view/2a2ca78656191cf942600bce8cac9b346006da0b
{"new": [{"attributes":{"type":"Contact","url":"/services/data/v54.0/sobjects/Contact/0034J00000tNAWtQAO"},"LastModifiedDate":"2022-05-23T08:42:14.000+0000","IsDeleted":false,"IsEmailBounced":false,"DoNotCall":false,"HasOptedOutOfEmail":false,"HasOptedOutOfFax":false,"SystemModstamp":"2022-05-23T08:42:14.000+0000","CleanStatus":"Pending","OwnerId":"0054J000001ipw6QAA","CreatedById":"0054J000001ipw6QAA","CreatedDate":"2022-05-23T08:42:14.000+0000","Id":"0034J00000tNAWtQAO","LastName":"jjjjjjjjjjjjjjjj","LastModifiedById":"0054J000001ipw6QAA"}], "old": [], "userId": "0054J000001ipw6QAA"}
Of course HTTP is evil for potentially sensitive data. If you don't see anything wrong with php app's certificate - I really think raising ticket with sf support would be the way to go.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | eyescream |

