PHP SDK Fax Permission Error

  • 1
  • Question
  • Updated 2 weeks ago
First time writing an integration using RC's PHP SDK. Installed SDK via Composer and setup the credentials/sandbox, etc. Authorization is fine, app is communicating.  Started with the demo/fax.php to test using file.txt (using demo installed with sdk) and I'm getting "Bad Request" but no error code.

I haven't changed anything in the SDK (other than the /path/to/vendor/autoload which is incorrect in _bootstrap)

How can I get more info so I can troubleshoot?

Here's what I'm getting back from RC:

--952ed22a92fb817145143eb568f4a4c84ce5a37b
Content-Type: application/json
Content-Disposition: form-data; name="json"; filename="request.json"
Content-Length: 61

{"to":[{"phoneNumber":"17474773958"}],"faxResolution":"High"}
--952ed22a92fb817145143eb568f4a4c84ce5a37b
Content-Type: application/octet-stream
Content-Disposition: form-data; name="file.txt"; filename="file.txt"
Content-Length: 10

Plain Text
--952ed22a92fb817145143eb568f4a4c84ce5a37b
Content-Disposition: form-data; name="ico_case_crm.png"; filename="ico_case_crm.png"
Content-Type: image/png

<html>
<head>
<META NAME="robots" CONTENT="noindex,nofollow">
<script src="/_Incapsula_Resource?SWJIYLWA=5074a744e2e3d891814e9a2dace20bd4,719d34d31c8e3a6e6fffd425f7e032f3">
</script>
<body>
</body></html>
--952ed22a92fb817145143eb568f4a4c84ce5a37b--

Exception: Bad Request
SDK HTTP Error at https://platform.devtest.ringcentral.com/restapi/v1.0/account/~/extension/~/fax
Response text: {
  "message" : "Bad Request",
  "errors" : [ ]
}
Previous: Response has unsuccessful status
#0 /home/drs/public_html/admin/ring-central/vendor/ringcentral/ringcentral-php/src/Platform/Platform.php(329): RingCentral\SDK\Http\Client->send(Object(GuzzleHttp\Psr7\Request))
#1 /home/drs/public_html/admin/ring-central/vendor/ringcentral/ringcentral-php/demo/fax.php(34): RingCentral\SDK\Platform\Platform->sendRequest(Object(GuzzleHttp\Psr7\Request)) 
#2 {main}
Photo of Nathan CFD

Nathan CFD

  • 234 Points 100 badge 2x thumb

Posted 1 month ago

  • 1
Photo of Phong Vu

Phong Vu, Devangelist

  • 5,416 Points 5k badge 2x thumb
Hi Nathan,

The demo code does not implement exception handling. Please put the code in "try catch" as shown below to detect the error message.
try {

    $rcsdk->platform()->get('/account/~/whatever');

} catch (\RingCentral\SDK\Http\ApiException $e) {

    // Getting error messages using PHP native interface
    print 'Expected HTTP Error: ' . $e->getMessage() . PHP_EOL;

    // In order to get Request and Response used to perform transaction:
    $apiResponse = $e->apiResponse();
    print_r($apiResponse->request());
    print_r($apiResponse->response());

    // Another way to get message, but keep in mind, that there could be no response if request has failed completely
    print '  Message: ' . $e->apiResponse->response()->error() . PHP_EOL;
 
}
Photo of Nathan CFD

Nathan CFD

  • 234 Points 100 badge 2x thumb
Thanks Phong, 

It did return an error which appears to be that it can't find the GuzzleHTTP dependency, but it did install in the /vendor/ directory.

Can you gleen any info from this response:

Expected HTTP Error: Resource not found
GuzzleHttp\Psr7\Request Object
(
    [method:GuzzleHttp\Psr7\Request:private] => GET
    [requestTarget:GuzzleHttp\Psr7\Request:private] => 
    [uri:GuzzleHttp\Psr7\Request:private] => GuzzleHttp\Psr7\Uri Object
        (
            [scheme:GuzzleHttp\Psr7\Uri:private] => https
            [userInfo:GuzzleHttp\Psr7\Uri:private] => 
            [host:GuzzleHttp\Psr7\Uri:private] => platform.devtest.ringcentral.com
            [port:GuzzleHttp\Psr7\Uri:private] => 
            [path:GuzzleHttp\Psr7\Uri:private] => /restapi/v1.0/account/~/whatever
            [query:GuzzleHttp\Psr7\Uri:private] => 
            [fragment:GuzzleHttp\Psr7\Uri:private] => 
        )

    [headers:GuzzleHttp\Psr7\Request:private] => Array
        (
            [Host] => Array
                (
                    [0] => platform.devtest.ringcentral.com
                )

            [content-type] => Array
                (
                    [0] => application/json
                )

            [accept] => Array
                (
                    [0] => application/json
                )

            [Authorization] => Array
                (
                    [0] => bearer U0pDMTJQMDFQQVMwMHxBQUFZVjVYenJFenhWellMemhJWktZTmFVTGtHRjBZNFF3cVBHa09Ca3plTW1ORG9CdDIyZXVpWHFaOXNzNUVqZ0lKNF9QWWRPMEVYNEhPV3FzbEwwTUtuLWlvamdZamh1cXc4RWFEc3FFZ0lVTHZ1aEdlX0tXajhRYU5GN21lVWYyM0VDaWpVT0MwenVOQjU4S3ZoS0tfUDhFbVMzVDMxaWdVQ042eTh2bzRTakJzUVlITzRabWNfaU5zZlZVMFpyU0o0c1hSc1ozdUlNUEhjMlk4Y1lnSVd8YUdjSmJ3fFVERENCS2s1QVA1dWhXZ1QzVmdRT3d8QUE
                )

            [User-Agent] => Array
                (
                    [0] => Unnamed/0.0.0 Linux/2.6.32-042stab133.2 PHP/7.0.33 RCPHPSDK/2.1.2
                )

            [RC-User-Agent] => Array
                (
                    [0] => Unnamed/0.0.0 Linux/2.6.32-042stab133.2 PHP/7.0.33 RCPHPSDK/2.1.2
                )

        )

    [headerNames:GuzzleHttp\Psr7\Request:private] => Array
        (
            [content-type] => content-type
            [accept] => accept
            [authorization] => Authorization
            [user-agent] => User-Agent
            [rc-user-agent] => RC-User-Agent
            [host] => Host
        )

    [protocol:GuzzleHttp\Psr7\Request:private] => 1.1
    [stream:GuzzleHttp\Psr7\Request:private] => GuzzleHttp\Psr7\Stream Object
        (
            [stream:GuzzleHttp\Psr7\Stream:private] => Resource id #78
            [size:GuzzleHttp\Psr7\Stream:private] => 0
            [seekable:GuzzleHttp\Psr7\Stream:private] => 1
            [readable:GuzzleHttp\Psr7\Stream:private] => 1
            [writable:GuzzleHttp\Psr7\Stream:private] => 1
            [uri:GuzzleHttp\Psr7\Stream:private] => php://temp
            [customMetadata:GuzzleHttp\Psr7\Stream:private] => Array
                (
                )

        )

)
GuzzleHttp\Psr7\Response Object
(
    [reasonPhrase:GuzzleHttp\Psr7\Response:private] => Not Found
    [statusCode:GuzzleHttp\Psr7\Response:private] => 404
    [headers:GuzzleHttp\Psr7\Response:private] => Array
        (
            [Server] => Array
                (
                    [0] => nginx
                )

            [Date] => Array
                (
                    [0] => Mon, 15 Apr 2019 17:53:20 GMT
                )

            [Content-Type] => Array
                (
                    [0] => application/json
                )

            [Content-Length] => Array
                (
                    [0] => 83
                )

            [Connection] => Array
                (
                    [0] => keep-alive
                )

            [RoutingKey] => Array
                (
                    [0] => SJC12P01
                )

            [RCRequestId] => Array
                (
                    [0] => 5b57ee94-5fa7-11e9-bb0c-005056bba23b
                )

        )

    [headerNames:GuzzleHttp\Psr7\Response:private] => Array
        (
            [server] => Server
            [date] => Date
            [content-type] => Content-Type
            [content-length] => Content-Length
            [connection] => Connection
            [routingkey] => RoutingKey
            [rcrequestid] => RCRequestId
        )

    [protocol:GuzzleHttp\Psr7\Response:private] => 1.1
    [stream:GuzzleHttp\Psr7\Response:private] => GuzzleHttp\Psr7\Stream Object
        (
            [stream:GuzzleHttp\Psr7\Stream:private] => Resource id #80
            [size:GuzzleHttp\Psr7\Stream:private] => 
            [seekable:GuzzleHttp\Psr7\Stream:private] => 1
            [readable:GuzzleHttp\Psr7\Stream:private] => 1
            [writable:GuzzleHttp\Psr7\Stream:private] => 1
            [uri:GuzzleHttp\Psr7\Stream:private] => php://temp
            [customMetadata:GuzzleHttp\Psr7\Stream:private] => Array
                (
                )

        )
 
)
Photo of Nathan CFD

Nathan CFD

  • 234 Points 100 badge 2x thumb
Also, it's returning this URL: https://platform.devtest.ringcentral.com/restapi/v1.0/account/258637004/extension/258637004/message-...

Where the Message changes each time; not sure where the account and extension variables are coming from, they are not part of the Sandbox credentials.
Photo of Phong Vu

Phong Vu, Devangelist

  • 5,396 Points 5k badge 2x thumb
Have you modified the demo code? If yes, can you post the code?

Important: Remember DO NOT post your Client ID, Client Secret or password here!

Account id and extension id is retrieved by the SDK after you login.
Photo of Nathan CFD

Nathan CFD

  • 234 Points 100 badge 2x thumb
Hi Phong, 

Actually, I reinstalled via composer and segmented the SDK/vendor/ from the "demo" area and wrote a very basic demo script and it's working.  I think there may have been some relative vs absolute path issues with some of the files in demo folder. 

This app is going to fax a page for each order and that page is getting written dynamically and saved as an HTML file.  I've run a couple of tests faxing HTML and it will not fax images regardless of how they are referenced (as http or absolute).  I really don't want to convert to PDF first as that strains resources. Any suggestions about faxing HTML with images?
Photo of Tyler Long

Tyler Long, Official Rep

  • 9,818 Points 5k badge 2x thumb
I am afraid that you cannot do that, unless you embed image into HTML as base64 data uri.

Alternatively, you can use some program to convert HTML to PDF before sending fax.
Photo of Tyler Long

Tyler Long, Official Rep

  • 9,828 Points 5k badge 2x thumb
You original web post specifies 

Content-Disposition: form-data; name="ico_case_crm.png"; filename="ico_case_crm.png" . Content-Type: image/png

However its content is <html> ...

You were sending HTML while you told the server that it's an image, it woundn't work.
(Edited)
Photo of Nathan CFD

Nathan CFD

  • 234 Points 100 badge 2x thumb
Hello Tyler,

Thank you for responding.

The ico_case_crm.png file was left over from the "out of the box" demo which didn't work.  I wrote a new page to test and it does work - and that page faxes an HTML document.

However, I'm still having trouble with images.  I have changed them to base64 data uri and they still do not appear on the fax.  Here's an example of the embedding syntax - any idea why it will not show up on the fax?

    <img src="data: image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2ODAgMiI+PGRlZnM+PHN0eWxlPi5he2ZpbGw6bm9uZTtzdHJva2U6IzIzMWYyMDtzdHJva2UtbWl0ZXJsaW1pdDoxMDtzdHJva2Utd2lkdGg6MnB4O308L3N0eWxlPjwvZGVmcz48dGl0bGU+cG1wLWxpbmU8L3RpdGxlPjxsaW5lIGNsYXNzPSJhIiB5MT0iMSIgeDI9IjY4MCIgeTI9IjEiLz48L3N2Zz4=" width="680" height="5" style="width: 680px; height: 5px;" />

Photo of Phong Vu

Phong Vu, Devangelist

  • 5,416 Points 5k badge 2x thumb
Hi Nathan,

I just tested and got the same issue. I checked the issue with an engineer and it turns out that we don't render html page as a fax attachment with any other element but texts. So no controls such as checkboxes, radio buttons, table with borders etc. and no images.

So unfortunately, it seems you have to convert to pdf or kind a "screenshot" image then send.

+ Phong
Photo of Nathan CFD

Nathan CFD

  • 234 Points 100 badge 2x thumb
Hello Phong,

Thanks for following up!

Okay, I guess I'll have to convert to PDF first; I was hoping to avoid that.

Maybe a last question (maybe)... I noticed that when I was testing, that if I submitted more than FOUR tests per minute, they were blocked for "too many requests".  Once in production, I'm guessing the client will do 20 or 30 hits within a 5 minute window three or four times per day.  Since the system automatically queue's faxes, why is there a hit limit? And, is there any way to have that lifted?



Photo of Phong Vu

Phong Vu, Devangelist

  • 5,316 Points 5k badge 2x thumb
There must be something wrong here. The Fax endpoint rate limit is classified as "Heavy" and that means the rate limit is 10 requests per 60 seconds.

Can you double check to verify that it was throttled at 4 requests per minute in your case? You can print the header after each request to see the remain limit. e.g.
HTTP/1.1 200 OK
X-Rate-Limit-Group: light
X-Rate-Limit-Limit: 50
X-Rate-Limit-Remaining: 20
X-Rate-Limit-Window: 60
Photo of Nathan CFD

Nathan CFD

  • 234 Points 100 badge 2x thumb
Hi Phong, 

I finished out the app - had it convert the html to pdf, etc.  and I've tested it a few times under simulated production use and it seems fine.  I was getting locked out at four when I was testing the "out of the box" demo.  Maybe there was something in the demo sending multiple hits.  

I did discuss with client and they are concerned about the 10/60 limit.  They will most likely send faxes three to four times a day - 20 or 30 faxes per session sent at 1 fax every two or three seconds (however long it takes someone to click "send fax" for each order on the list).

Do you know of a way for RC to allow usage like that (more than 10/60 for brief periods)?  Or, do I need to create a custom "in-house" queue to collect their hits, then slowly send them to RC?
Photo of Phong Vu

Phong Vu, Devangelist

  • 5,316 Points 5k badge 2x thumb
Hi Nathan,

First of all, congrats for making the app work!

Yes, we can help customer case by case to increase the rate limit based on some business justification. Please move on to graduate your app to the production, run a few test to see the exact rate limit your app gets when sending Faxes.

Then send your request for increase rate limit with your app name to devsupport@ringcentral.com, where our support engineers can help you to set the app with higher rate limit.

+ Phong
Photo of Nathan CFD

Nathan CFD

  • 234 Points 100 badge 2x thumb
That's great, thanks Phong! I really appreciate your help over the last few days while I dialed it in, thank you very much for your help!
Photo of Nathan CFD

Nathan CFD

  • 234 Points 100 badge 2x thumb
I haven't used the API for three days; I did a test and the RESPONSE was "QUEUED", but the fax never hit the RC Call Log (and no fax came through) I've done a couple of dozen tests from the API and straight code - json()->messageStatus is always "QUEUED", but it's not going anywhere, it never hits the RC Call Log.  I've checked and the API Credentials are "Active"; there's been no change to my app.  Is there any way to get a "QUEUED" response from RC, but the data not sent?  
Photo of Tyler Long

Tyler Long, Official Rep

  • 9,718 Points 5k badge 2x thumb
Are you testing sandbox? I am afraid that it is an known issue. Let me double check.
Photo of Nathan CFD

Nathan CFD

  • 234 Points 100 badge 2x thumb
Hi Tyler, yes - testing sandbox. 
Photo of Tyler Long

Tyler Long, Official Rep

  • 9,718 Points 5k badge 2x thumb
We know this issue. It is tracked by an internal JIRA ticket. I have requested engineering team's attention. Hopefully it will be resolved soon. I will keep you updated.
Photo of Nathan CFD

Nathan CFD

  • 234 Points 100 badge 2x thumb
Thanks Tyler! Let me know.
Photo of Tyler Long

Tyler Long, Official Rep

  • 9,718 Points 5k badge 2x thumb
Nathan, issue fixed.
Photo of Nathan CFD

Nathan CFD

  • 234 Points 100 badge 2x thumb
Hi Tyler, thanks for following up! There are still issues on my end, unfortunately. The app is getting a "Fax Queued" response from RC, and the Outgoing Fax shows up in the Call Log of the Sandbox Account.  But, the fax never reaches the destination (which is the Fax Number of my RC Account). I haven't altered any code.  Could there still be a lingering issue?
Photo of Nathan CFD

Nathan CFD

  • 234 Points 100 badge 2x thumb
...and, the call log shows TWO faxes for each attempt, each four minutes apart. But, none ever reach their destination.  Any thoughts?
Photo of Phong Vu

Phong Vu, Devangelist

  • 5,316 Points 5k badge 2x thumb
Can you read the message-store and check the fax status to see if they were sent?
Photo of Nathan CFD

Nathan CFD

  • 234 Points 100 badge 2x thumb
Hi Phong, I'm not sure what you mean by "message-store".  I can check the Call Log of the Sandbox account - and they show up there.  How can I access the message store? 
Photo of Phong Vu

Phong Vu, Devangelist

  • 5,316 Points 5k badge 2x thumb
Message-store is another endpoint for accessing history with metadata and attachments of messaging. It include, SMS, MMS, Voicemail and Fax messages.

Check this tutorial

Can you also test to send a Fax page to my sandbox number +19165464387 to see if I would receive it.
Photo of Nathan CFD

Nathan CFD

  • 234 Points 100 badge 2x thumb
Hi Phong, I sent a test fax, Thanks
Photo of Nathan CFD

Nathan CFD

  • 234 Points 100 badge 2x thumb
Hi Phong, the "Result" of the fax to your Sandbox account is "Sent".  I sent one to my Sandbox account and it came through and the result says "Sent".  I am using my companies "official" 888 fax number to test - and, all of those the result says "Unknown" and they don't come through.

So, my app is apparently working since it's faxing to both mine and your Sandbox accounts.

I went through the call log history and the "Result" for all of the test faxes to my 888 fax number were "Sent" until the error 9 days ago.  Ever since then, all of the "Result" is "Unknown".

Did something happen during the downtime that  either:
1) Broke the ability to fax out to 888 or toll-free numbers
2) Broke the ability to fax from a Sandbox account to a "production" number?
Photo of Phong Vu

Phong Vu, Devangelist

  • 5,316 Points 5k badge 2x thumb
Yes, I've received the fax you sent on Friday. So it means your app and codes work well on the sandbox environment now.

For the other faxes you sent earlier. Probably, they failed due to some issues in the sandbox environment and they wont be recovered and that is why the result is as "Unknown".

Can you check to send to other real fax number or to the production number if you have one. You can also graduate your app and try on your production account to get rid of the sandbox limitations.
Photo of Nathan CFD

Nathan CFD

  • 234 Points 100 badge 2x thumb
Hi Phong, I set up a land-line fax and it came through fine. Maybe there's something wrong with my main RC fax number.  Thanks for helping me troubleshoot!