2016-09-22 90 views
0

我想用indy 9.00.10在delphi 7上发送表情符号。我使用tnt VCL控件。 我发现这个网址为http://apps.timwhitlock.info/emoji/tables/unicode的Unicode和字节代码。 如何将此代码转换为用indy发送的delphi常量。用indy delphi7发送表情符号

我使用Delphi代码的信息发送到电报机器人:

procedure TBotThread.SendMessage(ChatID:String; Text : WideString; 
parse_mode:string;disable_notification:boolean); 
Var 
    Stream: TStringStream; 
    Params: TIdMultipartFormDataStream; 
    //Text : WideString; 
    msg : WideString; 
    Src : string; 
    LHandler: TIdSSLIOHandlerSocket; 
begin 
    try 
    try 
     if FShowBotLink then 
     Text := Text + LineBreak + FBotUser; 
     msg := '/sendmessage'; 
     Stream := TStringStream.Create(''); 
     Params := TIdMultipartFormDataStream.Create; 
     Params.AddFormField('chat_id',ChatID); 
     if parse_mode <> '' then 
     Params.AddFormField('parse_mode',parse_mode); 
     if disable_notification then 
     Params.AddFormField('disable_notification','true') 
     else 
     Params.AddFormField('disable_notification','false'); 
     Params.AddFormField('disable_web_page_preview','true'); 
     Params.AddFormField('text',UTF8Encode(Text)); 
     LHandler := TIdSSLIOHandlerSocket.Create(nil); 
     FidHttpSend.ReadTimeout := 30000; 
     FidHttpSend.IOHandler:=LHandler; 
     LHandler.SSLOptions.Method := sslvTLSv1; 
     LHandler.SSLOptions.Mode := sslmUnassigned; 
     FidHttpSend.HandleRedirects := true; 
     FidHttpSend.Post(BaseUrl + API + msg, Params, Stream); 
    finally 
     Params.Free; 
     Stream.Free; 
    ENd; 
except 
    on E: EIdHTTPProtocolException do 
    begin 
     if E.ReplyErrorCode = 403 then 
     begin 
     WriteToLog('Bot was blocked by the user'); 
     end; 
    end; 
end; 
end; 

字节样本emojies:

AERIAL_TRAMWAY = '\xf0\x9f\x9a\xa1'; 
AIRPLANE = '\xe2\x9c\x88'; 
ALARM_CLOCK = '\xe2\x8f\xb0'; 
ALIEN_MONSTER = '\xf0\x9f\x91\xbe'; 

遗憾的英语不好!

+0

印第安纳波利斯9不支持Unicode。你应该升级到Indy 10.如果这不是一个选项,我将不得不挖掘Indy 9的代码来为你提供其他选项。无论哪种方式,您实际发布的网址是?发布Unicode输入的要求是什么? –

+0

感谢雷米的评论。我改变这一行发送电话表情符号。 Params.AddFormField('text',UTF8Encode(Text + LineBreak +#$ 0000260E));这适用于我,但这个代码不起作用:#$ 1F601为“磨脸微笑的眼睛”表情符号。我张贴到电报机器人API:https://api.telegram.org/bot。表情符号是unicode? 。对不起英语不好。 –

+0

如何转换表情符号代码示例U + 1F601并在delphi中使用? –

回答

0

Telegram Bot API支持多种输入形式:

我们支持GETPOST HTTP方法。我们支持博特API请求的参数传递四种方式:

  • URL查询字符串
  • 应用程序/ x-WWW窗体-urlencoded
  • 应用/ JSON(除了上传文件)
  • 多/表单数据(用于上传文件)

您正在使用最后一个选项。

Indy 9不支持Delphi 2009+或Unicode。的string所有用途被假定为AnsiString,这是在Delphi 7的情况下的任何AnsiString添加到TIdMultipartFormDataStreamTStrings,即使是UTF-8编码的一个,将被发送原样通过TIdHTTP。但是,没有选项可以指定服务器字符串数据实际使用UTF-8作为字符集。但是,根据文档:

所有查询必须使用UTF-8。

因此,不指定明确的字符集可能不是问题。

如果您仍然有问题multipart/form-data,那么可以考虑使用application/x-www-form-urlencoded(使用TIdHTTP.Post(TStrings))或application/json(使用TIdHTTP.Post(TStream))代替:

procedure TBotThread.SendMessage(ChatID: String; Text: WideString; parse_mode: string; disable_notification: boolean); 
var 
    Params: TStringList; 
    LHandler: TIdSSLIOHandlerSocket; 
begin 
    if FShowBotLink then 
    Text := Text + LineBreak + FBotUser; 

    Params := TStringList.Create; 
    try 
    Params.Add('chat_id=' + UTF8Encode(ChatID)); 
    if parse_mode <> '' then 
     Params.Add('parse_mode=' + UTF8Encode(parse_mode)); 
    if disable_notification then 
     Params.Add('disable_notification=true') 
    else 
     Params.Add('disable_notification=false'); 
    Params.Add('disable_web_page_preview=true'); 
    Params.Add('text=' + UTF8Encode(Text)); 

    LHandler := TIdSSLIOHandlerSocket.Create(nil); 
    try 
     LHandler.SSLOptions.Method := sslvTLSv1; 
     LHandler.SSLOptions.Mode := sslmClient; 

     FidHttpSend.HandleRedirects := true; 
     FidHttpSend.ReadTimeout := 30000; 
     FidHttpSend.IOHandler := LHandler; 
     try 
     try 
      FidHttpSend.Post(BaseUrl + API + '/sendmessage', Params, TStream(nil)); 
     except 
      on E: EIdHTTPProtocolException do 
      begin 
      if E.ReplyErrorCode = 403 then 
      begin 
       WriteToLog('Bot was blocked by the user'); 
      end; 
      end; 
     end; 
     finally 
     FidHttpSend.IOHandler := nil; 
     end; 
    finally 
     LHandler.Free; 
    end; 
    finally 
    Params.Free; 
    end; 
end; 

procedure TBotThread.SendMessage(ChatID: String; Text: WideString; parse_mode: string; disable_notification: boolean); 
var 
    Params: TStringStream; 
    LHandler: TIdSSLIOHandlerSocket; 

    function JsonEncode(const wStr: WideString): string; 
    var 
    I: Integer; 
    Ch: WideChar; 
    begin 
    // JSON uses UTF-16 text, so no need to encode to UTF-8... 
    Result := ''; 
    for I := 1 to Length(wStr) do 
    begin 
     Ch := wStr[i]; 
     case Ch of 
     #8: Result := Result + '\b'; 
     #9: Result := Result + '\t'; 
     #10: Result := Result + '\n'; 
     #12: Result := Result + '\f'; 
     #13: Result := Result + '\r'; 
     '"': Result := Result + '\"'; 
     '\': Result := Result + '\\'; 
     '/': Result := Result + '\/'; 
     else 
     if (Ord(Ch) >= 32) and (Ord(Ch) <= 126) then 
      Result := Result + AnsiChar(Ord(wStr[i])) 
     else 
      Result := Result + '\u' + IntToHex(Ord(wStr[i]), 4); 
     end; 
    end; 
    end; 

begin 
    if FShowBotLink then 
    Text := Text + LineBreak + FBotUser; 

    Params := TStringStream.Create(''); 
    try 
    Params.WriteString('{'); 
    Params.WriteString('chat_id: "' + JsonEncode(ChatID) + '",'); 
    if parse_mode <> '' then 
     Params.WriteString('parse_mode: "' + JsonEncode(parse_mode) + '",') 
    if disable_notification then 
     Params.WriteString('disable_notification: True,') 
    else 
     Params.WriteString('disable_notification: False,'); 
    Params.WriteString('disable_web_page_preview: True,'); 
    Params.WriteString('text: "' + JsonEncode(Text) + '"'); 
    Params.WriteString('}'); 
    Params.Position := 0; 

    LHandler := TIdSSLIOHandlerSocket.Create(nil); 
    try 
     LHandler.SSLOptions.Method := sslvTLSv1; 
     LHandler.SSLOptions.Mode := sslmClient; 

     FidHttpSend.HandleRedirects := true; 
     FidHttpSend.ReadTimeout := 30000; 
     FidHttpSend.IOHandler := LHandler; 
     try 
     try 
      FidHttpSend.Request.ContentType := 'application/json'; 
      FidHttpSend.Post(BaseUrl + API + '/sendmessage', Params, TStream(nil)); 
     except 
      on E: EIdHTTPProtocolException do 
      begin 
      if E.ReplyErrorCode = 403 then 
      begin 
       WriteToLog('Bot was blocked by the user'); 
      end; 
      end; 
     end; 
     finally 
     FidHttpSend.IOHandler := nil; 
     end; 
    finally 
     LHandler.Free; 
    end; 
    finally 
    Params.Free; 
    end; 
end; 

话虽这么说,你的函数的Text参数是一个WideString,它使用UTF-16,所以你应该能够发送任何Unicode文本,包括emojis。如果您尝试在代码中生成文本,请确保UTF-16正确编码任何非ASCII字符。例如,代码点U+1F601 GRINNING FACE WITH SMILING EYES是宽字符$D83D $DE01在UTF-16:

var 
    Text: WideString; 

Text := 'hi ' + #$D83D#$DE01; // 'hi ' 
SendMessage('@channel', Text, 'Markup', False); 

或者,你可以在你的短信使用HTML,所以你可以使用编码数字HTML实体非ASCII字符。根据文档:

支持所有数字HTML实体。

代码点U+1F601是数字实体$#128513;在HTML:

var 
    Text: WideString; 

Text := 'hi $#128513;'; // 'hi ' 
SendMessage('@channel', Text, 'HTML', False); 
+0

非常感谢你雷米。 –