callfi_crawler/Program.cs
2024-06-21 01:18:29 +08:00

492 lines
19 KiB
C#

using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
class Program
{
public static readonly int POST_CRAWLER_INTERVAL = 1;
public static readonly int REQUEST_GOD_INTERVAL = 10 * 1000; // 10 secs
public static readonly int TOKEN_UPDATER_INTERVAL = 10 * 1000; // 5 secs
private static readonly string bearerToken = "AAAAAAAAAAAAAAAAAAAAANw1uQEAAAAAe7iEwpMcF%2FjNUZ4WLxEHpax3Ywg%3D0PV1pvJB23a47hWAIwB09olQesVhsz9fPKLg8edP2cwC5D6YHW";
private static readonly string searchUrl = "https://api.twitter.com/2/tweets/search/recent";
static async Task Main(string[] args)
{
StartPostCrawler();
StartRequestGod();
StartTokenCrawler();
while (true)
{
await Task.Delay(1000);
}
}
static async void StartRequestGod()
{
string requestUrl = $"https://api.callfi.io/get_requests.php";
while (true)
{
using (HttpClient client = new HttpClient())
{
HttpResponseMessage response = await client.GetAsync(requestUrl);
if (response.IsSuccessStatusCode)
{
string jsonResponse = await response.Content.ReadAsStringAsync();
JArray requests = JArray.Parse(jsonResponse);
for (int i = 0; i < requests.Count; i++)
{
string reqType = (requests[i]["request_type"] ?? "").ToString();
string reqId = requests[i]["id"].ToString();
if (reqType == "twitter_id")
{
string userTag = requests[i]["request_data"].ToString();
string userId = await GetTwitterId(userTag);
if (userId.Length > 0)
{
//Update twitter map
await AddTwitterTag(userTag, userId, reqId);
}
}
}
}
else
{
Console.WriteLine($"Request failed: {response.StatusCode} - {response.ReasonPhrase}");
}
}
await Task.Delay(REQUEST_GOD_INTERVAL);
}
}
static async Task<string> GetTwitterId(string userTag)
{
string requestUrl = $"https://api.twitter.com/2/users/by/username/{userTag.Replace("@", "")}";
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", bearerToken);
Console.WriteLine(requestUrl);
HttpResponseMessage response = await client.GetAsync(requestUrl);
if (response.IsSuccessStatusCode)
{
string jsonResponse = await response.Content.ReadAsStringAsync();
JObject userObj = JObject.Parse(jsonResponse);
return (userObj["data"]["id"] ?? "").ToString();
}
else
{
Console.WriteLine($"Request failed id: {response.StatusCode} - {response.ReasonPhrase}");
}
}
return "";
}
static async Task AddTwitterTag(string userTag, string userId, string reqId)
{
await CompleteRequest(reqId, userId);
string requestUrl = $"https://api.callfi.io/add_twitter_tag.php?userTag={userTag}&userId={userId}";
using (HttpClient client = new HttpClient())
{
HttpResponseMessage response = await client.GetAsync(requestUrl);
if (response.IsSuccessStatusCode)
{
string jsonResponse = await response.Content.ReadAsStringAsync();
if (jsonResponse == "0")
{
//Done
}
}
else
{
Console.WriteLine($"Request failed twittTag: {response.StatusCode} - {response.ReasonPhrase}");
}
}
}
static async Task CompleteRequest(string reqId, string remark)
{
string requestUrl = $"https://api.callfi.io/complete_request.php?id={reqId}&remarks={remark}";
Console.WriteLine(requestUrl);
using (HttpClient client = new HttpClient())
{
HttpResponseMessage response = await client.GetAsync(requestUrl);
if (response.IsSuccessStatusCode)
{
string jsonResponse = await response.Content.ReadAsStringAsync();
Console.WriteLine(jsonResponse);
if (jsonResponse == "0")
{
//Done
}
}
else
{
Console.WriteLine($"Request failed complete request: {response.StatusCode} - {response.ReasonPhrase}");
}
}
}
//sk-proj-okUjDHtCh22PaAuFZgraT3BlbkFJRinfIM5NwbU0zffUVRFq
static bool kickstarted = false;
static async void StartPostCrawler()
{
string searchString = "CallFi";
string query = Uri.EscapeDataString(searchString);
while (true)
{
DateTime now = DateTime.UtcNow;
DateTime startTime = now.AddMinutes(-POST_CRAWLER_INTERVAL * (kickstarted ? 1: 15));
kickstarted =true;
string startTimeStr = startTime.ToString("yyyy-MM-ddTHH:mm:ssZ");
string endTimeStr = now.ToString("yyyy-MM-ddTHH:mm:ssZ");
string requestUrl = $"{searchUrl}?query={query}&max_results=50&start_time={startTimeStr}&tweet.fields=author_id,created_at";
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", bearerToken);
HttpResponseMessage response = await client.GetAsync(requestUrl);
Console.WriteLine(requestUrl);
if (response.IsSuccessStatusCode)
{
string jsonResponse = await response.Content.ReadAsStringAsync();
JObject tweets = JObject.Parse(jsonResponse);
File.WriteAllText(AppDomain.CurrentDomain.BaseDirectory + $"/results_{DateTime.Now.Year}_{DateTime.Now.Month}_{DateTime.Now.Day}-{DateTime.Now.Hour}-{DateTime.Now.Minute}.txt", tweets.ToString());
Console.WriteLine(tweets.ToString());
try
{
JArray tweetsData = JArray.Parse(tweets["data"].ToString());
for (int i = 0; i < tweetsData.Count; i++)
{
string tweetId = tweetsData[i]["id"].ToString();
string tweetText = tweetsData[i]["text"].ToString();
string tweetAuthor = tweetsData[i]["author_id"].ToString();
string created_at = tweetsData[i]["created_at"].ToString();
string chatGPTResponse = await CalloutAskChatGPT(tweetText);
string[] data = chatGPTResponse.Split(',');
string code = "unknown";
string name = "unknown";
if (data[0] == "yes")
{
code = data[1];
name = (data.Length > 2) ? data[2] : "unknown";
}else{
//Check if participation tweet
string partChatGPTResponse = await ParticipationAskChatGPT(tweetText);
if(partChatGPTResponse.ToLower().Contains("yes")){
await Participation(tweetAuthor);
}else{
Console.WriteLine($"Ignoring tweet {tweetText}");
}
continue;
}
await AddTweet(tweetId, created_at, tweetText, tweetAuthor, code, name);
}
}
catch
{
Console.WriteLine("None");
}
}
else
{
Console.WriteLine($"Request failed Twitter fetch: {response.StatusCode} - {response.ReasonPhrase}");
}
}
await Task.Delay(POST_CRAWLER_INTERVAL * 60 * 1000);
}
}
static async Task AddTweet(string id, string createdAt, string text, string author, string tokenCode, string tokenName)
{
string requestUrl = $"https://api.callfi.io/add_tweet.php?tweet_id={id}&created_at={createdAt}&author_id={author}&text={Uri.EscapeDataString(text)}&token_code={Uri.EscapeDataString(tokenCode)}&token_name={Uri.EscapeDataString(tokenName)}";
Console.WriteLine(requestUrl);
using (HttpClient client = new HttpClient())
{
HttpResponseMessage response = await client.GetAsync(requestUrl);
if (response.IsSuccessStatusCode)
{
string jsonResponse = await response.Content.ReadAsStringAsync();
Console.WriteLine(jsonResponse);
if (jsonResponse == "0")
{
//Done
}
}
else
{
Console.WriteLine($"Request failed complete request: {response.StatusCode} - {response.ReasonPhrase}");
}
}
}
static async Task Participation(string author)
{
string requestUrl = $"https://api.callfi.io/participate.php?author_id={author}";
Console.WriteLine(requestUrl);
using (HttpClient client = new HttpClient())
{
HttpResponseMessage response = await client.GetAsync(requestUrl);
if (response.IsSuccessStatusCode)
{
string jsonResponse = await response.Content.ReadAsStringAsync();
Console.WriteLine(jsonResponse);
if (jsonResponse == "0")
{
//Done
}
}
else
{
Console.WriteLine($"Request failed complete request: {response.StatusCode} - {response.ReasonPhrase}");
}
}
}
static async void UpdateLeaderboard()
{
await UpdateTokens();
string requestUrl = "https://api.callfi.io/get_tweets.php";
List<string> Tokens = new List<string>();
using (HttpClient client = new HttpClient())
{
HttpResponseMessage response = await client.GetAsync(requestUrl);
if (response.IsSuccessStatusCode)
{
JArray jsonArr = JArray.Parse(await response.Content.ReadAsStringAsync());
Dictionary<string, string> TwitterHandles = new Dictionary<string, string>();
foreach(JObject tweet in jsonArr){
string tokenId = tweet["tokenCode"].ToString().Replace(" ","");
if(!Tokens.Contains(tokenId)){
Tokens.Add(tokenId);
}
string userId = tweet["author"].ToString().Replace(" ", "");
if(!TwitterHandles.ContainsKey(userId)){
HttpResponseMessage usernameResponse = await client.GetAsync("https://api.callfi.io/get_twitter_username.php?id="+userId);
string usernameTxt = await usernameResponse.Content.ReadAsStringAsync();
TwitterHandles.Add(userId, usernameTxt);
}
}
Dictionary<string, decimal> TokenPrices = new Dictionary<string, decimal>();
foreach(string token in Tokens){
try{
HttpResponseMessage priceResponse = await client.GetAsync("https://api.callfi.io/get_token_price.php?id="+token);
string priceResponseTxt = await priceResponse.Content.ReadAsStringAsync();
decimal price = decimal.Parse(priceResponseTxt);
TokenPrices.Add(token,price);
}catch(Exception e){
Console.WriteLine("Failed to get price of " + token);
}
}
Dictionary<string, decimal> Leaderboard = new Dictionary<string, decimal>();
foreach(JObject tweet in jsonArr){
string tokenId = tweet["tokenCode"].ToString().Replace(" ","");
decimal priceAtCreation = decimal.Parse(tweet["price_at_creation"].ToString());
decimal priceDiff = TokenPrices[tokenId] - priceAtCreation;
decimal priceDiffPerc = priceDiff / priceAtCreation;
decimal pointsAdded= priceDiffPerc;
string userTag = TwitterHandles[tweet["author"].ToString()];
if(!userTag.Contains("@")){continue;}
if(Leaderboard.ContainsKey(userTag)){
Leaderboard[userTag] += pointsAdded;
}else{
Leaderboard.Add(userTag, pointsAdded);
}
}
List<string> approvedUsers = await GetApprovedUsers();
foreach(string approvedUser in approvedUsers){
if(!Leaderboard.ContainsKey(approvedUser)){
Leaderboard.Add(approvedUser,0);
}
}
Console.WriteLine(JsonConvert.SerializeObject(Leaderboard));
foreach(KeyValuePair<string, decimal> leaderboardItem in Leaderboard){
string setLeaderboardItemUrl = $"https://api.callfi.io/set_leaderboard_item.php?username={leaderboardItem.Key}&points={leaderboardItem.Value}";
HttpResponseMessage priceResponse = await client.GetAsync(setLeaderboardItemUrl);
Console.WriteLine(setLeaderboardItemUrl);
string priceResponseTxt = await priceResponse.Content.ReadAsStringAsync();
}
}
else
{
Console.WriteLine($"Request failed: {response.StatusCode} - {response.ReasonPhrase}");
}
}
}
static async Task<List<string>> GetApprovedUsers(){
string requestUrl = "https://api.callfi.io/get_approved_users.php";
List<string> output = new List<string>();
using (HttpClient client = new HttpClient())
{
HttpResponseMessage response = await client.GetAsync(requestUrl);
if (response.IsSuccessStatusCode)
{
JArray usersJ = JArray.Parse(await response.Content.ReadAsStringAsync());
for(int i=0;i < usersJ.Count; i++){
output.Add(usersJ[i].ToString());
}
}
else
{
Console.WriteLine($"Request failed: {response.StatusCode} - {response.ReasonPhrase}");
}
}
return output;
}
static async Task<string> CalloutAskChatGPT(string text)
{
string context = @"I'm gonna give you few tweets i copied from twitter, After I send you the tweet, You must respond with if the tweet is about a web3 token/coin and which token are they talking about.
Response must be in following format. Also Ignore CallFi, CallingIt tags.
Whether its about a token/coin, token/coin, token/coin long name
example responses:
yes, DOGE, Doge
yes, TWEP, The Web3 Project
yes, PEPE, Pepe Meme
yes, COC, Cocktailbar
no";
HttpClient client = new HttpClient();
var url = "https://api.openai.com/v1/chat/completions";
var apiKey = "sk-proj-AUdPozaNLwzgZiFDty8HT3BlbkFJfJDONAwRJwfFmZ56nAZo";
var requestData = new
{
model = "gpt-3.5-turbo",
messages = new[]
{
new { role = "user", content = context },
new {role = "user", content = text}
},
temperature = 0.7
};
var json = Newtonsoft.Json.JsonConvert.SerializeObject(requestData);
var requestMessage = new HttpRequestMessage(HttpMethod.Post, url);
requestMessage.Headers.Add("Authorization", $"Bearer {apiKey}");
requestMessage.Content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.SendAsync(requestMessage);
var responseString = await response.Content.ReadAsStringAsync();
JObject resposneJson = JObject.Parse(responseString);
string resContent = resposneJson["choices"][0]["message"]["content"].ToString();
Console.WriteLine(resContent);
return resContent;
}
static async Task<string> ParticipationAskChatGPT(string text)
{
string context = @"Check if next message im gonna send you, is a participation post for my platform which is called CallFi, a platform for calling out upcoming tokens, Simply respond 'yes' or 'no' if it is a participation tweet with a mention to the web link callfi.io";
HttpClient client = new HttpClient();
var url = "https://api.openai.com/v1/chat/completions";
var apiKey = "sk-proj-AUdPozaNLwzgZiFDty8HT3BlbkFJfJDONAwRJwfFmZ56nAZo";
var requestData = new
{
model = "gpt-3.5-turbo",
messages = new[]
{
new { role = "user", content = context },
new {role = "user", content = text}
},
temperature = 0.7
};
var json = Newtonsoft.Json.JsonConvert.SerializeObject(requestData);
var requestMessage = new HttpRequestMessage(HttpMethod.Post, url);
requestMessage.Headers.Add("Authorization", $"Bearer {apiKey}");
requestMessage.Content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.SendAsync(requestMessage);
var responseString = await response.Content.ReadAsStringAsync();
JObject resposneJson = JObject.Parse(responseString);
string resContent = resposneJson["choices"][0]["message"]["content"].ToString();
Console.WriteLine(resContent);
return resContent;
}
static async void StartTokenCrawler()
{
while (true)
{
await UpdateTokens();
UpdateLeaderboard();
await Task.Delay(TOKEN_UPDATER_INTERVAL);
}
}
static async Task UpdateTokens()
{
string requestUrl = "https://api.callfi.io/get_tokens.php";
using (HttpClient client = new HttpClient())
{
HttpResponseMessage response = await client.GetAsync(requestUrl);
if (response.IsSuccessStatusCode)
{
}
else
{
Console.WriteLine($"Request failed: {response.StatusCode} - {response.ReasonPhrase}");
}
}
}
}