【Delphi】用于企业微信发送信息的示例程序(要求Delphi 10.1及更新版本)

 

 

unit uMainForm;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  Vcl.StdCtrls, System.JSON, uWeWork;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private const //以下三个常量的值需更换为实际值
    CorpID = 'xxxxxxxxxxxxxxxx';
    AgendID = '1234567';
    Secret = '############################################';
  private
    WeWork: TWeWork;
  public
    constructor Create(aOwner: TComponent); override;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses uTextBuilder;

constructor TForm1.Create(aOwner: TComponent);
begin
  inherited;
  OnCreate  := FormCreate;
  OnDestroy := FormDestroy;
  Button1.OnClick := Button1Click;
  Button2.OnClick := Button2Click;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  WeWork := TWeWork.Create(CorpID, AgendID, Secret);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  WeWork.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  JObj: TJSONObject;
begin
  TTextBuilder.Create
    .Add('你的快递已到,请携带工卡前往邮件中心领取。')
    .Add('出发前可查看<a href="http://work.weixin.qq.com">邮件中心视频实况</a>,聪明避开排队');

  JObj := WeWork.SendAppMsg('aUserName', TTextBuilder.Text); //注意:aUserName需更换为实际用户名
  Memo1.Lines.Text := JObj.Format;
  JObj.Free;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  TTextBuilder.Create
    .Add('您的会议室已经预定,稍后会同步到`邮箱`')
    .Add('> **事项详情**')
    .Add('> 事 项:<font color="info">开会</font>')
    .Add('> 组织者:@miglioguan')
    .Add('> 参与者:@miglioguan、@kunliu、@jamdeezhou、@kanexiong、@kisonwang')
    .Add('> ')
    .Add('> 会议室:<font color="info">广州TIT 1楼 301</font>')
    .Add('> 日 期:<font color="warning">2018年5月18日</font>')
    .Add('> 时 间:<font color="comment">上午9:00-11:00</font>')
    .Add('> ')
    .Add('> 请准时参加会议。')
    .Add('> ')
    .Add('> 如需修改会议信息,请点击:[修改会议信息](https://work.weixin.qq.com)"');

  with WeWork.SendAppMarkDown('aUserName', TTextBuilder.Text) do //注意:aUserName需更换
  begin
    Memo1.Lines.Text := Format;
    Free;
  end;
end;

end.
unit uWeWork;

interface

uses
  System.Classes, System.SysUtils, System.DateUtils, System.JSON,
  System.JSON.Types, System.JSON.Writers, System.JSON.Builders,
  IdIOHandler, IdIOHandlerSocket, IdIOHandlerStack, IdSSL, IdSSLOpenSSL,
  IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP;

type
  TWeWork = class(TObject)
  private const
    CPrefix  : String = 'https://qyapi.weixin.qq.com/cgi-bin/';
    CTokenURL: String = 'gettoken?corpid=ID&corpsecret=SECRET';
    CMsgUrl  : String = 'message/send?access_token=ACCESS_TOKEN';
  private
    FHttp: TIdHTTP;
    FExpireTime: TDateTime;
    FCorpID, FAgentID, FSecret, FToken: String;
    FSourceStream  : TStringStream;
    FResponseStream: TBytesStream;
    function GetToken: String;
    function HttpGet (const aUrl: String): TJSONObject;
    function HttpPost(const aUrl: String): TJSONObject;
  public
    function SendAppMsg(const aToUser, aMsg: String): TJSONObject;
    function SendAppMarkDown(const aToUser, aMsg: String): TJSONObject;
    property Token: String read GetToken;
    constructor Create(const aCorpID, aAgentID, aSecret: String); overload;
    destructor  Destroy; override;
  end;

implementation

uses uJSonBuilder;

constructor TWeWork.Create(const aCorpID, aAgentID, aSecret: String);
begin
  inherited Create();
  FCorpID  := aCorpID;
  FAgentID := aAgentID;
  FSecret  := aSecret;
  FExpireTime := 0;
  FHttp := TIdHTTP.Create(nil);
  FHttp.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(FHttp);
  FHttp.Request.ContentType := 'application/json';
  FHttp.Request.ContentEncoding := 'utf-8';
  FSourceStream := TStringStream.Create('', TEncoding.UTF8);
  FResponseStream := TBytesStream.Create;
end;

destructor TWeWork.Destroy;
begin
  FHttp.Free;
  FSourceStream.Free;
  FResponseStream.Free;
  inherited;
end;

function TWeWork.HttpGet(const aUrl: String): TJSONObject;
begin
  FResponseStream.Clear;
  FHttp.Get(CPrefix + aUrl, FResponseStream);
  Result := TJSONObject(TJSonObject.ParseJSONValue(FResponseStream.Bytes, 0, FResponseStream.Size));
end;

function TWeWork.HttpPost(const aUrl: String): TJSONObject;
begin
  FSourceStream.Clear;
  FSourceStream.WriteString(TJSONBuilder.JSON);
  FResponseStream.Clear;
  FHttp.Post(CPrefix + aUrl, FSourceStream, FResponseStream);
  Result := TJSONObject(TJSonObject.ParseJSONValue(FResponseStream.Bytes, 0, FResponseStream.Size));
end;

function TWeWork.GetToken: String;
var
  JObj: TJSONObject;
  ErrCode: Integer;
  ErrMsg: String;
begin
  if FExpireTime < Now then
  begin
    JObj := HttpGet(CTokenURL.Replace('ID', FCorpID).Replace('SECRET', FSecret));
    ErrCode := JObj.GetValue<Integer>('errcode');
    ErrMsg  := JObj.GetValue<String >('errmsg' );
    if ErrCode = 0 then
    begin
      FToken := JObj.GetValue<String>('access_token');
      FExpireTime := IncSecond(Now,  //Expire_In: 7200(2小时)-200 = 70000秒
           JObj.GetValue<Integer>('expires_in') - 200);
    end;
    JObj.Free;
    if ErrCode <> 0 then Exception.Create(ErrMsg);
  end;

  Result := FToken;
end;

function TWeWork.SendAppMsg(const aToUser, aMsg: String): TJSONObject;
begin
  TJSONBuilder.Create
    .BeginObject
       .Add('touser', aToUser)
       .Add('msgtype', 'text'  )
       .Add('agentid', FAgentID)
       .BeginObject('text')
          .Add('content', aMsg)
       .EndObject
    .EndObject;
  Result := HttpPost(CMsgUrl.Replace('ACCESS_TOKEN', Token));
end;

function TWeWork.SendAppMarkDown(const aToUser, aMsg: String): TJSONObject;
begin
  TJSONBuilder.Create
    .BeginObject
      .Add('touser' , aToUser)
      .Add('msgtype', 'markdown')
      .Add('agentid', FAgentID)
      .beginobject('markdown')
        .Add('content', aMsg)
      .endobject
    .EndObject;
  Result := HttpPost(CMsgUrl.Replace('ACCESS_TOKEN', Token));
end;

end.
unit uJSonBuilder;

interface

uses System.Classes, System.SysUtils, System.JSON, System.JSON.Types,
     System.JSON.Writers, System.JSON.Readers, System.JSON.Builders;

type  //TJSONObjectBuilder --- Delphi 10.1或更新版本才有此类
 TJSONBuilder = class(TJSONObjectBuilder)  //单实例类
  private
    StringBuilder : TStringBuilder;
    StringWriter  : TStringWriter;
    JSONTextWriter: TJsonTextWriter;
    class var FJSONBuilder: TJSONBuilder;
    class function GetJSON: string; static;
  public
    class property JSON: String read GetJSON;
    constructor Create(const AFormatting: TJsonFormatting = TJsonFormatting.None);
    destructor Destroy; override;
  end;

implementation

constructor TJSONBuilder.Create(const AFormatting: TJsonFormatting);
begin
  if FJSONBuilder <> nil then
    FJSONBuilder.Free;  //只保持单实例

  StringBuilder  := TStringBuilder.Create;
  StringWriter   := TStringWriter.Create(StringBuilder);
  JSONTextWriter := TJsonTextWriter.Create(StringWriter);
  JSONTextWriter.Formatting := AFormatting;
  inherited Create(JSONTextWriter);
  FJSONBuilder := Self;
end;

destructor TJSONBuilder.Destroy;
begin
  inherited;
  StringBuilder.Free;
  StringWriter.Free;
  JSONTextWriter.Free;
  FJSONBuilder := nil;
end;

class function TJSONBuilder.GetJSON: string;
begin
  if FJSONBuilder = nil then
    Result := ''
  else
    Result := FJSONBuilder.StringBuilder.ToString;
end;

initialization
  TJSONBuilder.FJSONBuilder := nil;

finalization
  if TJSONBuilder.FJSONBuilder <> nil then
    TJSONBuilder.FJSONBuilder.Free;

end.
unit uTextBuilder;

interface

uses System.Classes;

type
  TTextBuilder = class  //单实例类
  private
    FText: String;
    class var FTextBuilder: TTextBuilder;
    class function GetText: String; static;
  public
    function Clear: TTextBuilder;
    function Add(const S: String): TTextBuilder;
    class property Text: String read GetText;
    constructor Create; overload;
    destructor  Destroy; override;
  end;

implementation

constructor TTextBuilder.Create;
begin
  if FTextBuilder <> nil then  //仅保持单实例
    FTextBuilder.Free;
  inherited;

  FText := '';
  FTextBuilder := Self;
end;

destructor TTextBuilder.Destroy;
begin
  inherited;
  FTextBuilder := nil;
end;

class function TTextBuilder.GetText: String;
begin
  if FTextBuilder <> nil then
    Result := FTextBuilder.FText
  else
    Result := '';
end;

function TTextBuilder.Clear: TTextBuilder;
begin
  FText := '';
  Result := FTextBuilder;
end;

function TTextBuilder.Add(const S: String): TTextBuilder;
begin
  if FText = '' then
    FText := S
  else
    FText := FText + #10 + S;

  Result := FTextBuilder;
end;

initialization
  TTextBuilder.FTextBuilder := nil;

finalization
  if TTextBuilder.FTextBuilder <> nil then
    TTextBuilder.FTextBuilder.Free;

end.

 

  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值