sendmsg.pp 5.1 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. D:=Nil;
  56. F:=TFileStream.Create(aFileName,fmOpenRead or fmShareDenyWrite);
  57. try
  58. D:=GetJSON(F);
  59. if not (D is TJSONObject) then
  60. Raise EFCM.CreateFmt('Invalid JSON data in message file %s',[aFileName]);
  61. Msg.Title:=Obj.Get('title',Msg.Title);
  62. Msg.Body:=Obj.Get('body',Msg.Body);
  63. Msg.Image:=Obj.Get('image',Msg.Image);
  64. finally
  65. D.Free;
  66. F.Free;
  67. end;
  68. end;
  69. procedure TFCMApplication.ConfigureMessage(Msg : TNotificationMessage);
  70. begin
  71. if HasOption('m','message') then
  72. LoadMessageFromFile(Msg,GetOptionValue('m','message'));
  73. if HasOption('t','title') then
  74. Msg.Title:=GetoptionValue('t','title');
  75. if HasOption('b','body') then
  76. Msg.Body:=GetoptionValue('b','body');
  77. if HasOption('i','image') then
  78. Msg.Body:=GetoptionValue('i','image');
  79. end;
  80. procedure TFCMApplication.DoHandleNewToken(Sender: TObject; const aToken: TBearerToken);
  81. begin
  82. aToken.SaveToFile(FAccessTokenFile);
  83. end;
  84. procedure TFCMApplication.DoRun;
  85. const
  86. Short = 'hm:b:t:r:s:i:l:a:';
  87. Long : Array of string = ('help','message:','body:','title:','recipient:','service-account:','image:','log:','access-token:');
  88. var
  89. ErrorMsg: String;
  90. Msg : TNotificationMessage;
  91. Client : TFCMClient;
  92. Recip : String;
  93. begin
  94. Terminate;
  95. // quick check parameters
  96. ErrorMsg:=CheckOptions(Short,Long);
  97. if (ErrorMsg<>'') or HasOption('h','help') then
  98. begin
  99. Usage(ErrorMsg);
  100. Exit;
  101. end;
  102. Recip:=GetOptionValue('r','recipient');
  103. if Recip='' then
  104. begin
  105. Usage('Need a recipient');
  106. Exit;
  107. end;
  108. Msg:=nil;
  109. Client:=TFCMClient.Create(Self);
  110. Try
  111. ConfigureClient(Client);
  112. Msg:=TNotificationMessage.Create;
  113. ConfigureMessage(Msg);
  114. Client.Send(Msg,Recip);
  115. Finally
  116. Msg.Free;
  117. Client.Free;
  118. end;
  119. end;
  120. constructor TFCMApplication.Create(TheOwner: TComponent);
  121. begin
  122. inherited Create(TheOwner);
  123. StopOnException:=True;
  124. end;
  125. procedure TFCMApplication.Usage(Msg : String);
  126. begin
  127. Writeln('Error : ',Msg);
  128. Writeln('Usage: ', ExeName, ' [options] ');
  129. Writeln('where options is one or more of');
  130. Writeln('-h --help This message');
  131. Writeln('-a --access-token=FILE Save (and optionally load) received access token to FILE');
  132. Writeln('-b --body=TEXT Set message body text. Overrides settings in -m');
  133. Writeln('-i --image=URL Set message image URL. Overrides settings in -m');
  134. Writeln('-l --log=FILE Set log file - all HTTP requests will be logged in this file');
  135. writeln('-m --message=FILE Set message body, title and image from FILE, a json file with format:' );
  136. writeln(' { "title" : "string", ');
  137. Writeln(' "body" : "string", ');
  138. Writeln(' "image" : "url" } ');
  139. Writeln('-r --recipient=TOKEN Set message recipient token');
  140. writeln('-s --service-account=FILE Read service account data from FILE (google service account data)');
  141. Writeln('-t --title=TEXT Set message title text. Overrides settings in -m');
  142. ExitCode:=Ord(Msg<>'');
  143. end;
  144. var
  145. Application: TFCMApplication;
  146. begin
  147. DefaultWebClientClass:=TFPHTTPWebClient;
  148. Application:=TFCMApplication.Create(nil);
  149. Application.Title:='FCM Test Application';
  150. Application.Run;
  151. Application.Free;
  152. end.