Skip to content

Instantly share code, notes, and snippets.

@miglen
Created May 21, 2025 14:46
Show Gist options
  • Save miglen/f9b9485bc05d4077c15645a7f15796d0 to your computer and use it in GitHub Desktop.
Save miglen/f9b9485bc05d4077c15645a7f15796d0 to your computer and use it in GitHub Desktop.
Unofficial hacky Office RND User management API Script
import requests
from datetime import datetime
class OfficeRNDClient:
def __init__(self, username, password, org_name):
self.session = requests.Session()
self.base_url = 'https://hybrid.officernd.com'
self.username = username
self.password = password
self.org_id = org_name
self.cookies = {}
def login(self):
url = f'{self.base_url}/auth/signin'
data = {
'username': self.username,
'password': self.password
}
headers = {
'Content-Type': 'application/json'
}
response = self.session.post(url, json=data, headers=headers)
response.raise_for_status()
print("[INFO] Logged in successfully.")
self.cookies = self.session.cookies.get_dict()
def list_users(self, limit=10):
url = f'{self.base_url}/i/organizations/{self.org_id}/members/details'
params = {
'$select': '_id,name,email',
'$limit': limit,
'$sort': 'name:asc',
'$includeTotal': 'true'
}
response = self.session.get(url, params=params)
response.raise_for_status()
data = response.json()
# Either a list or dict with 'items'
users = data if isinstance(data, list) else data.get('items', [])
for user in users:
print(f"{user.get('name')} - {user.get('email')} - ID: {user.get('_id')}")
return users
def invite_user(self, user_id):
url = f'{self.base_url}/i/organizations/{self.org_id}/permissions/invite?role=Member&resend=false'
headers = {
"Content-Type": "application/json",
"rnd-source": "admin"
}
response = self.session.post(url, json=[user_id], headers=headers)
response.raise_for_status()
print(f"[✉️] Invitation sent to user ID {user_id}")
def add_user(self, name, email, team_id, office_id):
url = f'{self.base_url}/i/organizations/{self.org_id}/members'
start_date = datetime.utcnow().strftime("%Y-%m-%dT00:00:00.000Z")
data = {
"startDate": start_date,
"status": "active",
"team": team_id,
"office": office_id,
"teams": [],
"properties": {},
"name": name,
"email": email
}
response = self.session.post(url, json=data)
response.raise_for_status()
user = response.json()[0]
user_id = user["_id"]
print(f"[INFO] Added user {name} ({email}) with ID {user_id}")
self.invite_user(user_id)
return user
def delete_user(self, user_id):
# Step 1: Validate delete
validate_url = f'{self.base_url}/i/organizations/{self.org_id}/members/validate'
validate_data = {
"operation": "delete",
"data": {"member": user_id}
}
validate_headers = {"Content-Type": "application/json", "rnd-source": "admin"}
validate_resp = self.session.post(validate_url, json=validate_data, headers=validate_headers)
validate_resp.raise_for_status()
print(f"[INFO] Validated user {user_id} for deletion.")
# Step 2: Actual delete
delete_url = f'{self.base_url}/i/organizations/{self.org_id}/members'
delete_data = [user_id]
delete_headers = {"Content-Type": "application/json", "rnd-source": "admin"}
delete_resp = self.session.delete(delete_url, json=delete_data, headers=delete_headers)
delete_resp.raise_for_status()
print(f"[INFO] Deleted user with ID {user_id}")
# Example usage:
if __name__ == "__main__":
config = {
"username": "[email protected]", # must be admin
"password": "parola123",
"org_name": "company",
"org_id": "60ca523d23450103d79d11",
"team_id": "60ca523d23450103d79d11",
}
client = OfficeRNDClient(config['username'], config['password'], config['org_name'])
client.login()
client.list_users()
user = client.add_user("Firstname Lastname", "[email protected]", config['team_id'], config['org_id'])
client.delete_user(user["_id"])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment