From 43968bc7049847e8ce71847f20c2a3ae4ecc15ec Mon Sep 17 00:00:00 2001 From: Esteban Vincent Date: Tue, 19 May 2026 11:05:34 +0200 Subject: [PATCH] feat: add initial raycast scripts collection --- .gitignore | 1 + scripts/get_graph_user.sh | 91 ++++++++++++++++++++++++++++++++++++++ scripts/imgflip-meme.sh | 60 +++++++++++++++++++++++++ scripts/ipv4-get.sh | 16 +++++++ scripts/no-as-a-service.sh | 17 +++++++ scripts/x.sh | 17 +++++++ 6 files changed, 202 insertions(+) create mode 100644 .gitignore create mode 100755 scripts/get_graph_user.sh create mode 100755 scripts/imgflip-meme.sh create mode 100755 scripts/ipv4-get.sh create mode 100755 scripts/no-as-a-service.sh create mode 100755 scripts/x.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4c49bd7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.env diff --git a/scripts/get_graph_user.sh b/scripts/get_graph_user.sh new file mode 100755 index 0000000..eb7965d --- /dev/null +++ b/scripts/get_graph_user.sh @@ -0,0 +1,91 @@ +#!/bin/bash + +# Required parameters: +# @raycast.schemaVersion 1 +# @raycast.title Get Graph User +# @raycast.mode silent +# @raycast.argument1 { "type": "text", "placeholder": "User ID or UPN" } + +# Optional parameters: +# @raycast.icon 👤 + +# Documentation: +# @raycast.description Fetch MS Graph user info by ID or UPN +# @raycast.author Esteban Vincent + +USER_ID="$1" + +ENV_FILE="$HOME/Raycast/scripts/.env" +if [[ ! -f "$ENV_FILE" ]]; then + echo "❌ .env not found at $ENV_FILE" + exit 1 +fi + +set -o allexport +# shellcheck source=/dev/null +source "$ENV_FILE" +set +o allexport + +for var in AZURE_TENANT_ID AZURE_CLIENT_ID AZURE_CLIENT_SECRET; do + if [[ -z "${!var}" ]]; then + echo "❌ Missing $var in .env" + exit 1 + fi +done + +TOKEN_RESPONSE=$(curl -s -w "\n%{http_code}" \ + -X POST "https://login.microsoftonline.com/${AZURE_TENANT_ID}/oauth2/v2.0/token" \ + -d "client_id=${AZURE_CLIENT_ID}" \ + --data-urlencode "client_secret=${AZURE_CLIENT_SECRET}" \ + -d "scope=https://graph.microsoft.com/.default" \ + -d "grant_type=client_credentials") + +TOKEN_HTTP_STATUS=$(echo "$TOKEN_RESPONSE" | tail -n1) +TOKEN_BODY=$(echo "$TOKEN_RESPONSE" | sed '$d') + +if [[ "$TOKEN_HTTP_STATUS" != "200" ]]; then + TOKEN_ERROR=$(echo "$TOKEN_BODY" | jq -r '.error_description // .error // "unknown error"') + echo "❌ Token request failed (HTTP $TOKEN_HTTP_STATUS): $TOKEN_ERROR" + exit 1 +fi + +ACCESS_TOKEN=$(echo "$TOKEN_BODY" | jq -r '.access_token // empty') +if [[ -z "$ACCESS_TOKEN" ]]; then + echo "❌ No access_token in response: $TOKEN_BODY" + exit 1 +fi + +ENCODED_USER_ID=$(printf '%s' "$USER_ID" | jq -Rr '@uri') +USER_URL="https://graph.microsoft.com/v1.0/users/${ENCODED_USER_ID}?\$select=mail" +CURL_ERR_FILE=$(mktemp) +USER_RESPONSE=$(curl -s -S -w "\n%{http_code}" \ + -H "Authorization: Bearer $ACCESS_TOKEN" \ + -X GET "$USER_URL" 2>"$CURL_ERR_FILE") +CURL_EXIT=$? + +USER_HTTP_STATUS=$(echo "$USER_RESPONSE" | tail -n1) +USER_BODY=$(echo "$USER_RESPONSE" | sed '$d') + +if [[ $CURL_EXIT -ne 0 || "$USER_HTTP_STATUS" == "000" ]]; then + CURL_ERR=$(cat "$CURL_ERR_FILE") + rm -f "$CURL_ERR_FILE" + echo "❌ Graph API curl failed (exit $CURL_EXIT): $CURL_ERR" + exit 1 +fi +rm -f "$CURL_ERR_FILE" + +if [[ "$USER_HTTP_STATUS" == "404" ]]; then + echo "⚠️ User not found: $USER_ID" + exit 0 +fi + +if [[ "$USER_HTTP_STATUS" != "200" ]]; then + GRAPH_ERROR=$(echo "$USER_BODY" | jq -r '.error.message // "unknown error"') + GRAPH_CODE=$(echo "$USER_BODY" | jq -r '.error.code // "unknown"') + echo "❌ Graph API failed (HTTP $USER_HTTP_STATUS) [$GRAPH_CODE]: $GRAPH_ERROR" + exit 1 +fi + +MAIL=$(echo "$USER_BODY" | jq -r '.mail // .userPrincipalName // "N/A"') + +echo "$MAIL" diff --git a/scripts/imgflip-meme.sh b/scripts/imgflip-meme.sh new file mode 100755 index 0000000..6c56300 --- /dev/null +++ b/scripts/imgflip-meme.sh @@ -0,0 +1,60 @@ +#!/bin/bash + +# Required parameters: +# @raycast.schemaVersion 1 +# @raycast.title Generate Meme +# @raycast.mode compact + +# Optional parameters: +# @raycast.icon 🖼️ +# @raycast.argument1 { "type": "text", "placeholder": "meme query" } + +# Documentation: +# @raycast.description Generate a meme via imgflip webhook and copy image to clipboard +# @raycast.author Esteban Vincent + +ENV_FILE="$HOME/Raycast/scripts/.env" +if [[ ! -f "$ENV_FILE" ]]; then + echo "❌ .env not found at $ENV_FILE" + exit 1 +fi + +set -o allexport +# shellcheck source=/dev/null +source "$ENV_FILE" +set +o allexport + +# Re-read literally to preserve $ in value, strip surrounding quotes +N8N_WEBHOOK_IMGFLIP_API_KEY=$(grep -m1 '^N8N_WEBHOOK_IMGFLIP_API_KEY=' "$ENV_FILE" | cut -d= -f2- | sed "s/^['\"]//;s/['\"]$//") + +for var in N8N_WEBHOOK_BASE_URL N8N_WEBHOOK_IMGFLIP_API_KEY; do + if [[ -z "${!var}" ]]; then + echo "❌ Missing $var in .env" + exit 1 + fi +done + +QUERY="$1" +TMPFILE=$(mktemp /tmp/meme_XXXXXX.jpg) + +echo "⏳ Generating meme..." +RESPONSE=$(curl -s --request POST \ + --url "$N8N_WEBHOOK_BASE_URL/imgflip" \ + --header "apiKey: $N8N_WEBHOOK_IMGFLIP_API_KEY" \ + --header 'content-type: application/json' \ + --data "{\"query\": \"$QUERY\"}") + +IMAGE_URL=$(echo "$RESPONSE" | sed -n 's/.*"url":"\([^"]*\)".*/\1/p') + +if [ -z "$IMAGE_URL" ]; then + echo "Failed to generate meme ❌" + rm -f "$TMPFILE" + exit 1 +fi + +curl -s -o "$TMPFILE" "$IMAGE_URL" + +osascript -e "set the clipboard to (read (POSIX file \"$TMPFILE\") as JPEG picture)" + +rm -f "$TMPFILE" +echo "Meme copied to clipboard! 🖼️" diff --git a/scripts/ipv4-get.sh b/scripts/ipv4-get.sh new file mode 100755 index 0000000..3082912 --- /dev/null +++ b/scripts/ipv4-get.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# Required parameters: +# @raycast.schemaVersion 1 +# @raycast.title Get Public IPv4 +# @raycast.mode silent + +# Optional parameters: +# @raycast.icon 🌐 + +# Documentation: +# @raycast.author Esteban Vincent + +PUBLIC_IP=$(curl -s https://api64.ipify.org) +echo -n "$PUBLIC_IP" | pbcopy +echo "Copied to clipboard! ✅" \ No newline at end of file diff --git a/scripts/no-as-a-service.sh b/scripts/no-as-a-service.sh new file mode 100755 index 0000000..233335f --- /dev/null +++ b/scripts/no-as-a-service.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +# Required parameters: +# @raycast.schemaVersion 1 +# @raycast.title Random No +# @raycast.mode silent + +# Optional parameters: +# @raycast.icon ❌ + +# Documentation: +# @raycast.description Get a random rejection reason from No-as-a-Service +# @raycast.author Esteban Vincent + +REASON=$(curl -s https://naas.isalman.dev/no | sed -n 's/.*"reason":"\([^"]*\)".*/\1/p') +echo -n "$REASON" | pbcopy +echo "$REASON" diff --git a/scripts/x.sh b/scripts/x.sh new file mode 100755 index 0000000..0929d57 --- /dev/null +++ b/scripts/x.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +# Required parameters: +# @raycast.schemaVersion 1 +# @raycast.title x +# @raycast.mode silent + +# Optional parameters: +# @raycast.icon 🤖 + +# Documentation: +# @raycast.description Return bruno ✕ +# @raycast.author Esteban Vincent + +echo -n "✕" | pbcopy +echo "Copied to clipboard! ✅" +