Skip to content
This repository has been archived by the owner on Apr 4, 2024. It is now read-only.

Commit

Permalink
migrate to twitter api v2
Browse files Browse the repository at this point in the history
  • Loading branch information
ironoa committed Feb 19, 2024
1 parent 07fc4fa commit a34b173
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 63 deletions.
3 changes: 2 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
!Cargo.lock
!src
!messages
!config.sample.json
!config.sample.json
!config.yaml
4 changes: 2 additions & 2 deletions charts/polkadot-registrar-challenger/Chart.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
description: Polkadot Challenger
name: polkadot-registrar-challenger
version: v0.5.1
appVersion: v0.5.1
version: v0.6.0
appVersion: v0.6.0
apiVersion: v2
31 changes: 31 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
version: '3.1'

services:
challenger:
build:
context: .
dockerfile: Dockerfile
# command: ["/bin/bash", "-c", "tail -f /dev/null"]
restart: always
volumes:
- type: bind
source: ./config/
target: /etc/registrar/

watcher:
image: web3f/polkadot-registrar-watcher:v0.4.8
container_name: watcher
restart: always
volumes:
- type: bind
source: ./configWatcher/
target: /app/config

db:
image: mongo
container_name: db
restart: always
ports:
- "27017:27017"


94 changes: 34 additions & 60 deletions src/adapters/twitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,14 @@ impl TwitterClient {
async fn request_messages(&mut self) -> Result<Vec<ExternalMessage>> {
debug!("Requesting Twitter messages");
// Request message on parse those into a simpler type.
let url = String::from("https://api.twitter.com/2/dm_events");
let mut params = vec![];
params.push(("event_types", "MessageCreate"));
params.push(("dm_event.fields", "id,text,created_at,sender_id"));
let mut messages = self
.get_request::<ApiMessageRequest>(
"https://api.twitter.com/1.1/direct_messages/events/list.json",
None,
&url,
Some(&params),
)
.await?
.parse()?;
Expand Down Expand Up @@ -170,9 +174,8 @@ impl TwitterClient {
to_lookup.dedup();

// Lookup Twitter Ids and insert those into the cache.
debug!("Looking up Twitter Ids");
if !to_lookup.is_empty() {
let lookup_results = self.lookup_twitter_id(Some(&to_lookup), None).await?;
let lookup_results = self.lookup_twitter_id(Some(&to_lookup)).await?;
self.twitter_ids.extend(lookup_results);
}

Expand Down Expand Up @@ -304,8 +307,8 @@ impl TwitterClient {
async fn lookup_twitter_id(
&self,
twitter_ids: Option<&[&TwitterId]>,
accounts: Option<&[&String]>,
) -> Result<HashMap<TwitterId, String>> {
let url = String::from("https://api.twitter.com/2/users");
let mut params = vec![];

// Lookups for UserIds
Expand All @@ -319,94 +322,65 @@ impl TwitterClient {
// Remove trailing `,`.
lookup.pop();

params.push(("user_id", lookup.as_str()))
params.push(("ids", lookup.as_str()))
}

// Lookups for Accounts
let mut lookup = String::new();
if let Some(accounts) = accounts {
for account in accounts {
lookup.push_str(&account.as_str().replace('@', ""));
lookup.push(',');
}

// Remove trailing `,`.
lookup.pop();

params.push(("screen_name", lookup.as_str()))
#[derive(Deserialize)]
struct UserResponse {
data: Vec<UserData>,
}

#[derive(Deserialize)]
// Only `screen_name` required.
struct UserObject {
id: TwitterId,
screen_name: String,
// Only `name` required.
struct UserData {
id: String,
name: String,
}

debug!("Params: {:?}", params);

let user_objects = self
.get_request::<Vec<UserObject>>(
"https://api.twitter.com/1.1/users/lookup.json",
Some(&params),
)
.await?;
let user_response = self.get_request::<UserResponse>(&url, Some(&params)).await?;

if user_objects.is_empty() {
if user_response.data.is_empty() {
return Err(anyhow!("unrecognized data"));
}

Ok(user_objects
let result = user_response.data
.into_iter()
.map(|obj| (obj.id, format!("@{}", obj.screen_name.to_lowercase())))
.collect())
.map(|user| {
let id = TwitterId(user.id.parse().expect("Failed to parse user ID"));
(id, format!("@{}", user.name.to_lowercase()))
})
.collect();
Ok(result)
}
}

#[derive(Debug, Deserialize, Serialize)]
struct ApiMessageRequest {
events: Vec<ApiEvent>,
}

#[derive(Debug, Deserialize, Serialize)]
struct ApiEvent {
#[serde(rename = "type")]
t_type: String,
id: String,
created_timestamp: Option<String>,
message_create: ApiMessageCreate,
data: Vec<ApiMessage>,
}

#[derive(Debug, Deserialize, Serialize)]
struct ApiMessageCreate {
target: ApiTarget,
struct ApiMessage {
sender_id: Option<String>,
message_data: ApiMessageData,
}

#[derive(Debug, Deserialize, Serialize)]
struct ApiTarget {
recipient_id: String,
}

#[derive(Debug, Deserialize, Serialize)]
struct ApiMessageData {
text: String,
id: String,
created_at: Option<String>,
text: String
}

impl ApiMessageRequest {
fn parse(self) -> Result<Vec<ReceivedMessageContext>> {
let mut messages = vec![];

for event in self.events {
for m in self.data {
let message = ReceivedMessageContext {
sender: event
.message_create
sender: m
.sender_id
.ok_or_else(|| anyhow!("unrecognized data"))?
.try_into()?,
message: event.message_create.message_data.text,
id: event.id.parse().map_err(|_| anyhow!("unrecognized data"))?,
message: m.text,
id: m.id.parse().map_err(|_| anyhow!("unrecognized data"))?,
};

messages.push(message);
Expand Down

0 comments on commit a34b173

Please sign in to comment.