golang构建Asterisk PBX AGI/FASTAGI应用程序插件库goagi的使用

Golang构建Asterisk PBX AGI/FASTAGI应用程序插件库goagi的使用

简介

goagi是一个简单的Golang库,用于构建AGI脚本或FastAGI服务器。

import "github.com/staskobzar/goagi"

FastAGI使用

AGI对象通过New方法创建,接收三个参数:

  • Reader接口
  • Writer接口
  • Debugger接口(调试用,通常为nil)

Reader和Writer可以是任何实现了Read/Write方法的对象,如net.Conntls.Connos.Stdinos.Stdout等。

New方法会读取AGI会话设置环境变量并提供AGI命令接口。AGI环境变量和参数可以通过EnvEnvArgs方法访问。

AGI使用示例

import (
	"github.com/staskobzar/goagi"
	"os"
)

// 创建AGI实例
agi, err := goagi.New(os.Stdin, os.Stdout, nil)
if err != nil {
	panic(err)
}
// 发送Verbose命令
agi.Verbose("Hello World!")

FastAGI示例

ln, err := net.Listen("tcp", "127.0.0.1:4573")
if err != nil {
	panic(err)
}
for {
	conn, err := ln.Accept()
	if err != nil {
		panic(err)
	}
	go func(conn net.Conn) {
		// 为每个连接创建AGI实例
		agi, err := goagi.New(conn, conn, nil)
		if err != nil {
			panic(err)
		}
		// 发送Verbose命令
		agi.Verbose("Hello World!")
	}(conn)
}

命令响应接口

每个AGI命令方法都返回Response接口,提供对AGI响应值的访问。

成功响应示例:

200 result=1 (speech) endpos=9834523 results=5

失败响应示例:

511 Command Not Permitted on a dead channel or intercept routine

Response接口方法:

  • Code() int: 响应代码
  • RawResponse() string: 完整的AGI响应文本
  • Result() int: 返回result=字段的值
  • Value() string: 返回括号中的响应值
  • Data() string: 返回错误响应的文本或GetData等命令的DTMF值
  • EndPos() int64: 返回endpos=字段的值
  • Digit() string: 返回digit=字段的数字
  • SResults() int: 返回results=字段的值

调试器

调试器接口提供可配置输出的调试功能。

使用示例:

// 创建调试器
dbg := logger.New(os.Stdout, "myagi:", log.Lmicroseconds)
// 创建管道
r, w := net.Pipe()
// 创建带调试器的AGI实例
agi, err := goagi.New(r, w, dbg)

这个库提供了完整的AGI功能实现,可以方便地集成到Asterisk PBX系统中。


更多关于golang构建Asterisk PBX AGI/FASTAGI应用程序插件库goagi的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang构建Asterisk PBX AGI/FASTAGI应用程序插件库goagi的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


使用goagi构建Asterisk PBX AGI/FASTAGI应用程序

goagi是一个用于构建Asterisk PBX AGI( Asterisk Gateway Interface)和FASTAGI应用程序的Golang库。它简化了与Asterisk的交互过程,让开发者可以专注于业务逻辑的实现。

安装goagi

go get github.com/ziutek/goagi

基本概念

AGI是Asterisk与外部程序通信的接口协议,允许外部程序控制呼叫流程。FASTAGI是AGI的变种,使用TCP连接而不是标准输入/输出。

基本使用示例

1. 简单的AGI脚本

package main

import (
	"fmt"
	"log"
	"github.com/ziutek/goagi"
)

func main() {
	agi := goagi.New()
	
	// 读取AGI环境变量
	callerID := agi.Get("callerid")
	extension := agi.Get("extension")
	
	fmt.Printf("收到来自 %s 的呼叫,拨打的号码是 %s\n", callerID, extension)
	
	// 应答呼叫
	err := agi.Answer()
	if err != nil {
		log.Fatal(err)
	}
	
	// 播放欢迎语音
	err = agi.StreamFile("welcome")
	if err != nil {
		log.Println("播放欢迎语音失败:", err)
	}
	
	// 等待用户输入数字
	digit, err := agi.GetData("beep", 5000, 1)
	if err != nil {
		log.Println("获取用户输入失败:", err)
	} else {
		fmt.Println("用户输入:", digit)
	}
	
	// 挂断电话
	agi.Hangup()
}

2. FASTAGI服务器

package main

import (
	"fmt"
	"log"
	"net"
	"github.com/ziutek/goagi"
)

func handleConnection(conn net.Conn) {
	defer conn.Close()
	
	agi := goagi.New()
	agi.SetReader(conn)
	agi.SetWriter(conn)
	
	// 读取AGI参数
	callerID := agi.Get("callerid")
	extension := agi.Get("extension")
	
	fmt.Printf("处理来自 %s 的呼叫,拨打 %s\n", callerID, extension)
	
	// 应答呼叫
	if err := agi.Answer(); err != nil {
		log.Println("应答失败:", err)
		return
	}
	
	// 播放语音
	if err := agi.StreamFile("welcome"); err != nil {
		log.Println("播放语音失败:", err)
	}
	
	// 挂断
	agi.Hangup()
}

func main() {
	listener, err := net.Listen("tcp", ":4573")
	if err != nil {
		log.Fatal("无法启动服务器:", err)
	}
	defer listener.Close()
	
	fmt.Println("FASTAGI服务器运行在 :4573")
	
	for {
		conn, err := listener.Accept()
		if err != nil {
			log.Println("接受连接失败:", err)
			continue
		}
		go handleConnection(conn)
	}
}

核心功能

1. 环境变量获取

// 获取单个变量
callerID := agi.Get("callerid")

// 获取所有变量
vars := agi.GetAll()
fmt.Printf("所有AGI变量: %+v\n", vars)

2. 基本呼叫控制

// 应答呼叫
err := agi.Answer()

// 挂断呼叫
err := agi.Hangup()

// 设置呼叫变量
err := agi.SetVariable("CUSTOM_VAR", "value")

3. 语音播放与DTMF收集

// 播放语音文件
err := agi.StreamFile("welcome")

// 等待用户输入1位数字,超时5秒
digit, err := agi.GetData("beep", 5000, 1)

// 播放语音并收集DTMF
digit, err := agi.GetOption("menu-options", "123", 3)

4. 数据库操作

// 数据库查询
result, err := agi.DatabaseGet("family", "john")

// 数据库写入
err := agi.DatabasePut("family", "john", "doe")

高级用法

1. 语音识别(TTS)

// 使用Festival进行TTS
err := agi.Exec("Festival", "Hello, welcome to our service")

// 使用Google TTS
err := agi.Exec("GoogleTTS", "en", "Hello, how can I help you?")

2. 会议桥接

// 将呼叫加入会议
err := agi.Exec("MeetMe", "1234")

3. 呼叫转移

// 无条件转移
err := agi.Exec("Dial", "SIP/100")

// 遇忙转移
err := agi.Exec("Dial", "SIP/100,10,tT")

Asterisk配置

extensions.conf配置示例

[default]
exten => 123,1,AGI(agi://127.0.0.1:4573)
exten => 123,n,Hangup()

或者使用FASTAGI

[default]
exten => 123,1,AGI(agi://127.0.0.1:4573)
exten => 123,n,Hangup()

最佳实践

  1. 错误处理:始终检查AGI命令的返回错误
  2. 日志记录:记录重要的呼叫事件和错误
  3. 资源管理:确保及时关闭连接和释放资源
  4. 超时处理:为所有用户输入操作设置合理的超时
  5. 并发控制:FASTAGI服务器需要处理并发连接

goagi库为Golang开发者提供了构建强大Asterisk集成应用的便捷方式,结合Golang的高效和并发特性,可以创建高性能的电信应用。

回到顶部