Skip to content
59 changes: 28 additions & 31 deletions CSharp/Hangover.cs
Original file line number Diff line number Diff line change
@@ -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);
72 changes: 72 additions & 0 deletions CSharp/OpenAi/ChatGpt.cs
Original file line number Diff line number Diff line change
@@ -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<List<string>> 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<List<string>> 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<List<string>> DoRequest(string prompt)
{
var promptJson = new CompletionChatRequest
{
Messages = new List<CompletionChatMessage>
{
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<CompletionChatResponse>(responseContent, _serializerOptions);

if (response?.Content != null)
{
return response.Content.Split(";").ToList();
}

return new List<string>
{
"Talk to you later"
};
}
}
6 changes: 6 additions & 0 deletions CSharp/OpenAi/CompletionChatChoice.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Temp.OpenAi;

public record struct CompletionChatChoice
{
public CompletionChatMessage Message { get; set; }
}
12 changes: 12 additions & 0 deletions CSharp/OpenAi/CompletionChatMessage.cs
Original file line number Diff line number Diff line change
@@ -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;
}
7 changes: 7 additions & 0 deletions CSharp/OpenAi/CompletionChatResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Temp.OpenAi;

public record CompletionChatResponse
{
public CompletionChatChoice[] Choices { get; set; }
public string? Content => Choices.FirstOrDefault().Message.Content;
}
18 changes: 18 additions & 0 deletions CSharp/OpenAi/CompletionChatResquest.cs
Original file line number Diff line number Diff line change
@@ -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<CompletionChatMessage>? Messages { get; set; }
}
60 changes: 29 additions & 31 deletions CSharp/SmackMyBitch.cs
Original file line number Diff line number Diff line change
@@ -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}");
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

English | [简体中文](./README.zh-CN.md)
English | [简体中文](./README.zh-CN.md) | [Português](./README.pt-BR.md)

# Hacker Scripts

Expand Down
60 changes: 60 additions & 0 deletions README.pt-BR.md
Original file line number Diff line number Diff line change
@@ -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.