2016-01-10 6 views
1

Я пытаюсь выяснить, как использовать Delphi 10 Seattle и Indy для отправки запроса POST на Plivo или Twilio для отправки SMS-сообщений. Когда я использую этот код для усилий Twilio, я получаю Несанкционированное сообщение взамен (обратите внимание, что я отредактированный мое имя пользователя и код идентификации):Twilio или Plivo СМС с помощью Delphi

procedure TSendTextForm.TwilioSendSms(FromNumber, ToNumber, Sms: string; Var Response: TStrings); 

var 
    apiurl, apiversion, accountsid, authtoken, 
    url: string; 
    aParams, aResponse: TStringStream; 
    mHTTP : TidHttp; 

begin 

    mHTTP := TIdHTTP.Create(nil); 

    apiurl := 'api.twilio.com'; 
    apiversion := '2010-04-01'; 
    accountsid := 'AC2f7cda1e6a4e74376***************:2b521b60208af4c*****************'; 
    url := Format('https://%s/%s/Accounts/%s/SMS/Messages/', [apiurl, apiversion, accountsid]); 
    aParams := TStringStream.Create ; 
try 
    aParams.WriteString('&From=' + FromNumber); 
    aParams.WriteString('&To=' + ToNumber); 
    aParams.WriteString('&Body=' + Sms); 
    aResponse := TStringStream.Create; 
try 
    mHTTP.Post(url, aParams, aResponse); 
finally 
    Response.Text := aResponse.DataString; 
end; 
finally 
    aParams.Free; 
end; 
end; 

У меня есть подобный код для Plivo. Ни у одной компании нет поддержки Delphi. Может ли кто-нибудь сказать мне, что мне здесь не хватает? Спасибо.

Mic

+0

Я бы не рекомендовал использовать Plivo. Они не доставляли нам большое количество SMS, поэтому мы несколько раз обращались к их поддержке, ждали недели и ничего ... они просто берут наши деньги за невыполненные SMS и ничего не делают для решения проблемы. –

ответ

1

The Rest API документы на https://www.twilio.com/docs/api/rest говорят, что используется базовая авторизация:

HTTP requests to the REST API are protected with HTTP Basic authentication.

TIdHTTP имеет встроенную поддержку для обычной проверки подлинности. Просто установите для свойства TIdHTTP.Request.BasicAuthentication значение true и задайте IdHTTP.Request.Username и TIdHTTP.Request.Password свойствам по мере необходимости.

Другие советы:

  • TIdHTTP.Create(nil) может быть сокращено до TIdHTTP.Create
  • вар модификатор для ответов может быть изменен на сопзЬ

Ваш код также утечки памяти, так как Инди компонент не освобожден.

+1

'TIdHTTP.Post()' также имеет встроенную поддержку для размещения пар имя-значение в формате 'application/x-www-form-urlencoded'. Вы должны размещать 'TStringList' вместо' TStringStream'. Это не только задает 'TIdHTTP.Request.ContentType' (который вы не делаете), но особенно важно, чтобы зарезервированные символы, такие как пробельные символы, правильно закодированы, особенно в значении' Sms'. –

0

В Delphi 10 Сиэтл, есть некоторые компоненты REST с TRestClient

И TMS сделал компоненты для Twillio в их TMS Cloud пакет http://www.tmssoftware.com/site/cloudpack.asp

+1

Twilio не использует аутентификацию OAuth. –

+0

@Remy: Спасибо, что исправил меня –

3

Twilio евангелист здесь.

В дополнение к предложению Basic Auth, сделанное @mjn выше, существуют две другие проблемы в вашей выборке я считаю, будет вызывать проблемы:

Во-первых, в примере кода выше, ваш URL будет неправильно, потому что переменная accountsid объединяет оба символа sid и auth.

accountsid := 'AC2f7cda1e6a4e74376***************:2b521b60208af4c*****************'; 

В то время как вы сделать хотите сделать это для того, чтобы использовать обычную проверку подлинности, вы не хотите маркер аутентификации как часть URL. При создании url собственности вы просто хотите поставить SID в URL в качестве параметра, как это:

/Accounts/ACXXXXXXX/

Во-вторых, я хотел бы также предложить не используя /SMS ресурсы как его не рекомендуется. Вместо того, чтобы использовать /Messages, который новее и имеет больше возможностей:

/Accounts/ACXXXXXXX/Messages

0

Это смешно, но я просто хочу, чтобы опубликовать один и тот же вопрос о plivo. Я также пытаюсь заставить twilio и plivo работать. Мне все-таки удалось заставить twilio работать.С другой стороны, Plivo не будет работать с одним и тем же кодом, хотя оба они практически одинаковы.

Я использовал функции REST в delphi. Следующий код используется как для twilio, так и для plivo.

procedure TForm1.FormCreate(Sender: TObject); 
begin 
     // TypeCo 
     // = T = Twilio 
     // = P = Plivo 

     TypeCo := 'T'; 


     if TypeCo='T' then // Twillio 
     begin 
      AccountSid := 'ACd27xxxxxxxxxxxxxxxxxxxxxxb106e38'; // x's were replaced to hide ID 
      AuthToken := '24fxxxxxxxxxxxxxxxxxxxxxxxxf08ed'; // x's were replaced to hide Token 
      BaseURL := 'https://api.twilio.com'; 
      Resource := '/2010-04-01/Accounts/'+accountSid+'/Messages'; 
     end 
     else if TypeCO='P' then // Plivo 
     begin 
      AccountSid := 'MANTxxxxxxxxxxxxxXYM'; 
      AuthToken := 'ZDg0OxxxxxxxxxxxxxxxxxxxxxxxxxxxxjM5Njhh'; 
      BaseURL := 'https://api.plivo.com'; 
      Resource := '/v1/Account/'+accountSid+'/Message/'; 
     end; 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
     RESTClient := TRESTClient.Create(BaseURL); 
     try 
      RESTRequest := TRESTRequest.Create(RESTClient); 
      try 
       RESTResponse := TRESTResponse.Create(RESTClient); 
       try 
        HTTPBasicAuthenticator := THTTPBasicAuthenticator.Create('AC', 'c1234'); 

        try 
         RESTRequest.ResetToDefaults; 

         RESTClient.BaseURL := BaseURL; 
         RESTRequest.Resource := Resource; 
         HTTPBasicAuthenticator.UserName := AccountSid; 
         HTTPBasicAuthenticator.Password := AuthToken; 
         RESTClient.Authenticator := HTTPBasicAuthenticator; 
         RESTRequest.Client := RESTClient; 
         RESTRequest.Response := RESTResponse; 

         // Tried this to fix plivo error with no luck! 
         // RESTClient.Params.AddHeader('Content-Type', 'application/json'); 

         // "From" number is the send # setup in the twilio or plivo account. The "To" number is a verified number in your twilio or plivo account 

         if TypeCo='T' then // Twilio 
          SendSMS('+1602xxxxx55','+1602xxxxxx7', 'This is a test text from Twilio') // x's were replaced to hide telephone numbers 
         else if TypeCo='P' then // Plivo 
          SendSMS('1602xxxxx66','1602xxxxxx7', 'This is a test text from Plivo'); // x's were replaced to hide telephone numbers 

        finally 
         HTTPBasicAuthenticator.Free; 
        end; 
       finally 
        RESTResponse.Free; 
       end; 
      finally 
        RESTRequest.Free; 
      end; 
     finally 
       RESTClient.Free; 
     end; 

end; 


function TForm1.SendSMS(aFrom, aTo, aText: string): boolean; 
begin 
    result := True; 
    RESTRequest.ResetToDefaults; 

    RESTClient.BaseURL := BaseURL; 
    RESTRequest.Resource := Resource; 
    if TypeCo='T' then // Twilio 
    begin 
     RESTRequest.Params.AddUrlSegment('AccountSid', accountSid); 
     RESTRequest.Params.AddItem('From', aFrom); 
     RESTRequest.Params.AddItem('To', aTo); 
     RESTRequest.Params.AddItem('Body', aText); 
    end 
    else if TypeCo='P' then // Plivo 
    begin 
     RESTRequest.Params.AddUrlSegment('AccountSid', accountSid); 
     RESTRequest.Params.AddItem('src', aFrom); 
     RESTRequest.Params.AddItem('dst', aTo); 
     RESTRequest.Params.AddItem('text', aText); 
    end; 


    RESTRequest.Method := rmPOST; 
    RESTRequest.Execute; 

    // Show Success or Error Message 
    ErrorMsg.Clear; 
    ErrorMsg.Lines.Text := RESTResponse.Content; 

end; 

Как уже упоминалось, приведенный выше код отлично подходит для Twilio. Однако для Plivo я получаю следующее сообщение об ошибке:

{ 
    "api_id": "b124d512-b8b6-11e5-9861-22000ac69cc8", 
    "error": "use 'application/json' Content-Type and raw POST with json data" 
} 

Я пытался определить, как решить эту проблему. Я связался со службой поддержки Plivo и я получил следующий ответ:

The error "use 'application/json' Content-Type and raw POST with json data" is generated when the Header "Content-Type" is not set the value "application/json" 
Please add the Header Content-Type under Items in the Request Tab and set the Description as application/json. 

Я пытался добавить код в процедуре кнопки:

RESTClient.Params.AddHeader('Content-Type', 'application/json'); 

, но она по-прежнему дает ту же ошибку. Я думаю, что этот код действительно близок к работе в Plivo. Я новичок в REST-функциях, поэтому я не уверен, что еще попробовать. Я попытался присвоить «application/json» почти все, что примет его, и все равно получить ту же ошибку. Надеюсь, кто-то еще будет иметь представление о том, что сделает Plivo.

+0

из [this SO post] (http://stackoverflow.com/a/25047430/4731823), вы можете попробовать: 'var aParam: TRESTRequestParameter; начало RestReq.Method: = rmPOST; aParam: = RestReq.Params.AddItem(); aParam.Value: = TJSONObject.ParseJSONValue ('{' src ': aFrom,' dst ': aTo,' text ': aText}'); aParam.ContentType: = ctAPPLICATION_JSON; RestClient.Execute(); конец; ' – CharlieC

0

Наконец, я смог получить как Twilio, так и Plivo для отправки СМС-сообщений. С помощью Delphi REST Debugger и комментариев, сделанных в этом потоке, я наконец смог понять это. Спасибо! В функции SendSMS (для Plivo) вместо добавления каждого параметра мне пришлось добавить заголовок «Content-Type» для «application/json» и добавить параметры как RAW в тело, используя RESTRequest.AddBody(). Еще одно замечание, которое я изначально тестировал в Delphi XE5, и оно будет продолжать давать мне ту же ошибку, о которой упоминалось в более раннем сообщении. Когда я попробовал его в Delphi XE7, он, наконец, работал !!! Это должно работать и в Delphi 10 Seattle, но не проверено!

Это рабочая демонстрация. В форме вам нужно иметь следующие компоненты:

Button1: TButton; 
RESTClient: TRESTClient; 
RESTRequest: TRESTRequest; 
RESTResponse: TRESTResponse; 
HTTPBasicAuthenticator: THTTPBasicAuthenticator; 
ResponseMsg: TMemo; 

В OnCreate, изменить TypeCo от «T» или «Р» в зависимости от компании, которую вы хотите проверить. Тогда запустите его!

Вот код. Обратите внимание: я маскировал поля AccountSid, AuthToken и номера телефонов для обеспечения конфиденциальности.

procedure TForm1.FormCreate(Sender: TObject); 
begin 
     // TypeCo 
     // = T = Twilio 
     // = P = Plivo 

     TypeCo := 'P'; 

     if TypeCo='T' then // Twilio 
     begin 
      AccountSid := 'ACd2*************************06e38'; 
      AuthToken := '24f63************************8ed'; 
      BaseURL := 'https://api.twilio.com'; 
      Resource := '/2010-04-01/Accounts/'+accountSid+'/Messages'; 
     end 
     else if TypeCO='P' then // Plivo 
     begin 
      AccountSid := 'MAN*************IXYM'; 
      AuthToken := 'ZDg0*******************************5Njhh'; 
      BaseURL := 'https://api.plivo.com'; 
      Resource := '/v1/Account/'+accountSid+'/Message/'; 
     end; 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
var i:integer; 
begin 
    RESTClient.ResetToDefaults; 
    RESTRequest.ResetToDefaults; 
    ResponseMsg.Clear; 

    RESTClient.BaseURL := BaseURL; 
    RESTRequest.Resource := Resource; 
    HTTPBasicAuthenticator.UserName := AccountSid; 
    HTTPBasicAuthenticator.Password := AuthToken; 
    RESTClient.Authenticator := HTTPBasicAuthenticator; 
    RESTRequest.Client := RESTClient; 
    RESTRequest.Response := RESTResponse; 

    // Here is where you can loop through your messages for different recipients. 
    // I use the same "To" phone number in this test 
    for i := 1 to 3 do 
    begin 
      if TypeCo='T' then // Twilio 
       SendSMS('+1602******0','+1602******7', Format('This is test #%s using Twilio. Sent at %s',[inttostr(i),TimeToStr(Time)])) 
      else if TypeCo='P' then // Plivo 
       SendSMS('1662******2','1602******7', Format('This is test #%s using Plivo. Sent at %s',[inttostr(i),TimeToStr(Time)])); 

      // Show Success or Error Message 
      ResponseMsg.Lines.Add(RESTResponse.Content); 
      ResponseMsg.Lines.Add(''); 
      ResponseMsg.Refresh; 

    end; 
end; 


function TForm1.SendSMS(aFrom, aTo, aText: string):Boolean; 
begin 
    result := False; 
    RESTRequest.Params.Clear; 
    RESTRequest.ClearBody; 


    RESTClient.BaseURL := BaseURL; 
    RESTRequest.Resource := Resource; 
    if TypeCo='T' then // Twilio 
    begin 
      RESTRequest.Params.AddUrlSegment('AccountSid', accountSid); 
      RESTRequest.Params.AddItem('From', aFrom); 
      RESTRequest.Params.AddItem('To', aTo); 
      RESTRequest.Params.AddItem('Body', aText); 
    end 
    else if TypeCo='P' then // Plivo 
    begin 
      // NOTE: The following Header line needs to be commented out for Delphi Seattle 10 Update 1 (or probably newer) to work. The first original Delphi 10 Seattle version would not work at all for Plivo. In this case the following error would occur: "REST request failed: Error adding header: (87) The parameter is incorrect". This was due to the HTTPBasicAuthenticator username and password character lengths adding up to greater than 56. 
      RESTRequest.Params.AddItem('Content-Type', 'application/json', pkHTTPHEADER, [], ctAPPLICATION_JSON); 
     // RESTRequest.Params.AddItem('body', '', pkRequestBody, [], ctAPPLICATION_JSON); // Thought maybe I needed this code, but works without it. 
      RESTRequest.AddBody(Format('{"src":"%s","dst":"%s","text":"%s"}',[aFrom,aTo,aText]),ctAPPLICATION_JSON); 
    end; 

    RESTRequest.Method := rmPOST; 
    RESTRequest.Execute; 
    result := True; 
end; 
+0

Большое спасибо, Рон! Это было именно то, что мне нужно!У меня не было никакого опыта с REST, и это был отличный опыт для меня. Вы очень добры, что нашли время. Ваш пример отлично работает. –

+0

Я решил протестировать его в Delphi 10 Seattle (оригинальная первая версия), и это приведет к следующей ошибке: –

+0

Ошибка запроса REST: Ошибка добавления заголовка: (87) Параметр неверен. Это связано с тем, что длина имени пользователя и пароля добавляется до более чем 56 в HTTPBasicAuthenticator. UHGG! Затем я удалил строку заголовка приложения/json в функции SendSMS, и она снова работала. Не уверен, что происходит с различными версиями Delphi, но, надеюсь, он не будет меняться с версии на версию. Я отредактировал ответ и добавил комментарии к строке заголовка. Пастор Мик, не забудьте проверить это как ответ. –

Смежные вопросы