aethexDocs
3CX logo
Téléphonie

3CX

Connectez un système téléphonique 3CX auto-hébergé à Aethex avec l'API de configuration 3CX et l'API Aethex. Votre agent vocal se connecte à 3CX comme l'un de ses utilisateurs, répond aux appels vers votre numéro et passe des appels via le trunk opérateur de votre 3CX.

Fonctionnement

Aethex se connecte à 3CX comme un poste de bureau : il se connecte à 3CX en tant qu'utilisateur, avec l'identifiant SIP de cet utilisateur. 3CX traite alors l'agent comme n'importe quel autre utilisateur. Les appels que 3CX route vers l'utilisateur arrivent à l'agent, et les appels que l'agent passe sortent par vos règles sortantes 3CX et votre trunk opérateur.La configuration comporte deux volets. Côté 3CX, vous créez l'utilisateur, autorisez la périphérie SIP Aethex et routez votre numéro vers l'utilisateur, avec l'API de configuration 3CX. Côté Aethex, vous créez une ligne qui se connecte à 3CX et attribuez le numéro à votre agent, avec l'API Aethex.Seul 3CX auto-hébergé permet cette configuration. Les éditions 3CX SMB et Hosted by 3CX ne la prennent pas en charge.

AVANT DE COMMENCER

Avant de commencer

Chaque appel 3CX de ce guide utilise l'API de configuration 3CX, que 3CX inclut avec sa licence 8SC et supérieure avec IA.

Ce qu'il vous fautOù l'obtenir
3CX v20 auto-hébergé, avec un nom d'hôte public et une adresse IPv4 publique fixeVotre serveur 3CX. Aethex n'accepte pas les adresses privées.
Un client API 3CX avec accès à l'API de configurationConsole d'administration 3CX, Integrations > API > Add. Saisissez un Client ID, cochez Enable access to the 3CX Configuration API (XAPI), réglez Department sur System Wide et Role sur System Owner ou System Admin, puis enregistrez. 3CX n'affiche la clé API qu'une seule fois.
Un trunk opérateur dans 3CX qui reçoit le numéro qu'utilisera l'agentConsole d'administration 3CX, Voice & Chat. Ce guide écrit le numéro au format E.164, par exemple +15555550100.
Une clé API Aethex et un agentPortail développeur, Clés API. La clé doit avoir les scopes sip_trunks:write, sip_trunks:read, phone_numbers:write et calls:write, qui couvrent les trunks, les numéros et les appels.
ÉTAPE 01

Obtenir un jeton d'accès 3CX

Échangez le Client ID et la clé API contre un jeton d'accès sur POST /connect/token de votre serveur 3CX, puis envoyez le jeton dans un en-tête Bearer à chaque appel de l'API de configuration. Le jeton dure 60 minutes et 3CX ne délivre pas de jeton de rafraîchissement : demandez-en un nouveau quand il expire. Les chemins de l'API de configuration commencent par /xapi/v1.

Demander un jeton
bash
PBX=https://pbx.example.com

TOKEN=$(curl -s -X POST "$PBX/connect/token" \
  -d client_id=aethex-setup \
  -d client_secret="$THREECX_API_KEY" \
  -d grant_type=client_credentials | jq -r .access_token)

# Check the token works
curl -s -G "$PBX/xapi/v1/Defs" \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode '$select=Id'
ÉTAPE 02

Créer l'utilisateur 3CX de l'agent

Créez un utilisateur 3CX par agent. Demandez à 3CX le prochain numéro de poste libre, puis créez l'utilisateur avec ce numéro. Trois paramètres de la même requête comptent pour Aethex : PbxDeliversAudio fait passer l'audio de l'appel par 3CX, SRTPMode réglé sur SRTPEnabled active le chiffrement des médias (sans lui, les appels se connectent sans audio), et AuthID réglé sur le numéro de poste fait correspondre le nom de connexion à l'utilisateur.Relisez ensuite AuthID et AuthPassword. Ce sont le nom d'utilisateur et le mot de passe SIP avec lesquels Aethex se connecte à l'étape 6.

Attention
L'API de configuration n'a pas de champ pour Block remote non-tunnel connections (Insecure!). Tant que cette option est active, 3CX refuse la connexion d'Aethex et son Event Log affiche « Block WAN requests is ON ». Après avoir créé l'utilisateur, ouvrez-le dans la console d'administration 3CX (Users, l'utilisateur, puis Options), décochez cette case et enregistrez.
Créer l'utilisateur et lire ses identifiants
bash
# 1. Ask 3CX for the next free extension number
curl -s "$PBX/xapi/v1/Users/Pbx.GetFirstAvailableExtensionNumber()" \
  -H "Authorization: Bearer $TOKEN"
# { "Number": "120", ... }

# 2. Create the agent's user with that number
curl -s -X POST "$PBX/xapi/v1/Users" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "Number": "120",
    "FirstName": "Aethex",
    "LastName": "Agent",
    "AuthID": "120",
    "PbxDeliversAudio": true,
    "SRTPMode": "SRTPEnabled"
  }'
# The response carries the new user's Id. Keep it as USER_ID.

# 3. Read the SIP login Aethex will use
curl -s -G "$PBX/xapi/v1/Users($USER_ID)" \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode '$select=Number,AuthID,AuthPassword'
ÉTAPE 03

Autoriser la périphérie SIP Aethex

3CX bloque une adresse après plusieurs échecs de connexion. Ajoutez les deux adresses de la périphérie SIP Aethex à la liste de blocage IP de 3CX en tant qu'entrées Allow, pour qu'un échec de connexion pendant la configuration ne fasse pas bloquer Aethex. C'est l'équivalent API de Advanced > IP Blacklist dans la console d'administration.

Autoriser les deux adresses de périphérie
bash
for ip in 13.63.135.167 51.21.123.34; do
  curl -s -X POST "$PBX/xapi/v1/Blocklist" \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" \
    -d "{ \"IPAddrMask\": \"$ip\", \"BlockType\": \"Allow\", \"Description\": \"Aethex SIP edge\" }"
done
ÉTAPE 04

Router votre numéro vers l'agent

Les appels vers votre numéro arrivent sur votre trunk opérateur. Ajoutez une règle entrante qui envoie les appels de ce numéro à l'utilisateur de l'agent, pendant et en dehors des heures d'ouverture. Listez d'abord vos trunks : mettez le Number du trunk dans TrunkDN, et le numéro exactement comme DidNumbers l'affiche dans Data. Remplacez 120 par le numéro de poste de l'étape 2.

Ajouter la règle entrante
bash
# Find the carrier trunk and the number as 3CX stores it
curl -s -G "$PBX/xapi/v1/Trunks" \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode '$select=Id,Number,DidNumbers'

# Send calls for that number to the agent's user, at all hours
curl -s -X POST "$PBX/xapi/v1/InboundRules" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "RuleName": "Aethex agent",
    "Condition": "BasedOnDID",
    "Data": "15555550100",
    "TrunkDN": { "Number": "10000" },
    "OfficeHoursDestination": { "To": "Extension", "Number": "120" },
    "OutOfOfficeHoursDestination": { "To": "Extension", "Number": "120" }
  }'
ÉTAPE 05

Autoriser l'appel sortant pour l'agent

Ajoutez une règle sortante pour le poste de l'agent, sans préfixe ni limite de longueur de numéro, et routez-la vers votre trunk opérateur par l'Id du trunk. Le numéro présenté est par défaut celui du trunk.3CX applique la première règle qui correspond. Si une règle précédente couvre déjà le poste, ajoutez le poste aux DNRanges de cette règle avec PATCH /xapi/v1/OutboundRules(id), ou remontez la nouvelle règle avec POST /xapi/v1/OutboundRules/Pbx.MoveUpDown.

Remarque
3CX n'appelle que les pays de sa liste autorisée. Si vos clients sont dans d'autres pays, lisez la liste avec GET /xapi/v1/CountryCodes, ajoutez leurs indicatifs pays et renvoyez la liste complète avec PATCH /xapi/v1/CountryCodes.
Ajouter la règle sortante
bash
curl -s -X POST "$PBX/xapi/v1/OutboundRules" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "Name": "Aethex agent",
    "DNRanges": [{ "From": "120", "To": "120" }],
    "Routes": [{ "TrunkId": 1 }]
  }'

# Check the order: 3CX uses the first rule that matches the extension
curl -s -G "$PBX/xapi/v1/OutboundRules" \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode '$select=Id,Name,Priority,DNRanges'
ÉTAPE 06

Créer la ligne Aethex

Créez une ligne en mode register. Aethex se connecte à 3CX avec l'identifiant de l'utilisateur et maintient la connexion active, pour que 3CX puisse envoyer des appels à l'agent et accepter les siens. La réponse contient l'id de la ligne ; conservez-le pour les étapes 7 et 8. Le tableau explique chaque valeur.

ChampValeur pour 3CX
auth_moderegister : Aethex se connecte à 3CX comme un poste de bureau. Valide uniquement avec type réglé sur inbound ; Aethex ajoute lui-même le côté sortant.
numbersVotre numéro au format E.164. Une ligne register dessert exactement un numéro : créez donc une ligne par numéro.
outbound_addressLe nom d'hôte de votre 3CX et son port SIP, généralement 5060.
realm3CXPhoneSystem. 3CX répond au défi de connexion pour ce realm, pas pour son nom d'hôte. Sans lui, la ligne reste à failing.
auth_username, auth_passwordAuthID et AuthPassword de l'étape 2. Le mot de passe est stocké chiffré et n'est jamais renvoyé.
allowed_addressesL'adresse IPv4 publique de votre 3CX, comme seule entrée. Elle ouvre le pare-feu Aethex à votre 3CX.
transportudp ou tcp. Les lignes register ne prennent pas en charge TLS.
outbound_dial_formatdigits : Aethex envoie le numéro sans le + initial. 3CX modifie un numéro qui commence par +, et l'appel échoue alors avec « Number not found ».
outbound_from_userusername : les appels sortants transmettent le nom de connexion comme utilisateur SIP From, ce qui permet à 3CX d'associer l'appel à l'utilisateur de l'agent. Le numéro passe dans P-Asserted-Identity. Avec la valeur par défaut, number, 3CX refuse les appels de l'agent comme appel entrant non identifié.
Attention
Seuls certains champs peuvent changer après la création de la ligne : name, numbers, allowed_addresses, outbound_dial_format, les limites d'appel et status. Pour changer l'adresse 3CX, le realm, l'identifiant, le transport, le chiffrement des médias ou outbound_from_user, supprimez la ligne et créez-en une nouvelle.
Créer la ligne
bash
curl -X POST https://api.aethexai.com/api/v1/sip-trunks \
  -H "X-API-Key: $AETHEX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "3CX agent line",
    "type": "inbound",
    "auth_mode": "register",
    "numbers": ["+15555550100"],
    "outbound_address": "pbx.example.com:5060",
    "realm": "3CXPhoneSystem",
    "auth_username": "120",
    "auth_password": "<AuthPassword from step 2>",
    "allowed_addresses": ["203.0.113.10"],
    "transport": "udp",
    "outbound_dial_format": "digits",
    "outbound_from_user": "username"
  }'
ÉTAPE 07

Attribuer le numéro à votre agent

Enregistrez le numéro avec la ligne et l'agent. agent_id fait répondre l'agent aux appels vers le numéro. Réglez outbound_enabled sur true : une ligne register passe ses appels par ce lien entre le numéro et la ligne.

Associer le numéro
bash
curl -X POST https://api.aethexai.com/api/v1/phone-numbers/sip/register \
  -H "X-API-Key: $AETHEX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone_number": "+15555550100",
    "trunk_id": "<id returned in step 6>",
    "agent_id": "<your-agent-id>",
    "outbound_enabled": true
  }'
ÉTAPE 08

Vérifier la connexion et tester les appels

Environ une minute après la création de la ligne, Aethex se connecte à 3CX. GET /sip-trunks/:id renvoie alors registration_status à registered, et 3CX renvoie l'utilisateur avec IsRegistered à true. Si la ligne affiche failing, consultez Dépannage ci-dessous.Pour tester l'entrant, appelez votre numéro depuis un téléphone extérieur à 3CX. L'agent répond, et l'appel apparaît dans Reports de 3CX et dans votre journal d'appels Aethex. Pour tester le sortant, déclenchez un appel avec votre numéro comme from_number. Le téléphone sonne, l'agent parle quand on décroche, et 3CX signale l'appel comme sortant.

Vérifier la connexion et passer un appel de test
bash
# Aethex: the line logs in to 3CX within about a minute
curl -s https://api.aethexai.com/api/v1/sip-trunks/$TRUNK_ID \
  -H "X-API-Key: $AETHEX_API_KEY" | jq .registration_status
# "registered"

# 3CX: the agent's user shows as registered
curl -s -G "$PBX/xapi/v1/Users($USER_ID)" \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode '$select=Number,IsRegistered'

# Outbound: the agent calls a phone through 3CX
curl -X POST https://api.aethexai.com/api/v1/calls/trigger \
  -H "X-API-Key: $AETHEX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "<your-agent-id>",
    "to_number": "+15555550199",
    "from_number": "+15555550100"
  }'

Réseau et pare-feu

Ouvrez ces ports entre votre 3CX et la périphérie SIP Aethex (sip.aethexai.com, aux adresses de l'étape 3). L'audio utilise G.711 loi A (PCMA) ou loi mu (PCMU). La plage de ports médias de votre 3CX se trouve sous Ports > Media dans le tableau de bord 3CX.

SensSignalisationMédias (RTP)
Aethex vers 3CXTCP, UDP 5060UDP 9000–10999 (par défaut dans 3CX)
3CX vers AethexTCP, UDP 5060UDP 10000–60000

Dépannage

Les problèmes les plus fréquents, leur cause et la solution.

SymptômeCauseSolution
La ligne reste à failing, et l'Event Log de 3CX affiche « Block WAN requests is ON »Block remote non-tunnel connections est encore activé pour l'utilisateur.Décochez-le dans l'onglet Options de l'utilisateur, dans la console d'administration (étape 2).
La ligne reste à failingRealm, identifiant ou mot de passe incorrect.Recréez la ligne avec realm réglé sur 3CXPhoneSystem et les AuthID et AuthPassword de l'étape 2.
Les appelants tombent sur la messagerie vocaleAethex n'est pas connecté en tant qu'utilisateur de l'agent.Vérifiez que la ligne affiche registered et que l'utilisateur 3CX affiche IsRegistered (étape 8).
Les appels se connectent sans audioLe SRTP est désactivé pour l'utilisateur, ou les ports médias sont fermés.Réglez SRTPMode sur SRTPEnabled (étape 2) et ouvrez les ports indiqués dans Réseau et pare-feu.
Les appels sortants échouent, et l'Event Log de 3CX affiche « Unidentified Incoming Call » (appel entrant non identifié)La ligne envoie le numéro comme appelant au lieu du nom de connexion.Recréez la ligne avec outbound_from_user réglé sur username.
Les appels sortants échouent avec « Number not found »Le numéro a été envoyé avec un + initial.Réglez outbound_dial_format sur digits avec PATCH /sip-trunks/:id.
Les appels sortants échouent faute de règle sortante correspondanteAucune règle sortante ne couvre le poste de l'agent, ou une règle précédente correspond en premier.Ajoutez le poste à une règle qui route vers votre trunk opérateur (étape 5).