├── .gitignore ├── media └── OneDrive-Explorer.png ├── README.md ├── app.json ├── src ├── OneDriveFile.Table.al ├── GraphAPIHelper.Codeunit.al └── OneDriveExplorer.Page.al └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | .alpackages 2 | .vscode 3 | *.app -------------------------------------------------------------------------------- /media/OneDrive-Explorer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msnraju/OneDrive-Integration/HEAD/media/OneDrive-Explorer.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # How to use Microsoft Graph API in Business Central 2 | This repository contains sample code to get list of files and folders from OneDrive using Microsoft Graph API. 3 | This repository contains a sample code to get AuthToken using OAuth2. 4 | 5 | ## OneDrive folders in a NAV Page 6 | ![OneDrive Explorer](/media/OneDrive-Explorer.png) 7 | 8 | To learn how to do this, to know more details goto [www.msnJournals.com](https://www.msnjournals.com/post/how-to-use-microsoft-graph-api-in-business-central) 9 | 10 | 11 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "8c0a5b54-ad6e-4cb8-b61d-830e772a3e76", 3 | "name": "OneDrive-Integration", 4 | "publisher": "Default publisher", 5 | "version": "1.0.0.0", 6 | "brief": "", 7 | "description": "", 8 | "privacyStatement": "", 9 | "EULA": "", 10 | "help": "", 11 | "url": "", 12 | "logo": "", 13 | "dependencies": [ 14 | { 15 | "id": "63ca2fa4-4f03-4f2b-a480-172fef340d3f", 16 | "publisher": "Microsoft", 17 | "name": "System Application", 18 | "version": "16.0.0.0" 19 | }, 20 | { 21 | "id": "437dbf0e-84ff-417a-965d-ed2bb9650972", 22 | "publisher": "Microsoft", 23 | "name": "Base Application", 24 | "version": "16.0.0.0" 25 | } 26 | ], 27 | "screenshots": [], 28 | "platform": "16.0.0.0", 29 | "idRanges": [ 30 | { 31 | "from": 50100, 32 | "to": 50149 33 | } 34 | ], 35 | "contextSensitiveHelpUrl": "https://OneDrive-Integration.com/help/", 36 | "showMyCode": true, 37 | "runtime": "5.0" 38 | } -------------------------------------------------------------------------------- /src/OneDriveFile.Table.al: -------------------------------------------------------------------------------- 1 | table 50115 "OneDrive File" 2 | { 3 | DataClassification = ToBeClassified; 4 | 5 | fields 6 | { 7 | field(1; Id; Text[100]) 8 | { 9 | DataClassification = EndUserIdentifiableInformation; 10 | } 11 | field(2; Name; Text[250]) 12 | { 13 | DataClassification = EndUserIdentifiableInformation; 14 | } 15 | field(3; Size; Integer) 16 | { 17 | DataClassification = EndUserIdentifiableInformation; 18 | } 19 | field(4; WebUrl; Text[500]) 20 | { 21 | DataClassification = EndUserIdentifiableInformation; 22 | } 23 | field(5; "Is Folder"; Boolean) 24 | { 25 | DataClassification = EndUserIdentifiableInformation; 26 | } 27 | field(6; "Last Modified DateTime"; DateTime) 28 | { 29 | DataClassification = EndUserIdentifiableInformation; 30 | } 31 | } 32 | 33 | keys 34 | { 35 | key(PK; Id) 36 | { 37 | Clustered = true; 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 MSN Raju 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/GraphAPIHelper.Codeunit.al: -------------------------------------------------------------------------------- 1 | codeunit 50115 "Graph API Helper" 2 | { 3 | var 4 | OAuth2: Codeunit OAuth2; 5 | ClientIdTxt: Label '96e2efa1-a6fb-4f04-97d9-1f9ac9c15917', Locked = true; 6 | ClientSecret: Label '44Qi99bD4EC4S27~_.5htAp1o_lLd7tfBg', Locked = true; 7 | ResourceUrlTxt: Label 'https://graph.microsoft.com', Locked = true; 8 | OAuthAuthorityUrlTxt: Label 'https://login.microsoftonline.com/67c5a58a-7424-4d4d-b6c2-ddc89830cf74/oauth2/authorize', Locked = true; 9 | RedirectURLTxt: Label 'http://localhost:8080/BC160/OAuthLanding.htm', Locked = true; 10 | OneDriveRootQueryUri: Label 'https://graph.microsoft.com/v1.0/me/drive/root/children', Locked = true; 11 | 12 | procedure GetAccessToken(): Text 13 | var 14 | PromptInteraction: Enum "Prompt Interaction"; 15 | AccessToken: Text; 16 | AuthCodeError: Text; 17 | begin 18 | OAuth2.AcquireTokenByAuthorizationCode( 19 | ClientIdTxt, 20 | ClientSecret, 21 | OAuthAuthorityUrlTxt, 22 | RedirectURLTxt, 23 | ResourceURLTxt, 24 | PromptInteraction::Consent, 25 | AccessToken, 26 | AuthCodeError); 27 | 28 | if (AccessToken = '') or (AuthCodeError <> '') then 29 | Error(AuthCodeError); 30 | 31 | exit(AccessToken); 32 | end; 33 | 34 | procedure GetOneDriveFiles(): JsonObject 35 | var 36 | Client: HttpClient; 37 | RequestMessage: HttpRequestMessage; 38 | ResponseMessage: HttpResponseMessage; 39 | JsonResponse: JsonObject; 40 | AccessToken: Text; 41 | JsonContent: Text; 42 | begin 43 | AccessToken := GetAccessToken(); 44 | 45 | RequestMessage.Method('GET'); 46 | RequestMessage.SetRequestUri(OneDriveRootQueryUri); 47 | Client.DefaultRequestHeaders().Add('Authorization', StrSubstNo('Bearer %1', AccessToken)); 48 | Client.DefaultRequestHeaders().Add('Accept', 'application/json'); 49 | 50 | if Client.Send(RequestMessage, ResponseMessage) then 51 | if ResponseMessage.HttpStatusCode() = 200 then begin 52 | ResponseMessage.Content.ReadAs(JsonContent); 53 | JsonResponse.ReadFrom(JsonContent); 54 | exit(JsonResponse); 55 | end; 56 | end; 57 | } -------------------------------------------------------------------------------- /src/OneDriveExplorer.Page.al: -------------------------------------------------------------------------------- 1 | page 50110 "OneDrive Explorer" 2 | { 3 | PageType = List; 4 | ApplicationArea = All; 5 | UsageCategory = Administration; 6 | SourceTable = "OneDrive File"; 7 | SourceTableTemporary = true; 8 | Editable = false; 9 | 10 | layout 11 | { 12 | area(content) 13 | { 14 | repeater(Control1) 15 | { 16 | ShowCaption = false; 17 | field("Name"; Rec.Name) 18 | { 19 | ApplicationArea = All; 20 | 21 | trigger OnDrillDown() 22 | begin 23 | if WebUrl <> '' then 24 | Hyperlink(WebUrl); 25 | end; 26 | } 27 | field("Is Folder"; Rec."Is Folder") 28 | { 29 | ApplicationArea = All; 30 | } 31 | field("Size"; Rec.Size) 32 | { 33 | ApplicationArea = All; 34 | } 35 | field("Last Modified DateTime"; Rec."Last Modified DateTime") 36 | { 37 | ApplicationArea = All; 38 | } 39 | } 40 | } 41 | } 42 | 43 | actions 44 | { 45 | area(Processing) 46 | { 47 | action("Get OneDrive Root") 48 | { 49 | ApplicationArea = All; 50 | 51 | trigger OnAction() 52 | var 53 | TempOneDriveFile: Record "OneDrive File" temporary; 54 | GraphAPIHelper: Codeunit "Graph API Helper"; 55 | JContent: JsonObject; 56 | JToken: JsonToken; 57 | begin 58 | JContent := GraphAPIHelper.GetOneDriveFiles(); 59 | if JContent.Get('value', JToken) then 60 | ReadFolders(JToken.AsArray(), TempOneDriveFile); 61 | 62 | Rec.Copy(TempOneDriveFile, true); 63 | Rec.FindFirst(); 64 | end; 65 | } 66 | } 67 | } 68 | 69 | local procedure ReadFolders(JsonFolders: JsonArray; var TempOneDriveFile: Record "OneDrive File" temporary) 70 | var 71 | JToken: JsonToken; 72 | 73 | begin 74 | foreach JToken in JsonFolders do 75 | ReadFolder(JToken.AsObject(), TempOneDriveFile); 76 | end; 77 | 78 | local procedure ReadFolder(JsonFolder: JsonObject; var TempOneDriveFile: Record "OneDrive File" temporary) 79 | var 80 | JObject: JsonObject; 81 | JToken, JPropToken : JsonToken; 82 | begin 83 | TempOneDriveFile.Init(); 84 | if JsonFolder.Get('id', JToken) then 85 | TempOneDriveFile.Id := JToken.AsValue().AsText(); 86 | if JsonFolder.Get('name', JToken) then 87 | TempOneDriveFile.Name := JToken.AsValue().AsText(); 88 | if JsonFolder.Get('webUrl', JToken) then 89 | TempOneDriveFile.WebUrl := JToken.AsValue().AsText(); 90 | if JsonFolder.Get('webUrl', JToken) then 91 | TempOneDriveFile.WebUrl := JToken.AsValue().AsText(); 92 | if JsonFolder.Get('size', JToken) then 93 | TempOneDriveFile.Size := JToken.AsValue().AsInteger(); 94 | if JsonFolder.Get('lastModifiedDateTime', JToken) then 95 | TempOneDriveFile."Last Modified DateTime" := JToken.AsValue().AsDateTime(); 96 | if JsonFolder.Get('folder', JPropToken) then 97 | TempOneDriveFile."Is Folder" := true; 98 | TempOneDriveFile.Insert; 99 | end; 100 | } 101 | --------------------------------------------------------------------------------