Browse Source

* CLI example for FCM push messages

Michaël Van Canneyt 1 year ago
parent
commit
5ea775dc58

+ 55 - 0
packages/fcl-web/examples/fcm/cli/sendmsg.lpi

@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="12"/>
+    <General>
+      <Flags>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <MainUnitHasScaledStatement Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <Title Value="FCM Test Application"/>
+      <UseAppBundle Value="False"/>
+      <ResourceType Value="res"/>
+    </General>
+    <BuildModes>
+      <Item Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <UseFileFilters Value="True"/>
+    </PublishOptions>
+    <RunParams>
+      <FormatVersion Value="2"/>
+    </RunParams>
+    <Units>
+      <Unit>
+        <Filename Value="sendmsg.pp"/>
+        <IsPartOfProject Value="True"/>
+      </Unit>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="11"/>
+    <Target>
+      <Filename Value="sendmsg"/>
+    </Target>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+      <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
+    </SearchPaths>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions>
+      <Item>
+        <Name Value="EAbort"/>
+      </Item>
+      <Item>
+        <Name Value="ECodetoolError"/>
+      </Item>
+      <Item>
+        <Name Value="EFOpenError"/>
+      </Item>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 177 - 0
packages/fcl-web/examples/fcm/cli/sendmsg.pp

@@ -0,0 +1,177 @@
+program sendmsg;
+
+{$mode objfpc}{$H+}
+
+uses
+  {$IFDEF UNIX}
+  cthreads,
+  {$ENDIF}
+  Classes, SysUtils, CustApp, fpjson, jsonparser, fpfcmsender, opensslsockets, fpfcmtypes, fpwebclient, fphttpwebclient;
+
+type
+
+  { TFCMApplication }
+
+  TFCMApplication = class(TCustomApplication)
+  private
+    FAccessTokenFile : String;
+    procedure ConfigureClient(aClient: TFCMClient);
+    procedure ConfigureMessage(Msg: TNotificationMessage);
+    procedure DoHandleNewToken(Sender: TObject; const aToken: TBearerToken);
+    procedure LoadMessageFromFile(Msg: TNotificationMessage; const aFileName: string);
+  protected
+    procedure DoRun; override;
+  public
+    constructor Create(TheOwner: TComponent); override;
+    procedure Usage(Msg: String); virtual;
+  end;
+
+{ TFCMApplication }
+
+procedure TFCMApplication.ConfigureClient(aClient : TFCMClient);
+
+var
+  CfgFile : string;
+
+begin
+  // Service account info
+  CfgFile:=GetOptionValue('s','service-account');
+  if CfgFile='' then
+    CfgFile:=ChangeFileExt(ParamStr(0),'-service-account.json');
+  if not FileExists(CfgFile) then
+    Raise EInOutError.CreateFmt('No service account configuration file found: %s',[CfgFile]);
+  aClient.InitServiceAccount(CfgFile,'');
+  // Access token reuse
+  if HasOption('a','access-token') then
+    begin
+    FAccessTokenFile:=GetOptionValue('a','access-token');
+    // Load initial token
+    if FileExists(FAccessTokenFile) then
+      aClient.BearerToken.LoadFromFile(FAccessTokenFile);
+    // Set handler so we save the token when it was fetched.
+    aClient.OnNewBearerToken:=@DoHandleNewToken;
+    end;
+  // Log file
+  if HasOption('l','log') then
+    aClient.LogFile:=GetOptionValue('l','log');
+end;
+
+procedure TFCMApplication.LoadMessageFromFile(Msg : TNotificationMessage; const aFileName : string);
+
+Var
+  F : TFileStream;
+  D : TJSONData;
+  Obj : TJSONObject absolute D;
+
+begin
+  F:=TFileStream.Create(aFileName,fmOpenRead or fmShareDenyWrite);
+  try
+    D:=GetJSON(F);
+    if not (D is TJSONObject) then
+      Raise EFCM.CreateFmt('Invalid JSON data in message file %s',[aFileName]);
+    Msg.Title:=Obj.Get('title',Msg.Title);
+    Msg.Body:=Obj.Get('body',Msg.Body);
+    Msg.Image:=Obj.Get('image',Msg.Image);
+  finally
+    F.Free;
+  end;
+end;
+
+
+procedure TFCMApplication.ConfigureMessage(Msg : TNotificationMessage);
+
+
+begin
+  if HasOption('m','message') then
+    LoadMessageFromFile(Msg,GetOptionValue('m','message'));
+  if HasOption('t','title') then
+    Msg.Title:=GetoptionValue('t','title');
+  if HasOption('b','body') then
+    Msg.Body:=GetoptionValue('b','body');
+  if HasOption('i','image') then
+    Msg.Body:=GetoptionValue('i','image');
+
+end;
+
+procedure TFCMApplication.DoHandleNewToken(Sender: TObject; const aToken: TBearerToken);
+begin
+  aToken.SaveToFile(FAccessTokenFile);
+end;
+
+procedure TFCMApplication.DoRun;
+
+const
+  Short = 'hm:b:t:r:s:i:l:a:';
+  Long : Array of string = ('help','message:','body:','title:','recipient:','service-account:','image:','log:','access-token:');
+
+var
+  ErrorMsg: String;
+  Msg : TNotificationMessage;
+  Client : TFCMClient;
+  Recip : String;
+
+begin
+  Terminate;
+  // quick check parameters
+  ErrorMsg:=CheckOptions(Short,Long);
+  if (ErrorMsg<>'') or HasOption('h','help') then
+    begin
+    Usage(ErrorMsg);
+    Exit;
+    end;
+  Recip:=GetOptionValue('r','recipient');
+  if Recip='' then
+    begin
+    Usage('Need a recipient');
+    Exit;
+    end;
+  Msg:=nil;
+  Client:=TFCMClient.Create(Self);
+  Try
+    ConfigureClient(Client);
+    Msg:=TNotificationMessage.Create;
+    ConfigureMessage(Msg);
+    Client.Send(Msg,Recip);
+  Finally
+    Msg.Free;
+    Client.Free;
+  end;
+end;
+
+constructor TFCMApplication.Create(TheOwner: TComponent);
+begin
+  inherited Create(TheOwner);
+  StopOnException:=True;
+end;
+
+procedure TFCMApplication.Usage(Msg : String);
+begin
+  Writeln('Error : ',Msg);
+  Writeln('Usage: ', ExeName, ' [options] ');
+  Writeln('where options is one or more of');
+  Writeln('-h --help                  This message');
+  Writeln('-a --access-token=FILE     Save (and optionally load) received access token to FILE');
+  Writeln('-b --body=TEXT             Set message body text. Overrides settings in -m');
+  Writeln('-i --image=URL             Set message image URL. Overrides settings in -m');
+  Writeln('-l --log=FILE              Set log file - all HTTP requests will be logged in this file');
+  writeln('-m --message=FILE          Set message body, title and image from FILE, a json file with format:' );
+  writeln('                           { "title"  : "string", ');
+  Writeln('                             "body" : "string", ');
+  Writeln('                             "image" : "url" } ');
+  Writeln('-r --recipient=TOKEN       Set message recipient token');
+  writeln('-s --service-account=FILE  Read service account data from FILE (google service account data)');
+  Writeln('-t --title=TEXT            Set message title text. Overrides settings in -m');
+  ExitCode:=Ord(Msg<>'');
+end;
+
+var
+  Application: TFCMApplication;
+
+begin
+  DefaultWebClientClass:=TFPHTTPWebClient;
+  Application:=TFCMApplication.Create(nil);
+  Application.Title:='FCM Test Application';
+  Application.Run;
+  Application.Free;
+end.
+