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 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 Tokens = new List(); using (HttpClient client = new HttpClient()) { HttpResponseMessage response = await client.GetAsync(requestUrl); if (response.IsSuccessStatusCode) { JArray jsonArr = JArray.Parse(await response.Content.ReadAsStringAsync()); Dictionary TwitterHandles = new Dictionary(); 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 TokenPrices = new Dictionary(); 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 Leaderboard = new Dictionary(); 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 approvedUsers = await GetApprovedUsers(); foreach(string approvedUser in approvedUsers){ if(!Leaderboard.ContainsKey(approvedUser)){ Leaderboard.Add(approvedUser,0); } } Console.WriteLine(JsonConvert.SerializeObject(Leaderboard)); foreach(KeyValuePair 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> GetApprovedUsers(){ string requestUrl = "https://api.callfi.io/get_approved_users.php"; List output = new List(); 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 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 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}"); } } } }