REST and API script

Hello,

I would like to insert a dummy item with metadata from another computer connected to the network. I use REST to execute this command:

POST /execute command=InsertDummyPlaylistItem Jay-Z - Empire State Of Mind (feat. Alicia Keys)

procedure OnExecuteCommand(Command: string); begin if copy(Command, 1, 24) = 'InsertDummyPlaylistItem ' then begin InsertDummyPlaylistItem(copy(Command, 25, 255)); end; end;

[code]procedure InsertDummyPlaylistItem(Metadata: string);
var
dpi: IDummyPlaylistItem;
i: integer;

begin
for i := 1 to length(Metadata) do begin
if (Metadata[i] = ‘-’) then begin
// Create a dummy playlist item
dpi := Factory.CreateDummyPlaylistItem;
dpi.SetArtist(copy(Metadata, 0, i-2));
dpi.SetTitle(copy(Metadata, i+2, 255));

  CurrentPlaylist.Insert(CurrentPlaylist.GetNextIndex, dpi);
  exit;
end;

end;
end;[/code]

How can I more properly separate the artist and the title, with " - " as delimiter?


How can I read a json from an http call? My api looks like this : {“song”:{“artist”:“Jay-Z”,“title”:“Empire State Of Mind (feat. Alicia Keys)”}}
I would like to add the text on a button, like this: api := HTTPGet('APIURL'); ExecuteCommand('ARTIST TEXT ' + api.song.artist);

Thanks.

Assuming you are on v6.1, you can use this new function in your background script:

procedure OnRESTRequest(Request: TRESTRequest; var Response: IPersistentStorage);
begin
end;

It will be triggered when a (POST) request is made that contains JSON data as payload.

TRESTRequest is declared as:

  TRESTRequest = record
    Method: string;
    Document: string;
    Parameters: IStrings;
    UploadDocument: IPersistentStorage;
    AuthUserID: integer;
    AuthUserName: string;
    AuthUserPermissions: string;
  end;

So you can do a POST to some URL (e.g. /insertdummy) with your JSON data in the body, e.g. in the same format you mentioned: {“song”:{“artist”:“Jay-Z”,“title”:“Empire State Of Mind (feat. Alicia Keys)”}}

Then use UploadDocument (which is the DOM of the JSON) to access the data:

procedure OnRESTRequest(Request: TRESTRequest; var Response: IPersistentStorage);
var
  song: IPersistentObject;
  dpi: IDummyPlaylistItem;
begin
  if (Request.Document = '/insertdummy') and (Request.UploadDocument.GetType = ptObject) and Request.UploadDocument.AsObject.FindObject('song', song) then begin

    dpi := Factory.CreateDummyPlaylistItem;
    dpi.SetArtist(song.FindString('artist', ''));
    dpi.SetTitle(song.FindString('title', ''));

    CurrentPlaylist.Insert(CurrentPlaylist.GetNextIndex, dpi);
  end;
end;

As for the second question, you use JSONToPersistentStorage to convert the result of the HTTP call into an IPersistentStorage interface, and then proceed like above:

var
  res: IPersistentStorage;
  song: IPersistentObject;
  dpi: IDummyPlaylistItem;
begin
  res := JSONToPersistentStorage(HTTPGet(APIURL));
  
  if (res.GetType = ptObject) and res.AsObject.FindObject('song', song) then begin
    dpi := Factory.CreateDummyPlaylistItem;
    dpi.SetArtist(song.FindString('artist', ''));
    dpi.SetTitle(song.FindString('title', ''));
    CurrentPlaylist.Insert(CurrentPlaylist.GetNextIndex, dpi);
  end;
end.

Note: All code typed straight into the browser and untested.

Edit: Fixed parameters for FindString.

Hello,

Thank you for your answer, I’m on v6.1.

I can do a POST with my JSON data in the body, but I can’t access the data with song.FindString('artist').

I get the following error: Invalid number of parameters

Can the addition of Method = 'POST in the if clause be beneficial?

Sorry, try

song.FindString('artist', '');

The second parameter is the default value that is returned if no “artist” key was found.

Everything works a lot now, thank you very much!