آموزش Workflow تحلیل صندوق صوتی با n8n و هوش مصنوعی ویرا

آموزش Workflow تحلیل صندوق صوتی با n8n

این Workflow به‌صورت خودکار پیام‌های صوتی صندوق صوتی را پردازش می‌کند.

بعد از اینکه یک پیام صوتی در سیموتل ثبت شد، مراحل زیر انجام می‌شود:

  • دریافت اطلاعات تماس
  • دریافت فایل صوتی
  • ارسال فایل به هوش مصنوعی ویرا
  • انتظار تا پایان پردازش
  • دریافت نتیجه تحلیل
  • استخراج اطلاعات مهم

در پایان، اپراتور بدون گوش دادن به فایل صوتی، خلاصه تماس را مشاهده می‌کند.

پیش‌نیازها

قبل از استفاده از این Workflow موارد زیر باید آماده باشند.

  • نصب n8n
  • دسترسی به API تلینا
  • دسترسی به API ویرا

آشنایی با ساختار Workflow

در n8n هر مستطیل یک Node نام دارد.

هر Node فقط یک کار انجام می‌دهد.

خروجی هر Node به Node بعدی ارسال می‌شود.

تنظیمات سمت تلینا

ایجاد رویداد API برای ارسال ویس‌میل به n8n

برای ارسال خودکار رویداد پیام صوتی (Voicemail) به n8n، ابتدا وارد پنل مدیریت تلینا شوید و مسیر زیر را طی کنید:

تنظیمات حساب های API سپس روی API جدید و بعد افزودن رویداد API کلیک کنید.

در صفحه بازشده، تنظیمات را مطابق تصویر زیر تکمیل کنید.

ایجاد حساب API برای دانلود فایل صوتی

پس از دریافت رویداد در n8n، لازم است فایل صوتی ویس‌میل از تلینا دانلود شود. برای این کار، n8n باید از طریق API به تلینا درخواست ارسال کرده و لینک دانلود فایل صوتی را دریافت کند.

برای ایجاد دسترسی API، در پنل تلینا به مسیر زیر بروید:

تنظیمات API ← سپس روی API جدید و بعد ایجاد اکانت API کلیک کنید.

در صفحه بازشده، اطلاعات را مطابق تصویر زیر وارد کنید.

در بخش دسترسی‌های API ، گزینه مربوط به Voicemail را فعال کنید تا این حساب امکان دریافت لینک فایل‌های صوتی را داشته باشد .تنظیمات این بخش باید مطابق تصویر زیر انجام شود.

دریافت API Key

پس از ایجاد حساب API، یک API Key برای شما تولید می‌شود. این کلید برای احراز هویت درخواست‌های n8n به تلینا استفاده می‌شود و باید در Nodeهای مربوط به فراخوانی API در n8n وارد شود.

نمونه API Key تولیدشده در تصویر زیر نمایش داده شده است.

تنظیمات سمت n8n

مرحله اول Webhook

هدف

این Node نقطه شروع Workflow است.

هر زمان سیموتل یک پیام صوتی جدید دریافت کند، اطلاعات تماس را از طریق HTTP به این Webhook ارسال می‌کند و Workflow اجرا می‌شود.

تنظیمات Node

Path

voicemail

این مقدار آدرس Webhook را مشخص می‌کند.

در نتیجه آدرس زیر ایجاد می‌شود.

https://YOUR-N8N/webhook/voicemail

سیموتل باید اطلاعات صندوق صوتی را به همین آدرس ارسال کند.

HTTP Method

GET

زیرا سیموتل اطلاعات را به‌صورت GET ارسال می‌کند.

Authentication

None

در این پروژه هیچ احراز هویتی برای Webhook تعریف نشده است.

در صورت نیاز می‌توان Basic Auth یا Header Authentication نیز فعال کرد.

خروجی

Webhook اطلاعات زیر را دریافت می‌کند.

[

{

“headers” :{

“host”: “n8n……ir”,

“accept-encoding”: “gzip, deflate”,

“authorization”: “Basic dGVzdDoxMjM0”,

“connection”: “close”,

“x-real-ip”: “5…..171”,

“true-client-ip”: “5…..171”,

“x-forwarded-proto”: “https”,

“x-forwarded-port”: “443”,

“x-forwarded-for”: “5……171”,

“x-request-id”: “…………fa59dac142a2a31”,

“x-country-code”: “IR”,

“x-sid”: “2075”,

“ar-real-ip”: “5……171”,

“ar-real-country”: “IR”,

“ar-sid”: “2075”,

“user-agent”: “python-requests/2.24.0”,

“accept”: “/”,

“cdn-loop”: “arvancloud; count=1”

},

“params”: {},

“query”: {

“caller”: “0939…3404”,

“cuid”: “1782982024.11645”,

“date”: “2026-07-02 08:47:33.986753”,

“duration”: “18”,

“event_name”: “VoiceMail”,

“filename”: “311_1782982025-vm-record-file-4594.mp3”,

“id”: “6a4625a51366466a7022146c”,

“number”: “311”,

“state”: “SUCCESS”

},

“body”: {},

“webhookUrl”: “https://n8n…ir/webhook-test/voicemail”,

“executionMode”: “test”

}

]

مرحله دوم Get Audio Name (Code)

هدف

استخراج نام فایل صوتی از اطلاعات Webhook

تنظیمات Node

Language

JavaScript

Mode

Run Once for All Items

Code

return [
{
filename: $input.first().json.query.filename
}
];

این کد نام فایل صوتی را استخراج می‌کند.

خروجی

[
{
“filename”: “311_1782982025-vm-record-file-4594.mp3”
}
]

مرحله سوم Get Audio Link

هدف

دریافت لینک دانلود فایل از API سیموتل

تنظیمات Node

Method

POST

URL

https://panel.hostedpbx.ir/api/v4.1/voicemails/audio/download

این API لینک دانلود فایل را برمی‌گرداند.

Headers

X-APIKEY

مقدار این Header همان API Key پنل سیموتل است. بدون این Header درخواست رد خواهد شد.

مثلاً

X-APIKEY:xxxxxxxxxxxxxxxx

Body Type

JSON

Body

{
  "file":

“{{$json.filename}}”

}

نام فایل از مرحله قبل دریافت می‌شود.

خروجی

[

{

“success”: 1,

“message”: “Requested operation is done successfully”,

“data”: {

“audioLink”: “https://storage.hostedpbx.ir/api/v1.1/download/token/ITqASNbCCoDKqvsRfKshwibvvoEugMfOxNJepcucDYlbzkSKtjXcFdbCjqWehmaFBvqCApgKkWmImECkvpTuDMvudtDhTnQDRovF

}

}

]

مرحله چهارم Download Audio File

هدف

دانلود فایل صوتی.

تنظیمات Node

Method

GET

URL

{{$json.data.audioLink}}

این مقدار از مرحله قبل دریافت می‌شود.

خروجی

مرحله پنجم Send To Vira

هدف

ارسال فایل صوتی به هوش مصنوعی ویرا.

تنظیمات Node

Method

POST

URL

https://api.vira-id.ir/webhook/call/create

Headers

Authorization
Bearer YOUR_API_KEY

Body Type

Form Data

پارامتر اول

Name: audio
Type: Binary

Input Data Field Name:

data

همان فایل دانلود شده.

پارامتر دوم

Name: lang

Type: From data

Value: fa

مشخص می‌کند فایل فارسی است.

خروجی

ویرا یک شناسه پردازش برمی‌گرداند.

Id: 65895

مرحله ششم Request Status

هدف

بررسی وضعیت پردازش ویرا.

هر ۳ دقیقه یک درخواست وضعیت به ویرا ارسال می‌شود تا بررسی کند آیا صوت مربوط به id تولید شده در مرحله قبل تحلیل شده است و یا خیر اگر تحلیل کامل باشد complete:true می‌باشد و می‌توان از محتوا استفاده کرد

تنظیمات

Method

GET

URL

https://api.vira-id.ir/webhook/call/details

Query Parameter

Specify Query Parameters: Using Fields Below

id
{{$json.result.id}}

Header

Authorization
Bearer YOUR_API_KEY

Accept

application/json

خروجی

اگر پردازش تمام نشده باشد

[

{

“success”: true,

“completed”: false,

“result”: {

“id”: 65895,

“title”: “Untitled”,

“duration”: 18.942,

“speakers”: null,

“summary”: “”,

“customer_satisfaction”:1,

“sections”: {

“raw”: “json\n[\n {\n \"end\": 3.73,\n \"text\": \"سلام وقت شما بخیر\",\n \"start\": 2.21,\n \"speaker\": \"speaker_0\"\n },\n {\n \"end\": 9.25,\n \"text\": \"من از سرویس شما استفاده می‌کنم سرویس خیلی خوبیه گزارشات خوبی میده و خیلی عالی هستش\",\n \"start\": 3.73,\n \"speaker\": \"speaker_0\"\n },\n {\n \"end\": 17.58,\n \"text\": \"و تمایل دارم که با شما همکاری کنم توی ارائه این محصول لطفاً با من در تماس باشید برای اطلاعات تکمیلی\",\n \"start\": 10.37,\n \"speaker\": \"speaker_0\"\n }\n]\n

},

“token”: 12,

“created_at”: “2026-07-02T09:00:51.421Z”,

“prioritization”: {

},

“products”: [

]

}

}

]

اگر تمام شده باشد

[

{

“success”: true,

“completed”: true,

“result”: {

“id”: 65895,

“title”: “Untitled”,

“duration”: 18.942,

“speakers”: null,

“summary”: “مشتری از کیفیت سرویس و گزارشات آن ابراز رضایت کرده و تمایل دارد برای همکاری در ارائه محصول با سازمان در تماس باشد.”,

“customer_satisfaction”: 5,

“sections”: {

“raw”: “json\n[\n {\n \"end\": 3.73,\n \"text\": \"سلام وقت شما بخیر\",\n \"start\": 2.21,\n \"speaker\": \"speaker_0\"\n },\n {\n \"end\": 9.25,\n \"text\": \"من از سرویس شما استفاده می‌کنم سرویس خیلی خوبیه گزارشات خوبی میده و خیلی عالی هستش\",\n \"start\": 3.73,\n \"speaker\": \"speaker_0\"\n },\n {\n \"end\": 17.58,\n \"text\": \"و تمایل دارم که با شما همکاری کنم توی ارائه این محصول لطفاً با من در تماس باشید برای اطلاعات تکمیلی\",\n \"start\": 10.37,\n \"speaker\": \"speaker_0\"\n }\n]\n

},

“token”: 12,

“created_at”: “2026-07-02T09:00:51.421Z”,

“prioritization”: {

“conversion_chance”: 80,

“loss_chance”: 0,

“urgency”: 3,

“required_effort”: “medium”

},

“products”:

}

}

]

به همراه اطلاعات تحلیل.

مرحله هفتم IF

هدف

بررسی پایان پردازش.

تنظیمات

Condition

{{$json.completed}}

Operator

Equals

Value

true

عملکرد

اگر نتیجه True باشد Workflow ادامه پیدا می‌کند.

اگر False باشد Node Wait اجرا می‌شود.

مرحله هشتم Wait

هدف

صبر کردن قبل از بررسی مجدد.

تنظیمات

Duration

180 Seconds

بعد از ۳ دقیقه دوباره Request Status اجرا می‌شود.

مرحله نهم Merge

هدف

ترکیب اطلاعات تماس اولیه با نتیجه تحلیل ویرا.

تنظیمات

Mode

Combine

Combine By

Combine by Position

دلیل استفاده: یک شاخه اطلاعات تماس را نگه داشته است و شاخه دیگر نتیجه تحلیل را تولید می‌کند. این Node هر دو را در یک خروجی واحد ادغام می‌کند.

مرحله دهم Finish (Code)

هدف

تبدیل اطلاعات خام ویرا به اطلاعات قابل استفاده است.

در این مرحله:

  • متن مکالمه استخراج می‌شود.
  • تاریخ و ساعت تبدیل می‌شوند.
  • خلاصه تماس آماده می‌شود.
  • احتمال از دست رفتن مشتری استخراج می‌شود.
  • میزان رضایت مشتری استخراج می‌شود.
  • میزان فوریت استخراج می‌شود.
  • احتمال تبدیل مشتری استخراج می‌شود.

در پایان خروجی مرتب شده‌ای تولید می‌شود

کد جاوا اسکریپت

const data = $input.first().json;

const query = data.query;

const analysis = data.result;

let raw = analysis.sections.raw;

raw = raw

.replace(/^```json\s*/i, “”)

.replace(/```$/i, “”)

.trim();

const sections = JSON.parse(raw);

const transcript = sections

.map(item => item.text)

.join(" ");

const dateObj = new Date(query.date);

const date = dateObj.toISOString().split(“T”)[0];

const time = dateObj.toTimeString().split(" ")[0];

return [

{

json: {

call: {

caller: query.caller,

mailbox: query.number,

date: date,

time: time,

filename: query.filename

},

analysis: {

summary: analysis.summary,

transcript: transcript,

customer_satisfaction: analysis.customer_satisfaction,

loss_chance: analysis.prioritization.loss_chance,

conversion_chance: analysis.prioritization.conversion_chance,

urgency: analysis.prioritization.urgency,

equired_effort: analysis.prioritization.required_effort,

}

}

}

];

خروجی

[

{

“call”: {

“caller”: “0939…3404”,

“mailbox”: “311”,

“date”: “2026-07-02”,

“time”: “08:47:33”,

“filename”: “311_1782982025-vm-record-file-4594.mp3”

},

“analysis”: {

“summary”: “مشتری از کیفیت سرویس و گزارشات آن ابراز رضایت کرده و تمایل دارد برای همکاری در ارائه محصول با سازمان در تماس باشد.”,

“transcript”: “سلام وقت شما بخیر من از سرویس شما استفاده می‌کنم سرویس خیلی خوبیه گزارشات خوبی میده و خیلی عالی هستش و تمایل دارم که با شما همکاری کنم توی ارائه این محصول لطفاً با من در تماس باشید برای اطلاعات تکمیلی”,

“customer_satisfaction”: 5,

“loss_chance”: 0,

“conversion_chance”: 80,

“urgency”: 3,

“equired_effort”: “medium”

}

}

]