Difficulty using sp_OAMethod [MSXML2.ServerXMLHTTP] to post multipart/form-data - sql-server

Code attempts to post a multpart form to API service. which does not recognize it as multipart.
(Content should be multipart)
The request works fine in Postman, I think I could trouble shoot it if I could see the actual HTTP request being sent.
CREATE PROCEDURE [dbo].[test_QAAPI_attachments]
as
BEGIN
SET TEXTSIZE -1;
Declare #Object as Int;
DECLARE #hr int;
Declare #json as table(Json_Table nvarchar(max));
DECLARE #contentType VARCHAR(8000);
DECLARE #contentTypeForm VARCHAR(8000);
Declare #url as Varchar(2048);
Declare #errorDesc as nvarchar (max);
Declare #len as int;
DECLARE #resp int;
DECLARE #jsonText nvarchar(max);
DECLARE #authHeader as varchar(4000);
DECLARE #ret Int;
DECLARE #token Int;
DECLARE #responseText VARCHAR(8000);
DECLARE #runMode as varchar(5); -- run, test, train
SET #contentType = 'application/json';
SET #contentTypeForm = 'application/x-www-form-urlencoded';
DECLARE #moduleReference varchar(2);
DECLARE #formattedAccount varchar(21);
DECLARE #fileBinary as varbinary(max)
Declare #jsonReturned as varchar(max)
Set #errorDesc = 'No Errors'
SET #contentType = 'application/json';
set #url = 'https://qaapi71.auth.civicalg.com/main/api/v2/authority/login'
SET #jsonText =
'{
"userName": "apitest",
"password": "[REMOVED]"
}'
-- Getting the accessToken from Authority API...
Exec #hr=sp_OACreate 'MSXML2.ServerXMLHTTP', #Object OUT
EXEC #hr= sp_OAMethod #Object, 'open', NULL, 'post', #url, 'false'
EXEC sp_OAMethod #Object, 'SETRequestHeader', null, 'Content-Type', 'application/json'
EXEC sp_OAMethod #Object, 'send', null, #jsonText
EXEC sp_OAMethod #Object, 'responseText', #json OUT
INSERT into #json (Json_Table) exec sp_OAGetProperty #Object, 'responseText'
Select #authHeader = 'Bearer ' + f.accessToken
FROM OPENJSON(
(select * from #json), N'$.result')
WITH (
accessToken nvarchar(4000) N'$.accessToken'
) as f
Delete #json
DECLARE #formBody varchar(max);
set #url= 'https://qaapi71.auth.civicalg.com/main/api/v2/recordManagement/attachments'
-- text below copied directly from successful Postman http request...
SET #formBody='
----------------------------028844704192657132624492
Content-Disposition: form-data; name="apiVersion"
2
----------------------------028844704192657132624492
Content-Disposition: form-data; name="ModuleReference"
DD
----------------------------028844704192657132624492
Content-Disposition: form-data; name="FormattedAccount"
002.2020.00005653.001
----------------------------028844704192657132624492
Content-Disposition: form-data; name="ExternalDocumentType"
UPLOAD
----------------------------028844704192657132624492
Content-Disposition: form-data; name="Description"
some description
----------------------------028844704192657132624492
Content-Disposition: form-data; name="FileName"
test.jpg
----------------------------028844704192657132624492
Content-Disposition: form-data; name="FileUpload"; filename=""
----------------------------028844704192657132624492--'
-- final [--] indicates the end.
DECLARE #boundary as varchar(200)
SET #boundary='----------------------------028844704192657132624492'
DECLARE #L as varchar(20)
SET #L=CAST (len(#formBody) as varchar)
-- Open the connection.
EXEC #ret = sp_OACreate 'MSXML2.ServerXMLHTTP', #token OUT;
IF #ret <> 0 RAISERROR('Unable to open HTTP connection.', 20, 3);
-- Send the request.
EXEC #ret = sp_OAMethod #token, 'Open', null, 'POST', #Url, 'false';
EXEC #ret = sp_OAMethod #token, 'setRequestHeader', NULL, 'Authorization', #authHeader;
EXEC #ret = sp_OAMethod #token, 'setRequestHeader', NULL, 'Content-Length',#L;
EXEC #ret = sp_OAMethod #token, 'setRequestHeader', NULL, 'Content-Type','multipart/form-data','boundary',#boundary;
EXEC #ret = sp_OAMethod #token, 'send',NULL, #formBody;
EXEC sp_OAMethod #token, 'responseText', #responseText OUTPUT
INSERT into #json (Json_Table) exec sp_OAGetProperty #token, 'responseText'
select #formBody
select * from #json
END

Related

SOAP 1.1 request from t-sql

I have copied the code from setting soap request properties from T-sql and make some litle changes.
If soap version 1.2 the code works fine. My problem is that soap version 1.1 wants to load the PELTT01.wsdl file to work.
declare
#Url varchar(1024),
#HttpMethod varchar(10),
#ParamsValues varchar(1024),
#SoapAction varchar(8000),
#datefrom varchar(30),
#dateto varchar(30),
#sessionid as varchar(3000),
#xmlOut1 varchar(8000),
#RequestText as varchar(8000),
#wsdl as varchar(8000),
#responseHeader varchar(4000)
DECLARE #t table (ID int, strxml xml)
set #Url = 'http://212.205.47.226:9003'
set #HttpMethod = 'soap'
set #SoapAction = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:pel="/PELTT01">
<soapenv:Header/>
<soapenv:Body>
<pel:READ>
<pel:wpel_code>999999999</pel:wpel_code>
<pel:wpel_user>9999999</pel:wpel_user>
<pel:wpel_pass>9999999</pel:wpel_pass>
<pel:wpel_vg>ZK000000000GR</pel:wpel_vg>
<pel:wpel_ref>?</pel:wpel_ref>
<pel:wpel_flag>1</pel:wpel_flag>
</pel:READ>
</soapenv:Body>
</soapenv:Envelope>'
declare #obj int
,#response varchar(8000)
,#responseText varchar(8000)
,#status varchar(50)
,#statusText varchar(1024)
,#method varchar(10) = (case when #HttpMethod in ('soap','SOAP') then 'POST' else #HttpMethod end)
exec sp_OACreate 'MSXML2.ServerXMLHTTP', #obj out
exec sp_OAMethod #obj, 'Open', null, #method, #Url, 'false'
exec sp_OAMethod #obj, 'setRequestHeader', null, 'Content-Type', 'text/xml; charset=utf-8'
exec sp_OAMethod #obj, 'setRequestHeader', null, 'SOAPAction', #SoapAction
exec sp_OAMethod #obj, 'send', null, #SoapAction
exec sp_OAGetProperty #obj, 'responseText', #responseText out
EXECUTE sp_OAMethod #Obj, 'getAllResponseHeaders', #responseHeader OUT
exec sp_OAGetProperty #obj, 'Status', #status out
exec sp_OADestroy #obj
SELECT #status 'status', #responseText 'responsetext', #responseHeader 'Response Header'

Call formsite API from SQL Server

I am trying to call Formsite API from SQL Server to get the data but I am unable to get the data it is returning me null, below is the script which I am using to get the data.
This is my API link (dummy link):
https://fs29.formsite.com/api/v2/xyz/forms/form14/
Access Token (also dummy):
myaccesskey
And the script which I am using is
DECLARE #authHeader NVARCHAR(64);
DECLARE #contentType NVARCHAR(64);
DECLARE #postData NVARCHAR(MAX);
DECLARE #responseText NVARCHAR(MAX);
DECLARE #responseXML NVARCHAR(MAX);
DECLARE #ret INT;
DECLARE #status NVARCHAR(32);
DECLARE #statusText NVARCHAR(32);
DECLARE #token INT;
DECLARE #url NVARCHAR(256);
-- Set Authentications
SET #authHeader = 'Bearer **mykey**';
SET #contentType = 'application/json';
SET #url = 'https://fs29.formsite.com/api/v2/GwYV/forms/form14/' -- Dummy api url
EXEC #ret = sp_OACreate 'MSXML2.XMLHTTP', #token OUT;
SELECT #token
IF #ret <> 0
RAISERROR('Unable to open HTTP connection.', 10, 1);
-- build a request
EXEC #ret = sp_OAMethod #token, 'open', NULL, 'GET', #url, 'false';
EXEC #ret = sp_OAMethod #token, 'setRequestHeader', NULL, 'Authorization', #authHeader;
EXEC #ret = sp_OAMethod #token, 'setRequestHeader', NULL, 'Content-type', #contentType;
EXEC #ret = sp_OAMethod #token, 'setRequestHeader', NULL, 'Cache-Control', 'no-cache' ;
EXEC #ret = sp_OAMethod #token, 'send'
-- Handle response
EXEC #ret = sp_OAGetProperty #token, 'status', #status OUT;
EXEC #ret = sp_OAGetProperty #token, 'statusText', #statusText OUT;
EXEC #ret = sp_OAGetProperty #token, 'responseText', #responseText OUT;
-- Print responses
SELECT #responseText
PRINT 'Status: ' + #status + ' (' + #statusText + ')';
PRINT 'Response text: ' + #responseText;

Calling API from SQL Server [Issue]

I am working with API and MSSQL. I need to call an API from SQL Server. But On execution, its response is null. Can anyone list errors if some in the queries?
The API responds but the issue is it shows error in Authentication while I'm using exact correct credentials. It's a POST API.
This is the only way I found correct on browsing the whole a day on Google. Can someone help or list errors?
DECLARE #authHeader NVARCHAR(MAX)= 'Basic XXXXXXXXXXXXXXXXXXXXXXXXXXX-XXXXXXXXXXXXXXXX'
DECLARE #contentType NVARCHAR(64) = 'application/json; charset=utf-8'
DECLARE #appVersion NVARCHAR(20) = '3.2.1'
DECLARE #appkey NVARCHAR(50) = 'XXXXXXXXXXXXXXXXXXXXXXXXXXX'
DECLARE #deviceId NVARCHAR(50) = 'XXXXXXXXXXXXXXXXXXXXXXXXXXX'
DECLARE #deviceType int = 1;
DECLARE #language int = 1;
DECLARE #status NVARCHAR(32);
DECLARE #statusText NVARCHAR(32);
DECLARE #Body as VARCHAR(8000) =
'{
"itemId":"XXXXXXXXXXXXXXXXXXXXXXX",
"itemType":XXXXXXXXXXXXX,
"liked":"true"
}'
DECLARE #responseText NVARCHAR(2000);
DECLARE #token INT;
DECLARE #url NVARCHAR(256) = 'https://api-stage.testapp.com/v4/test';
Exec sp_OACreate 'MSXML2.ServerXMLHTTP', #token OUT;
EXEC sp_OAMethod #token, 'open', NULL, 'POST', #url, 'false'
EXEC sp_OAMethod #token, 'setRequestHeader', NULL, 'Authentication', #authHeader
EXEC sp_OAMethod #token, 'setRequestHeader', NULL, 'Content-type', #contentType
EXEC sp_OAMethod #token, 'setRequestHeader', NULL, 'appVersion', #appVersion
EXEC sp_OAMethod #token, 'setRequestHeader', NULL, 'appkey', #appkey
EXEC sp_OAMethod #token, 'setRequestHeader', NULL, 'deviceId', #deviceId
EXEC sp_OAMethod #token, 'setRequestHeader', NULL, 'devicetype', #deviceType
EXEC sp_OAMethod #token, 'setRequestHeader', NULL, 'language', #language
EXEC sp_OAMethod #token, 'send', null
Exec sp_OAMethod #token, 'setRequestBody', null, 'Body', #body
EXEC sp_OAGetProperty #token, 'status', #status OUT;
EXEC sp_OAGetProperty #token, 'statusText', #statusText OUT;
EXEC sp_OAGetProperty #token, 'responseText', #responseText OUT;
PRINT 'Status: ' + #status + ' (' + #statusText + ')';
PRINT 'Response text: ' + #responseText;
Select #ResponseText as Response

SQL Server - Call a REST API using a virtual CSV

I have the code below that makes a request to an API and works fine, using JSON content-type to another endpoint.
DECLARE #Object AS int;
DECLARE #ResponSEText AS Varchar(8000);
DECLARE #Token AS Varchar(8000);
DECLARE #xmltest AS Varchar(8000);
DECLARE #hResult AS int
DECLARE #source varchar(255), #desc varchar(255)
DECLARE #LocationId varchar(25);
DECLARE #Body AS varchar(8000) = '{
"UserName": "test.integration12",
"Password": "Urgent123"
}'
--EXEC sp_OACREATE 'MSXML2.XMLHTTP', #Object OUT;
EXEC sp_OACREATE 'MSXML2.ServerXMLHttp', #Object OUT;
EXEC sp_OAMethod #Object, 'open', NULL, 'POST',
'https://urgentcargus.azure-api.net/api/LoginUser', 'false'
EXEC sp_OAMethod #Object, 'SETRequestHeader', null, 'Content-Type', 'application/json'
DECLARE #len int
SET #len = len(#body)
EXEC sp_OAMethod #Object, 'SETRequestHeader', null, 'Ocp-Apim-Subscription-Key','4f82f9d067914287979884f920d86ffb'
EXEC sp_OAMethod #Object, 'SETRequestHeader', null, 'Ocp-Apim-Trace:true'
EXEC sp_OAMethod #Object, 'SETRequestHeader', null, 'Content-Length', #len
EXEC sp_OAMethod #Object, 'SETRequestBody', null, 'Body', #body
EXEC sp_OAMethod #Object, 'sEND', null, #body
EXEC sp_OAMethod #Object, 'responSEText', #ResponSEText OUTPUT
I would like to adapt the code above in order to send the values of the parameters like a virtual csv file instead of an XML or JSON protocol with the appropriate format to another endpoint using a different content-type and I cannot figure it out how to do this:
DECLARE #Object AS int;
DECLARE #ResponSEText AS Varchar(8000);
DECLARE #Token AS Varchar(8000);
DECLARE #xmltest AS Varchar(8000);
DECLARE #hResult AS int
DECLARE #source varchar(255), #desc varchar(255)
DECLARE #LocationId varchar(25);
DECLARE #Body AS varchar(8000) = -- here should go the parameters which are username, clientid, password and file (where file has to be the virtual CSV file with the columns and rows separated by "|"
EXEC sp_OACREATE 'MSXML2.ServerXMLHttp', #Object OUT;
EXEC sp_OAMethod #Object, 'open', NULL, 'POST',
'https://www.selfawb.ro/import_awb_integrat.php', 'false'
EXEC sp_OAMethod #Object, 'SETRequestHeader', null, 'Content-Type', 'text/xml'
EXEC sp_OAMethod #Object, 'SETRequestHeader', null, 'Ocp-Apim-Trace:true'
EXEC sp_OAMethod #Object, 'SETRequestBody', null, 'Body', #body
EXEC sp_OAMethod #Object, 'sEND', null, #body
EXEC sp_OAMethod #Object, 'responSEText', #ResponSEText OUTPUT
I asked the owner of the API and they provided to me an example as shown in the print screen below:
Example
Does anyone can give me a hint or a hand? Thanks
If you want to send a virtual file, e.g. a file that you generate in memory then send as an attachment as part of the POST, then you would just need include the csv text as part of the post as an attachment with a filename. Try using PostMan to set this up using an actual csv file and analyze the POST to view how to format the csv text to be serialized over the wire as a csv file attachment.
Otherwise if you are using SQL 2016 or above, you can parse csv text using STRING_SPLIT. Hope this helps.
DECLARE #CsvParams NVARCHAR(256) =
'UserName,test.integration12,'
+ 'Password,Urgent123'
SELECT value FROM STRING_SPLIT(#CsvParams, ',');
The code above produces a table with the separated values:
More on STRING_SPLIT here:
STRING_SPLIT (Transact-SQL)

Call Rest TaxJar API from SQL Server Code

I'm working on calling TaxJar API from SQL Server, I saw some articles like:
calling an api from sql server stored-procedure
but unfirtunately I did know how to pass a Token value to the call
Here is a sample of the Get Call I'm making in Poestman:
https://api.taxjar.com/v2/rates/90404-3370
Token: XXXXXXXXXXX
Postman sample
anythoyghts how to do it please?
Thanks
here is a code sample of what i've done so far:
DECLARE
#Result INT,
#Text nVARCHAR(max),
#Obj int,
#HTTPStatus smallint,
#URL Varchar(MAX)
DECLARE #output varchar(255);
DECLARE #hr int;
DECLARE #source varchar(255);
DECLARE #description varchar(255);
SET #Text = '-H "Authorization: Bearer [TOKEN VALUE]'
SET #Url = 'https://api.taxjar.com/v2/rates/90404-3370 \'
EXEC #Result = sp_OACreate 'WinHttp.WinHttpRequest.5.1', #Obj OUT
EXEC #Result = sp_OAMethod #Obj, 'open', NULL, 'GET', #URL, false
EXEC #Result = sp_OAMethod #Obj, 'setRequestHeader', NULL, 'Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept'
EXEC #Result = sp_OAMethod #Obj, 'setRequestHeader', NULL, 'Access-Control-Allow-Origin', '*'
EXEC #Result = sp_OAMethod #Obj, 'setRequestHeader', NULL, 'Content-Type', 'application/json'
EXEC #Result = sp_OAMethod #Obj, send, NULL, #Text
EXEC #Result = sp_OAGetProperty #Obj, 'status', #HTTPStatus OUT
PRINT #Result
EXEC #Result = sp_OAGetErrorInfo #obj, #source OUT, #description OUT;
IF #Result = 0
BEGIN
SET #output = ' Source: ' + #source + CHAR(13) + CHAR(10)
SET #output = #output + ' Description: ' + #description
PRINT 'OLE Automation Error Information';
PRINT #output
END
================================================================
UPDATE:
HERE IS MY SQL CODE AND IT WORKED PARTIALLY
DECLARE #authHeader NVARCHAR(64);
DECLARE #contentType NVARCHAR(64);
DECLARE #postData NVARCHAR(MAX);
DECLARE #responseText NVARCHAR(MAX);
DECLARE #responseXML NVARCHAR(MAX);
DECLARE #ret INT;
DECLARE #status NVARCHAR(32);
DECLARE #statusText NVARCHAR(32);
DECLARE #token INT;
DECLARE #url NVARCHAR(256);
-- Set Authentications
SET #authHeader = 'Bearer [TOKEN VALUE]';
SET #contentType = 'application/json';
SET #url = 'https://api.taxjar.com/v2/summary_rates'
EXEC #ret = sp_OACreate 'WinHttp.WinHttpRequest.5.1', #token OUT;
IF #ret <> 0 RAISERROR('Unable to open HTTP connection.', 10, 1);
-- build a request
EXEC #ret = sp_OAMethod #token, 'open', NULL, 'GET', #url, 'false';
EXEC #ret = sp_OAMethod #token, 'setRequestHeader', NULL, 'Authorization', #authHeader;
EXEC #ret = sp_OAMethod #token, 'setRequestHeader', NULL, 'Content-type', #contentType;
EXEC #ret = sp_OAMethod #token, 'setRequestHeader', NULL, 'Cache-Control', 'no-cache' ;
EXEC #ret = sp_OAMethod #token, 'send'
-- Handle responce
EXEC #ret = sp_OAGetProperty #token, 'status', #status OUT;
EXEC #ret = sp_OAGetProperty #token, 'statusText', #statusText OUT;
EXEC #ret = sp_OAGetProperty #token, 'responseText', #responseText OUT;
-- Print responec
PRINT 'Status: ' + #status + ' (' + #statusText + ')';
PRINT 'Response text: ' + #responseText;
THE URL IS RETURNING NOTHING IN SQL BUT IN POSTMAN IT RETURNS VALUES!
Try using this CLR Stored proc https://github.com/geral2/SQL-APIConsumer
DECLARE #Result AS TABLE
(
Token VARCHAR(MAX)
)
INSERT INTO #Result
exec [dbo].[APICaller_POST]
#URL = 'http://localhost:5000/api/auth/login'
,#BodyJson = '{"Username":"gdiaz","Password":"password"}'
DECLARE #Token AS VARCHAR(MAX)
SELECT TOP 1 #Token = CONCAT('Bearer ',Json.Token)
FROM #Result
CROSS APPLY ( SELECT value AS Token FROM OPENJSON(Result)) AS [Json]
EXEC [dbo].[APICaller_GETAuth]
#URL = 'http://localhost:5000/api/values'
, #Token = #Token

Resources