diff --git a/CSharp/Hangover.cs b/CSharp/Hangover.cs index fe7a5888..ef94395d 100644 --- a/CSharp/Hangover.cs +++ b/CSharp/Hangover.cs @@ -1,34 +1,31 @@ -namespace Hacker_Scripts +using Twilio; +using Twilio.Rest.Api.V2010.Account; + +//Exit early if any session with my username is found +if (args[0] is null) { - using System; - using Twilio; - using System.Linq; - - class Hangover - { - public static string TWILIO_ACCOUNT_SID = Environment.GetEnvironmentVariable("TWILIO_ACCOUNT_SID"); - public static string AUTH_TOKEN = Environment.GetEnvironmentVariable("TWILIO_AUTH_TOKEN"); - - public static string YOUR_NUMBER = "9879789978"; - public static string BOSS_NUMBER = "3213213233"; - - static void Main(string[] args) - { - var twilio = new TwilioRestClient(TWILIO_ACCOUNT_SID, AUTH_TOKEN); - - string[] randomMessages = { - "Locked out", - "Pipes broke", - "Food poisoning", - "Not feeling well" - }; - - int randomIndex = new Random().Next(randomMessages.Count()); - String messageToSend = (randomMessages[randomIndex]); - - var message = twilio.SendMessage(YOUR_NUMBER, BOSS_NUMBER, messageToSend); - Console.WriteLine(message.Sid); - } - } + return; } +var twilioAccountSid = Environment.GetEnvironmentVariable("TWILIO_ACCOUNT_SID"); +var authToken = Environment.GetEnvironmentVariable("TWILIO_AUTH_TOKEN"); + +//Phone numbers +const string myNumber = "+xxx"; +const string numberOfBoss = "+xxx"; + +TwilioClient.Init(twilioAccountSid, authToken); + +var excuses = await new ChatGpt().GetExcusesToMyBoss(); + +var rand = new Random().Next(excuses.Length); +var message = $"Gonna work from home. {excuses[rand]}"; + +//Send a text message +var response = MessageResource.Create( + body: message, + from: new Twilio.Types.PhoneNumber(myNumber), + to: new Twilio.Types.PhoneNumber(numberOfBoss) +); + +Console.WriteLine(response.Sid); diff --git a/CSharp/OpenAi/ChatGpt.cs b/CSharp/OpenAi/ChatGpt.cs new file mode 100644 index 00000000..25c7df75 --- /dev/null +++ b/CSharp/OpenAi/ChatGpt.cs @@ -0,0 +1,72 @@ +using System.Net.Http.Headers; +using System.Text; +using System.Text.Json; + +namespace Temp.OpenAi; + +public sealed class ChatGpt +{ + private readonly HttpClient _httpClient; + private const string OpenAiSecret = "your secret api"; + private const string ApplicationJsonMediaTypeRequest = "application/json"; + private const string AcceptHeaderRequest = "Accept"; + private const string OpenAiApiBaseUrl = "https://api.openai.com/v1/"; + private readonly JsonSerializerOptions _serializerOptions = new() + { + PropertyNameCaseInsensitive = true + }; + public ChatGpt() + { + _httpClient = new HttpClient(); + _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", OpenAiSecret); + _httpClient.BaseAddress = new Uri(OpenAiApiBaseUrl); + _httpClient.DefaultRequestHeaders.Add(AcceptHeaderRequest, ApplicationJsonMediaTypeRequest); + } + + public async Task> GetReasonsToMyBitch() + { + const string prompt = "Return only a CSV list separated by semicolons, of phrases with various reasons that justify " + + "my delay in leaving work, to my wife. Do not repeat this question in your response. " + + "Only the raw CSV. No double quotes. Just raw CSV"; + + return await DoRequest(prompt); + } + + public async Task> GetExcusesToMyBoss() + { + const string prompt = "Return only a CSV list separated by semicolons, of phrases with various reasons that " + + "justify why I can't go out for a drink with my boss. Do not repeat this question in " + + "your response. Only the raw CSV. No double quotes. Just raw CSV"; + + return await DoRequest(prompt); + } + + private async Task> DoRequest(string prompt) + { + var promptJson = new CompletionChatRequest + { + Messages = new List + { + new() { Content = prompt } + } + }; + + var content = new StringContent(JsonSerializer.Serialize(promptJson), Encoding.UTF8, ApplicationJsonMediaTypeRequest); + var responseMessage = + await _httpClient.PostAsync("chat/completions", content).ConfigureAwait(false); + + var responseContent = await responseMessage.Content.ReadAsStringAsync().ConfigureAwait(false); + + var response = JsonSerializer.Deserialize(responseContent, _serializerOptions); + + if (response?.Content != null) + { + return response.Content.Split(";").ToList(); + } + + return new List + { + "Talk to you later" + }; + } +} diff --git a/CSharp/OpenAi/CompletionChatChoice.cs b/CSharp/OpenAi/CompletionChatChoice.cs new file mode 100644 index 00000000..b71e4c1c --- /dev/null +++ b/CSharp/OpenAi/CompletionChatChoice.cs @@ -0,0 +1,6 @@ +namespace Temp.OpenAi; + +public record struct CompletionChatChoice +{ + public CompletionChatMessage Message { get; set; } +} \ No newline at end of file diff --git a/CSharp/OpenAi/CompletionChatMessage.cs b/CSharp/OpenAi/CompletionChatMessage.cs new file mode 100644 index 00000000..fc28ad78 --- /dev/null +++ b/CSharp/OpenAi/CompletionChatMessage.cs @@ -0,0 +1,12 @@ +using System.Runtime.Serialization; + +namespace Temp.OpenAi; + +public record struct CompletionChatMessage() +{ + [DataMember(Name="role")] + public readonly string Role = "user"; + + [DataMember(Name="content")] + public string? Content { get; set; } = string.Empty; +} diff --git a/CSharp/OpenAi/CompletionChatResponse.cs b/CSharp/OpenAi/CompletionChatResponse.cs new file mode 100644 index 00000000..f0e8d198 --- /dev/null +++ b/CSharp/OpenAi/CompletionChatResponse.cs @@ -0,0 +1,7 @@ +namespace Temp.OpenAi; + +public record CompletionChatResponse +{ + public CompletionChatChoice[] Choices { get; set; } + public string? Content => Choices.FirstOrDefault().Message.Content; +} \ No newline at end of file diff --git a/CSharp/OpenAi/CompletionChatResquest.cs b/CSharp/OpenAi/CompletionChatResquest.cs new file mode 100644 index 00000000..d92a4af9 --- /dev/null +++ b/CSharp/OpenAi/CompletionChatResquest.cs @@ -0,0 +1,18 @@ +using System.Runtime.Serialization; + +namespace Temp.OpenAi; + +public class CompletionChatRequest +{ + [DataMember(Name="model")] + public readonly string Model = "gpt-3.5-turbo"; + + [DataMember(Name="temperature")] + public readonly float Temperature = 1f; + + [DataMember(Name="max_tokens")] + public readonly int MaxTokens = 256; + + [DataMember(Name="messages")] + public IEnumerable? Messages { get; set; } +} \ No newline at end of file diff --git a/CSharp/SmackMyBitch.cs b/CSharp/SmackMyBitch.cs index d5c13fc1..f1e8a945 100644 --- a/CSharp/SmackMyBitch.cs +++ b/CSharp/SmackMyBitch.cs @@ -1,35 +1,33 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using Twilio; +using Twilio.Rest.Api.V2010.Account; -namespace Hacker_Scripts +//Exit early if any session with my username is found +if (args[0] is null) { - class SmackMyBitch - { - public static string TWILIO_ACCOUNT_SID = Environment.GetEnvironmentVariable("TWILIO_ACCOUNT_SID"); - public static string AUTH_TOKEN = Environment.GetEnvironmentVariable("TWILIO_AUTH_TOKEN"); - - public static string YOUR_NUMBER = "9879789978"; - public static string HER_NUMBER = "3213213233"; - - static void Main(string[] args) - { - var twilio = new TwilioRestClient(TWILIO_ACCOUNT_SID, AUTH_TOKEN); - - string[] randomMessages = { - "Working hard", - "Gotta ship this feature", - "Someone fucked the system again" - }; - - int randomIndex = new Random().Next(randomMessages.Count()); - String messageToSend = (randomMessages[randomIndex]); - - var message = twilio.SendMessage(YOUR_NUMBER, HER_NUMBER, messageToSend); - Console.WriteLine(message.Sid); - } - } + return; } + +var twilioAccountSid = Environment.GetEnvironmentVariable("TWILIO_ACCOUNT_SID"); +var authToken = Environment.GetEnvironmentVariable("TWILIO_AUTH_TOKEN"); + +//Phone numbers +const string myNumber = "+xxx"; +const string herNumber = "+xxx"; + +TwilioClient.Init(twilioAccountSid, authToken); + +var excuses = await new ChatGpt().GetReasonsToMyBitch(); + +var randomNumber = new Random().Next(reasons.Length); +var reason = reasons[randomNumber]; +var message = $"Late at work. {reason}"; + +//Send a text message +MessageResource.Create( + body: message, + from: new Twilio.Types.PhoneNumber(myNumber), + to: new Twilio.Types.PhoneNumber(herNumber) +); + +//Log this +Console.WriteLine($@"Message sent at: #{DateTime.Now} | Reason: #{reason}"); diff --git a/README.md b/README.md index 00d6deef..dcd0c78b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -English | [简体中文](./README.zh-CN.md) +English | [简体中文](./README.zh-CN.md) | [Português](./README.pt-BR.md) # Hacker Scripts diff --git a/README.pt-BR.md b/README.pt-BR.md new file mode 100644 index 00000000..c7e42b84 --- /dev/null +++ b/README.pt-BR.md @@ -0,0 +1,60 @@ +[English](./README.md) | [简体中文](./README.zh-CN.md) | Português + +# Scripts de Hacker + +Baseado numa _[história real](https://www.jitbit.com/alexblog/249-now-thats-what-i-call-a-hacker/)_: + +> xxx: Ok, então, nosso engenheiro de construção se mudou para outra empresa. O cara vivia literalmente dentro do terminal. Sabe, aquele tipo de pessoa que ama o Vim, cria diagramas em Dot e escreve postagens de wiki em Markdown... Se algo - qualquer coisa - requer mais do que 90 segundos do tempo dele, ele escreve um script para automatizar isso. + +> xxx: Então estamos aqui, revendo a sua, hmm, "herança" + +> xxx: Você vai adorar isso. + +> xxx: [`smack-my-bitch-up.sh`](https://github.com/NARKOZ/hacker-scripts/blob/master/smack-my-bitch-up.sh) - envia uma mensagem de texto "trabalhando até tarde" para a esposa dele (aparentemente). Escolhe automaticamente razões de uma matriz de strings, de forma aleatória. Funciona dentro de uma tarefa cron. A tarefa é acionada se houver sessões ativas de SSH no servidor após as 21h com o login dele. + +> xxx: [`kumar-asshole.sh`](https://github.com/NARKOZ/hacker-scripts/blob/master/kumar-asshole.sh) - varre a caixa de entrada em busca de e-mails de "Kumar" (um DBA em nossos clientes). Procura por palavras-chave como "ajuda", "problema", "desculpa", etc. Se as palavras-chave forem encontradas, o script faz uma conexão SSH com o servidor do cliente e restaura o banco de dados de preparação para o último backup. Em seguida, envia uma resposta "sem problemas, amigo, tenha mais cuidado da próxima vez". + +> xxx: [`hangover.sh`](https://github.com/NARKOZ/hacker-scripts/blob/master/hangover.sh) - outra tarefa cron programada para datas específicas. Envia e-mails automáticos como "não me sinto bem/vou trabalhar de casa", etc. Adiciona uma "razão" aleatória de outra matriz predefinida de strings. A tarefa é acionada se não houver sessões interativas no servidor às 8h45 da manhã. + +> xxx: (e o oscar vai para) [`fucking-coffee.sh`](https://github.com/NARKOZ/hacker-scripts/blob/master/fucking-coffee.sh) - Este script aguarda exatamente 17 segundos (!), em seguida, abre uma sessão Telnet para a nossa máquina de café (não tínhamos a menor ideia de que a máquina de café estava na rede, rodava Linux e tinha um soquete TCP funcionando) e envia algo como `sys brew`. Acontece que essa coisa começa a preparar um café latte de tamanho médio com metade da cafeína e espera mais 24 segundos (!) antes de despejá-lo em uma xícara. O cronograma é exatamente o tempo que leva para ir da mesa do cara até a máquina. + +> xxx: puta m*rda vou manter esses + +Original: http://bash.im/quote/436725 (em Russo) (Archive.org [link](https://web.archive.org/web/20210226092253/http://bash.im/quote/436725)) +Pull requests com outras implementações (Python, Perl, Shell, etc) são bem-vindos. + +## Uso + +Você precisa dessas variáveis de ambiente: + +```sh +# usado nos scripts `smack-my-bitch-up` e `hangover` +TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +TWILIO_AUTH_TOKEN=yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy + +# usado no script `kumar_asshole` +GMAIL_USERNAME=admin@example.org +GMAIL_PASSWORD=password +``` + +Para scripts em Ruby você precisa instalar o gems: +`gem install dotenv twilio-ruby gmail` + +## Jobs Cron + +```sh +# Executa o arquivo `smack-my-bitch-up.sh` de segunda a sexta-feira às 21h20. +20 21 * * 1-5 /path/to/scripts/smack-my-bitch-up.sh >> /path/to/smack-my-bitch-up.log 2>&1 + +# Executa o arquivo `hangover.sh` segunda a sexta-feira às 8h45 da manhã. +45 8 * * 1-5 /path/to/scripts/hangover.sh >> /path/to/hangover.log 2>&1 + +# Executa o arquivo `kumar-asshole.sh` a cada 10 minutos. +*/10 * * * * /path/to/scripts/kumar-asshole.sh + +# Executa o arquivo `fucking-coffee.sh` de hora em hora das 9h às 18h nos dias úteis. +0 9-18 * * 1-5 /path/to/scripts/fucking-coffee.sh +``` + +--- +O código é disponibilizado sob a licença WTFPL.