question

nathan-cfd15565 avatar image
nathan-cfd15565 asked Byrne Reese edited

PHP SDK Fax Permission Error

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}

sdk
1 |3000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

Phong Vu avatar image
Phong Vu answered
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;   
}
1 |3000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

nathan-cfd15565 avatar image
nathan-cfd15565 answered
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                  (                  )            )   
)
1 |3000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

nathan-cfd15565 avatar image
nathan-cfd15565 answered Tyler Liu commented
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.
3 comments
1 |3000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

Phong Vu avatar image Phong Vu ♦♦ commented ·
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.
0 Likes 0 ·
nathan-cfd15565 avatar image nathan-cfd15565 commented ·
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?
0 Likes 0 ·
Tyler Liu avatar image Tyler Liu ♦ commented ·
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.
0 Likes 0 ·
Tyler Liu avatar image
Tyler Liu answered
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.
1 |3000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

nathan-cfd15565 avatar image
nathan-cfd15565 answered
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;" />

1 |3000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

Phong Vu avatar image
Phong Vu answered
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
1 |3000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

nathan-cfd15565 avatar image
nathan-cfd15565 answered nathan-cfd15565 commented
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?



19 comments
1 |3000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

Phong Vu avatar image Phong Vu ♦♦ commented ·

Hi Nathan,


First of all, congrats for making the app work!


Yes, we can help customers 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 tests to see the exact rate limit your app gets when sending Faxes.


Then send your request for increase rate limit with your app name on a support ticket, where our support engineers can help you to set the app with higher rate limit.


+ Phong

1 Like 1 ·
Phong Vu avatar image Phong Vu ♦♦ commented ·
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.
1 Like 1 ·
Phong Vu avatar image Phong Vu ♦♦ commented ·
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
0 Likes 0 ·
nathan-cfd15565 avatar image nathan-cfd15565 commented ·
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?



0 Likes 0 ·
nathan-cfd15565 avatar image nathan-cfd15565 commented ·
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!
0 Likes 0 ·
Show more comments

Developer sandbox tools

Using the RingCentral Phone for Desktop, you can dial or receive test calls, send and receive test SMS or Fax messages in your sandbox environment.

Download RingCentral Phone for Desktop:

Tip: switch to the "sandbox mode" before logging in the app:

  • On MacOS: press "fn + command + f2" keys
  • On Windows: press "Ctrl + F2" keys