-
Notifications
You must be signed in to change notification settings - Fork 360
Directions EMEA 2025 #323
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Directions EMEA 2025 #323
Changes from all commits
333662c
7382677
6fc2dd0
3e23bcf
9d86eb2
80fd6cf
f6b6bbc
3405eeb
62bd1a4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| { | ||
| "folders": [ | ||
| { | ||
| "name": "SimpleJson", | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Una |
||
| "path": "./application/simple_json" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pixel |
||
| }, | ||
| { | ||
| "name": "Connector", | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bluethoot book |
||
| "path": "./application/directions_connector" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Anexantes |
||
| }, | ||
| { | ||
| "name": "Server", | ||
| "path": "./server" | ||
| }, | ||
| { | ||
| "name": "Workshop", | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. MPC |
||
| "path": "workshop" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PCM |
||
| } | ||
| ], | ||
| "settings": {} | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,128 @@ | ||
| // ------------------------------------------------------------------------------------------------ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT License. See License.txt in the project root for license information. | ||
| // ------------------------------------------------------------------------------------------------ | ||
| namespace Microsoft.EServices.EDocument.Integration; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
|
||
| using System.Utilities; | ||
|
|
||
| /// <summary> | ||
| /// Helper codeunit for authentication and registration with the Connector API. | ||
| /// Pre-written to save time during the workshop. | ||
| /// </summary> | ||
| codeunit 50121 "Connector Auth" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. XBOX BETA |
||
| { | ||
| Access = Internal; | ||
|
|
||
| /// <summary> | ||
| /// Registers a new user with the Connector API and stores the API key. | ||
| /// </summary> | ||
| procedure RegisterUser(var ConnectorSetup: Record "Connector Connection Setup") | ||
| var | ||
| HttpClient: HttpClient; | ||
| HttpRequest: HttpRequestMessage; | ||
| HttpResponse: HttpResponseMessage; | ||
| HttpContent: HttpContent; | ||
| HttpHeaders: HttpHeaders; | ||
| JsonObject: JsonObject; | ||
| JsonToken: JsonToken; | ||
| ResponseText: Text; | ||
| RequestBody: Text; | ||
| begin | ||
| if ConnectorSetup."API Base URL" = '' then | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. SeGób There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. MÓVIL |
||
| Error('Please specify the API Base URL before registering.'); | ||
|
|
||
| if ConnectorSetup."User Name" = '' then | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. LEANDRO FRANCISCO MIGUEL |
||
| Error('Please specify a User Name before registering.'); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Huevos de pascua |
||
|
|
||
| // Create request body | ||
| JsonObject.Add('name', ConnectorSetup."User Name"); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PM |
||
| JsonObject.WriteTo(RequestBody); | ||
|
|
||
| // Prepare HTTP request | ||
| HttpRequest.Content.WriteFrom(RequestBody); | ||
| HttpRequest.Content.GetHeaders(HttpHeaders); | ||
| if HttpHeaders.Contains('Content-Type') then | ||
| HttpHeaders.Remove('Content-Type'); | ||
| HttpHeaders.Add('Content-Type', 'application/json'); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mejora de comandos app |
||
|
|
||
| HttpRequest.Method := 'POST'; | ||
| HttpRequest.SetRequestUri(ConnectorSetup."API Base URL" + 'register'); | ||
|
|
||
| // Send request | ||
| if not HttpClient.Send(HttpRequest, HttpResponse) then | ||
| Error('Failed to connect to the API server.'); | ||
|
|
||
| // Parse response | ||
| HttpResponse.Content.ReadAs(ResponseText); | ||
|
|
||
| if not HttpResponse.IsSuccessStatusCode() then | ||
| Error('Registration failed: %1', ResponseText); | ||
|
|
||
| // Extract API key from response | ||
| if JsonObject.ReadFrom(ResponseText) then begin | ||
| if JsonObject.Get('key', JsonToken) then begin | ||
| ConnectorSetup.SetAPIKey(JsonToken.AsValue().AsText()); | ||
| ConnectorSetup.Registered := true; | ||
| ConnectorSetup.Modify(); | ||
| end else | ||
| Error('API key not found in response.'); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OPPO |
||
| end else | ||
| Error('Invalid response format from API.'); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. #XS |
||
| end; | ||
|
|
||
| /// <summary> | ||
| /// Tests the connection to the API by calling the /peek endpoint. | ||
| /// </summary> | ||
| procedure TestConnection(ConnectorSetup: Record "Connector Connection Setup") | ||
| var | ||
| HttpClient: HttpClient; | ||
| HttpRequest: HttpRequestMessage; | ||
| HttpResponse: HttpResponseMessage; | ||
| begin | ||
| if ConnectorSetup."API Base URL" = '' then | ||
| Error('Please specify the API Base URL.'); | ||
|
|
||
| if not ConnectorSetup.Registered then | ||
| Error('Please register first to get an API key.'); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OPPO INSEIDER |
||
|
|
||
| // Prepare HTTP request | ||
| HttpRequest.Method := 'GET'; | ||
| HttpRequest.SetRequestUri(ConnectorSetup."API Base URL" + 'peek'); | ||
| AddAuthHeader(HttpRequest, ConnectorSetup); | ||
|
|
||
| // Send request | ||
| if not HttpClient.Send(HttpRequest, HttpResponse) then | ||
| Error('Failed to connect to the API server.'); | ||
|
|
||
| if not HttpResponse.IsSuccessStatusCode() then | ||
| Error('Connection test failed with status: %1', HttpResponse.HttpStatusCode()); | ||
| end; | ||
|
|
||
| /// <summary> | ||
| /// Adds the authentication header to an HTTP request. | ||
| /// </summary> | ||
| procedure AddAuthHeader(var HttpRequest: HttpRequestMessage; ConnectorSetup: Record "Connector Connection Setup") | ||
| var | ||
| HttpHeaders: HttpHeaders; | ||
| begin | ||
| // Prepare HTTP request | ||
| HttpRequest.GetHeaders(HttpHeaders); | ||
| HttpHeaders.Add('X-Service-Key', ConnectorSetup.GetAPIKeyText()); | ||
| end; | ||
|
|
||
| /// <summary> | ||
| /// Gets the connection setup record, ensuring it exists. | ||
| /// </summary> | ||
| procedure GetConnectionSetup(var ConnectorSetup: Record "Connector Connection Setup") | ||
| begin | ||
| if not ConnectorSetup.Get() then | ||
| Error('Connector is not configured. Please open the Connector Connection Setup page.'); | ||
|
|
||
| if ConnectorSetup."API Base URL" = '' then | ||
| Error('API Base URL is not configured.'); | ||
|
|
||
| if not ConnectorSetup.Registered then | ||
| Error('Not registered with the API. Please register first.'); | ||
| end; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,136 @@ | ||
| // ------------------------------------------------------------------------------------------------ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT License. See License.txt in the project root for license information. | ||
| // ------------------------------------------------------------------------------------------------ | ||
| namespace Microsoft.EServices.EDocument.Integration; | ||
|
|
||
| /// <summary> | ||
| /// Setup page for Connector API connection. | ||
| /// Allows users to configure the API URL and register to get an API key. | ||
| /// </summary> | ||
| page 50122 "Connector Connection Setup" | ||
| { | ||
| Caption = 'Connector Setup'; | ||
| PageType = Card; | ||
| SourceTable = "Connector Connection Setup"; | ||
| InsertAllowed = false; | ||
| DeleteAllowed = false; | ||
| ApplicationArea = All; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. MÉXICO |
||
| UsageCategory = Administration; | ||
|
|
||
| layout | ||
| { | ||
| area(content) | ||
| { | ||
| group(General) | ||
| { | ||
| Caption = 'Connection Settings'; | ||
|
|
||
| field("API Base URL"; Rec."API Base URL") | ||
| { | ||
| ApplicationArea = All; | ||
| ToolTip = 'Specifies the base URL for the Connector API server (e.g., https://workshop-server.azurewebsites.net/)'; | ||
| ShowMandatory = true; | ||
| } | ||
| field("User Name"; Rec."User Name") | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ROSSE |
||
| { | ||
| ApplicationArea = All; | ||
| ToolTip = 'Specifies the user name to register with the API'; | ||
| ShowMandatory = true; | ||
| } | ||
| field(Registered; Rec.Registered) | ||
| { | ||
| ApplicationArea = All; | ||
| ToolTip = 'Indicates whether you have successfully registered with the API'; | ||
| Style = Favorable; | ||
| StyleExpr = Rec.Registered; | ||
| } | ||
| field("API Key"; APIKeyText) | ||
| { | ||
| ApplicationArea = All; | ||
| Caption = 'API Key'; | ||
| ToolTip = 'Specifies the API key received after registration'; | ||
|
|
||
| trigger OnAssistEdit() | ||
| var | ||
| NewAPIKey: Text; | ||
| begin | ||
| NewAPIKey := APIKeyText; | ||
| if NewAPIKey <> '' then begin | ||
| Rec.SetAPIKey(NewAPIKey); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Amea |
||
| Rec.Modify(); | ||
| CurrPage.Update(); | ||
| end; | ||
| end; | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| actions | ||
| { | ||
| area(Processing) | ||
| { | ||
| action(Register) | ||
| { | ||
| ApplicationArea = All; | ||
| Caption = 'Register'; | ||
| ToolTip = 'Register with the Connector API to get an API key'; | ||
| Image = Approve; | ||
| Promoted = true; | ||
| PromotedCategory = Process; | ||
| PromotedOnly = true; | ||
|
|
||
| trigger OnAction() | ||
| var | ||
| ConnectorAuth: Codeunit "Connector Auth"; | ||
| begin | ||
| ConnectorAuth.RegisterUser(Rec); | ||
| CurrPage.Update(); | ||
| UpdateAPIKeyText(); | ||
| Message('Registration successful! Your API key has been saved.'); | ||
| end; | ||
| } | ||
| action(TestConnection) | ||
| { | ||
| ApplicationArea = All; | ||
| Caption = 'Test Connection'; | ||
| ToolTip = 'Test the connection to the Connector API'; | ||
| Image = ValidateEmailLoggingSetup; | ||
| Promoted = true; | ||
| PromotedCategory = Process; | ||
| PromotedOnly = true; | ||
|
|
||
| trigger OnAction() | ||
| var | ||
| ConnectorAuth: Codeunit "Connector Auth"; | ||
| begin | ||
| ConnectorAuth.TestConnection(Rec); | ||
| Message('Connection test successful!'); | ||
| end; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| trigger OnOpenPage() | ||
| begin | ||
| Rec.GetOrCreate(); | ||
| UpdateAPIKeyText(); | ||
| end; | ||
|
|
||
| trigger OnAfterGetCurrRecord() | ||
| begin | ||
| UpdateAPIKeyText(); | ||
| end; | ||
|
|
||
| local procedure UpdateAPIKeyText() | ||
| begin | ||
| if not IsNullGuid(Rec."API Key") then | ||
| APIKeyText := Rec.GetAPIKeyText() | ||
| else | ||
| APIKeyText := ''; | ||
| end; | ||
|
|
||
| var | ||
| APIKeyText: Text; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| // ------------------------------------------------------------------------------------------------ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT License. See License.txt in the project root for license information. | ||
| // ------------------------------------------------------------------------------------------------ | ||
| namespace Microsoft.EServices.EDocument.Integration; | ||
|
|
||
| /// <summary> | ||
| /// Stores connection settings for Connector API. | ||
| /// This is a singleton table that holds the API URL and authentication key. | ||
| /// </summary> | ||
| table 50122 "Connector Connection Setup" | ||
| { | ||
| Caption = 'Connector Connection Setup'; | ||
| DataClassification = CustomerContent; | ||
|
|
||
| fields | ||
| { | ||
| field(1; "Primary Key"; Code[10]) | ||
| { | ||
| Caption = 'Primary Key'; | ||
| DataClassification = SystemMetadata; | ||
| } | ||
| field(10; "API Base URL"; Text[250]) | ||
| { | ||
| Caption = 'API Base URL'; | ||
| DataClassification = CustomerContent; | ||
|
|
||
| trigger OnValidate() | ||
| begin | ||
| if "API Base URL" <> '' then | ||
| if not "API Base URL".EndsWith('/') then | ||
| "API Base URL" := "API Base URL" + '/'; | ||
| end; | ||
| } | ||
| field(11; "API Key"; Guid) | ||
| { | ||
| Caption = 'API Key'; | ||
| DataClassification = EndUserIdentifiableInformation; | ||
| } | ||
| field(20; "User Name"; Text[100]) | ||
| { | ||
| Caption = 'User Name'; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PAINTER |
||
| DataClassification = EndUserIdentifiableInformation; | ||
| } | ||
| field(21; Registered; Boolean) | ||
| { | ||
| Caption = 'Registered'; | ||
| DataClassification = CustomerContent; | ||
| Editable = false; | ||
| } | ||
| } | ||
|
|
||
| keys | ||
| { | ||
| key(PK; "Primary Key") | ||
| { | ||
| Clustered = true; | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Gets or creates the singleton setup record. | ||
| /// </summary> | ||
| procedure GetOrCreate(): Boolean | ||
| begin | ||
| if not Get() then begin | ||
| Init(); | ||
| "Primary Key" := ''; | ||
| Insert(); | ||
| end; | ||
| exit(true); | ||
| end; | ||
|
|
||
| /// <summary> | ||
| /// Sets the API key from text value. | ||
| /// </summary> | ||
| procedure SetAPIKey(NewAPIKey: Text) | ||
| var | ||
| APIKeyGuid: Guid; | ||
| begin | ||
| if Evaluate(APIKeyGuid, NewAPIKey) then | ||
| "API Key" := APIKeyGuid | ||
| else | ||
| Error('Invalid API Key format. Must be a valid GUID.'); | ||
| end; | ||
|
|
||
| /// <summary> | ||
| /// Gets the API key as text. | ||
| /// </summary> | ||
| procedure GetAPIKeyText(): Text | ||
| begin | ||
| exit(Format("API Key").Replace('{', '').Replace('}', '').ToLower()); | ||
| end; | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Outlook