Extending Electronic Reporting Destinations: Integration with OneDrive (III)

On August 10, 2024, I realized there was a mistake in the SaveField method of the TST2_OneDriveERDest_OneDrive class related to the parameters. This issue has now been fixed.

In this final post of the series, I’m going to explain how to send files to OneDrive. Since I’ve implemented this functionality in a separate class, it’s more independent from the ER destinations. This is intentional because we may want to reuse the class for other developments. If you are extending destinations that aren’t for OneDrive but still use a REST API, this approach may be helpful.

We’ll create two classes: one to help deserialize the response containing the token, and another to communicate with the API.

When deserializing, we only need the token value from the JSON response:

[DataContract]
class TST2_OneDriveApi_RefreshTokenJson
{    
    str accessToken;

    [DataMember("access_token")]
    public str parmaccessToken(str _accessToken = accessToken)
    {
        accessToken = _accessToken;
        return accessToken;
    }

}

The communication class will have two methods: one to retrieve the token and another to send the files.

class TST2_OneDriveAPI
{
    // The token and connection record will have class-level scope
    private TST2_OneDriveCon oneDriveCon;
    private str token;

    // When creating a new instance of the class,
    // it will automatically find the connection record and retrieve the token.
    public void new(str _connectionTableId)
    {
        oneDriveCon = TST2_OneDriveCon::find(_connectionTableId);
        token = this.getToken();        
    }

    public str getToken()
    {
        // Define the endpoint URL
        str url = "https://login.microsoftonline.com/consumers/oauth2/v2.0/token";
    
        // Define the parameters
        str grant_type = "refresh_token";
        str client_id = oneDriveCon.AppClientId;
        str client_secret = oneDriveCon.TST2_AppSecretEdit(false,"");
        str response_type = "code";
        str response_mode = "query";
        str scope = "https://graph.microsoft.com/.default";
        str refresh_token = oneDriveCon.TST2_RefreshTokenEdit(false,"");

        // Create the form encoded content
        str postData = strFmt(
            "grant_type=%1&client_id=%2&client_secret=%3&response_type=%4&response_mode=%5&scope=%6&refresh_token=%7",
                          grant_type, client_id, client_secret, response_type, response_mode, scope, refresh_token);

        // Initialize the HttpClient
        System.Net.Http.HttpClient httpClient = new System.Net.Http.HttpClient();
        System.Net.Http.HttpContent content = new System.Net.Http.StringContent(
            postData, System.Text.Encoding::UTF8, "application/x-www-form-urlencoded");

        // Send the request and get the response
        System.Net.Http.HttpResponseMessage response = httpClient.PostAsync(url, content).Result;

        // Read the response content
        str responseContent = response.Content.ReadAsStringAsync().Result;

        TST2_OneDriveApi_RefreshTokenJson xppObject = FormJsonSerializer::deserializeObject(
                                                        classNum(TST2_OneDriveApi_RefreshTokenJson),
                                                        responseContent);
        
        //Returns the token parameter from the deserialized object
        return xppObject.parmaccessToken();

    }

    // Sends the file from the stream to OneDrive
    public void sendFile(System.IO.Stream _stream  , str _folderId, str _filename)
    {
        str url = strFmt("https://graph.microsoft.com/v1.0/me/drive/items/%1:/%2:/content", _folderId, _filename);      

        // Authorization header
        str headerKey = "Authorization";
        str headerValue = "Bearer " + token;

        // Create the request
        System.Net.WebRequest request = System.Net.WebRequest::Create(url);
        request.Method = "PUT";
        request.ContentType = "application/octet-stream";
        
        // Add the authorization header
        System.Net.WebHeaderCollection headers = request.Headers;
        headers.Add(headerKey, headerValue);

        // Write the binary content to the request stream
        System.IO.Stream requestStream = request.GetRequestStream();
        _stream.CopyTo(requestStream);
        requestStream.Close();
        _stream.Close();

        // Get the response from the API
        System.Net.HttpWebResponse response = request.GetResponse() as System.Net.HttpWebResponse;
    }
}

Now, when creating a new file with this destination, the file should be saved in the configured OneDrive folder:


Posted

in

, , , ,

by

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *