'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?)

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.

remote site setting with HTTP instead of HTTPS

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