Twitter library for Delphi
2013 fix/update: http://code.google.com/p/delphi-twitter-library/
Edit: As of December 2012 Twitter api is using GZip in every callback, so you’ll have to enable content encoding before every Get/Post call, and then load the result from a gzipped stream in the RequestDone procs.
Edit June 2012: This twitter library is now deprecated and will no longer be updated. I’ve rewritten it as a generic OAuth lib to use with both Twitter and Imgur (and any other OAuth 1.0 services) for a closed source project.
This is my take on Open Auth and Twitter for Delphi. I recently had to look into it to update a twitter plugin for my Mal Upater application, so I made this small library along with a test application TwitMee. There is barely nothing at all for Delphi, and the little
I found was overcomplicated and didn’t work with Unicode (f.e. japanese symbols etc) (my library does).
I’ve been asked by a few people to make it open source, so here’s the code, use it freely as long you comply with the GPL v3 license.
Requirements: one of the latest versions of Delphi which includes Unicode. (probably easy to adapt using Jedi’s jcl implementation
for unicode strings as well).
TwitterLib - 1690 downloads
Twitter object unit:
{
You can contact me at: http://eden.fm
License Version: GPL v3
The contents of this file are subject to the GPL License Version
3 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.gnu.org/licenses/gpl.html
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
You may use the code freely for freeware and commercial applications, as long
you keep a notice the software is using my library, and the original source
of my code isn't modified.
TwitterLib for Delphi v0.1. Developed by http://eden.fm
Usage: see usage.pas for details.
3rd party: I'm using ICS' overbyte winsock library, which you can get
at www.overbyte.be
After you install that, you need to overwrite (or place in your app folder)
the file "OverbyteIcsHttpProt.pas" which is included in the rar where you
obtained this file. It's a slightly modified version of the ICS THttpCli
component to ease a bit the header modifications before a call.
- b64asm: this is a very fast implementation I found to encode into base64
I was originally using madshi's madCrypt unit, which was actually as fast,
but this should be easier to distribute.
}
unit TwitterLib;
interface
Uses Windows, SysUtils, Classes, StdCtrls,
b64ASM, OverbyteIcsSha1, OverbyteIcsHttpProt;
Const
RequestTokenURL = 'http://api.twitter.com/oauth/request_token';
RequestAccessURL = 'http://api.twitter.com/oauth/access_token';
RequestTwitURL = 'http://api.twitter.com/1/statuses/update.xml';
shell32 = 'shell32.dll';
{$EXTERNALSYM ShellExecute}
function ShellExecute(hWnd: hWnd; Operation, FileName, Parameters,
Directory: PWideChar; ShowCmd: Integer): HINST; stdcall;
Type
TwitterRequests = (trDummy, trRequestToken, trRequestAccess, trTwit);
Type
TwitterCli = class(TObject)
private
FOnReqDone: TNotifyEvent;
FOnBeforeSocketCall: TNotifyEvent;
// use this to set socket proxy option, since sockets are created/destroyed on demand
procedure TriggerReqDone; virtual;
procedure TriggerBeforeSocketCall; virtual;
procedure RecreateSocket;
// CallbackProc: pointer;
// VCL handlers
procedure HTTPClientDocEnd(Sender: TObject);
procedure HTTPClientHeaderEnd(Sender: TObject);
procedure HTTPClientRequestDone(Sender: TObject; RqType: THttpRequest;
ErrCode: Word);
procedure HTTPClientBeforeHeaderSend(Sender: TObject; const Method: string;
Headers: TStrings);
procedure BuildSignature;
procedure GetTimeStamp;
procedure GetNonce;
procedure GenerateBaseURL(Method, url: string);
procedure ParseTokenandTokenSecret(rawResult: string);
procedure ParseAccessData(rawResult: string);
public
ConsumerKey: string;
ConsumerSecret: string;
OAuthToken: string;
OAuthTokenSecret: string;
AccessToken: string;
AccessTokenSecret: string;
AccessUserID: string;
AccessScreenName: string;
URLRequestToken: string;
URLRequestAccess: string;
URLTwit: string;
SignBase: string;
TStamp: string;
Nonce: string;
Signature: string;
Postvars: Ansistring;
AuthHeader: string;
HTTPClient: THttpCli;
RefURL: string;
ResultStrings: TStringList;
LastReq: TwitterRequests;
DebugMode: Boolean;
DebugMemo: TMemo;
LastHttpStatus: Integer;
AccessPIN: String;
SendStatus: String;
Constructor Create(CKey, CSecret: string); // virtual;
Destructor Destroy; override;
procedure RequestToken; // socket call
procedure RequestAccess; // socket call
procedure SendTwit(twit: string); // socket call
procedure RequestPIN; // call browser
function RequestPinURL: string;
procedure SetStoredLogin(AToken, ATokenSecret: string);
published
property OnReqDone: TNotifyEvent read FOnReqDone write FOnReqDone;
property OnBeforeSocketCall: TNotifyEvent read FOnBeforeSocketCall
write FOnBeforeSocketCall;
end;
function UrlEncode2(const S: String): String;
function UrlEncodeExceptUnicode(const S: String): String;
function DateTimeToUnix(DelphiTime: TDateTime): Int64;
function urlEncodeRFC3986(url: string): string;
function HasUnicode(src: string): Boolean;
function BuildHexedUtf8String(src: string): string;
implementation
function ShellExecute; external shell32 name 'ShellExecuteW';
function BuildHexedUtf8String(src: string): string;
Var
ut: utf8string;
a: Integer;
BinarySize: Integer;
InputString: utf8string;
StringAsBytes: array of Byte;
begin
Result := '';
for a := 1 to length(src) do
begin
if Ord(src[a]) < 255 then
begin
if src[a] = ' ' then
Result := Result + '%2520'
else
Result := Result + UrlEncode2(src[a]);
end
else
begin
ut := src[a];
BinarySize := 3; // (Length(InputString) + 1) * SizeOf(Char);
SetLength(StringAsBytes, BinarySize);
Move(ut[1], StringAsBytes[0], BinarySize);
Result := Result + '%25' + IntToHex(StringAsBytes[0], 2);
Result := Result + '%25' + IntToHex(StringAsBytes[1], 2);
Result := Result + '%25' + IntToHex(StringAsBytes[2], 2);
end;
end;
end;
function HasUnicode(src: string): Boolean;
Var
a: Integer;
begin
Result := False;
for a := 1 to length(src) do
if Ord(src[a]) > 255 then
Exit(True);
end;
function DateTimeToUnix(DelphiTime: TDateTime): Int64;
begin
Result := Round((DelphiTime - 25569) * 86400);
end;
function UrlEncode2(const S: String): String;
var
I: Integer;
Ch: Char;
begin
Result := '';
for I := 1 to length(S) do
begin
Ch := S[I];
if ((Ch >= '0') and (Ch <= '9')) or ((Ch >= 'a') and (Ch <= 'z')) or
((Ch >= 'A') and (Ch <= 'Z')) or (Ch = '.') or (Ch = '-') or (Ch = '_') or
(Ch = '~') then
Result := Result + Ch
else
begin
// if HasUnicode(Ch) then Result := Result + BuildHexedUtf8String(Ch)
{ else } Result := Result + '%' + IntToHex(Ord(Ch), 2);
end;
end;
end;
function UrlEncodeExceptUnicode(const S: String): String;
var
I: Integer;
Ch: Char;
begin
Result := '';
for I := 1 to length(S) do
begin
Ch := S[I];
if ((Ch >= '0') and (Ch <= '9')) or ((Ch >= 'a') and (Ch <= 'z')) or
((Ch >= 'A') and (Ch <= 'Z')) or (Ch = '.') or (Ch = '-') or (Ch = '_') or
(Ch = '~') or HasUnicode(Ch) then
Result := Result + Ch
else
Result := Result + '%' + IntToHex(Ord(Ch), 2);
end;
end;
function urlEncodeRFC3986(url: string): string;
var
URL1: string;
begin
URL1 := UrlEncode2(url);
URL1 := StringReplace(URL1, '+', ' ', [rfReplaceAll, rfIgnoreCase]);
Result := URL1;
end;
Constructor TwitterCli.Create(CKey, CSecret: string);
begin
inherited Create;
ConsumerKey := CKey;
ConsumerSecret := CSecret;
DebugMode := False;
URLRequestToken := RequestTokenURL;
URLRequestAccess := RequestAccessURL;
URLTwit := RequestTwitURL;
ResultStrings := TStringList.Create;
end;
Destructor TwitterCli.Destroy;
begin
ResultStrings.Free;
inherited Destroy;
end;
procedure TwitterCli.BuildSignature;
Var
SignKey: string;
begin
SignKey := UrlEncode2(ConsumerSecret) + '&' + UrlEncode2(OAuthTokenSecret);
Signature := { madCrypt.Encode } b64ASM.Base64Encode
(HMAC_SHA1_EX(SignBase, SignKey));
if DebugMode then
if Assigned(DebugMemo) then
with TMemo(DebugMemo) do
begin
Lines.Add('- Build Signature -');
Lines.Add('SignKey=' + SignKey);
Lines.Add('Signature=' + Signature);
Lines.Add('----------------------------------');
end;
end;
procedure TwitterCli.GetTimeStamp;
begin
TStamp := IntToStr(DateTimeToUnix(Now));
end;
procedure TwitterCli.GetNonce;
Var
a: Integer;
begin
Nonce := '';
for a := 1 to 20 do
Nonce := Nonce + Chr(Random(26) + 65);
end;
procedure TwitterCli.GenerateBaseURL(Method, url: string);
Var
ver, tok, cbak: string;
begin
GetNonce;
GetTimeStamp;
if AccessPIN <> '' then
ver := 'oauth_verifier=' + AccessPIN + '&'
else
ver := '';
// if OAuthToken <> '' then tok := 'oauth_token=' + OAuthToken + '&' else tok := '';
tok := 'oauth_token=' + OAuthToken + '&';
if LastReq <> trTwit then
cbak := 'oauth_callback=oob&';
SignBase := Method + '&' + UrlEncode2(url) + '&' +
UrlEncode2(cbak + 'oauth_consumer_key=' + ConsumerKey + '&' + 'oauth_nonce='
+ Nonce + '&' + 'oauth_signature_method=HMAC-SHA1' + '&' +
'oauth_timestamp=' + TStamp + '&' + tok + ver // access PIN if any
+ 'oauth_version=1.0');
if SendStatus <> '' then
SignBase := SignBase + UrlEncode2('&status=') + BuildHexedUtf8String
(SendStatus);
if DebugMode then
if Assigned(DebugMemo) then
with TMemo(DebugMemo) do
begin
Lines.Add('- Generate Base URL -');
Lines.Add('base=' + SignBase);
Lines.Add('----------------------------------');
end;
end;
procedure TwitterCli.RequestToken;
begin
LastReq := trRequestToken;
OAuthToken := '';
OAuthTokenSecret := '';
AccessToken := '';
AccessTokenSecret := '';
AccessPIN := '';
GenerateBaseURL('GET', URLRequestToken);
BuildSignature;
Postvars := 'oauth_consumer_key' + '=' + ConsumerKey + '&' +
'oauth_signature_method' + '=' + 'HMAC-SHA1' + '&' + 'oauth_signature' + '='
+ UrlEncode2(Signature) + '' + '&' + 'oauth_timestamp' + '=' + TStamp + '&'
+ 'oauth_nonce' + '=' + Nonce + '&' + 'oauth_token' + '=' + OAuthToken + '&'
+ 'oauth_callback' + '=' + 'oob' + '&' + 'oauth_version' + '=' + '1.0';
RecreateSocket;
HTTPClient.ExtraSendHeader := 'Authorization: OAuth oauth_nonce="' + Nonce +
'", oauth_callback="oob", oauth_token="' + OAuthToken +
'", oauth_signature_method="HMAC-SHA1", oauth_timestamp="' + TStamp +
'", oauth_consumer_key="' + ConsumerKey + '", oauth_signature="' +
UrlEncode2(Signature) + '", oauth_version="1.0"';
With HTTPClient do
begin
Reference := RefURL;
RcvdStream := TMemoryStream.Create;
// SendStream := TMemoryStream.Create;
// SendStream.Write(postvars[1], Length(postvars));
// SendStream.Seek(0, soFromBeginning);
Accept := '*/*';
url := URLRequestToken; // + '?' + postvars;
ResultStrings.Clear;
if DebugMode then
if Assigned(DebugMemo) then
with TMemo(DebugMemo) do
begin
Lines.Add('- Request Token Start -');
Lines.Add('postvars=' + Postvars);
Lines.Add('url=' + url);
Lines.Add('----------------------------------');
end;
try
GetAsync;
except
on E: Exception do
begin
RcvdStream.Destroy;
RcvdStream := nil;
// SendStream.Destroy; SendStream := nil;
ResultStrings.Text := 'ERROR ' + E.Message;
LastHttpStatus := HTTPClient.StatusCode;
TriggerReqDone;
FreeAndNil(HTTPClient);
Exit;
end;
end; // try
end; // with
end;
procedure TwitterCli.RequestAccess;
begin
LastReq := trRequestAccess;
GenerateBaseURL('GET', URLRequestAccess);
BuildSignature;
Postvars := 'oauth_consumer_key' + '=' + ConsumerKey + '&' + 'oauth_nonce' +
'=' + Nonce + '&' + 'oauth_signature_method' + '=' + 'HMAC-SHA1' + '&' +
'oauth_signature' + '=' + UrlEncode2(Signature) + '' + '&' +
'oauth_timestamp' + '=' + TStamp + '&' + 'oauth_token' + '=' + OAuthToken +
'&' + 'oauth_callback' + '=' + 'oob' + '&' + 'oauth_verifier' + '=' +
AccessPIN + '&' + 'oauth_version' + '=' + '1.0'; // + '&' +
// 'oauth_callback' + '=' + 'oob' + '&' +
RecreateSocket;
HTTPClient.ExtraSendHeader := 'Authorization: OAuth oauth_nonce="' + Nonce +
'", oauth_callback="oob", oauth_token="' + OAuthToken +
'", oauth_verifier="' + AccessPIN +
'", oauth_signature_method="HMAC-SHA1", oauth_timestamp="' + TStamp +
'", oauth_consumer_key="' + ConsumerKey + '", oauth_signature="' +
UrlEncode2(Signature) + '", oauth_version="1.0"';
With HTTPClient do
begin
Reference := RefURL;
RcvdStream := TMemoryStream.Create;
url := URLRequestAccess; // + '?' + postvars;
ResultStrings.Clear;
if DebugMode then
if Assigned(DebugMemo) then
with TMemo(DebugMemo) do
begin
Lines.Add('- Request Access Start -');
Lines.Add('postvars=' + Postvars);
Lines.Add('url=' + url);
Lines.Add('----------------------------------');
end;
try
GetAsync;
except
on E: Exception do
begin
RcvdStream.Destroy;
RcvdStream := nil;
ResultStrings.Text := 'ERROR ' + E.Message;
LastHttpStatus := HTTPClient.StatusCode;
FreeAndNil(HTTPClient);
TriggerReqDone;
Exit;
end;
end; // try
end; // with
end;
procedure TwitterCli.SendTwit(twit: string);
begin
// showmessage(twit);
// twit := URLEncode2(twit);
// fix issue, # + unicode fails
LastReq := trTwit;
if HasUnicode(twit) then
begin
twit := UrlEncodeExceptUnicode(twit);
// StringReplace(twit,'#','%2523',[rfReplaceAll]);
SendStatus := twit;
end
else
SendStatus := UrlEncode2(utf8Encode(twit));
AccessPIN := '';
GenerateBaseURL('POST', URLTwit);
BuildSignature;
Postvars := 'oauth_consumer_key' + '=' + ConsumerKey + '&' + 'oauth_nonce' +
'=' + Nonce + '&' + 'oauth_signature_method' + '=' + 'HMAC-SHA1' + '&' +
'oauth_signature' + '=' + UrlEncode2(Signature) + '' + '&' +
'oauth_timestamp' + '=' + TStamp + '&' + 'oauth_token' + '=' + AccessToken +
'&' + 'oauth_callback' + '=' + 'oob' + '&' + 'oauth_version' + '=' + '1.0';
if HasUnicode(twit) then
Postvars := 'status=' + { urlencode2 } ((utf8Encode(twit)))
else
Postvars := 'status=' + UrlEncode2(twit);
SendStatus := '';
RecreateSocket;
HTTPClient.ExtraSendHeader := 'Authorization: OAuth ' + 'oauth_consumer_key="'
+ ConsumerKey + '", oauth_signature_method="HMAC-SHA1", oauth_timestamp="' +
TStamp + '", oauth_nonce="' + Nonce +
'", oauth_version="1.0", oauth_token="' + AccessToken +
'", oauth_signature="' + UrlEncode2(Signature) + '"';
With HTTPClient do
begin
Reference := RefURL;
RcvdStream := TMemoryStream.Create;
SendStream := TMemoryStream.Create;
SendStream.Write(Postvars[1], length(Postvars));
SendStream.Seek(0, soFromBeginning);
url := URLTwit; // + '?' + postvars;
ResultStrings.Clear;
if DebugMode then
if Assigned(DebugMemo) then
with TMemo(DebugMemo) do
begin
Lines.Add('- Request twit Start -');
Lines.Add('postvars=' + Postvars);
Lines.Add('url=' + url);
Lines.Add('----------------------------------');
end;
try
PostAsync;
except
on E: Exception do
begin
RcvdStream.Destroy;
RcvdStream := nil;
SendStream.Destroy;
SendStream := nil;
ResultStrings.Text := 'ERROR ' + E.Message;
LastHttpStatus := HTTPClient.StatusCode;
FreeAndNil(HTTPClient);
TriggerReqDone;
Exit;
end;
end; // try
end; // with
end;
procedure TwitterCli.TriggerReqDone;
begin
if Assigned(FOnReqDone) then
FOnReqDone(Self);
end;
procedure TwitterCli.TriggerBeforeSocketCall;
begin
if Assigned(FOnBeforeSocketCall) then
FOnBeforeSocketCall(Self);
end;
procedure TwitterCli.HTTPClientDocEnd(Sender: TObject);
begin
//
end;
procedure TwitterCli.HTTPClientBeforeHeaderSend(Sender: TObject;
const Method: string; Headers: TStrings);
begin
if DebugMode then
if Assigned(DebugMemo) then
with TMemo(DebugMemo) do
begin
Lines.Add('- Socket Before Header Send -');
Lines.Add(Headers.Text);
Lines.Add('----------------------------------');
end;
end;
procedure TwitterCli.HTTPClientHeaderEnd(Sender: TObject);
begin
if DebugMode then
if Assigned(DebugMemo) then
with TMemo(DebugMemo) do
begin
Lines.Add('- Socket Header End -');
Lines.Add(HTTPClient.RcvdHeader.Text);
Lines.Add('----------------------------------');
end;
end;
procedure TwitterCli.HTTPClientRequestDone(Sender: TObject;
RqType: THttpRequest; ErrCode: Word);
Label CleanUp;
begin
if DebugMode then
if Assigned(DebugMemo) then
with TMemo(DebugMemo) do
begin
Lines.Add('- Request Done Socket DocEnd -');
Lines.Add('result=' + ResultStrings.Text);
Lines.Add('status code=' + IntToStr(HTTPClient.StatusCode));
Lines.Add('headers=' + HTTPClient.RcvdHeader.Text);
Lines.Add('----------------------------------');
end;
if (RqType = httpGET) or (RqType = httpPOST) then
begin
if (ErrCode <> 0) or (HTTPClient.StatusCode <> 200) then
Goto CleanUp;
end
else
Exit;
try
HTTPClient.RcvdStream.WriteBuffer(#0' ', 1);
HTTPClient.RcvdStream.Position := 0;
ResultStrings.LoadFromStream(HTTPClient.RcvdStream);
finally
end;
LastHttpStatus := HTTPClient.StatusCode;
if (LastReq = trRequestToken) and (LastHttpStatus = 200) then
ParseTokenandTokenSecret(ResultStrings.Text);
if (LastReq = trRequestAccess) and (LastHttpStatus = 200) then
ParseAccessData(ResultStrings.Text);
CleanUp:
HTTPClient.RcvdStream.Destroy;
HTTPClient.RcvdStream := nil;
if LastReq = trTwit then
begin
HTTPClient.SendStream.Destroy;
HTTPClient.SendStream := nil;
end;
FreeAndNil(HTTPClient);
TriggerReqDone;
end;
procedure TwitterCli.RecreateSocket;
begin
HTTPClient := THttpCli.Create(nil);
With HTTPClient do
begin
OnDocEnd := HTTPClientDocEnd;
OnHeaderEnd := HTTPClientHeaderEnd;
OnRequestDone := HTTPClientRequestDone;
OnBeforeHeaderSend := HTTPClientBeforeHeaderSend;
TriggerBeforeSocketCall;
end;
end;
procedure TwitterCli.ParseTokenandTokenSecret(rawResult: string);
begin
// parse tokens after request token
if Pos('oauth_callback_confirmed=true', rawResult) = 0 then
begin
LastHttpStatus := 0;
Exit;
end;
try
Delete(rawResult, 1, Pos('=', rawResult));
OAuthToken := Copy(rawResult, 1, Pos('&oauth_token_secret=',
rawResult) - 1);
Delete(rawResult, 1, Pos('=', rawResult));
OAuthTokenSecret := Copy(rawResult, 1, Pos('&oauth_callback_confirmed=true',
rawResult) - 1);
except
LastHttpStatus := 0;
end;
if DebugMode then
if Assigned(DebugMemo) then
with TMemo(DebugMemo) do
begin
Lines.Add('- Parse Token and TokenSecret -');
Lines.Add('Token=' + OAuthToken);
Lines.Add('TokenSecret=' + OAuthTokenSecret);
Lines.Add('----------------------------------');
end;
end;
procedure TwitterCli.RequestPIN;
begin
ShellExecute(0, nil, PChar('https://twitter.com/oauth/authorize?oauth_token='
+ OAuthToken), '', '', SW_SHOWNORMAL);
end;
function TwitterCli.RequestPinURL;
begin
Result := 'https://twitter.com/oauth/authorize?oauth_token=' + OAuthToken;
end;
procedure TwitterCli.ParseAccessData(rawResult: string);
begin
// parse tokens after request acccess
if Pos('user_id', rawResult) = 0 then
begin
LastHttpStatus := 0;
Exit;
end;
try
Delete(rawResult, 1, Pos('=', rawResult));
AccessToken := Copy(rawResult, 1, Pos('&oauth_token_secret=',
rawResult) - 1);
Delete(rawResult, 1, Pos('=', rawResult));
AccessTokenSecret := Copy(rawResult, 1, Pos('&user_id=', rawResult) - 1);
Delete(rawResult, 1, Pos('=', rawResult));
AccessUserID := Copy(rawResult, 1, Pos('&screen_name=', rawResult) - 1);
Delete(rawResult, 1, Pos('=', rawResult));
AccessScreenName := rawResult;
OAuthToken := AccessToken;
OAuthTokenSecret := AccessTokenSecret;
except
LastHttpStatus := 0;
end;
if DebugMode then
if Assigned(DebugMemo) then
with TMemo(DebugMemo) do
begin
Lines.Add('- Parse Access Data -');
Lines.Add('AccessToken=' + AccessToken);
Lines.Add('AccessTokenSecret=' + AccessTokenSecret);
Lines.Add('AccessUserID=' + AccessUserID);
Lines.Add('AccessScreenName=' + AccessScreenName);
Lines.Add('----------------------------------');
end;
end;
procedure TwitterCli.SetStoredLogin(AToken: string; ATokenSecret: string);
begin
AccessToken := AToken;
AccessTokenSecret := ATokenSecret;
OAuthToken := AccessToken;
OAuthTokenSecret := AccessTokenSecret;
end;
end.
usage
// start by defining and creating the twitter object:
Var
Twit: TwitterCli;
Twit := TwitterCli.Create(TKey, TSecret);
with Twit do
begin
// You can specify a TMemo here for debugging purposes, which will output relevant
// data sent and received to twitter.
// DebugMode := True;
// DebugMemo := Memo1;
OnReqDone := TwitterCallBackProc;
RefURL := 'http://eden.fm';
end;
// TwitterCallBackProc is a simple method that's called after each request:
procedure TTwitMeMain.TwitterCallBackProc(Sender: TObject);
// TKey and TSecret are your app key and secret you get from Twitter after
// you register your app with them
// you can also specify a callback for TriggerBeforeSocketCall
// which will trigger just before a socket call. Here you can alter
// the socket to specify a proxy by accessing Twit.HTTPClient
// (as per ICS THttpCli properties)
// Next we need to request a token from Twitter:
// If you had already done this step before you can skip it, look at the
// end of this doc for details
Twit.RequestToken;
// Right after the call, control is given back to your application, since the
// call is asynchronous (non-blocking). the callback proc will be called after
// after we get the initial token from twitter, we need to send the user to
// twitter.com so they will login and get a PIN code to enter in your app
Twit.RequestPIN;
// you could also use Twit.RequestPinURL
// to get the URL in a string if you wish to copy it to the user in the
// clipboard or any other means, in case your app fails to launch the URL
// in the browser
// once done, the user has to give the PIN to us, in an edit box for example,
// then we tell the library the pin and request the final access tokens:
Twit.AccessPIN := Edit1.Text;
Twit.RequestAccess;
// our callback proc will be called once again and we are ready to send
// messages to twitter
// always check Twit.LastHttpStatus in the callback proc, if not 200 then
// something went wrong. You can check the variables ResultStrings.Text
// and LastHttpStatus for details on what went wrong
// now we can send a message with
Twit.SendTwit('test message');
// you can also use unicode here, like Japanese kanjis
// tested also with problematic symbols like # $ ! ' & etc
// * Note about access request: after you complete the acess steps,
// you can store these 2 string variables:
//
// Twit.AccessToken
// Twit.AccessTokenSecret
// and simply do: SetStoredLogin(a,b);
// after creating the twitter object (a and b being those 2 vars we stored
// and your app is ready to send without any previous steps
// And that's it, pretty simple. Note that this is a very simple implementation
// and we should check for other status codes from Twitter. I will be updating
// the library to fully implement the entire API eventually.
// a little more help. this is what my callback proc on TwitMee looks like:
procedure TTwitMeMain.TwitterCallBackProc(Sender: TObject);
begin
if Twit.LastHttpStatus <> 200 then
begin
Label1.Font.Color := clRed;
Label1.Caption := 'Error communicating with Twitter.';
Exit;
end;
if Twit.LastReq = trRequestToken then
begin
FlatEdit1.Text := 'Enter PIN here and click on Send button';
Twit.RequestPIN;
Exit;
end;
if Twit.LastReq = trRequestAccess then
begin
Label1.Font.Color := clWhite;
Label1.Caption := 'Ready to send.';
Authenticated := True;
FlatEdit1.Text := '';
SaveSettings;
Exit;
end;
if Twit.LastReq = trTwit then
begin
FlatEdit1.Text := '';
Label1.Caption := 'Message sent.';
Exit;
end;
end;
