Twilio API到SSIS的数据流

问题描述

尝试从Twilio API中读取记录,然后将其用于SSIS数据流中并将记录保存在sql Server数据库中。使用https://www.twilio.com/docs/sms/api/message-resource#read-multiple-message-resources中的api文档,我已经能够阅读消息,但是对下一步的工作有些困惑,我只想将其用作数据流的来源,因此不要尝试做任何花哨的事情在.net中,更多的是sql专家,所以对C#不太熟悉。

我是否一直认为这太简单了?假设我能够读取消息(看起来好像不是JSON格式,已经使用Twilio.dll拆分了各个字段),然后将其放入变量中,然后循环遍历每一行并传递到输出缓冲区。

本质上,正在尝试这样的事情:



    public override void CreateNewOutputRows()
    {
         string accountSid = "AAAA";

         string authToken = "1111";

        TwilioClient.Init(accountSid,authToken);

        var response = MessageResource.Read();

        foreach (var msg in response)
        {
            Output0Buffer.AddRow();
            Output0Buffer.ID = msg.Sid.ToString();
            Output0Buffer.Message = msg.Body.ToString();
        }
    }
```

解决方法

这是一个不使用Twilio库并且不使用数据流的示例。

我们基本上正在寻找类似的东西:

enter image description here

  1. 截断我们正在加载的表
  2. 我们将使用For循环容器,因为我们必须考虑分页。
  3. 进行REST调用的C#脚本任务
  4. 用于解析JSON的存储过程,插入到表中并评估下一个url值,然后将其返回,以查看是否需要再次处理。

Twilio在响应中返回的默认值为50条记录,最大为1000条。如果您想要的不是默认值,则可以使用URL参数“?PageSize = 60”进行更改。如果有更多记录,则特定的页面大小,响应将包括下一个要获取下一组记录的URL。

两个变量:

enter image description here

NextUrl设置为

https://api.twilio.com/2010-04-01/Accounts/{AccountSid}/Messages.json

用于循环容器

enter image description here

一旦NextUrl = STOP,循环将停止。我们在存储过程中进行处理。插入数据后,我们检查该值,如果为NULL,则将其设置为STOP。

脚本任务 enter image description here

传入URL,在脚本中设置apiResponse使其返回。

您将需要包括以下内容: enter image description here

Main()的代码

try
            {
                string apiUrl = Dts.Variables["NextUrl"].Value.ToString();

                string userName = ""; //accountSid found in Twilio account console
                string passwd = ""; //authToken found in Twilio account console

                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

                HttpClient client = new HttpClient();

                client.DefaultRequestHeaders.Accept.Clear();

                byte[] authToken = Encoding.ASCII.GetBytes($"{userName}:{passwd}");
                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",Convert.ToBase64String(authToken));

                HttpResponseMessage response;

                // Execute the REST GET
                response = client.GetAsync(apiUrl).GetAwaiter().GetResult();

                // Get the JSON response.
                string contentString = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();

                Dts.Variables["apiResponse"].Value = contentString; //Passing the response back out.

                Dts.TaskResult = (int)ScriptResults.Success;
            }

            catch (Exception ex)
            {
                //This code will cause the ssis to fail and bubble back out the error from this code
                Dts.Events.FireError(-1,"Error",ex.Message,String.Empty,0);
                Dts.TaskResult = (int)ScriptResults.Failure;

            }

使用NVARCHAR(MAX)参数创建一个存储过程,以接受apiResponse并返回NextUrl值。该任务将类似于:

enter image description here

参数映射:

enter image description here

结果集:

enter image description here

然后,存储过程本身将类似于:

CREATE PROCEDURE [dbo].[InsertTwilioMessage]
    @apiResponse NVARCHAR(MAX)
AS
    DECLARE @NextUrl NVARCHAR(2000);

    INSERT INTO [dbo].[TwilioMessage] (
                                          [body],[num_segments],[direction],[from],[date_updated],[price],[error_message],[uri],[account_sid],[num_media],[to],[date_created],[status],[sid],[date_sent],[messaging_service_sid],[error_code],[price_unit],[api_version]
                                      )
                SELECT [rsp].[body],[rsp].[num_segments],[rsp].[direction],[rsp].[from],[rsp].[date_updated],[rsp].[price],[rsp].[error_message],[rsp].[uri],[rsp].[account_sid],[rsp].[num_media],[rsp].[to],[rsp].[date_created],[rsp].[status],[rsp].[sid],[rsp].[date_sent],[rsp].[messaging_service_sid],[rsp].[error_code],[rsp].[price_unit],[rsp].[api_version]
                FROM OPENJSON(@apiResponse,'$.messages') --data is in the messages array
                           WITH (
                                    [body] NVARCHAR(255) '$.body',[num_segments] NVARCHAR(255) '$.num_segments',[direction] NVARCHAR(255) '$.direction',[from] NVARCHAR(255) '$.from',[date_updated] NVARCHAR(255) '$.date_updated',[price] NVARCHAR(255) '$.price',[error_message] NVARCHAR(255) '$.error_message',[uri] NVARCHAR(255) '$.uri',[account_sid] NVARCHAR(255) '$.account_sid',[num_media] NVARCHAR(255) '$.num_media',[to] NVARCHAR(255) '$.to',[date_created] NVARCHAR(255) '$.date_created',[status] NVARCHAR(255) '$.status',[sid] NVARCHAR(255) '$.sid',[date_sent] NVARCHAR(255) '$.date_sent',[messaging_service_sid] NVARCHAR(255) '$.messing_serivce_sid',[error_code] NVARCHAR(255) '$.error_code',[price_unit] NVARCHAR(255) '$.price_unit',[api_version] NVARCHAR(255) '$.api_version'
                                ) AS [rsp];


    SELECT @NextUrl = [next_page_uri]
    FROM
           OPENJSON(@apiResponse)
               WITH (
                        [next_page_uri] NVARCHAR(2000) '$.next_page_uri'
                    );

                    -- we check for null of NextUrl and return STOP to stop the for loop
                    --if not we return out the Url to go back around and get more data
    SELECT CASE WHEN @NextUrl IS NOT NULL THEN CONCAT('https://api.twilio.com',@NextUrl)
                ELSE 'STOP'
           END AS [NextUrl];

SSIS变量NextUrl get被存储过程返回的内容覆盖。如果不等于STOP,则继续执行for循环,现在将该URL传递到脚本任务中以获取下一组数据,依此类推...

,

最终可以使它在C#中工作。问题在于正在使用的dll版本在最新版本之间无法正常工作。