LinqToTwitter 列出指定日期以来的 DM
Posted
技术标签:
【中文标题】LinqToTwitter 列出指定日期以来的 DM【英文标题】:LinqToTwitter List DMs since a specified date 【发布时间】:2021-05-13 06:54:27 【问题描述】:是否可以在指定日期之后列出私信?如果我有大量直接消息,如果我必须翻阅许多结果,我会很快达到速率限制。我想跟踪我上次查询 DirectMessageEventsType.List
的时间,并将下一次查询限制为仅在该日期之后发送/接收的消息。
【问题讨论】:
【参考方案1】:您可能已经知道,Twitter API 中用于列出 DM 的唯一参数是 count
和 cursor
。也就是说,这里有一个可能很方便的解决方法。它涉及在 LINQ to Twitter 查询之后的 LINQ to Objects 查询:
using System;
using System.Linq;
using System.Collections.Generic;
using System.Threading.Tasks;
using LinqToTwitter;
using LinqToTwitter.OAuth;
using System.Diagnostics;
namespace TwitterDMListDate
class Program
static async Task Main()
TwitterContext twitterCtx = await GetTwitterContext();
int count = 50; // set to a low number to demo paging
string cursor = "";
List<DMEvent> allDmEvents = new();
bool isPastCreatedAt = false;
DateTime lastCreatedAt = DateTime.UtcNow.AddHours(-1);
// you don't have a valid cursor until after the first query
DirectMessageEvents dmResponse =
await
(from dm in twitterCtx.DirectMessageEvents
where dm.Type == DirectMessageEventsType.List &&
dm.Count == count
select dm)
.SingleOrDefaultAsync();
isPastCreatedAt = CheckPastCreatedAt(dmResponse, lastCreatedAt);
allDmEvents.AddRange(dmResponse?.Value?.DMEvents ?? new List<DMEvent>());
cursor = dmResponse?.Value?.NextCursor ?? "";
while (!string.IsNullOrWhiteSpace(cursor) && !isPastCreatedAt)
dmResponse =
await
(from dm in twitterCtx.DirectMessageEvents
where dm.Type == DirectMessageEventsType.List &&
dm.Count == count &&
dm.Cursor == cursor
select dm)
.SingleOrDefaultAsync();
allDmEvents.AddRange(dmResponse?.Value?.DMEvents ?? new List<DMEvent>());
cursor = dmResponse?.Value?.NextCursor ?? "";
isPastCreatedAt = CheckPastCreatedAt(dmResponse, lastCreatedAt);
if (!allDmEvents.Any())
Console.WriteLine("No items returned");
return;
Console.WriteLine($"Response Count: allDmEvents.Count");
Console.WriteLine("Responses:");
allDmEvents.ForEach(evt =>
DirectMessageCreate? msgCreate = evt.MessageCreate;
if (evt != null && msgCreate != null)
Console.WriteLine(
$"DM ID: evt.ID\n" +
$"From ID: msgCreate.SenderID ?? "None"\n" +
$"To ID: msgCreate.Target?.RecipientID ?? "None"\n" +
$"Message Text: msgCreate.MessageData?.Text ?? "None"\n");
);
static bool CheckPastCreatedAt(DirectMessageEvents dmResponse, DateTime lastCreatedAt)
return
(from dm in dmResponse.Value.DMEvents
where dm.CreatedAt <= lastCreatedAt
select dm)
.Any();
static async Task<TwitterContext> GetTwitterContext()
var auth = new PinAuthorizer()
CredentialStore = new InMemoryCredentialStore
ConsumerKey = "",
ConsumerSecret = ""
,
GoToTwitterAuthorization = pageLink =>
var psi = new ProcessStartInfo
FileName = pageLink,
UseShellExecute = true
;
Process.Start(psi);
,
GetPin = () =>
Console.WriteLine(
"\nAfter authorizing this application, Twitter " +
"will give you a 7-digit PIN Number.\n");
Console.Write("Enter the PIN number here: ");
return Console.ReadLine() ?? string.Empty;
;
await auth.AuthorizeAsync();
var twitterCtx = new TwitterContext(auth);
return twitterCtx;
实现这项工作的两个变量是isPastCreatedAt
和lastCreatedAt
。 isPastCreatedAt
标记一组 DM(来自大小为 count
的查询)包含一个或多个早于某个日期的 DM 的条件。符合isPastCreatedAt
条件的日期是lastCreatedAt
。本质上,一旦我们的推文早于lastCreatedAt
,我们就不想继续查询,因为后续查询保证返回所有早于lastCreatedAt
的推文。
演示将lastCreatedAt
设置为提前一小时。请注意,它使用的是 UTC 时间,因为那是 Twitter 使用的时间。在您的应用程序中,您应该跟踪这个时间,将其重新设置为自上一组查询以来收到的最旧推文的CreatedAt
属性。
在每次 LINQ to Twitter 查询 DM 之后,都会调用 CheckPastCreatedAt
。这是设置isPastCreatedAt
的地方。该方法的内部是一个 LINQ to Objects 查询。它查询 LINQ to Twitter 刚刚返回的 DM 列表,检查是否有任何 DM 包含早于lastCreatedAt
日期的日期。它使用CreatedAt
属性,顾名思义,这就是在此演示中命名变量和方法的原因,以确保查询不会过度浪费速率限制。它还使用了Any
运算符,比Count
高效得多,但我跑题了。
请注意,Main
中的 while
语句为您可能用于遍历游标的内容添加了一个附加条件:&& !isPastCreatedAt
。这就是防止你走得太远和浪费速率限制的原因。
完成此操作后,您只需要再做一件事 - 过滤掉您已经收到的 DM 以避免重复。但是,我的直觉是你已经知道了。
虽然这不是您可能希望的答案,但它确实为使用 Twitter API 的任何人概述了一个重要的模式,无论是 LINQ to Twitter 还是任何其他优秀的库。也就是说,使用 Twitter API 为您提供的内容进行查询,然后在本地过滤结果。虽然其他一些库提供了有时感觉很有帮助的额外抽象,但 LINQ to Twitter 采用更原始的方法来更接近 Twitter API 本身。因为在这种情况下,最好直观地了解发生了什么问题,这样您就可以推断出满足您需求的其他解决方案。
【讨论】:
感谢您的详尽回复!我现在会深入研究。以上是关于LinqToTwitter 列出指定日期以来的 DM的主要内容,如果未能解决你的问题,请参考以下文章