صفحه 1 از 2 12 آخرآخر
نمایش نتایج 1 تا 40 از 49

نام تاپیک: کار با API ربات تلگرام در دلفی 7

  1. #1
    کاربر دائمی آواتار mjdeveloper
    تاریخ عضویت
    بهمن 1385
    محل زندگی
    تهران
    پست
    124

    Cool کار با API ربات تلگرام در دلفی 7

    با سلام و احترام خدمت دوستان و اساتید بزرگوار

    می خوام در این تاپیک طریقه کار با API ربات های تلگرام در دلفی رو خدمت دوستان آموزش بدم . شاید بتونه گره از کار برخی دوستان باز کنه.

    طریقه کار به این صورت هست که ابتدا باید در تلگرام ربات خود را بسازید که طریقه ساختش راحت هست و من وارد این مقوله نمیشم.
    بعد از ساخت ربات ،تلگرام یه توکن منحصر به فرد برای رباتتون در اختیار شما میذاره که شبیه این هست
    123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11

    حالا شما باید با آدرس اصلی تلگرام و با استفاده از این توکن با تلگرام در ارتباط باشید. طریقه ارتباط هم Http Post &Get هست. که در کدی که من استفاده کردم برای این کار در دلفی 7 از Indy و کامپوننت TidHttp هست.

    درخواست ها رو به ربات تلگرام به صورت زیر ارسال می کنیم.
    https://api.telegram.org/bot<token>/METHOD_NAME


    پاسخ هایی که ربات تلگرام براتون میفرسته بصورت متنی و در قالب JSON هست.
    نمونه یک پاسخ:
    {    "ok":true,
    "result":
    [
    {
    "update_id":658807363,
    "message":
    {
    "message_id":41,
    "from":
    {
    "id":79060780,
    "first_name":"mehdi",
    "last_name":"Jafari",
    "username":"ShahvarIMS"
    },
    "chat":
    {
    "id":79060780,
    "first_name":"mehdi",
    "last_name":"Jafari",
    "username":"ShahvarIMS",
    "type":"private"
    },
    "date":1468481903,
    "text":"\/features",
    "entities":
    [{
    "type":"bot_command",
    "offset":0,
    "length":9
    }]
    }
    }
    ]
    }




    برای کار با این فرمت JSON در دلفی 7 نیاز به کامپوننت و یا کلاس های از پیش طراحی شده دارید و مثل اینکه در دلفی های بالاتر این مشکل رفع شده و دلفی های جدید JSON رو ساپورت میکنن. چون من دیگه سراغشون نرفتم اطلاعات دقیقی ندارم متاسفانه. من در این کد از یک Unit به نام LkJSON v1.07 که در دلفی 7 هم کامپایل میشه استفاده کردم که خدا به این دوست عزیز جناب آقای Leonid Koninin خیرش رو بده انشاالله.

    خوب نگران کامپوننت و این unit و کار با JSON نباشید من آخر کد رو میذارم.
    دوتا Dll هم کنار برنامه استفاده میشه :
    libeay32.dll
    ssleay32.dll
    دقت کنید اینا ورژن های مختلفی داره که باید با ورژن Indy شما بخونه.

    خوب حالا بریم سراغ کد برنامه

    ابتدا می بایست یه سری unit ها به بخش use اصلی اضافه کنید که همش رو میذارم
    uses  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection,
    IdTCPClient, IdHTTP,IdSSLOpenSSL, Buttons;



    البته با انداختن کامپوننت TidHttp روی فرم یه سریش اتومات اضافه میشه.

    آردس ارسال درخواست به ربات:
      BaseUrl = 'https://api.telegram.org/bot';



    گرفتن اطلاعات ربات:
    ما می خواین این آدرس رو post کنیم
    https://api.telegram.org/bot123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11/getMe


    Var  Src : string;
    LHandler: TIdSSLIOHandlerSocket;
    begin
    API := edtAPI.Text;
    try
    LHandler := TIdSSLIOHandlerSocket.Create(nil);
    try
    IdHTTP1.ReadTimeout := 30000;
    IdHTTP1.IOHandler:=LHandler;
    LHandler.SSLOptions.Method := sslvTLSv1;
    LHandler.SSLOptions.Mode := sslmUnassigned;
    Src:= IdHTTP1.Get(BaseUrl + API + '/getme');
    memoResponse.lines.clear;
    memoresponse.lines.add(src);
    memoRequest.Text := IdHTTP1.Response.RawHeaders.Text;
    finally
    LHandler.Free;
    end;
    except on E: Exception do
    Showmessage(E.Message);
    end;


    خوب اگر یخورده تحقیق کرده باشید بات تلگرام شماره تلفن رو نمیشناسه و فقط با Chat_ID کار میکنه. یعنی به هر شخصی که بخواین پیام بفرستید ابتدا باید Chat_id اون شخص رو در بیارید و سپس به اون پیام مناسب رو ارسال کنید. شخص هنگامی که رباط شما رو ادد میکنه و یه درخواست یا Bot Command رو که با فرمت /CommandName هست رو برای Bot میفرسته با بررسی همین پیام دریافتی میشه Chat_ID فرد رو به دست آورد، تو کد JSON بالا ID حاوی Chat_id فرد هست که نمونه یک پیام ارسالی به Bot هست.
    پس با بررسی پیام ارسالی هم میشه Chat_id اون بابا رو بدست آورد و هم اینکه تو Text که متن پیام هست درخواستش رو بررسی کرد و پبام مناسبی براش ارسال کرد.

    با استفاده از این بات می تونید chat_id خودتون رو دربیارید و تو تست برنامه ازش استفاده کنید :
    @get_id_bot


    ارسال پیام متنی:
    Var  IDUser : String;
    Text : WideString;
    msg : WideString;
    Src : string;
    LHandler: TIdSSLIOHandlerSocket;
    begin
    API := edtAPI.Text;
    IDUser := Edit1.Text;
    Text := edtMessage.Text;
    try
    msg := UTF8Encode('chat_id='+IDUser+'&'+'text='+ Text);
    LHandler := TIdSSLIOHandlerSocket.Create(nil);


    IdHTTP1.ReadTimeout := 30000;
    IdHTTP1.IOHandler:=LHandler;
    LHandler.SSLOptions.Method := sslvTLSv1;
    LHandler.SSLOptions.Mode := sslmUnassigned;
    IdHTTP1.HandleRedirects := true;
    memoRequest.Text := BaseUrl + API + '/sendmessage?' + msg;
    Src := IdHTTP1.Get(BotUrl + API +'/sendmessage?' + msg);
    memoResponse.lines.clear;
    memoresponse.lines.add(src);
    except
    on E: EIdHTTPProtocolException do
    begin
    memoRequest.Text := IdHTTP1.Response.RawHeaders.Text;
    if not ((E.ReplyErrorCode = 301) or (E.ReplyErrorCode = 302)) then raise;
    Src := E.ErrorMessage;
    ShowMessage(Src);
    end
    end;


    در این کد چون ارتباط ما رو رو تلگرام بصورت اتوماتیک قطع می کنه Indy یک خطا صادر میکنه با متن زیر که الان که تاریخ 26 تیر 95 هست دارم روش کار میکنم ببینم می تونم خفتش کنم یا نه. البته برنامه بدون هیچ مشکلی کار میکنه.
    Connection Closed Gracefully


    دوستان و اساتید اگه بابت رفع این خطا بتونن راهنمایی کنم ممنون میشم .

    خوب حالا کد زیر پیام هایی رو که از طرف افراد مختلف برای Bot ارسال شده رو در قالب JSON برای شما میاره البته JSON رو من در این کد به اصطلاح Deserialize می کنم.
    var  Offset:integer;
    msg : WideString;
    Src : string;
    LHandler: TIdSSLIOHandlerSocket;
    begin
    API := edtAPI.Text;
    try
    Offset := 0;
    msg := UTF8Encode('/getUpdates');
    //msg := UTF8Encode('/Update?update_id=1');
    LHandler := TIdSSLIOHandlerSocket.Create(nil);


    IdHTTP1.ReadTimeout := 30000;
    IdHTTP1.IOHandler:=LHandler;
    LHandler.SSLOptions.Method := sslvTLSv1;
    LHandler.SSLOptions.Mode := sslmUnassigned;
    IdHTTP1.HandleRedirects := true;
    memoRequest.Text := BaseUrl + API + msg;
    Src := IdHTTP1.Get(BotUrl + API + msg);
    memUpdates.lines.clear;
    DeserializeJSON(src);
    //memUpdates.lines.add(src);
    except
    on E: EIdHTTPProtocolException do
    begin
    //memoRequest.Text := IdHTTP1.Response.RawHeaders.Text;
    if not ((E.ReplyErrorCode = 301) or (E.ReplyErrorCode = 302)) then raise;
    Src := E.ErrorMessage;
    ShowMessage(Src);
    end
    end;

    اینم کد Deserialize کردن JSON
    procedure TForm1.DeserializeJSON(returnval: string);var
    systems : TStrings;
    returnval2: string;
    json , item , ResultNode , OKNode , msgNode ,fromNode :TlkJSONbase;
    i,j: integer;
    list: TlkJSONObject;
    okVal : boolean;
    nodename : String;
    begin
    json:= TlkJSON.ParseText(returnval);
    OKNode := TlkJSONboolean(json).Field['ok'];
    okVal := OKNode.Value;
    ResultNode := TlkJSONlist(json).Field['result'];
    for i := 0 to pred(ResultNode.Count) do
    begin
    item := TlkJSONlist(ResultNode).child[i];
    msgNode := TlkJSONObject(item).Field['message'];


    memUpdates.Lines.Add('Update_id: ' + VarToStr(item.Field['update_id'].Value));


    if msgNode.Field['from'].Field['id'] <> nil then
    memUpdates.Lines.Add('Chat_id: ' + VarToStr(msgNode.Field['from'].Field['id'].Value));


    if msgNode.Field['from'].Field['first_name'] <> nil then
    memUpdates.Lines.Add('first_name: ' + VarToStr(msgNode.Field['from'].Field['first_name'].Value));


    if msgNode.Field['from'].Field['last_name'] <> nil then
    memUpdates.Lines.Add('last_name: ' + VarToStr(msgNode.Field['from'].Field['last_name'].Value));


    if msgNode.Field['from'].Field['username'] <> nil then
    memUpdates.Lines.Add('username: ' + VarToStr(msgNode.Field['from'].Field['username'].Value));


    if msgNode.Field['text'] <> nil then
    memUpdates.Lines.Add('Message Text: ' + VarToStr(msgNode.Field['text'].Value));


    memUpdates.Lines.Add('-----------------------------');


    end;
    end;


    متد GetUpdates ربات تلگرام پارامترهای مختلفی داره که می تونید اونا رو از آدرس زیر بررسی بفرمایید که می تونن تعداد خاصی پیام رو خفت کنه و برای شما بیاره. حالا پیام های دریافتی رو می تونید بررسی بفرمایید و اولا Chat_id رو بردارید و تو بانک اطلاعاتی خودتون ذخیره کنید و همچنین پاسخ مناسب به افرادی که کامند خاصی رو درخواست کردن ، بدهید. قاعدتا این بخش خود باید بصور مثال هر چند لحظه هی اجرا بشه تا درخواست ها رو بگیره از BOT. این کار باعث میشه که بات شما کاملا Interactive بشه. متد های تلگرام رو بررسی بفرمایید متد Update هم داره.

    درپایان هم عاجزانه تقاضا دارم از دوستانی که این کد رو توسعه می دن . هر کسی به نتیجه های خوبی رسید مثلا ارسال عکس و استیکر و فایل و اینا رو بهش اضافه کردید برای من و بقیه دوستان دیگه هم بذارید.


    کوچیک همه شما.
    مهدی جعفری

    توجه: در چند پست پایین تر آخرین نسخه ویرایش شده رو گذاشتم اون رو دانلود بفرمایید
    فایل های ضمیمه فایل های ضمیمه
    آخرین ویرایش به وسیله mjdeveloper : سه شنبه 05 مرداد 1395 در 14:08 عصر

  2. #2

    نقل قول: کار با API ربات تلگرام در دلفی 7

    سلام
    ممنون از به اشتراك گذاري اين مطلب

  3. #3
    کاربر دائمی آواتار joker
    تاریخ عضویت
    بهمن 1381
    محل زندگی
    اصفهان
    سن
    42
    پست
    1,326

    نقل قول: کار با API ربات تلگرام در دلفی 7

    اینم نسخه XE5


    dllهای سازگار با indy 10
    http://indy.fulgan.com/SSL/openssl-1...i386-win32.zip
    فایل های ضمیمه فایل های ضمیمه

  4. #4
    کاربر دائمی آواتار mjdeveloper
    تاریخ عضویت
    بهمن 1385
    محل زندگی
    تهران
    پست
    124

    نقل قول: کار با API ربات تلگرام در دلفی 7

    خیلی سپاسگزارم امیدوارم بقیه دوستان هم تو توسعه این کد کمک کنن تا بقیه هم استفاده کنن.

  5. #5
    کاربر دائمی آواتار mjdeveloper
    تاریخ عضویت
    بهمن 1385
    محل زندگی
    تهران
    پست
    124

    نقل قول: کار با API ربات تلگرام در دلفی 7

    من روی ارسال تصویر در تلگرام کار میکنم

    کد زیر رو برای post کردن عکس زدم ولی جواب نمیده . خطای read timeout یا unsupported media type میده . اساتید لطفا کمک کنید


    varIDUser : String;
    Stream: TStringStream;
    Params: TIdMultipartFormDataStream;
    msg : WideString;
    LHandler: TIdSSLIOHandlerSocket;
    Src , boundry : string;
    begin
    API := edtAPI.Text;
    IDUser := Edit1.Text;
    Stream := TStringStream.Create('');
    try
    Params := TIdMultipartFormDataStream.Create;
    try
    //Params.AddFile('File1', 'C:\test.txt','image/png');
    Params.AddFormField('chat_id',IDUser);
    Params.AddFile('File1', 'E:\image.png','image/png');
    //Data.CopyFrom(Params,0);
    //Params.AddFormField(' test',',');
    try
    msg := '/sendPhoto';
    LHandler := TIdSSLIOHandlerSocket.Create(nil);
    //IdHTTP1.Request.ContentType := 'multipart/form-data';
    IdHTTP1.ReadTimeout := 30000;
    IdHTTP1.IOHandler:=LHandler;
    LHandler.SSLOptions.Method := sslvTLSv1;
    LHandler.SSLOptions.Mode := sslmUnassigned;
    IdHTTP1.HandleRedirects := true;
    IdHTTP1.Request.ContentType := 'multipart/form-data';

    idhttp1.Request.SetHeaders;
    memoResponse.Text :=idhttp1.Request.RawHeaders.Text;
    memoRequest.Text := BaseUrl + API + msg;
    IdHTTP1.Post(BaseUrl + API + msg, Params,Stream);
    except
    on E: Exception do
    showmessage('Error encountered during POST: ' + E.Message+ ': '
    + intToStr(IdHTTP1.Response.ResponseCode))
    end;
    ShowMessage(Stream.DataString);
    finally
    Params.Free;
    end;
    finally
    Stream.Free;
    end;

  6. #6
    کاربر دائمی آواتار mjdeveloper
    تاریخ عضویت
    بهمن 1385
    محل زندگی
    تهران
    پست
    124

    نقل قول: کار با API ربات تلگرام در دلفی 7

    دوستان سلام
    این هم کد ارسال تصویر با ربات تلگرام

    Use IdMultipartFormData


    procedure TForm1.SendPostData;var
    Stream: TStringStream;
    Params: TIdMultipartFormDataStream;
    msg : WideString;
    LHandler: TIdSSLIOHandlerSocket;
    IDUser : string;
    begin
    API := edtAPI.Text;
    IDUser := Edit1.Text;
    msg := '/sendPhoto';
    Stream := TStringStream.Create('');
    try
    Params := TIdMultipartFormDataStream.Create;
    try
    Params.AddFile('photo', 'E:\image.png','');
    Params.AddFormField('chat_id',IDUser);
    Params.AddFormField('caption','this is a image caption!');
    try
    LHandler := TIdSSLIOHandlerSocket.Create(nil);
    //IdHTTP1.ReadTimeout := 300000;
    IdHTTP1.IOHandler:=LHandler;
    LHandler.SSLOptions.Method := sslvTLSv1;
    LHandler.SSLOptions.Mode := sslmUnassigned;
    IdHTTP1.HandleRedirects := true;
    //idhttp1.Request.ContentType := Params.RequestContentType;
    memoRequest.Text := BaseUrl + API + msg;
    IdHTTP1.Post(BaseUrl + API + msg, Params, Stream);
    except
    on E: Exception do
    ShowMessage('Error encountered during POST: ' + E.Message);
    end;
    ShowMessage(Stream.DataString);
    finally
    Params.Free;
    end;
    finally
    Stream.Free;
    end;
    end;

  7. #7
    کاربر دائمی آواتار mjdeveloper
    تاریخ عضویت
    بهمن 1385
    محل زندگی
    تهران
    پست
    124

    نقل قول: کار با API ربات تلگرام در دلفی 7

    برای ارسال caption فارسی این تیکه کد رو تغییر بدین
    Params.AddFormField('caption',UTF8Encode('تست ارسال فارسی'));

  8. #8

    نقل قول: کار با API ربات تلگرام در دلفی 7

    درود بر شما جناب جعفری! آیا راجع به حل مشکل پیام خطای صادر شده از Indy راه حلی پیدا کردید؟

  9. #9
    کاربر دائمی آواتار mjdeveloper
    تاریخ عضویت
    بهمن 1385
    محل زندگی
    تهران
    پست
    124

    نقل قول: کار با API ربات تلگرام در دلفی 7

    دوستان سلام کد ارسال پیام متنی با استفاده از بات تلگرام رو تصحیح کردم که خطای Cannection Closed Carefully رو نده دیگه:

    Var
    Stream: TStringStream;
    Params: TIdMultipartFormDataStream;
    IDUser : String;
    Text : WideString;
    msg : WideString;
    Src : string;
    LHandler: TIdSSLIOHandlerSocket;
    begin
    API := edtAPI.Text;
    IDUser := Edit1.Text;
    Text := edtMessage.Text;
    try
    try
    msg := '/sendmessage';
    Stream := TStringStream.Create('');
    Params := TIdMultipartFormDataStream.Create;
    Params.AddFormField('chat_id',IDUser);
    Params.AddFormField('text',UTF8Encode('ارسال پيام با استفاده ار بات تلگرام'));


    LHandler := TIdSSLIOHandlerSocket.Create(nil);
    IdHTTP1.ReadTimeout := 30000;
    IdHTTP1.IOHandler:=LHandler;
    LHandler.SSLOptions.Method := sslvTLSv1;
    LHandler.SSLOptions.Mode := sslmUnassigned;
    IdHTTP1.HandleRedirects := true;
    memoRequest.Text := BaseUrl + API + msg;
    IdHTTP1.Post(BaseUrl + API + msg, Params, Stream);
    memoResponse.Text := Stream.DataString;
    finally
    Params.Free;
    Stream.Free;
    ENd;
    except
    on E: EIdHTTPProtocolException do
    begin
    memoRequest.Text := IdHTTP1.Response.RawHeaders.Text;
    if not ((E.ReplyErrorCode = 301) or (E.ReplyErrorCode = 302)) then raise;
    Src := E.ErrorMessage;
    ShowMessage(Src);
    end
    end;
    end;

  10. #10
    کاربر دائمی آواتار mjdeveloper
    تاریخ عضویت
    بهمن 1385
    محل زندگی
    تهران
    پست
    124

    Cool نقل قول: کار با API ربات تلگرام در دلفی 7

    دوستان نسخه جدید و اصلاح شده رو کامل میذارم . ما رو از دعای خیرتون بی نصیب نکنید.
    فایل های ضمیمه فایل های ضمیمه

  11. #11

    نقل قول: کار با API ربات تلگرام در دلفی 7

    جناب جعفری ضمن عرض تشکر و دعای خیر برای جنابعالی!
    ظاهرا یه پیام خطا برای افرادی که بات ایجاد شده را در تلگرامشان استارت نکرده اند و یا آن را بلاک کردند صادر می شود...
    HTTP/1.1 403 Forbiden
    امکان فارسی سازی یا هندل آن هست؟

  12. #12
    کاربر دائمی آواتار mjdeveloper
    تاریخ عضویت
    بهمن 1385
    محل زندگی
    تهران
    پست
    124

    نقل قول: کار با API ربات تلگرام در دلفی 7

    نمیشه گفت خطا میده . معمولا ایندی برای گزارش روی IDE در حالت Debug این خطا رو نمایش میده. برای خفت کردنش قسمت Exception رو تغییر بدید حله.

    procedure TForm1.btnSendMsgClick(Sender: TObject);Var
    Stream: TStringStream;
    Params: TIdMultipartFormDataStream;
    IDUser : String;
    Text : WideString;
    msg : WideString;
    Src : string;
    LHandler: TIdSSLIOHandlerSocket;
    begin
    API := edtAPI.Text;
    IDUser := Edit1.Text;
    Text := edtMessage.Text;
    try
    try
    msg := '/sendmessage';
    Stream := TStringStream.Create('');
    Params := TIdMultipartFormDataStream.Create;
    Params.AddFormField('chat_id',IDUser);
    Params.AddFormField('text',UTF8Encode(edtMessage.T ext));


    LHandler := TIdSSLIOHandlerSocket.Create(nil);
    IdHTTP1.ReadTimeout := 30000;
    IdHTTP1.IOHandler:=LHandler;
    LHandler.SSLOptions.Method := sslvTLSv1;
    LHandler.SSLOptions.Mode := sslmUnassigned;
    IdHTTP1.HandleRedirects := true;
    memoRequest.Text := BaseUrl + API + msg;
    IdHTTP1.Post(BaseUrl + API + msg, Params, Stream);
    memoResponse.Text := Stream.DataString;
    finally
    Params.Free;
    Stream.Free;
    ENd;
    except
    on E: EIdHTTPProtocolException do
    begin
    memoRequest.Text := IdHTTP1.Response.RawHeaders.Text;
    memoResponse.Text := IdHTTP1.Response.ResponseText;
    if E.ReplyErrorCode = 403 then
    begin
    ShowMessage('Bot was blocked by the user');
    end;
    end;
    end;
    end;

  13. #13

    نقل قول: کار با API ربات تلگرام در دلفی 7

    با عرض سلام خدمت اساتید محترم.
    یه سوال داشتم... میخوام یکسری شماره تلفن(فرض کنید یک فایل اکسل یا ورد شامل 1000 شماره تلفن) بصورت خودکار به تلگرام مخصوص PC اضافه (ادد) کنم.آیا راهی وجود داره؟
    با تشکر

  14. #14
    کاربر دائمی آواتار mjdeveloper
    تاریخ عضویت
    بهمن 1385
    محل زندگی
    تهران
    پست
    124

    Cool نقل قول: کار با API ربات تلگرام در دلفی 7

    با سلام خدمت دوستان


    ادامه مقاله رو به درخواست دوستان می خوام تکمیل کنم و مباحث حرفه ای در مورد ربات تلگرام و هندلینگ اون با دلفی رو توضیح بدم. و سعی بر اینه که دلفی کارهای محترم از سایر زبان ها تو این زمینه عقب نیفتن.

    در این مقاله سعی میکنم نحوه نوشتن سرویس بصورت Thread و مبحث long Polling که قطعا قسمت مهم کار هست رو توضیح بدم و همچنین طریقه افزودن ReplyKeyboardMarkup و InlineKeyboardMarkup و Callbackquery رو و مهم اینکه چطوری از پایگاه داده دیتا مورد نظر رو با توجه به درخواست به طرف نمایش بدیم.

    دکمه های ReplyKeyboardMarkup دکمه هایی هستند که زیر بخش نوشتن پیام اضافه میشن و می تونن به عنوان منو استفاده بشن.
    دکمه های InlineKeyboardMarkup دکمه هایی هستن که زیر پیام ظاهر میشن و با CallBack Query مدیریت میشن و میشه کلیک کاربر رو فهمید. بطور مثال نظرسنجی

    خوب، ما به دو طریق می تونیم با ربات تلگرام ارتباط داشته باشیم و پیام ها و دستوراتی که با بات ارسال میشه رو دریافت کنیم . یکی Webhook هست که قطعا به یک هاست و سرویس اینترنتی نیاز داره، در واقع webhook آدرس اینترنتی هست که به بات معرفی میشه و بات از این به بعد هر پیام رو که دریافت می کنه بصورت اتوماتیک به آدرس Webhook میفرسته.خوب ما اینجا چون یه سرویس ویندوزی می نویسیم با این امکان کار نداریم پس باید خودمون دست به کار بشیم و پیام های بات رو در یک سرویس که تعطیل نمیشه هی واکشی کنیم و جواب مناسب رو به هر پیام بدیم.
    قبلا عرض کرده بودم که بات فقط با Chat_id کار میکنه و هر شخص یا بهتر بگیم اکانت تلگرام یه Chat_ID منحصر بفرد داره که می تونیم برای اطلاع رسانی های بعدی این Chat_id رو تو بانک ذخیره کنیم.

    خوب بریم سراغ کد نویسی
    چیزی که برای شروع کار بهش نیاز داریم یک ربات خشک و خالی هست که با BotFather@ می سازید و Token ربات رو دریافت میکنید. که با چند دستور ساده تلگرام برای شما میسازه.
    یک عدد دلفی و اینترنت

    در این کد نویسی من از indy و کامپوننت idHttp استفاده می کنم روی دلفی 7 . (کوزه گریم دیگه)
    کنار نرم افزارمون چند تا dll هم استفاده میشه که libeay32.dll و ssleay32.dll هست دقت کنید این Dllها با ورژن ایندی باید مطابقت داشته باشه. ایندی من 9.00.10 هست.

    بسیار عالی، کنار نرم افزار ما یه setting.ini هست با Notepad بازش کنید و توکن بات رو توش قرار بدین. کانکشن بانک اطلاعاتی هم می تونه اینجا قرار بگیره . تو این کد من فعلا غیر فعالش کردم . خودتون بخش های غیر فعال شده رو می تونید درست کنید.
    (ببخشید یخورده جو گرفته منو بذارین خودمونی تر بگم)

    حالا می خوام کدها رو شرح بدم خدمت شما:
    uses  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection,
    IdTCPClient, IdHTTP,IdSSLOpenSSL, Buttons, IdMultipartFormData, OleCtrls,
    SHDocVw,IniFiles, DB, ADODB, ExtCtrls;

    بخش uses که معرفی حضورتون هست

    خوب برای اینکه بتونیم Long Polling پیاده کنیم من از thread برای این کار استفاده کردم
    type  TBotThread = class(TThread)
    private
    protected
    procedure Execute; override;
    Procedure WriteToLog(st:string);
    procedure SendMessage(ChatID, Text, parse_mode:string;disable_notification:boolean);
    procedure SendMessageAndKey(ChatID,Text,Keys, parse_mode:string;disable_notification:boolean);

    // Get Data From DB For Learn!
    Function GetDataFromDB(ChatID:String;mode: Integer) : WideString;

    Function CheckNumbers(NCode:String) : Boolean;

    public
    FActive: Boolean ;
    FidHttpGet : TIdHTTP;
    FidHttpSend : TIdHTTP;
    Fmemo : TMemo;
    FConnection: TADOConnection;
    FAdoDataset : TADODataSet;
    FBotUser : String;
    FShowBotLink : Boolean;
    constructor Create(Active:Boolean;IdHTTPGet,idHttpSend : TIdHTTP;memo : TMemo);
    destructor Destroy; override;
    end;


    در این نرم افزار کوچک ولی هوشمند، من از سه کامپوننت idHttp استفاده می کنم یکی برای گرفتن اطلاعات ربات، یکی برای دریافت پیام های بات و یکی هم برای ارسال پیام.
    در کد بالا دو متد SendMessage و SendMessageAndkey رو پیاده کردم که متد اول پیام ساده ارسال می کنه و متد دوم علاوه بر پیام ساده یک کیبورد هم اضافه می کنه که همون منوهای پایین بات هست.
    یه سری از کامپوننت های روی فرم اصلی رو ترد همینطوری نمیشناسه پس باید براش تعریف کنیم و موقع ساخت بهش بدیم مثل دو تا idHttp کانکشن بان و همچنین یه Dataset نام کاربری بات رو برای نمایش ته هر پیام.
    متدی هم به نام GetDataFromDB براش تعریف کردم تا داده ها رو از بانک اطلاعاتی بخونه و با توجه به درخواست کاربر بهش نمایش بده. شما می تونید متد های مختلفی داشته باشید که هر متد اطلاعات خاصی رو از بانک واکشی کنه.
    یه متد WriteToLog هم گذاشتم تا خطاهای Thread لاگ کنه.

    خوب بریم سراغ تعریف های اولیه و ساخت THread
    var  fmMain: TfmMain;
    API : string;
    ini : TIniFile;
    ConnStr : string;
    TelegService : TBotThread;


    implementation


    uses uLkJSON, un_SyncLog, ConstUnit, UGutility;




    تنظیماتی مثل Token بات و همچنین کانکشن بانک رو از فایل Setting.ini کنار برنامه می خونم.
    procedure TfmMain.LoadSetting;var
    i, Timecount : integer;
    begin
    try
    ini := TIniFile.Create(ExtractFilePath(Application.ExeNam e)+'Setting.ini');
    Connstr := ini.ReadString('Server','ConnectionString','');
    API := ini.ReadString('Telegram' , 'Token' , '');
    finally
    ini.Free;
    end;
    end;


    این متد پایین لاگ رو پر میکنه:
    procedure TfmMain.WriteToLog(st: string);var logFile : TextFile;
    logdate : String;
    begin
    AssignFile(logFile, 'TelegLog.txt');
    if FileExists('TelegLog.txt') then
    Append(logFile)
    else
    Rewrite(logFile);
    logdate := DateTimeToStr(Now);
    Writeln(logFile,logdate + ' - ' + st);
    CloseFile(logFile);
    end;


    procedure TfmMain.ResetLog;
    var logFile : TextFile;
    begin
    AssignFile(logFile, 'TelegLog.txt');
    Rewrite(logFile);
    CloseFile(logFile);
    end;


    متد زیر هم اطلاعات بات رو که با متد Getme از تلگرام در قالب json گرفته میشه رو Deserialize می کنه و تو دو تا Label نمایش میده.
    procedure TfmMain.DeserializeJSONBotInfo(returnval: string);var
    systems : TStrings;
    returnval2: string;
    json , item , ResultNode , OKNode , msgNode ,fromNode :TlkJSONbase;
    i,j: integer;
    list: TlkJSONObject;
    okVal : boolean;
    nodename : String;
    begin
    json:= TlkJSON.ParseText(returnval);
    OKNode := TlkJSONboolean(json).Field['ok'];
    okVal := OKNode.Value;
    ResultNode := TlkJSONlist(json).Field['result'];
    if okVal then
    begin
    lblBotName.Caption := VarToStr(ResultNode.Field['first_name'].Value);
    lblUserName.Caption := '@' + VarToStr(ResultNode.Field['username'].Value);
    end;
    end;


    خوب حالا بریم سراغ متد های Thread
    متد constructor برای ترد که دوتا idHttp و یک Memo رو توش میفرستم تا پیام های دریافتی رو تو Memo مونیتور کنه.
    constructor TBotThread.Create(Active: Boolean;IdHTTPGet,idHttpSend : TIdHTTP;memo : TMemo);begin
    inherited Create(True);
    FActive := Active;
    FIDHTTPGet := IdHTTPGet;
    FidHttpSend := idHttpSend;
    Fmemo := memo;
    end;


    اینم Destroy
    destructor TBotThread.Destroy;begin
    inherited Destroy;
    end;


    خوب متد های SendMessage و SendMessageAndKey رو قبل از متد Execute که متد اصلی ما هست توضیح میدم: ابتدا کل متد و سپس خط به خط توضیحش رو میدم تا براتون روشنتر بشه قضیه:
    procedure TBotThread.SendMessage(ChatID, Text, 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','tr ue');
    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;


    متد SendMessage پارامترهایی داره که دوتاش مشخصه پارامتر Parse_mode تو ارسال پیام تلگرام می تونه با مقادیر html و markdown استفاده بشه که نمایانگر فرمت پیام شماست. حالا پیام شما می تنه در قالب html و یا با کاراکتر هایی که برای تلگرام کلاینت معنا و مفهوم خاصی داره، ارسال بشه. برای اینکه بهتر درک کنید یه سر به اینجا بزنید
    پارامتر disable_notification هم به پیام میگه بصورت Silent بره یا نه با سر و صدا بره!
    یه پارامتر هم به نام disable_web_page_preview تو این کد استفاده کردم که باعث میشه اگر متن پیامتون حاوی لینک باشه پایین پیام Preview این صفحه اینترنتی رو نمایش بده یا نه.
    دیتا رو هم بصورت MultipartFormData به سرور تلگرام ارسال میکنیم.

    خوب حالا متد SendMessageAndKey رو توضیحش رو خدمت شما بدم.

    procedure TBotThread.SendMessageAndKey(ChatID, Text,Keys, parse_mode: string;disable_notification:Boolean);Var
    Stream: TStringStream;
    Params: TIdMultipartFormDataStream;
    msg : WideString;
    Src : string;
    LHandler: TIdSSLIOHandlerSocket;
    Json : TMemoryStream;
    btn : string;
    UTF8 : UTF8String;
    BytesCount : integer;
    begin
    btn := keys;
    Json := TMemoryStream.Create;
    UTF8 := AnsiToUtf8(btn);
    BytesCount := Length(UTF8);
    Json.WriteBuffer(UTF8[1], BytesCount);
    Json.Position := 0;
    try
    try
    if FShowBotLink then
    Text := Text + LineBreak + FBotUser;
    msg := '/sendmessage';
    Stream := TStringStream.Create('');
    Params := TIdMultipartFormDataStream.Create;
    Params.AddObject('reply_markup','application/json',Json);
    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('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;


    این متد علاوه بر پارامتر های متد SendMessage یه پارامترKeys هم اضافه داره که این پارامتر حاوی اون کیبوردی هست که می خوای پایین بات یا زیر پیامتون نمایش داده بشه.
    این کیبورد ها در قالب شی Json همراه با متن پیام ما ارسال میشه یه نمونه از این کیبوردها اینطوری هست:

      MainMenu = '{"keyboard": [["منوي2","منوي1"],["منوي4", "منوي3"],["ارتباط با ما" ,"منوي5"]], "resize_keyboard": true }';


    دو نوع کیبود داریم که یکی ReplyKeyboardMarkup هست و دیگری InlineKeyboardMarkup

    نمونه inline keyboard :
    LikeMenuInline = '{"inline_keyboard": [[{ "text": "Delphi", "callback_data": "Delphi" }],[{ "text": "Asp.net", "callback_data": "Asp.net" }],[{ "text": "Java","callback_data": "Java" }]]}';


    ReplyKeyboardMarkup در پایین بات ظاهر میشه و InlineKeyboardMarkup پایین پیام ارسالی.

    ReplyKeyboardMarkup یک آرایه ای از آرایه های متنی هست که بسته به تعداد آرایه های داخلی، تعداد سطر و ستون دکمه ها تعیین میشه. کاربر با کلیک بر روی هر دکمه باعث میشه متن دکمه ارسال بشه بصورت پیام ساده که حاوی شی JSON Message هست
    InlineKeyboardMarkup هم یه آرایه ای از InlineKeyboardButton هست که خود اون فیلدهایی مثل Text و Callback_data یا همون مقداری که برگشت داده میشه هست. کاربر با کلیک روی این دکمه باعث میشه فرمتی متفاوت از پیام معمولی برای بات ارسال بشه که حاوی شی JSON به نام callback_query هست و اطلاعاتی از قیبل ارسال کننده، پیام و مهم تر از همه data هست که همون مقدار callback_data دکمه هست.

    نمونه یک دریافت کلیک InlineKeyboardMarkup به صورت json:

    '{"ok":true,"result":[{    "update_id":485550139,'#$A'
    "callback_query":{
    "id":"339563465400824028",
    "from":{
    "id":11111111,
    "first_name":"mehdi",
    "last_name":"Jafari",
    "username":"ShahvarIMS"
    },
    "message":{
    "message_id":165,
    "from":{
    "id":200483732,
    "first_name":"Shahvar2Bot",
    "username":"Shahvar2bot"
    },
    "chat":{
    "id":11111111,
    "first_name":"mehdi",
    "last_name":"Jafari",
    "username":"ShahvarIMS",
    "type":"private"
    },
    "date":1474169323,
    "text":"\u0634\u0645\u0627 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0641\u0639\u0627\u0644\u0633\u0627\u0632\u064a
    \u0648 \u0627\u0637\u0644\u0627\u0639 \u0631\u0633\u0627\u0646\u064a \u0628\u0631\u0627\u064a
    \u0647\u0646\u0631\u0622\u0645\u0648\u0632 \u0634\u064a\u0631\u0632\u0627\u062f \u0622\u0698\u064a\u0631
    \u0631\u0627 \u062f\u0627\u0631\u064a\u062f \u0622\u064a\u0627 \u062a\u0627\u064a\u064a\u062f
    \u0645\u064a \u0646\u0645\u0627\u064a\u064a\u062f\u061f\n@Shahv ar2bot",
    "entities":[{
    "type":"mention",
    "offset":90,
    "length":12
    }]
    },
    "data":"1"
    }
    }]}'


    خوب حالا میرم سراغ قسمت اصلی ماجرا یعنی متد Execute ترد:

    procedure TBotThread.Execute;var
    Offset:integer;
    msg : WideString;
    Src : WideString;
    LHandler: TIdSSLIOHandlerSocket;
    last_update_id : int64;
    json , item , ResultNode , OKNode , msgNode ,fromNode :TlkJSONbase;
    i,j: integer;
    list: TlkJSONObject;
    okVal : boolean;
    nodename : String;
    MessageText : WideString;
    ChatID, username , NCode , CallbackData: String;
    IsOKCommand : Boolean;
    SaveRet : integer;
    begin
    msg := UTF8Encode('/getUpdates');
    LHandler := TIdSSLIOHandlerSocket.Create(nil);
    FidHttpGet.ReadTimeout := 60000;
    FidHttpGet.IOHandler:=LHandler;
    LHandler.SSLOptions.Method := sslvTLSv1;
    LHandler.SSLOptions.Mode := sslmUnassigned;
    FidHttpGet.HandleRedirects := true;
    last_update_id := 0;
    while not Terminated do
    Begin
    try
    Src := FidHttpGet.Get(BotUrl + API + msg + '?offset=' + IntToStr(last_update_id + 1));
    json:= TlkJSON.ParseText(Src);
    OKNode := TlkJSONboolean(json).Field['ok'];
    okVal := OKNode.Value;
    ResultNode := TlkJSONlist(json).Field['result'];
    if ResultNode.Count > 0 then
    Begin
    Fmemo.Clear;
    item := TlkJSONlist(ResultNode).child[ResultNode.Count - 1];
    last_update_id := StrToInt64(VarToStr(item.Field['update_id'].Value));
    for i := 0 to pred(ResultNode.Count) do
    begin
    CallbackData := '';
    IsOKCommand := False;
    MessageText := 'No Message';
    item := TlkJSONlist(ResultNode).child[i];
    if TlkJSONObject(item).Field['message'] <> nil then
    Begin
    msgNode := TlkJSONObject(item).Field['message'];
    if msgNode.Field['update_id'] <> nil then
    Fmemo.Lines.Add('Update_id: ' + VarToStr(item.Field['update_id'].Value));
    if msgNode.Field['from'].Field['id'] <> nil then
    Begin
    ChatID := VarToStr(msgNode.Field['from'].Field['id'].Value);
    Fmemo.Lines.Add('Chat_id: ' + ChatID);
    End;
    if msgNode.Field['from'].Field['first_name'] <> nil then
    Fmemo.Lines.Add('first_name: ' + VarToStr(msgNode.Field['from'].Field['first_name'].Value));
    if msgNode.Field['from'].Field['last_name'] <> nil then
    Fmemo.Lines.Add('last_name: ' + VarToStr(msgNode.Field['from'].Field['last_name'].Value));
    if msgNode.Field['from'].Field['username'] <> nil then
    Begin
    username := VarToStr(msgNode.Field['from'].Field['username'].Value);
    Fmemo.Lines.Add('username: ' + username);
    End;
    if msgNode.Field['text'] <> nil then
    Begin
    MessageText := VarToStr(msgNode.Field['text'].Value);
    Fmemo.Lines.Add('Message Text: ' + MessageText);
    End;
    End
    Else
    Begin
    if TlkJSONObject(item).Field['callback_query'] <> nil then
    Begin
    msgNode := TlkJSONObject(item).Field['callback_query'];
    if msgNode.Field['from'].Field['id'] <> nil then
    Begin
    ChatID := VarToStr(msgNode.Field['from'].Field['id'].Value);
    Fmemo.Lines.Add('Chat_id: ' + ChatID);
    End;
    if msgNode.Field['from'].Field['first_name'] <> nil then
    Fmemo.Lines.Add('first_name: ' + VarToStr(msgNode.Field['from'].Field['first_name'].Value));
    if msgNode.Field['from'].Field['last_name'] <> nil then
    Fmemo.Lines.Add('last_name: ' + VarToStr(msgNode.Field['from'].Field['last_name'].Value));
    if msgNode.Field['from'].Field['username'] <> nil then
    Begin
    username := VarToStr(msgNode.Field['from'].Field['username'].Value);
    Fmemo.Lines.Add('username: ' + username);
    End;
    if msgNode.Field['data'] <> nil then
    Begin
    CallbackData := VarToStr(msgNode.Field['data'].Value);
    Fmemo.Lines.Add('Callback_data: ' + CallbackData);
    End;
    End;
    End;
    if (UpperCase(MessageText) = '/START') OR (UpperCase(MessageText) = '/ACTIVATE') then
    Begin
    SendMessageAndKey(ChatID, 'درود بر شما ' + LineBreak + 'به ربات هوشمند من خوش آمديد'+
    LineBreak + 'تبريک ربات کار ميکنه' ,MainMenu,'',false);


    WriteToLog('ChatID:' + ChatID + ' username:' + username );
    Continue;
    //Sleep(500);
    //SendMessageAndKey(ChatID, 'درود بر شما ' + #13#10 + 'به ربات هوشمند شاهوار خوش آمديد');
    End
    else
    Begin
    if (MessageText = 'No Message') And (CallbackData = '') then
    Begin
    SendMessage(ChatID, IncorrectChoose,Markdown,True);
    IsOKCommand := true;
    Continue;
    End
    Else
    Begin
    if CallbackData = 'yes' then
    Begin
    SendMessageAndKey(ChatID, congratulation,MainMenu,Markdown,True)
    End;
    if CallbackData = 'no' then
    Begin
    SendMessageAndKey(ChatID, 'شما خير را انتخاب کرديد!!!',MainMenu,Markdown,True)
    End;

    if MessageText = Widestring(Menu_Item1) then
    SendMessageAndKey(ChatID, PleaseChooseItem,SubMenu,Markdown,True);

    if MessageText = Widestring(Menu_Item2) then
    SendMessageAndKey(ChatID, 'آيا مطمئن هستيد؟' + LineBreak + 'نمونه پرسيدن يک سوال از کاربر',ConfirmMenuInLine,Markdown,True);

    if MessageText = Widestring(Menu_Item3) then
    SendMessageAndKey(ChatID, 'نمونه نظر سنجي' + LineBreak + 'کدام زبان برنامه نويسي رو دوست داريد؟',LikeMenuInline,Markdown,True);

    if MessageText = Widestring(Menu_MainMenu) then
    SendMessageAndKey(ChatID, PleaseChooseItem,MainMenu,Markdown,True);

    if MessageText = Widestring(Menu_ContactUs) then
    SendMessage(ChatID, GetCompanyInfo ,Markdown,False);

    // Get SbMenu Items And Answer it From Data Base
    if MessageText = Widestring(SubMenu_LastItem) then
    SendMessageAndKey(ChatID, GetDataFromDB(ChatID,1),SubMenu,HTML,False);

    if MessageText = Widestring(SubMenu_3Item) then
    SendMessageAndKey(ChatID, GetDataFromDB(ChatID,2),SubMenu,HTML,False);

    if MessageText = Widestring(SubMenu_AllItems) then
    SendMessageAndKey(ChatID, GetDataFromDB(ChatID,3),SubMenu,HTML,False);

    if CallbackData = 'Delphi' then
    Begin
    SendMessageAndKey(ChatID, 'شما ' + CallbackData + ' را انتخاب کرديد',MainMenu,Markdown,True)
    End;

    if CallbackData = 'Asp.net' then
    Begin
    SendMessageAndKey(ChatID, 'شما ' + CallbackData + ' را انتخاب کرديد',MainMenu,Markdown,True)
    End;

    if CallbackData = 'Java' then
    Begin
    SendMessageAndKey(ChatID, 'شما ' + CallbackData + ' را انتخاب کرديد',MainMenu,Markdown,True)
    End;
    End;

    //SendMessage(ChatID, 'شما گزينه ' + '"' + MessageText + '" ' + 'را انتخاب کرديد');
    Sleep(500);
    End;

    end;
    End
    Else
    Continue;
    except
    on E: EIdHTTPProtocolException do
    begin
    if not ((E.ReplyErrorCode = 301) or (E.ReplyErrorCode = 302)) then raise;
    Src := E.ErrorMessage;
    ShowMessage(Src);
    end
    end;
    ENd;
    end;


    بسیار خوب این متد رو توضیحش رو شروع میکنم:
    در این متد با استفاده از متد GetUpdates تلگرام ما پیام های ارسالی به بات رو واکشی میکنیم. این متد یه پارامتر به نام Offset داره که می تونه حاوی Update_id یک پیام باشه. چنانچه GetUpdate بدون پارامتر فراخونی بشه تلگرام 100 پیام آخر بات رو برای ما میاره . ولی ما نمی خوای هی پیامهایی که پاسخ داده شده رو دوباره بیاره پس offset رو با آخرین update_id+1 پر میکنیم اینکار باعث میشه پیامهای پیشین بصورت اتوماتیک تلگرام اونها رو confirm کنه و دیگه تو getupdate نیاد.

    مبحث Long polling رو که خدمت شما عرض کردم این حلقه اون رو پوشش میده یعنی تا زمانی که بات پیام داره باید پاسخگو باشیم .
    while not Terminated do
    Begin


    واکشی پیام ها: این خط از کد پیام ها رو واکشی میکنه: ما ابتدا last_update_id برابر صفر میذاریم و بعد با آخرین update_id پرش میکنیم.

    Src := FidHttpGet.Get(BotUrl + API + msg + '?offset=' + IntToStr(last_update_id + 1));


    پیامهای واکشی شده در Src بصورت json پر مشن و با تیکه کد زیر اونها رو deserialize میکنیم که ResultNode حاوی پیام ها خواهد بود.
    json:= TlkJSON.ParseText(Src);          OKNode := TlkJSONboolean(json).Field['ok'];
    okVal := OKNode.Value;
    ResultNode := TlkJSONlist(json).Field['result'];


    حالا در حلقه For پایین تمام پیام ها رو بررسی میکنیم و پاسخ مناسب هر پیام رو میدیم.
    if  ResultNode.Count > 0 then          Begin
    Fmemo.Clear;
    item := TlkJSONlist(ResultNode).child[ResultNode.Count - 1];
    last_update_id := StrToInt64(VarToStr(item.Field['update_id'].Value));
    for i := 0 to pred(ResultNode.Count) do
    begin


    این تیکه کد حاوی یک پیام از مجموعه پیام های بات هست
    item := TlkJSONlist(ResultNode).child[i];


    حالا ممکنه دو حالت پیش بیاد یک اینکه پیام حاوی شی Message باشه یا حاوی callback_query . اگر تو کد دقت کنید بنده دو حالت رو با if چک کردم .

    if TlkJSONObject(item).Field['message'] <> nil then

    و
    if TlkJSONObject(item).Field['callback_query'] <> nil then

    تو حالت اول یه پیام ساده یا کلیک روی ReplaykeyboardMarkup هست و تو حالت دوم InlineKeyboard کلیک شده.

    خوب حالا ما متن پیام یا Callback_data رو تو IFهای بالا دریافت می کنیم و همچنین مشخصات پیام و نفرارسالی و مهمتراز همه Chat_id فرد رو.
    حالا پاسخگویی رو شروع میکنیم

    if (UpperCase(MessageText) = '/START') OR (UpperCase(MessageText) = '/ACTIVATE') then              Begin
    SendMessageAndKey(ChatID, 'درود بر شما ' + LineBreak + 'به ربات هوشمند من خوش آمديد'+
    LineBreak + 'تبريک ربات کار ميکنه' ,MainMenu,'',false);

    WriteToLog('ChatID:' + ChatID + ' username:' + username );
    Continue;
    //Sleep(500);
    //SendMessageAndKey(ChatID, 'درود بر شما ' + #13#10 + 'به ربات هوشمند شاهوار خوش آمديد');
    End
    else
    Begin
    if (MessageText = 'No Message') And (CallbackData = '') then
    Begin
    SendMessage(ChatID, IncorrectChoose,Markdown,True);
    IsOKCommand := true;
    Continue;
    End
    Else
    Begin

    if CallbackData = 'yes' then
    Begin
    SendMessageAndKey(ChatID, congratulation,MainMenu,Markdown,True)
    End;
    if CallbackData = 'no' then
    Begin
    SendMessageAndKey(ChatID, 'شما خير را انتخاب کرديد!!!',MainMenu,Markdown,True)
    End;

    if MessageText = Widestring(Menu_Item1) then
    SendMessageAndKey(ChatID, PleaseChooseItem,SubMenu,Markdown,True);

    if MessageText = Widestring(Menu_Item2) then
    SendMessageAndKey(ChatID, 'آيا مطمئن هستيد؟' + LineBreak + 'نمونه پرسيدن يک سوال از کاربر',ConfirmMenuInLine,Markdown,True);

    if MessageText = Widestring(Menu_Item3) then
    SendMessageAndKey(ChatID, 'نمونه نظر سنجي' + LineBreak + 'کدام زبان برنامه نويسي رو دوست داريد؟',LikeMenuInline,Markdown,True);

    if MessageText = Widestring(Menu_MainMenu) then
    SendMessageAndKey(ChatID, PleaseChooseItem,MainMenu,Markdown,True);

    if MessageText = Widestring(Menu_ContactUs) then
    SendMessage(ChatID, GetCompanyInfo ,Markdown,False);

    // Get SbMenu Items And Answer it From Data Base
    if MessageText = Widestring(SubMenu_LastItem) then
    SendMessageAndKey(ChatID, GetDataFromDB(ChatID,1),SubMenu,HTML,False);

    if MessageText = Widestring(SubMenu_3Item) then
    SendMessageAndKey(ChatID, GetDataFromDB(ChatID,2),SubMenu,HTML,False);


    if MessageText = Widestring(SubMenu_AllItems) then
    SendMessageAndKey(ChatID, GetDataFromDB(ChatID,3),SubMenu,HTML,False);

    if CallbackData = 'Delphi' then
    Begin
    SendMessageAndKey(ChatID, 'شما ' + CallbackData + ' را انتخاب کرديد',MainMenu,Markdown,True)
    End;

    if CallbackData = 'Asp.net' then
    Begin
    SendMessageAndKey(ChatID, 'شما ' + CallbackData + ' را انتخاب کرديد',MainMenu,Markdown,True)
    End;

    if CallbackData = 'Java' then
    Begin
    SendMessageAndKey(ChatID, 'شما ' + CallbackData + ' را انتخاب کرديد',MainMenu,Markdown,True)
    End;

    End;


    خوب کسی که اولین بار بات شما رو ادد میکنه ابتدا با کامند Start/ شروع میکنه و باقی ماجرا دیگه تیکه کد بالا مشخصه که متن پیام با گزینه هایی مقایسه می شه و پاسخ داده میشه و با هر پاسخ امکان داره Keyboard نمایش داده شده تو بات تغییر کنه.

    این کد دکمه استارت سرویس:
    procedure TfmMain.btnStartServiceClick(Sender: TObject);begin
    TelegService := TBotThread.Create(True,IdHTTP1,IdHTTP3,memoRespons e);
    TelegService.FConnection := schlConn;
    TelegService.FAdoDataset := ADODataSet1;
    TelegService.FBotUser := lblUserName.Caption;
    TelegService.FShowBotLink := True;
    TelegService.FreeOnTerminate := true;
    TelegService.Resume;
    btnStartService.Enabled := false;
    btnStopService.Enabled := true;
    end;


    توجه: حتما ابتدا یه بات بسازید و توکن اون رو تو setting.ini بذارید و سپس اجرا کنید

    خوب در پایان هم کد براتون میذارم ولی حدود چهار ماه چشام در اومد تا به اینجا رسید
    یا علی مدد
    دوستدار همتون هستم
    مهدی جعفری
    فایل های ضمیمه فایل های ضمیمه
    آخرین ویرایش به وسیله mjdeveloper : یک شنبه 28 شهریور 1395 در 18:32 عصر

  15. #15

    نقل قول: کار با API ربات تلگرام در دلفی 7

    با سلام خدمت جناب آقای جعفری عزیز
    واقعا عالی و کامل بود و بسیار ممنون از شما که اینقدر کامل و جامع زحمت کشید

  16. #16
    کاربر دائمی آواتار mjdeveloper
    تاریخ عضویت
    بهمن 1385
    محل زندگی
    تهران
    پست
    124

    نقل قول: کار با API ربات تلگرام در دلفی 7

    دوستان پیام های خصوصی مبنی بر خطای بستن سرویس تلگرام و گرفتن Access Violation گزارش شده که کد های زیر رو تغییر بدید در کد:
    دکمه Start:
    TelegService.FreeOnTerminate := False;

    —------------------—
    procedure TfmMain.btnStopServiceClick(Sender: TObject);
    begin
    if Assigned(TelegService) then
    begin
    TelegService.Free;
    end;
    btnStartService.Enabled := true;
    btnStopService.Enabled := False;
    end;


    procedure TfmMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    begin
    if Assigned(TelegService) then
    begin
    TelegService.Free;
    end;
    end;




    ممنون بابت گزارش خطا : انشاالله با اینکار رفع میشه.

  17. #17
    کاربر جدید آواتار aboualfazl
    تاریخ عضویت
    خرداد 1389
    محل زندگی
    https://t.me/pump_upp
    پست
    28

    نقل قول: کار با API ربات تلگرام در دلفی 7

    نقل قول نوشته شده توسط mjdeveloper مشاهده تاپیک
    دوستان پیام های خصوصی مبنی بر خطای بستن سرویس تلگرام و گرفتن Access Violation گزارش شده که کد های زیر رو تغییر بدید در کد:
    دکمه Start:
    TelegService.FreeOnTerminate := False;

    —------------------—
    procedure TfmMain.btnStopServiceClick(Sender: TObject);
    begin
    if Assigned(TelegService) then
    begin
    TelegService.Free;
    end;
    btnStartService.Enabled := true;
    btnStopService.Enabled := False;
    end;


    procedure TfmMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    begin
    if Assigned(TelegService) then
    begin
    TelegService.Free;
    end;
    end;




    ممنون بابت گزارش خطا : انشاالله با اینکار رفع میشه.
    اولا ممنون از زحمات شما .

    این کد رو اصلاح کنید :

    procedure TfmMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    begin
    if btnStopService.Enabled = True then
    begin
    if Assigned(TelegService) then
    begin
    TelegService.Free;
    end;
    end;
    end;

  18. #18

    نقل قول: کار با API ربات تلگرام در دلفی 7

    سلام و تشکر فراوان بابت اطلاعات ارزشمندی که قرار دادین.
    من یه سوال دارم. ربات من با تغییراتی که روش انجام دادم کامل کار می کنه ولی وقتی از متد SetChatAction استفاده می کنم و دو پارامتر Chat_id , action رو ست می کنم، خطای 400 میده.
    اگه ممکنه راهنمایی بفرمایید.

    msg := '/sendChatAction';
    try
    Stream := TStringStream.Create('');
    Params := TIdMultipartFormDataStream.Create;
    Params.AddFormField('chat_id',ChatID);
    Params.AddFormField('action',ChatAction);
    try
    LHandler := TIdSSLIOHandlerSocket.Create(nil);
    // FidHttpSend.ReadTimeout := 300000;
    FidHttpSend.IOHandler:=LHandler;
    LHandler.SSLOptions.Method := sslvTLSv1;
    LHandler.SSLOptions.Mode := sslmUnassigned;
    FidHttpSend.HandleRedirects := true;
    //idhttp1.Request.ContentType := Params.RequestContentType;
    FidHttpSend.Post(BaseUrl + API + msg, Params, Stream);

    except
    on E: Exception do
    begin
    ShowMessage(Stream.DataString);
    ShowMessage('Error encountered during POST: ' + E.Message);
    end;
    end;
    finally
    ShowMessage(Stream.DataString);
    Params.Free;
    Stream.Free;
    end;

  19. #19

    نقل قول: کار با API ربات تلگرام در دلفی 7

    سلام
    ممنون از راهنمایی آموزش خوبیتان
    می خواستم بدانم چطوری می شود از کاربر یک سوال پرسید و بعد برای کاربر یک کی برد اعدادی آورد و بعد ببینیم کاربر چه کد ملی را زده و بعد در دیتابیس سرچش کنیم
    مثلا کد ملی را وارد کند و بعد از زدن کد ملی ربات جستجو کند و بگوید شما در دیتابیس هستید یا نه؟؟
    خیلی تلاش کردم ولی جوابی که کاربر می دهد را نمی توانم ببینم
    ممنون می شوم راهنمایی بفرمائید


                      if MessageText = Widestring(Menu_Item2) then
    SendMessageAndKey(ChatID, 'کد ملي را وارد نمائيد',answerInline,Markdown,True);

  20. #20

    نقل قول: کار با API ربات تلگرام در دلفی 7

    از اساتید محترم خواهشمندم اگر در این مورد می توانند کمک بفرمایند

  21. #21
    کاربر دائمی آواتار mjdeveloper
    تاریخ عضویت
    بهمن 1385
    محل زندگی
    تهران
    پست
    124

    Lightbulb نقل قول: کار با API ربات تلگرام در دلفی 7

    نقل قول نوشته شده توسط h_mohamadi مشاهده تاپیک
    سلام
    ممنون از راهنمایی آموزش خوبیتان
    می خواستم بدانم چطوری می شود از کاربر یک سوال پرسید و بعد برای کاربر یک کی برد اعدادی آورد و بعد ببینیم کاربر چه کد ملی را زده و بعد در دیتابیس سرچش کنیم
    مثلا کد ملی را وارد کند و بعد از زدن کد ملی ربات جستجو کند و بگوید شما در دیتابیس هستید یا نه؟؟
    خیلی تلاش کردم ولی جوابی که کاربر می دهد را نمی توانم ببینم
    ممنون می شوم راهنمایی بفرمائید


                      if MessageText = Widestring(Menu_Item2) then
    SendMessageAndKey(ChatID, 'کد ملي را وارد نمائيد',answerInline,Markdown,True);
    برای کار با بانک اطلاعاتی و محاوره با کاربر و همچنین ذخیره مقادیری که کاربر ارسال میکنه شما می تونید یه جدول برای ذخیره Chat_ID با فیلدهای دیگه ای که نیاز دارید از کاربر بگیرید و ذخیره کنید داشته باشید و مهم تر از همه یه فیلد به نام RequestStatus بصورت رشته یا عددی داشته در این جدول باشید تا مرحله به مرحله وضعیت کاربر رو داشته باشید و رصد کنید. مثال می زنم:
    1.کاربر ربات رو استارت می کنه شما حداقل chat_id رو تو جدول ثبت می کنید
    2 . به کاربر پیغام میدهید "لطفا کد ملی را وارد کنید" . و بلافاصله بعد از دادن این پیام RequestStatus را برابر با مثلا مقدار EnterNCode برای این کاربر قرار می دهید
    3. از این به بعد پیام کاربر رو بعنوان کد ملی در نظر می گیرید
    ReqStatus = GetRequestStatus(Chat_ID);// get from db
    if ReqStatus='EnterNCode' then
    Begin
    NCode := MessageText;
    //search DB and etc.
    End;

    4. بطور مثال طرف تو بانک اطلاعاتی شما با کد ملی یافت میشه و بعد بهش میگید رمزش رو وارد کنه و بلافاصله بعد از این پیام شما RequestStatus را برابر با EnterPassword قرار میدید و پیام بعدی کاربر رو رمز در نظر میگیرید.
    ReqStatus = GetRequestStatus(Chat_ID);
    if ReqStatus='EnterPassword' then
    Begin
    password := MessageText;
    //search DB and etc.
    End;

    در ابتدای متد Execute باید RequestStatus یا همان مرحله ای کاربر قرار داره رو بگیرید و در ادامه این مراحل رو چک کنید و پیام های کاربر را با توجه به وضعیت فعلی، مقادیر فیلدهای درخواستی خود قلمداد کنید
    به نظر بنده بهترین راه یا میشه گفت تنها راه همینه.
    اینم پیشنهاد: برای گرفتن یه مقدار مثل کد ملی از کاربر بهتره خودش تایپ کنه گرفتن این مقدار با کیبورد ساختگی شما خیلی داستان داره و باید عدد بع عدد گرفته بشه ذخیره بشه و status نگهدارید
    امیدوارم کمکتون کنه.
    آخرین ویرایش به وسیله mjdeveloper : پنج شنبه 15 تیر 1396 در 09:25 صبح

  22. #22

    نقل قول: کار با API ربات تلگرام در دلفی 7

    سلام
    سپاس از پست فوق العاده کاربردی تون
    من این ربات رو راه اندازی کردم و همه چیز خوب کار می کرد، ولی امروز که برنامه رو اجرا می کنم خطای Error Connecting With SSL میده. با توجه به اینکه تا دیروز همه چیز خوب بود، به نظرتون چی باعث این اتفاق شده؟
    من از indy 9.0.10 استفاده می کردم، ارتقاء دادم به 9.0.18 و بعد ارتقاء به 10 متناسب با هرکدوم هم DLL های متناسب رو کپی کردم ولی مشکل برطرف نشد.
    اگه دوستان راه حلی دارن ممنون میشم ارائه بدن.
    از طرفی DLL هایی که توی این پست ارائه شده بود رو وقتی کپی می کنم پیغام خطای Could Not Load SSL Library میده. ولی وقتی DLL های ورژن 9 رو استفاده می کنم پیام Error Connecting With SSL

  23. #23

    نقل قول: کار با API ربات تلگرام در دلفی 7

    سلام دوستان
    می خواستم ببینم چطوری می شود که ربات بتواند یک تصویر را هم ارسال کند

  24. #24
    کاربر جدید
    تاریخ عضویت
    اسفند 1389
    محل زندگی
    بهشت زمین
    پست
    10

    نقل قول: کار با API ربات تلگرام در دلفی 7

    نقل قول نوشته شده توسط mojtaba_bahrami مشاهده تاپیک
    سلام
    سپاس از پست فوق العاده کاربردی تون
    من این ربات رو راه اندازی کردم و همه چیز خوب کار می کرد، ولی امروز که برنامه رو اجرا می کنم خطای Error Connecting With SSL میده. با توجه به اینکه تا دیروز همه چیز خوب بود، به نظرتون چی باعث این اتفاق شده؟
    من از indy 9.0.10 استفاده می کردم، ارتقاء دادم به 9.0.18 و بعد ارتقاء به 10 متناسب با هرکدوم هم DLL های متناسب رو کپی کردم ولی مشکل برطرف نشد.
    اگه دوستان راه حلی دارن ممنون میشم ارائه بدن.
    از طرفی DLL هایی که توی این پست ارائه شده بود رو وقتی کپی می کنم پیغام خطای Could Not Load SSL Library میده. ولی وقتی DLL های ورژن 9 رو استفاده می کنم پیام Error Connecting With SSL

    سلام خدمت دوستان
    این خطا
    Error Connecting With SSL برای من هم اتفاق می افتد. و فقط مشکل من این خطاست. این خطا هنگامی رخ می دهد که برنامه میخواهد کد
    Src := IdHTTP1.Get(BotUrl + API + msg);
    را اجرا کند.
    لطفا برای رفع این خطا راهنمایی فرمایید.

  25. #25

    نقل قول: کار با API ربات تلگرام در دلفی 7

    نقل قول نوشته شده توسط alipil مشاهده تاپیک
    سلام خدمت دوستان
    این خطا
    Error Connecting With SSL برای من هم اتفاق می افتد. و فقط مشکل من این خطاست. این خطا هنگامی رخ می دهد که برنامه میخواهد کد
    Src := IdHTTP1.Get(BotUrl + API + msg);
    را اجرا کند.
    لطفا برای رفع این خطا راهنمایی فرمایید.
    من هم این مشکل را دارم؟
    مورد از چی است؟

  26. #26
    کاربر جدید
    تاریخ عضویت
    اسفند 1389
    محل زندگی
    بهشت زمین
    پست
    10

    نقل قول: کار با API ربات تلگرام در دلفی 7

    نقل قول نوشته شده توسط h_mohamadi مشاهده تاپیک
    من هم این مشکل را دارم؟
    مورد از چی است؟

    واقعا نمیدونم مشکل از کجاست، اما اینو میدونم که فقط اولین بار که برنامه اجرا میشه و میخواد اطلاعات رو ارسال کنه یا دریافت کنه این ارور داده میشه. بعدش دیگه برنامه خیلی عالی کارشو انجام میده!
    فکر کنم اگر بتونیم این ارور رو مخفی کنیم، مشکل حل بشه. البته من نتونستم این ارور رو مخفی کنم.
    کلا برنامه ارور زیاد داره که باید کنترل بشه. مثلا وقتی اینترنت برای دقایقی قطع میشه، پشت سر هم ارور میده. این ها باید نمایش داده نشه. چون وقتی اینترنت وصل میشه, برنامه به کارش ادامه میده!

    از دوستان اگر کسی هست که میتونه ارورهای برنامه رو مخفی کنه، بگه که ما هم انجام بدیم.
    متشکرم

  27. #27
    کاربر جدید
    تاریخ عضویت
    اسفند 1389
    محل زندگی
    بهشت زمین
    پست
    10

    نقل قول: کار با API ربات تلگرام در دلفی 7

    سلام دوست من
    اول اینکه در فایل ضمیمه ای که ارسال کردید، یه فایلی کم هست که باعث شده برنامه اجرا نشه!
    دوم اینکه من مبحث دریافت جواب از منوی
    InlineKeyboardMarkup
    رو اصلا متوجه نشدم و وقتی میخوام از کدهای شما توی برنامه ام استفاده کنم، اصلا برنامه کار نمیکنه و گزینه کلیک شده رو برنمیگردونه!
    سومین مطلب اینکه اگر بخواهیم به همراه متنمون اموجی هم ارسال کنیم، یا متنهای حامل اموجی رو دریافت کنیم، همچنین برای دریافت یک فایل (فایل، تصویر، صوت، فیلم) چه کدی رو استفاده کنیم؟
    ممنون میشم جواب بدید.

  28. #28
    کاربر دائمی آواتار mjdeveloper
    تاریخ عضویت
    بهمن 1385
    محل زندگی
    تهران
    پست
    124

    نقل قول: کار با API ربات تلگرام در دلفی 7

    مشکل
    Error Connecting With SSL با ارتقا به indy 10 باید حل بشه و من این کار رو کردم و مشکل حل شد و دیگه این خطا رو دریافت نکردم.

  29. #29
    کاربر دائمی آواتار mjdeveloper
    تاریخ عضویت
    بهمن 1385
    محل زندگی
    تهران
    پست
    124

    نقل قول: کار با API ربات تلگرام در دلفی 7

    نقل قول نوشته شده توسط alipil مشاهده تاپیک
    سلام دوست من
    اول اینکه در فایل ضمیمه ای که ارسال کردید، یه فایلی کم هست که باعث شده برنامه اجرا نشه!
    دوم اینکه من مبحث دریافت جواب از منوی
    InlineKeyboardMarkup
    رو اصلا متوجه نشدم و وقتی میخوام از کدهای شما توی برنامه ام استفاده کنم، اصلا برنامه کار نمیکنه و گزینه کلیک شده رو برنمیگردونه!
    سومین مطلب اینکه اگر بخواهیم به همراه متنمون اموجی هم ارسال کنیم، یا متنهای حامل اموجی رو دریافت کنیم، همچنین برای دریافت یک فایل (فایل، تصویر، صوت، فیلم) چه کدی رو استفاده کنیم؟
    ممنون میشم جواب بدید.
    1. دوست عزیز من از همین کد استفاده می کنم و خیلی از دوستان دیگه هم بر داشتن و مثل اینکه درست بوده و تونستن اجرا کنن.
    2. برای دریافت فایل هم هنوز کد نزدم که آماده داشته باشم ولی روند کار بصورت زیر هست . که اگر شما زحمتش رو کشیدید برای بقیه هم بذارید و همچنین برای من.

    دریافت فایل:
    1.کاربر عکس به ربات ارسال می کنه .
    2. ربات شما با getupdate پیام رو دریافت میکنه و نتیجه شبیه زیر هست
    {"ok":true,"result":
    [{
    "update_id":839925807,
    "message":{
    "message_id":61,
    "from":
    {
    "id":79060780,
    "first_name":"mehdi",
    "last_name":"Jafari",
    "username":"MjDeveloper",
    "language_code":"en-US"
    },
    "chat":
    {
    "id":79060780,
    "first_name":"mehdi",
    "last_name":"Jafari",
    "username":"MjDeveloper",
    "type":"private"
    },
    "date":1499596170,
    "photo":[{
    "file_id":"AgADBAAD_6gxG1EpEFPNIr8YHIITG08YqRkABMY H8HZUe1inQm0DAAEC",
    "file_size":2734,
    "width":90,
    "height":90}
    ,
    {"file_id":"AgADBAAD_6gxG1EpEFPNIr8YHIITG08YqRkABF U7V07oQYu0QW0DAAEC",
    "file_size":14179,
    "width":200,
    "height":200
    }
    ]}
    }]
    }



    3.شما File_ID رو بر می دارید و مجدد پست می کنید به تلگرام و پاسخی حاوی File_path دریافت می کنید
    4. مثال ارسال پست file_id . به آدرس دقت کنید
    https://api.telegram.org/bot<token>/getfile?file_id=AgADBAAD_6gxG1EpEFPNIr8YHIITG08YqR  kABFU7V07oQYu0QW0DAAEC

    5. نتیجه پست کردن file_id به نلگرام شبیه زیر هست که file_path رو داره
    {"ok":true,"result":{"file_id":"AgADBAAD_6gxG1EpEF  PNIr8YHIITG08YqRkABFU7V07oQYu0QW0DAAEC","file_size  ":14179,"file_path":"photos/file_0.jpg"}}

    6. حالا با استفاده از file_path می تونید لینک دانلود رو بسازید و دانلود کنید
    https://api.telegram.org/file/bot<token>/<file_path>

    برای دریافت عکس:
    https://api.telegram.org/file/bot<token>/photos/file_0.jpg

    دانلود شروع میشه

    ---------------- برای فایل های دیگه مانند document-----------------
    فقط مسیر دانلود متفاوت میشه

    {"ok":true,"result":{"file_id":"BQADBAAD8AADUSkQU1  4d-TTauBAyAg","file_size":100140,"file_path":"documen  ts/esfControl.png"}}


    https://api.telegram.org/file/bot<token>/documents/esfControl.png


    امیدوارم کمکتون کنه.
    حالا اگر فرصت کنم کد براش میزنم و میذارم ولی اگر کسی از دوستان زحمتش رو کشید ممنون میشم کد بذاره بقیه هم استفاده کنن.

    کد دریافت فایل را در این پست مشاهده بفرمایید
    آخرین ویرایش به وسیله mjdeveloper : پنج شنبه 06 مهر 1396 در 15:22 عصر

  30. #30
    کاربر جدید
    تاریخ عضویت
    اسفند 1389
    محل زندگی
    بهشت زمین
    پست
    10

    نقل قول: کار با API ربات تلگرام در دلفی 7

    نقل قول نوشته شده توسط mjdeveloper مشاهده تاپیک
    1. دوست عزیز من از همین کد استفاده می کنم و خیلی از دوستان دیگه هم بر داشتن و مثل اینکه درست بوده و تونستن اجرا کنن.
    2. برای ارسال فایل هم هنوز کد نزدم که آماده داشته باشم ولی روند کار بصورت زیر هست . که اگر شما زحمتش رو کشیدید برای بقیه هم بذارید و همچنین برای من.

    دریافت فایل:
    1.کاربر عکس به ربات ارسال می کنه .
    2. ربات شما با getupdate پیام رو دریافت میکنه و نتیجه شبیه زیر هست
    {"ok":true,"result":
    [{
    "update_id":839925807,
    "message":{
    "message_id":61,
    "from":
    {
    "id":79060780,
    "first_name":"mehdi",
    "last_name":"Jafari",
    "username":"MjDeveloper",
    "language_code":"en-US"
    },
    "chat":
    {
    "id":79060780,
    "first_name":"mehdi",
    "last_name":"Jafari",
    "username":"MjDeveloper",
    "type":"private"
    },
    "date":1499596170,
    "photo":[{
    "file_id":"AgADBAAD_6gxG1EpEFPNIr8YHIITG08YqRkABMY H8HZUe1inQm0DAAEC",
    "file_size":2734,
    "width":90,
    "height":90}
    ,
    {"file_id":"AgADBAAD_6gxG1EpEFPNIr8YHIITG08YqRkABF U7V07oQYu0QW0DAAEC",
    "file_size":14179,
    "width":200,
    "height":200
    }
    ]}
    }]
    }



    3.شما File_ID رو بر می دارید و مجدد پست می کنید به تلگرام و پاسخی حاوی File_path دریافت می کنید
    4. مثال ارسال پست file_id . به آدرس دقت کنید
    https://api.telegram.org/bot<token>/getfile?file_id=AgADBAAD_6gxG1EpEFPNIr8YHIITG08YqR  kABFU7V07oQYu0QW0DAAEC

    5. نتیجه پست کردن file_id به نلگرام شبیه زیر هست که file_path رو داره
    {"ok":true,"result":{"file_id":"AgADBAAD_6gxG1EpEF  PNIr8YHIITG08YqRkABFU7V07oQYu0QW0DAAEC","file_size  ":14179,"file_path":"photos/file_0.jpg"}}

    6. حالا با استفاده از file_path می تونید لینک دانلود رو بسازید و دانلود کنید
    https://api.telegram.org/file/bot<token>/<file_path>

    برای دریافت عکس:
    https://api.telegram.org/file/bot<token>/photos/file_0.jpg

    دانلود شروع میشه

    ---------------- برای فایل های دیگه مانند document-----------------
    فقط مسیر دانلود متفاوت میشه

    {"ok":true,"result":{"file_id":"BQADBAAD8AADUSkQU1  4d-TTauBAyAg","file_size":100140,"file_path":"documen  ts/esfControl.png"}}


    https://api.telegram.org/file/bot<token>/documents/esfControl.png


    امیدوارم کمکتون کنه.
    حالا اگر فرصت کنم کد براش میزنم و میذارم ولی اگر کسی از دوستان زحمتش رو کشید ممنون میشم کد بذاره بقیه هم استفاده کنن.


    ===========


    ممنونم ممنونم
    خیلی خوشحال شدم که جوابمو دادین.
    حتما اگر به دست آوردی رسیدم به دوستان ارائه میدم.

    من dll‌ های مربوط به نسخه 10 رو جایگزین کردم ، indy 10 ‌رو نتونستم دانلود و نصب کنم. اگر indy 10 رو در دلفی نصب کنم، مشکل برطرف میشه؟

    مشکل ارورها موقع قطع اینترنت چطور برطرف میشه؟

    بازم ممنونم از پاسخگویی

  31. #31
    کاربر جدید
    تاریخ عضویت
    اسفند 1389
    محل زندگی
    بهشت زمین
    پست
    10

    نقل قول: کار با API ربات تلگرام در دلفی 7

    من با استفاده از مطالب شما، این ربات @GUinfobot رو ساختم و یک کیس هم به عنوان سرور همیشه روشن گذاشتم تا روبات همیشه قابل استفاده باشه.
    به نظرم ضعف استفاده از دلفی همین باشه که باید یک کیس یا سرور همیشه روشن و آنلاین باشه تا روبات بتونه کار کنه. ولی نقطه قوتش اینه که که نیاز نیست هزینه های سالانه خرید هاست و ssl‌ بدیم. و محدودیت حجم برای دیتای روبات هم نداریم.
    آخرین ویرایش به وسیله alipil : شنبه 01 مهر 1396 در 21:08 عصر

  32. #32
    کاربر جدید
    تاریخ عضویت
    اسفند 1389
    محل زندگی
    بهشت زمین
    پست
    10

    نقل قول: کار با API ربات تلگرام در دلفی 7

    نقل قول نوشته شده توسط mjdeveloper مشاهده تاپیک
    با سلام خدمت دوستان

    ....

    توجه: حتما ابتدا یه بات بسازید و توکن اون رو تو setting.ini بذارید و سپس اجرا کنید

    خوب در پایان هم کد براتون میذارم ولی حدود چهار ماه چشام در اومد تا به اینجا رسید
    یا علی مدد
    دوستدار همتون هستم
    مهدی جعفری


    این خط ارور میده
    UGutility in 'UGutility.pas';

    ظاهرا این فایل باید باشه که نیست...
    [Fatal Error] D7_Teleg.dpr(9): File not found: 'RzEdit.dcu'

  33. #33
    کاربر دائمی آواتار mjdeveloper
    تاریخ عضویت
    بهمن 1385
    محل زندگی
    تهران
    پست
    124

    نقل قول: کار با API ربات تلگرام در دلفی 7

    نقل قول نوشته شده توسط alipil مشاهده تاپیک
    این خط ارور میده
    UGutility in 'UGutility.pas';

    ظاهرا این فایل باید باشه که نیست...
    [Fatal Error] D7_Teleg.dpr(9): File not found: 'RzEdit.dcu'

    یه سری unit های اضافی که برای پروژه خودم هست رو می تونید حذف کنید از هر یونیتی خطا داشتید حذف کنید

  34. #34
    کاربر دائمی آواتار mjdeveloper
    تاریخ عضویت
    بهمن 1385
    محل زندگی
    تهران
    پست
    124

    نقل قول: کار با API ربات تلگرام در دلفی 7

    نقل قول نوشته شده توسط alipil مشاهده تاپیک
    من با استفاده از مطالب شما، این ربات @GUinfobot رو ساختم و یک کیس هم به عنوان سرور همیشه روشن گذاشتم تا روبات همیشه قابل استفاده باشه.
    به نظرم ضعف استفاده از دلفی همین باشه که باید یک کیس یا سرور همیشه روشن و آنلاین باشه تا روبات بتونه کار کنه. ولی نقطه قوتش اینه که که نیاز نیست هزینه های سالانه خرید هاست و ssl‌ بدیم. و محدودیت حجم برای دیتای روبات هم نداریم.
    آفرین بر شما دوست عزیز.
    موفق باشید

  35. #35
    کاربر دائمی آواتار mjdeveloper
    تاریخ عضویت
    بهمن 1385
    محل زندگی
    تهران
    پست
    124

    Cool نقل قول: کار با API ربات تلگرام در دلفی 7

    نقل قول نوشته شده توسط alipil مشاهده تاپیک
    ===========


    ممنونم ممنونم
    خیلی خوشحال شدم که جوابمو دادین.
    حتما اگر به دست آوردی رسیدم به دوستان ارائه میدم.

    من dll‌ های مربوط به نسخه 10 رو جایگزین کردم ، indy 10 ‌رو نتونستم دانلود و نصب کنم. اگر indy 10 رو در دلفی نصب کنم، مشکل برطرف میشه؟

    مشکل ارورها موقع قطع اینترنت چطور برطرف میشه؟

    بازم ممنونم از پاسخگویی
    پروژه باید مجدد روی indy 10 کامپایل بشه و تغییراتی در کد لازم هست : و همچنین dll های ایندی 10 رو کنار برنامه بذارید. صرفا با گذاشتن dll ها کنار نسخه قدیمی مشکل حل نمیشه.

    توابع ارسال پیام متنی و ارسال پیام متنی حاوی کیبورد اینطوری خواهد شد:

    procedure TBotThread.SendMessage(ChatID:String; Text : WideString; parse_mode:string;disable_notification:boolean);Va  r
    Stream: TStringStream;
    Params: TIdMultipartFormDataStream;
    //Text : WideString;
    msg : WideString;
    Src : string;
    LHandler: TIdSSLIOHandlerSocketOpenSSL;
    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','tr ue');
    Params.AddFormField('text',UTF8Encode(Text),'utf-8').ContentTransfer:='8bit';
    //Params.AddFormField('text',Text);
    LHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
    FidHttpSend.ReadTimeout := 30000;
    FidHttpSend.IOHandler:=LHandler;
    LHandler.SSLOptions.Method := sslvTLSv1;
    LHandler.SSLOptions.Mode := sslmClient;
    FidHttpSend.HandleRedirects := true;
    //FidHttpSend.Request.CharSet:= 'UTF-8';
    FidHttpSend.Post(BaseUrl + API + msg, Params, Stream);
    finally
    LHandler.Free;
    Params.Free;
    Stream.Free;
    ENd;
    except
    on E: EIdHTTPProtocolException do
    begin
    if E.ErrorCode = 403 then
    begin
    WriteToLog('Bot was blocked by the user');
    end;
    end;
    end;
    end;


    procedure TBotThread.SendMessageAndKey(ChatID:String; Text : WideString;Keys, parse_mode:string;disable_notification:boolean);
    Var
    Stream: TStringStream;
    Params: TIdMultipartFormDataStream;
    msg : WideString;
    Src : string;
    LHandler: TIdSSLIOHandlerSocketOpenSSL;
    Json : TMemoryStream;
    btn : string;
    UTF8 : UTF8String;
    BytesCount : integer;
    SaveMsgID : boolean;
    begin
    btn := keys;
    SaveMsgID := False;
    if pos('force_reply',btn) > 0 then
    SaveMsgID := True;
    Json := TMemoryStream.Create;
    UTF8 := AnsiToUtf8(btn);
    BytesCount := Length(UTF8);
    Json.WriteBuffer(UTF8[1], BytesCount);
    Json.Position := 0;
    try
    try
    if FShowBotLink then
    Text := Text + LineBreak + FBotUser;
    msg := '/sendmessage';
    Stream := TStringStream.Create('');
    Params := TIdMultipartFormDataStream.Create;
    Params.AddObject('reply_markup','application/json','UTF-8',Json);
    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('text',UTF8Encode(Text),'utf-8').ContentTransfer:='8bit';
    LHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
    FidHttpSend.ReadTimeout := 30000;
    FidHttpSend.IOHandler:=LHandler;
    LHandler.SSLOptions.Method := sslvTLSv1;
    LHandler.SSLOptions.Mode := sslmClient;
    FidHttpSend.HandleRedirects := true;
    FidHttpSend.Post(BaseUrl + API + msg, Params, Stream);
    //fmMain.Memo1.Text := Stream.DataString;
    if SaveMsgID then
    SaveMessageID(Stream.DataString,ChatID);
    finally
    Json.Free;
    LHandler.Free;
    Params.Free;
    Stream.Free;
    ENd;
    except
    on E: EIdHTTPProtocolException do
    begin
    if E.ErrorCode = 403 then
    begin
    WriteToLog('Bot was blocked by the user');
    end;
    end;
    end;
    end;

  36. #36
    کاربر دائمی آواتار mjdeveloper
    تاریخ عضویت
    بهمن 1385
    محل زندگی
    تهران
    پست
    124

    نقل قول: کار با API ربات تلگرام در دلفی 7

    دوستان خوشحال میشم ربات های نوشته شده با این کد رو معرفی بفرمایید و یا تو زمینه ارسال به تلگرام تو چه نرم افزار هایی از این کد استفاده کردید

  37. #37
    کاربر جدید
    تاریخ عضویت
    اسفند 1389
    محل زندگی
    بهشت زمین
    پست
    10

    نقل قول: کار با API ربات تلگرام در دلفی 7

    نقل قول نوشته شده توسط mjdeveloper مشاهده تاپیک
    دوستان سلام
    این هم کد ارسال تصویر با ربات تلگرام

    Use IdMultipartFormData


    procedure TForm1.SendPostData;var
    Stream: TStringStream;
    Params: TIdMultipartFormDataStream;
    msg : WideString;
    LHandler: TIdSSLIOHandlerSocket;
    IDUser : string;
    begin
    API := edtAPI.Text;
    IDUser := Edit1.Text;
    msg := '/sendPhoto';
    Stream := TStringStream.Create('');
    try
    Params := TIdMultipartFormDataStream.Create;
    try
    Params.AddFile('photo', 'E:\image.png','');
    Params.AddFormField('chat_id',IDUser);
    Params.AddFormField('caption','this is a image caption!');
    try
    LHandler := TIdSSLIOHandlerSocket.Create(nil);
    //IdHTTP1.ReadTimeout := 300000;
    IdHTTP1.IOHandler:=LHandler;
    LHandler.SSLOptions.Method := sslvTLSv1;
    LHandler.SSLOptions.Mode := sslmUnassigned;
    IdHTTP1.HandleRedirects := true;
    //idhttp1.Request.ContentType := Params.RequestContentType;
    memoRequest.Text := BaseUrl + API + msg;
    IdHTTP1.Post(BaseUrl + API + msg, Params, Stream);
    except
    on E: Exception do
    ShowMessage('Error encountered during POST: ' + E.Message);
    end;
    ShowMessage(Stream.DataString);
    finally
    Params.Free;
    end;
    finally
    Stream.Free;
    end;
    end;

    سلام
    همونطور که آقای مهدی جعفری عزیز فرموده بودن، من دیشب روی کد ارسال فایل کار کردم و قرار شد اگر به نتیجه ای رسیدم، اینجا بگم تا همه دوستان استفاده کنن.
    ارسال فایلها به دو صورت است:
    1. ارسال هر فایلی صرفا به صورت فایل مثل : فایل متنی، عکس، فیلم، صوت، apk، exe ، dll , .......
    2. ارسال فایلهایی با فرمت متداول و قابل نمایش در خود تلگرام (عکس، فیلم، صوت)


    1. اگر میخواهید هر فایل رو ارسال کنید، فقط کافیه در کدهای بالا به جای /sendPhoto از /senddocument استفاده کنید و نیز پارامتر photo را به document تغییر دهید.
    2. اگر میخواهید فایلهایی با فرمت متداول قابل نمایش در تلگرام رو ارسال کنید، باید نوع فایل رو مشخص نمایید. مثلا در کدهای فوق که آقای جعفری نوشتن، چون قرار بوده عکس ارسال کنند، از عبارت Photo , sendphoto استفاده شده است. پس برای ارسال ویدئو باید از عبارت video و sendvideo استفاده کرد. در این صورت است که عکس در خود برنامه تلگرام قابل نمایش است و خود تلگرام قادر است که ویدئو را پلی کند! حالا اگر همین عکس یا فیلم به صورت document ارسال شود، با آن مانند یک فایل رفتار شده و گوشی از شما میخواهد تا یک برنامه را جهت نمایش آن انتخاب کنید. مثلا عکس توسط گالری نمایش داده میشه و ویدئو با یک برنامه ای که برای نمایش فیلم نصب کردید نمایش داده میشه و ...

  38. #38
    کاربر جدید
    تاریخ عضویت
    اسفند 1389
    محل زندگی
    بهشت زمین
    پست
    10

    نقل قول: کار با API ربات تلگرام در دلفی 7

    نقل قول نوشته شده توسط mjdeveloper مشاهده تاپیک
    پروژه باید مجدد روی indy 10 کامپایل بشه و تغییراتی در کد لازم هست : و همچنین dll های ایندی 10 رو کنار برنامه بذارید. صرفا با گذاشتن dll ها کنار نسخه قدیمی مشکل حل نمیشه.

    توابع ارسال پیام متنی و ارسال پیام متنی حاوی کیبورد اینطوری خواهد شد:

    procedure TBotThread.SendMessage(ChatID:String; Text : WideString; parse_mode:string;disable_notification:boolean);Va  r
    Stream: TStringStream;
    Params: TIdMultipartFormDataStream;
    //Text : WideString;
    msg : WideString;
    Src : string;
    LHandler: TIdSSLIOHandlerSocketOpenSSL;
    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','tr ue');
    Params.AddFormField('text',UTF8Encode(Text),'utf-8').ContentTransfer:='8bit';
    //Params.AddFormField('text',Text);
    LHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
    FidHttpSend.ReadTimeout := 30000;
    FidHttpSend.IOHandler:=LHandler;
    LHandler.SSLOptions.Method := sslvTLSv1;
    LHandler.SSLOptions.Mode := sslmClient;
    FidHttpSend.HandleRedirects := true;
    //FidHttpSend.Request.CharSet:= 'UTF-8';
    FidHttpSend.Post(BaseUrl + API + msg, Params, Stream);
    finally
    LHandler.Free;
    Params.Free;
    Stream.Free;
    ENd;
    except
    on E: EIdHTTPProtocolException do
    begin
    if E.ErrorCode = 403 then
    begin
    WriteToLog('Bot was blocked by the user');
    end;
    end;
    end;
    end;


    procedure TBotThread.SendMessageAndKey(ChatID:String; Text : WideString;Keys, parse_mode:string;disable_notification:boolean);
    Var
    Stream: TStringStream;
    Params: TIdMultipartFormDataStream;
    msg : WideString;
    Src : string;
    LHandler: TIdSSLIOHandlerSocketOpenSSL;
    Json : TMemoryStream;
    btn : string;
    UTF8 : UTF8String;
    BytesCount : integer;
    SaveMsgID : boolean;
    begin
    btn := keys;
    SaveMsgID := False;
    if pos('force_reply',btn) > 0 then
    SaveMsgID := True;
    Json := TMemoryStream.Create;
    UTF8 := AnsiToUtf8(btn);
    BytesCount := Length(UTF8);
    Json.WriteBuffer(UTF8[1], BytesCount);
    Json.Position := 0;
    try
    try
    if FShowBotLink then
    Text := Text + LineBreak + FBotUser;
    msg := '/sendmessage';
    Stream := TStringStream.Create('');
    Params := TIdMultipartFormDataStream.Create;
    Params.AddObject('reply_markup','application/json','UTF-8',Json);
    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('text',UTF8Encode(Text),'utf-8').ContentTransfer:='8bit';
    LHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
    FidHttpSend.ReadTimeout := 30000;
    FidHttpSend.IOHandler:=LHandler;
    LHandler.SSLOptions.Method := sslvTLSv1;
    LHandler.SSLOptions.Mode := sslmClient;
    FidHttpSend.HandleRedirects := true;
    FidHttpSend.Post(BaseUrl + API + msg, Params, Stream);
    //fmMain.Memo1.Text := Stream.DataString;
    if SaveMsgID then
    SaveMessageID(Stream.DataString,ChatID);
    finally
    Json.Free;
    LHandler.Free;
    Params.Free;
    Stream.Free;
    ENd;
    except
    on E: EIdHTTPProtocolException do
    begin
    if E.ErrorCode = 403 then
    begin
    WriteToLog('Bot was blocked by the user');
    end;
    end;
    end;
    end;

    خیلی متشکرم آقای جعفری، در مورد ارسال پیام متنی با منویی که زیر آن هست یعنی (InlineKeyboardMarkup) مشکلی نیست، فقط وقتی که کاربر یکی از گزینه های منو رو انتخاب میکنه، اصلا نمیتونم گزینه ی انتخاب شده رو دریافت کنم.
    برنامه ارور میده. در مرحله ی دریافت اطلاعات از روبات (سرور تلگرام) ارور میده. به طوری که حتی اگر بعد از انتخاب منو، پیامهای دیگه ای از سوی کاربر به ربات ارسال شده باشه، اونها رو هم نمیتونه دریافت کنه و کلا برنامه از کار می افته.
    اگر ممکنه خیلی شسته و رفته تر بفرمایید که چجوری متوجه بشم کدوم گزینه انتخاب شده.
    متشکرم

  39. #39
    کاربر دائمی آواتار mjdeveloper
    تاریخ عضویت
    بهمن 1385
    محل زندگی
    تهران
    پست
    124

    نقل قول: کار با API ربات تلگرام در دلفی 7

    استفاده از Emoji:

    برخی ایموجی ها رو من کد html رو در آوردم چون خیلی زیاده همش وقت نشد:
    یونیت رو به پروژه ادد کنید


    طریقه استفاده:
    SendMessage(ChatID,'متن شما'+ DoubleExclamationMark_Emoji,HTML,False);
    فایل های ضمیمه فایل های ضمیمه

  40. #40
    کاربر دائمی آواتار mjdeveloper
    تاریخ عضویت
    بهمن 1385
    محل زندگی
    تهران
    پست
    124

    نقل قول: کار با API ربات تلگرام در دلفی 7

    دوستان چون من کم وقت می کنم به اینجا سر بزنم اگر سوالی کاری داشتید می تونید تو تلگرام در خدمت شما باشم

    @mjdeveolper

صفحه 1 از 2 12 آخرآخر

تاپیک های مشابه

  1. سوال: کار با api‌ های تلگرام در دلفی
    نوشته شده توسط hadisalahi2 در بخش مباحث عمومی دلفی و پاسکال
    پاسخ: 16
    آخرین پست: پنج شنبه 24 تیر 1395, 17:43 عصر
  2. سوال: کار با فایل های متنی در دلفی txt-text
    نوشته شده توسط hassan p.b در بخش مباحث عمومی دلفی و پاسکال
    پاسخ: 20
    آخرین پست: یک شنبه 09 شهریور 1393, 00:38 صبح
  3. کار با Windows Agent ها در دلفی
    نوشته شده توسط alidehban در بخش مباحث عمومی دلفی و پاسکال
    پاسخ: 2
    آخرین پست: یک شنبه 15 فروردین 1389, 08:59 صبح
  4. کار با کامپوننت fast report در دلفی
    نوشته شده توسط nasim_leila در بخش کامپوننت های سایر شرکت ها، و توسعه کامپوننت
    پاسخ: 4
    آخرین پست: چهارشنبه 02 خرداد 1386, 11:26 صبح

برچسب های این تاپیک

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •