sendmsg.pp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. program sendmsg;
  2. {$mode objfpc}{$H+}
  3. uses
  4. {$IFDEF UNIX}
  5. cthreads,
  6. {$ENDIF}
  7. Classes, SysUtils, CustApp, fpjson, jsonparser, fpfcmclient, opensslsockets, fpfcmtypes, fpwebclient, fphttpwebclient;
  8. type
  9. { TFCMApplication }
  10. TFCMApplication = class(TCustomApplication)
  11. private
  12. FAccessTokenFile : String;
  13. procedure ConfigureClient(aClient: TFCMClient);
  14. procedure ConfigureMessage(Msg: TNotificationMessage);
  15. procedure DoHandleNewToken(Sender: TObject; const aToken: TBearerToken);
  16. procedure LoadMessageFromFile(Msg: TNotificationMessage; const aFileName: string);
  17. protected
  18. procedure DoRun; override;
  19. public
  20. constructor Create(TheOwner: TComponent); override;
  21. procedure Usage(Msg: String); virtual;
  22. end;
  23. { TFCMApplication }
  24. procedure TFCMApplication.ConfigureClient(aClient : TFCMClient);
  25. var
  26. CfgFile : string;
  27. begin
  28. // Service account info
  29. CfgFile:=GetOptionValue('s','service-account');
  30. if CfgFile='' then
  31. CfgFile:=ChangeFileExt(ParamStr(0),'-service-account.json');
  32. if not FileExists(CfgFile) then
  33. Raise EInOutError.CreateFmt('No service account configuration file found: %s',[CfgFile]);
  34. aClient.InitServiceAccount(CfgFile,'');
  35. // Access token reuse
  36. if HasOption('a','access-token') then
  37. begin
  38. FAccessTokenFile:=GetOptionValue('a','access-token');
  39. // Load initial token
  40. if FileExists(FAccessTokenFile) then
  41. aClient.BearerToken.LoadFromFile(FAccessTokenFile);
  42. // Set handler so we save the token when it was fetched.
  43. aClient.OnNewBearerToken:=@DoHandleNewToken;
  44. end;
  45. // Log file
  46. if HasOption('l','log') then
  47. aClient.LogFile:=GetOptionValue('l','log');
  48. end;
  49. procedure TFCMApplication.LoadMessageFromFile(Msg : TNotificationMessage; const aFileName : string);
  50. Var
  51. F : TFileStream;
  52. D : TJSONData;
  53. Obj : TJSONObject absolute D;
  54. begin
  55. F:=TFileStream.Create(aFileName,fmOpenRead or fmShareDenyWrite);
  56. try
  57. D:=GetJSON(F);
  58. if not (D is TJSONObject) then
  59. Raise EFCM.CreateFmt('Invalid JSON data in message file %s',[aFileName]);
  60. Msg.Title:=Obj.Get('title',Msg.Title);
  61. Msg.Body:=Obj.Get('body',Msg.Body);
  62. Msg.Image:=Obj.Get('image',Msg.Image);
  63. finally
  64. F.Free;
  65. end;
  66. end;
  67. procedure TFCMApplication.ConfigureMessage(Msg : TNotificationMessage);
  68. begin
  69. if HasOption('m','message') then
  70. LoadMessageFromFile(Msg,GetOptionValue('m','message'));
  71. if HasOption('t','title') then
  72. Msg.Title:=GetoptionValue('t','title');
  73. if HasOption('b','body') then
  74. Msg.Body:=GetoptionValue('b','body');
  75. if HasOption('i','image') then
  76. Msg.Body:=GetoptionValue('i','image');
  77. end;
  78. procedure TFCMApplication.DoHandleNewToken(Sender: TObject; const aToken: TBearerToken);
  79. begin
  80. aToken.SaveToFile(FAccessTokenFile);
  81. end;
  82. procedure TFCMApplication.DoRun;
  83. const
  84. Short = 'hm:b:t:r:s:i:l:a:';
  85. Long : Array of string = ('help','message:','body:','title:','recipient:','service-account:','image:','log:','access-token:');
  86. var
  87. ErrorMsg: String;
  88. Msg : TNotificationMessage;
  89. Client : TFCMClient;
  90. Recip : String;
  91. begin
  92. Terminate;
  93. // quick check parameters
  94. ErrorMsg:=CheckOptions(Short,Long);
  95. if (ErrorMsg<>'') or HasOption('h','help') then
  96. begin
  97. Usage(ErrorMsg);
  98. Exit;
  99. end;
  100. Recip:=GetOptionValue('r','recipient');
  101. if Recip='' then
  102. begin
  103. Usage('Need a recipient');
  104. Exit;
  105. end;
  106. Msg:=nil;
  107. Client:=TFCMClient.Create(Self);
  108. Try
  109. ConfigureClient(Client);
  110. Msg:=TNotificationMessage.Create;
  111. ConfigureMessage(Msg);
  112. Client.Send(Msg,Recip);
  113. Finally
  114. Msg.Free;
  115. Client.Free;
  116. end;
  117. end;
  118. constructor TFCMApplication.Create(TheOwner: TComponent);
  119. begin
  120. inherited Create(TheOwner);
  121. StopOnException:=True;
  122. end;
  123. procedure TFCMApplication.Usage(Msg : String);
  124. begin
  125. Writeln('Error : ',Msg);
  126. Writeln('Usage: ', ExeName, ' [options] ');
  127. Writeln('where options is one or more of');
  128. Writeln('-h --help This message');
  129. Writeln('-a --access-token=FILE Save (and optionally load) received access token to FILE');
  130. Writeln('-b --body=TEXT Set message body text. Overrides settings in -m');
  131. Writeln('-i --image=URL Set message image URL. Overrides settings in -m');
  132. Writeln('-l --log=FILE Set log file - all HTTP requests will be logged in this file');
  133. writeln('-m --message=FILE Set message body, title and image from FILE, a json file with format:' );
  134. writeln(' { "title" : "string", ');
  135. Writeln(' "body" : "string", ');
  136. Writeln(' "image" : "url" } ');
  137. Writeln('-r --recipient=TOKEN Set message recipient token');
  138. writeln('-s --service-account=FILE Read service account data from FILE (google service account data)');
  139. Writeln('-t --title=TEXT Set message title text. Overrides settings in -m');
  140. ExitCode:=Ord(Msg<>'');
  141. end;
  142. var
  143. Application: TFCMApplication;
  144. begin
  145. DefaultWebClientClass:=TFPHTTPWebClient;
  146. Application:=TFCMApplication.Create(nil);
  147. Application.Title:='FCM Test Application';
  148. Application.Run;
  149. Application.Free;
  150. end.