Initial monorepo — everything BlackRoad in one place
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
This commit is contained in:
260
bin/br-linkedin
Executable file
260
bin/br-linkedin
Executable file
@@ -0,0 +1,260 @@
|
||||
#!/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
|
||||
Reference in New Issue
Block a user