bin/ 230 CLI tools (ask-*, br-*, agent-*, roadid, carpool) scripts/ 99 automation scripts fleet/ Node configs and deployment workers/ Cloudflare Worker sources (roadpay, road-search, squad webhooks) roadc/ RoadC programming language roadnet/ Mesh network (5 APs, WireGuard) operator/ Memory system scripts config/ System configs dotfiles/ Shell configs docs/ Documentation BlackRoad OS — Pave Tomorrow. RoadChain-SHA2048: d1a24f55318d338b RoadChain-Identity: alexa@sovereign RoadChain-Full: d1a24f55318d338b24b60bad7be39286379c76ae5470817482100cb0ddbbcb97e147d07ac7243da0a9f0363e4e5c833d612b9c0df3a3cd20802465420278ef74875a5b77f55af6fe42a931b8b635b3d0d0b6bde9abf33dc42eea52bc03c951406d8cbe49f1a3d29b26a94dade05e9477f34a7d4d4c6ec4005c3c2ac54e73a68440c512c8e83fd9b1fe234750b898ef8f4032c23db173961fe225e67a0432b5293a9714f76c5c57ed5fdf35b9fb40fd73c03ebf88b7253c6a0575f5afb6a6b49b3bda310602fb1ef676859962dad2aebbb2875814b30eee0a8ba195e482d4cbc91d8819e7f38f6db53e8063401649c77bb994371473cabfb917fb53e8cbe73d60
261 lines
6.6 KiB
Bash
Executable File
261 lines
6.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# br-linkedin - BlackRoad OS LinkedIn CLI
|
|
# Post to BlackRoad OS, Inc. company page from terminal
|
|
# Company URN: urn:li:organization:111783522
|
|
|
|
set -euo pipefail
|
|
|
|
# Config
|
|
LINKEDIN_ORG_URN="urn:li:organization:111783522"
|
|
LINKEDIN_API_URL="https://api.linkedin.com/v2/ugcPosts"
|
|
ENV_FILE="$HOME/.blackroad/.env.linkedin"
|
|
|
|
# Colors
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m'
|
|
|
|
# Help
|
|
show_help() {
|
|
cat << EOF
|
|
${BLUE}br-linkedin${NC} - Post to BlackRoad OS, Inc. LinkedIn company page
|
|
|
|
${YELLOW}USAGE:${NC}
|
|
br-linkedin post "Your post content here"
|
|
br-linkedin setup
|
|
br-linkedin verify
|
|
br-linkedin help
|
|
|
|
${YELLOW}COMMANDS:${NC}
|
|
post <text> Post to LinkedIn company page
|
|
setup Configure OAuth token
|
|
verify Verify token and permissions
|
|
help Show this help
|
|
|
|
${YELLOW}EXAMPLES:${NC}
|
|
br-linkedin post "Shipping v1.0 today 🚀"
|
|
br-linkedin post "BlackRoad OS now supports 30k+ agents"
|
|
|
|
${YELLOW}SETUP:${NC}
|
|
1. Run: br-linkedin setup
|
|
2. Follow OAuth flow
|
|
3. Save access token
|
|
4. Start posting
|
|
|
|
${YELLOW}ORGANIZATION:${NC}
|
|
BlackRoad OS, Inc.
|
|
URN: ${LINKEDIN_ORG_URN}
|
|
|
|
EOF
|
|
}
|
|
|
|
# Setup OAuth
|
|
setup_oauth() {
|
|
echo -e "${BLUE}br-linkedin setup${NC}"
|
|
echo ""
|
|
echo "To post to LinkedIn, you need an OAuth access token."
|
|
echo ""
|
|
echo -e "${YELLOW}Step 1: Create LinkedIn Developer App${NC}"
|
|
echo " → https://www.linkedin.com/developers/apps"
|
|
echo " → Name: BlackRoad OS CLI"
|
|
echo " → Page: BlackRoad OS, Inc."
|
|
echo ""
|
|
echo -e "${YELLOW}Step 2: Enable Required Products${NC}"
|
|
echo " → Share on LinkedIn"
|
|
echo " → Sign In with LinkedIn"
|
|
echo ""
|
|
echo -e "${YELLOW}Step 3: Note Your Credentials${NC}"
|
|
read -p " Client ID: " CLIENT_ID
|
|
read -sp " Client Secret: " CLIENT_SECRET
|
|
echo ""
|
|
echo ""
|
|
echo -e "${YELLOW}Step 4: Authorize App${NC}"
|
|
|
|
AUTH_URL="https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id=${CLIENT_ID}&redirect_uri=http://localhost:8080&scope=w_organization_social%20r_organization_social"
|
|
|
|
echo " Opening browser to authorize..."
|
|
echo " URL: ${AUTH_URL}"
|
|
|
|
if command -v open &> /dev/null; then
|
|
open "$AUTH_URL"
|
|
elif command -v xdg-open &> /dev/null; then
|
|
xdg-open "$AUTH_URL"
|
|
else
|
|
echo " Please open this URL manually: ${AUTH_URL}"
|
|
fi
|
|
|
|
echo ""
|
|
read -p " After authorizing, paste the 'code' from URL: " AUTH_CODE
|
|
echo ""
|
|
|
|
echo -e "${YELLOW}Step 5: Exchange Code for Token${NC}"
|
|
|
|
TOKEN_RESPONSE=$(curl -s -X POST https://www.linkedin.com/oauth/v2/accessToken \
|
|
-H "Content-Type: application/x-www-form-urlencoded" \
|
|
-d "grant_type=authorization_code" \
|
|
-d "code=${AUTH_CODE}" \
|
|
-d "redirect_uri=http://localhost:8080" \
|
|
-d "client_id=${CLIENT_ID}" \
|
|
-d "client_secret=${CLIENT_SECRET}")
|
|
|
|
ACCESS_TOKEN=$(echo "$TOKEN_RESPONSE" | grep -o '"access_token":"[^"]*"' | cut -d'"' -f4)
|
|
EXPIRES_IN=$(echo "$TOKEN_RESPONSE" | grep -o '"expires_in":[0-9]*' | cut -d':' -f2)
|
|
|
|
if [ -z "$ACCESS_TOKEN" ]; then
|
|
echo -e "${RED}✗ Failed to get access token${NC}"
|
|
echo "$TOKEN_RESPONSE"
|
|
exit 1
|
|
fi
|
|
|
|
mkdir -p "$HOME/.blackroad"
|
|
cat > "$ENV_FILE" << EOL
|
|
# LinkedIn OAuth Configuration
|
|
# Generated: $(date)
|
|
LINKEDIN_ACCESS_TOKEN=${ACCESS_TOKEN}
|
|
LINKEDIN_EXPIRES_IN=${EXPIRES_IN}
|
|
LINKEDIN_CLIENT_ID=${CLIENT_ID}
|
|
LINKEDIN_CLIENT_SECRET=${CLIENT_SECRET}
|
|
EOL
|
|
|
|
chmod 600 "$ENV_FILE"
|
|
|
|
echo -e "${GREEN}✓ Setup complete!${NC}"
|
|
echo ""
|
|
echo "Token saved to: $ENV_FILE"
|
|
echo "Expires in: $((EXPIRES_IN / 86400)) days"
|
|
echo ""
|
|
echo "Test it:"
|
|
echo " br-linkedin verify"
|
|
echo " br-linkedin post \"Hello from the terminal!\""
|
|
}
|
|
|
|
# Verify token
|
|
verify_token() {
|
|
if [ ! -f "$ENV_FILE" ]; then
|
|
echo -e "${RED}✗ Not configured${NC}"
|
|
echo "Run: br-linkedin setup"
|
|
exit 1
|
|
fi
|
|
|
|
source "$ENV_FILE"
|
|
|
|
if [ -z "${LINKEDIN_ACCESS_TOKEN:-}" ]; then
|
|
echo -e "${RED}✗ No access token found${NC}"
|
|
echo "Run: br-linkedin setup"
|
|
exit 1
|
|
fi
|
|
|
|
echo -e "${BLUE}Verifying token...${NC}"
|
|
|
|
RESPONSE=$(curl -s -H "Authorization: Bearer $LINKEDIN_ACCESS_TOKEN" \
|
|
"https://api.linkedin.com/v2/organizationalEntityAcls?q=roleAssignee")
|
|
|
|
if echo "$RESPONSE" | grep -q "111783522"; then
|
|
echo -e "${GREEN}✓ Token valid${NC}"
|
|
echo -e "${GREEN}✓ Access to BlackRoad OS, Inc. confirmed${NC}"
|
|
return 0
|
|
else
|
|
echo -e "${RED}✗ Token invalid or missing permissions${NC}"
|
|
echo "$RESPONSE"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Post to LinkedIn
|
|
post_to_linkedin() {
|
|
local TEXT="$1"
|
|
|
|
if [ -z "$TEXT" ]; then
|
|
echo -e "${RED}✗ Post text required${NC}"
|
|
echo "Usage: br-linkedin post \"Your text here\""
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -f "$ENV_FILE" ]; then
|
|
echo -e "${RED}✗ Not configured${NC}"
|
|
echo "Run: br-linkedin setup"
|
|
exit 1
|
|
fi
|
|
|
|
source "$ENV_FILE"
|
|
|
|
if [ -z "${LINKEDIN_ACCESS_TOKEN:-}" ]; then
|
|
echo -e "${RED}✗ No access token${NC}"
|
|
echo "Run: br-linkedin setup"
|
|
exit 1
|
|
fi
|
|
|
|
echo -e "${BLUE}Posting to LinkedIn...${NC}"
|
|
echo ""
|
|
echo -e "${YELLOW}Preview:${NC}"
|
|
echo "─────────────────────────────────────"
|
|
echo "$TEXT"
|
|
echo "─────────────────────────────────────"
|
|
echo ""
|
|
|
|
# Build JSON payload
|
|
PAYLOAD=$(jq -n \
|
|
--arg text "$TEXT" \
|
|
--arg org "$LINKEDIN_ORG_URN" \
|
|
'{
|
|
author: $org,
|
|
lifecycleState: "PUBLISHED",
|
|
specificContent: {
|
|
"com.linkedin.ugc.ShareContent": {
|
|
shareCommentary: {
|
|
text: $text
|
|
},
|
|
shareMediaCategory: "NONE"
|
|
}
|
|
},
|
|
visibility: {
|
|
"com.linkedin.ugc.MemberNetworkVisibility": "PUBLIC"
|
|
}
|
|
}')
|
|
|
|
RESPONSE=$(curl -s -w "\n%{http_code}" -X POST "$LINKEDIN_API_URL" \
|
|
-H "Authorization: Bearer $LINKEDIN_ACCESS_TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d "$PAYLOAD")
|
|
|
|
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
|
|
BODY=$(echo "$RESPONSE" | head -n-1)
|
|
|
|
if [ "$HTTP_CODE" = "201" ]; then
|
|
POST_ID=$(echo "$BODY" | grep -o '"id":"[^"]*"' | cut -d'"' -f4)
|
|
echo -e "${GREEN}✓ Posted successfully!${NC}"
|
|
echo ""
|
|
echo "Post ID: $POST_ID"
|
|
echo "View at: https://www.linkedin.com/company/blackroad-os-inc/"
|
|
else
|
|
echo -e "${RED}✗ Post failed (HTTP $HTTP_CODE)${NC}"
|
|
echo "$BODY"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Main
|
|
case "${1:-}" in
|
|
post)
|
|
shift
|
|
post_to_linkedin "$*"
|
|
;;
|
|
setup)
|
|
setup_oauth
|
|
;;
|
|
verify)
|
|
verify_token
|
|
;;
|
|
help|--help|-h)
|
|
show_help
|
|
;;
|
|
*)
|
|
echo -e "${RED}Unknown command: ${1:-}${NC}"
|
|
echo ""
|
|
show_help
|
|
exit 1
|
|
;;
|
|
esac
|