codeunit 60000 "SBC Spotify API Mgt"
{
procedure GetRequest(AdditionalURL: Text; var Data: Text; var httpStatusCode: Integer; PageScope: Text; var NextPageID: Integer): Boolean
var
SpotifyGeneralSetup: Record "SBC Spotify General Setup";
JSONMgt: Codeunit "SBC JSON Mgt";
httpClient: HttpClient;
httpResponseMessage: HttpResponseMessage;
requestUri: Text;
begin
SpotifyGeneralSetup.get();
SpotifyGeneralSetup.TestField("Spotify API URL");
NextPageID := 0;
requestUri := SpotifyGeneralSetup."Spotify API URL" + AdditionalURL;
httpClient.DefaultRequestHeaders().Add(
'Authorization',
'Bearer ' + GetSpotifyAccessToken());
if httpClient.Get(requestUri, httpResponseMessage) then begin
httpResponseMessage.Content().ReadAs(Data);
httpStatusCode := httpResponseMessage.HttpStatusCode();
if not httpResponseMessage.IsSuccessStatusCode() then
Error(RequestErr, httpStatusCode, Data);
if not SkipNextPage then
NextPageID := JSONMgt.GetNextPageID(Data, PageScope);
exit(true);
end else
Error(RequestErr, httpStatusCode, Data);
end;
procedure SendRequest(contentToSend: Text; RequestMethod: Text; AdditionalURL: Text): text
var
SBCSpotifyGeneralSetup: Record "SBC Spotify General Setup";
client: HttpClient;
request: HttpRequestMessage;
response: HttpResponseMessage;
contentHeaders: HttpHeaders;
content: HttpContent;
requestUri: Text;
responseText: Text;
errorBodyContent: Text;
begin
SBCSpotifyGeneralSetup.get();
SBCSpotifyGeneralSetup.TestField("Spotify API URL");
requestUri := SBCSpotifyGeneralSetup."Spotify API URL" + AdditionalURL;
content.WriteFrom(contentToSend);
content.GetHeaders(contentHeaders);
contentHeaders.Clear();
contentHeaders.Add('Content-Type', 'application/json');
request.Content := content;
request.SetRequestUri(requestUri);
request.Method := RequestMethod;
client.DefaultRequestHeaders().Add(
'Authorization',
'Bearer ' + GetSpotifyAccessToken());
client.Send(request, response);
response.Content().ReadAs(responseText);
if not response.IsSuccessStatusCode() then begin
response.Content().ReadAs(errorBodyContent);
Error(RequestErr, response.HttpStatusCode(), errorBodyContent);
end;
exit(responseText);
end;
procedure GetSpotifyAccessToken(): Text
var
SBCSpotifyGeneralSetup: Record "SBC Spotify General Setup";
OAuth20Application: Record "OAuth 2.0 Application";
OAuth20AppHelper: Codeunit "OAuth 2.0 App. Helper";
MessageText: Text;
begin
SBCSpotifyGeneralSetup.Get();
SBCSpotifyGeneralSetup.TestField("Spotify OAuth settings");
OAuth20Application.Get(SBCSpotifyGeneralSetup."Spotify OAuth settings");
if not OAuth20AppHelper.RequestAccessToken(OAuth20Application, MessageText) then
Error(MessageText);
exit(OAuth20AppHelper.GetAccessToken(OAuth20Application));
end;
procedure GetMyPlaylists()
var
SBCJSONMgt: Codeunit "SBC JSON Mgt";
NextPageID: Integer;
NextPageExist: Boolean;
AddUrl: Text;
Data: Text;
HttpStatusCode: Integer;
begin
NextPageExist := true;
while NextPageExist do begin
AddUrl := StrSubstNo('me/playlists?limit=50&offset=%1', NextPageID);
if GetRequest(AddUrl, Data, HttpStatusCode, '', NextPageID) then
SBCJSONMgt.UpdateMyPlaylists(Data);
NextPageExist := NextPageID <> 0;
end;
end;
procedure GetPlaylistTracks(var SBCTrack: Record "SBC Track"; PlaylistId: Text)
var
SBCJSONMgt: Codeunit "SBC JSON Mgt";
NextPageID: Integer;
NextPageExist: Boolean;
AddUrl: Text;
Data: Text;
HttpStatusCode: Integer;
begin
NextPageExist := true;
while NextPageExist do begin
AddUrl := StrSubstNo('playlists/%2/tracks?limit=100&offset=%1', NextPageID, PlaylistId);
if GetRequest(AddUrl, Data, HttpStatusCode, '', NextPageID) then
SBCJSONMgt.UpdateTracks(SBCTrack, Data);
NextPageExist := NextPageID <> 0;
end;
end;
procedure SearchItems(var SBCTrack: Record "SBC Track"; SearchString: Text; SearchType: Enum "SBC Search Type")
var
SBCJSONMgt: Codeunit "SBC JSON Mgt";
DialogW: Dialog;
NextInt: Integer;
NextPageID: Integer;
NextPageExist: Boolean;
AddUrl: Text;
Data: Text;
HttpStatusCode: Integer;
begin
//For now just only tracks search supported
if SearchType <> SearchType::track then
exit;
NextPageExist := true;
DialogW.Open('Continue... #1########', NextInt);
while NextPageExist do begin
AddUrl := StrSubstNo('search?q=%1&type=%2&limit=50&offset=%3', SearchString, SearchType, NextPageID);
if GetRequest(AddUrl, Data, HttpStatusCode, 'tracks', NextPageID) then
SBCJSONMgt.UpdateTracks(SBCTrack, Data);
NextPageExist := NextPageID <> 0;
end;
DialogW.Close();
end;
procedure SetSkipNextPage(BooleanValue: Boolean)
begin
SkipNextPage := BooleanValue;
end;
var
SkipNextPage: Boolean;
RequestErr: Label 'Request failed with HTTP Code:: %1 Request Body:: %2', Comment = '%1 = HttpCode, %2 = RequestBody';
}
codeunit 60001 "SBC JSON Mgt"
{
procedure SelectJsonToken(JObject: JsonObject; Path: Text): Text
var
JToken: JsonToken;
begin
if JObject.SelectToken(Path, JToken) then
if NOT JToken.AsValue().IsNull() then
exit(JToken.AsValue().AsText());
end;
procedure GetValueAsText(JToken: JsonToken; ParamString: Text): Text
var
JObject: JsonObject;
begin
JObject := JToken.AsObject();
exit(SelectJsonToken(JObject, ParamString));
end;
local procedure EvaluateUTCDateTime(DataTimeText: Text) EvaluatedDateTime: DateTime;
var
TypeHelper: Codeunit "Type Helper";
ValueVariant: Variant;
begin
ValueVariant := EvaluatedDateTime;
IF TypeHelper.Evaluate(ValueVariant, DataTimeText, '', TypeHelper.GetCultureName()) THEN
EvaluatedDateTime := ValueVariant;
end;
procedure GetNextPageID(Data: Text; PageScope: Text): Integer
var
JToken: JsonToken;
JToken2: JsonToken;
JObject: JsonObject;
ExitValue: Integer;
begin
if Data = '' then
exit;
JToken.ReadFrom(Data);
JObject := JToken.AsObject();
if PageScope <> '' then begin
JObject.SelectToken(PageScope, JToken2);
JObject := JToken2.AsObject();
end;
JObject.Get('next', JToken2);
if JToken2.AsValue().IsNull() then
ExitValue := 0
else begin
JObject.Get('limit', JToken2);
ExitValue := JToken2.AsValue().AsInteger();
JObject.Get('offset', JToken2);
ExitValue += JToken2.AsValue().AsInteger();
end;
exit(ExitValue);
end;
procedure UpdateMyPlaylists(Data: Text)
var
SBCSpotifyPlaylist: Record "SBC Spotify Playlist";
JToken: JsonToken;
JToken2: JsonToken;
JObject: JsonObject;
JObject2: JsonObject;
JArray: JsonArray;
JArray2: JsonArray;
PlaylistId: Text;
begin
if Data = '' then
exit;
JToken.ReadFrom(Data);
JObject := JToken.AsObject();
JObject.SelectToken('items', JToken);
JArray := JToken.AsArray();
foreach JToken in JArray do begin
PlaylistId := GetValueAsText(JToken, 'id');
if SBCSpotifyPlaylist.Get(PlaylistId) then
SBCSpotifyPlaylist.Delete(true);
SBCSpotifyPlaylist.Init();
SBCSpotifyPlaylist.Id := CopyStr(PlaylistId, 1, MaxStrLen(SBCSpotifyPlaylist.Id));
SBCSpotifyPlaylist.Name := CopyStr(GetValueAsText(JToken, 'name'), 1, MaxStrLen(SBCSpotifyPlaylist.Name));
SBCSpotifyPlaylist.Description := CopyStr(GetValueAsText(JToken, 'description'), 1, MaxStrLen(SBCSpotifyPlaylist.Description));
evaluate(SBCSpotifyPlaylist.Collaborative, GetValueAsText(JToken, 'collaborative'));
evaluate(SBCSpotifyPlaylist.Public, GetValueAsText(JToken, 'public'));
SBCSpotifyPlaylist.Href := CopyStr(GetValueAsText(JToken, 'href'), 1, MaxStrLen(SBCSpotifyPlaylist.Href));
SBCSpotifyPlaylist."Owner Id" := CopyStr(GetValueAsText(JToken, 'owner.id'), 1, MaxStrLen(SBCSpotifyPlaylist."Owner Id"));
SBCSpotifyPlaylist."Owner Name" := CopyStr(GetValueAsText(JToken, 'owner.display_name'), 1, MaxStrLen(SBCSpotifyPlaylist."Owner Name"));
SBCSpotifyPlaylist."Snapshot Id" := CopyStr(GetValueAsText(JToken, 'snapshot_id'), 1, MaxStrLen(SBCSpotifyPlaylist."Snapshot Id"));
SBCSpotifyPlaylist."Tracks Href" := CopyStr(GetValueAsText(JToken, 'tracks.href'), 1, MaxStrLen(SBCSpotifyPlaylist."Tracks Href"));
evaluate(SBCSpotifyPlaylist."Tracks Count", GetValueAsText(JToken, 'tracks.total'));
JObject2 := JToken.AsObject();
if JObject2.SelectToken('images', Jtoken2) then begin
JArray2 := JToken2.AsArray();
foreach JToken2 in JArray2 do
if SBCSpotifyPlaylist."Image Url" = '' then
SBCSpotifyPlaylist."Image Url" := CopyStr(GetValueAsText(JToken, 'url'), 1, MaxStrLen(SBCSpotifyPlaylist."Image Url"));
end;
SBCSpotifyPlaylist.Insert(true);
end;
end;
procedure UpdateTracks(var SBCTrack: Record "SBC Track"; Data: Text)
var
JToken: JsonToken;
JToken2: JsonToken;
JObject: JsonObject;
JObject2: JsonObject;
JArray: JsonArray;
JArray2: JsonArray;
TrackId: Text;
BaseParamString: Text;
begin
if Data = '' then
exit;
JToken.ReadFrom(Data);
JObject := JToken.AsObject();
if not JObject.SelectToken('items', JToken) then
JObject.SelectToken('tracks.items', JToken)
else
BaseParamString := 'track.';
JArray := JToken.AsArray();
foreach JToken in JArray do begin
TrackId := GetValueAsText(JToken, BaseParamString + 'id');
if not SBCTrack.Get(TrackId) then begin
SBCTrack.Init();
SBCTrack.Id := CopyStr(TrackId, 1, MaxStrLen(SBCTrack.Id));
SBCTrack.Name := CopyStr(GetValueAsText(JToken, BaseParamString + 'name'), 1, MaxStrLen(SBCTrack.Name));
evaluate(SBCTrack."Duration ms", GetValueAsText(JToken, BaseParamString + 'duration_ms'));
SBCTrack."Added At" := DT2Date(EvaluateUTCDateTime(GetValueAsText(JToken, 'added_at')));
SBCTrack."Added by Id" := CopyStr(GetValueAsText(JToken, 'added_by.id'), 1, MaxStrLen(SBCTrack."Added by Id"));
SBCTrack."Added by Url" := CopyStr(GetValueAsText(JToken, 'added_by.href'), 1, MaxStrLen(SBCTrack."Added by Url"));
SBCTrack."Album Id" := CopyStr(GetValueAsText(JToken, BaseParamString + 'album.id'), 1, MaxStrLen(SBCTrack."Album Id"));
SBCTrack."Album Name" := CopyStr(GetValueAsText(JToken, BaseParamString + 'album.name'), 1, MaxStrLen(SBCTrack."Album Name"));
SBCTrack."Track uri" := CopyStr(GetValueAsText(JToken, BaseParamString + 'uri'), 1, MaxStrLen(SBCTrack."Track uri"));
SBCTrack."Album Release Date" := DT2Date(EvaluateUTCDateTime(GetValueAsText(JToken, BaseParamString + 'album.release_date')));
SBCTrack."Track External URL" := CopyStr(GetValueAsText(JToken, BaseParamString + 'external_urls.spotify'), 1, MaxStrLen(SBCTrack."Track External URL"));
Evaluate(SBCTrack."Album Total Tracks", GetValueAsText(JToken, BaseParamString + 'album.total_tracks'));
JObject2 := JToken.AsObject();
if JObject2.SelectToken(BaseParamString + 'album.images', Jtoken2) then begin
JArray2 := JToken2.AsArray();
foreach JToken2 in JArray2 do
if SBCTrack."Album Image Href" = '' then
SBCTrack."Album Image Href" := CopyStr(GetValueAsText(JToken2, 'url'), 1, MaxStrLen(SBCTrack."Album Image Href"));
end;
JObject2 := JToken.AsObject();
if JObject2.SelectToken(BaseParamString + 'artists', Jtoken2) then begin
JArray2 := JToken2.AsArray();
foreach JToken2 in JArray2 do begin
SBCTrack."Artist Id" := CopyStr(GetValueAsText(JToken2, 'id'), 1, MaxStrLen(SBCTrack."Artist Id"));
SBCTrack."Artist href" := CopyStr(GetValueAsText(JToken2, 'href'), 1, MaxStrLen(SBCTrack."Artist href"));
SBCTrack."Artist Name" := CopyStr(GetValueAsText(JToken2, 'name'), 1, MaxStrLen(SBCTrack."Artist Name"));
end;
end;
SBCTrack.Insert(true);
SBCTrack.Mark(true);
end else
SBCTrack.Mark(true);
end;
SBCTrack.MarkedOnly(true);
end;
procedure DeleteTracksFromPlaylist(var SBCTrack: Record "SBC Track"; PlaylistId: Text)
var
SBCSpotifyAPIMgt: Codeunit "SBC Spotify API Mgt";
contentToSend: Text;
JObject: JsonObject;
JObject2: JsonObject;
JArray: JsonArray;
i: Integer;
begin
if SBCTrack.FindSet() then
repeat
i += 1;
Clear(JObject);
JObject.Add('uri', SBCTrack."Track uri");
JArray.Add(JObject);
//50 tracks per request deletion limit
if (i mod 50 = 0) or (i = SBCTrack.Count()) then begin
JObject2.Add('tracks', JArray);
JObject2.WriteTo(contentToSend);
SBCSpotifyAPIMgt.SendRequest(contentToSend, 'DELETE', StrSubstNo('playlists/%1/tracks', PlaylistId));
Clear(JObject2);
Clear(JArray);
end;
until SBCTrack.Next() = 0;
SBCTrack.DeleteAll(true);
end;
procedure AddTracksToPlaylist(var SBCTrack: Record "SBC Track"; PlaylistId: Text)
var
SBCSpotifyAPIMgt: Codeunit "SBC Spotify API Mgt";
contentToSend: Text;
JValue: JsonValue;
JObject2: JsonObject;
JArray: JsonArray;
i: Integer;
begin
if SBCTrack.FindSet() then
repeat
i += 1;
Clear(JValue);
JValue.SetValue(SBCTrack."Track uri");
JArray.Add(JValue);
//100 tracks per request deletion limit
if (i mod 100 = 0) or (i = SBCTrack.Count()) then begin
JObject2.Add('uris', JArray);
JObject2.WriteTo(contentToSend);
SBCSpotifyAPIMgt.SendRequest(contentToSend, 'POST', StrSubstNo('playlists/%1/tracks', PlaylistId));
Clear(JObject2);
Clear(JArray);
end;
until SBCTrack.Next() = 0;
end;
procedure ModifyPlaylist(EntityName: Text; EntityValue: Text; PlaylistId: Text)
var
SBCSpotifyAPIMgt: Codeunit "SBC Spotify API Mgt";
contentToSend: Text;
JObject: JsonObject;
begin
JObject.Add(EntityName, EntityValue);
JObject.WriteTo(contentToSend);
SBCSpotifyAPIMgt.SendRequest(contentToSend, 'PUT', StrSubstNo('playlists/%1', PlaylistId));
end;
procedure GetSpotifyUserId(): Text
var
SBCSpotifyAPIMgt: Codeunit "SBC Spotify API Mgt";
JToken: JsonToken;
NextPageID: Integer;
AddUrl: Text;
Data: Text;
HttpStatusCode: Integer;
begin
SBCSpotifyAPIMgt.SetSkipNextPage(true);
AddUrl := 'me';
if not SBCSpotifyAPIMgt.GetRequest(AddUrl, Data, HttpStatusCode, 'empty', NextPageID) then
exit;
if Data = '' then
exit;
JToken.ReadFrom(Data);
exit(GetValueAsText(JToken, 'id'));
end;
procedure CreatePlaylist(EntityName: Text; EntityValue: Text) PlaylistId: Text
var
SBCSpotifyAPIMgt: Codeunit "SBC Spotify API Mgt";
contentToSend: Text;
JObject: JsonObject;
JToken: JsonToken;
begin
JObject.Add(EntityName, EntityValue);
JObject.WriteTo(contentToSend);
JToken.ReadFrom(SBCSpotifyAPIMgt.SendRequest(contentToSend, 'POST', StrSubstNo('users/%1/playlists', GetSpotifyUserId())));
exit(GetValueAsText(JToken, 'id'));
end;
}
No comments:
Post a Comment