Skip to content

Instantly share code, notes, and snippets.

@shawty
Last active August 4, 2022 15:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shawty/32240da324d0af6e49c8b22c1a3cc22f to your computer and use it in GitHub Desktop.
Save shawty/32240da324d0af6e49c8b22c1a3cc22f to your computer and use it in GitHub Desktop.
C# code to parse an asterisk voicemail.conf configuration file in the asterisk telephony toolkit. NOTE: depends on "IniParser" available from : https://github.com/rickyah/ini-parser
namespace TelephonyServices.DataModels;
public class MailboxConfig
{
public string MailboxNumber { get; set; } = "";
public string MailboxSecret { get; set; } = "";
public string MailboxName { get; set; } = "";
public string MailboxEmail { get; set; } = "";
public string MailboxPager { get; set; } = "";
public string MailboxOptions { get; set; } = "";
}
using IniParser;
using IniParser.Model;
namespace DataModels;
public class VoicemailConfig
{
public Dictionary<string, string> Options { get; set; } = new();
public Dictionary<string, Dictionary<string, MailboxConfig?>> Mailboxes { get; set; } = new();
public MailboxConfig? FindMailbox (string mailbox, string context = "default")
{
if (!Mailboxes.ContainsKey(context)) return null;
return !Mailboxes[context].ContainsKey(mailbox) ? null : Mailboxes[context][mailbox];
}
public void LoadVoicemailConf(string voicemailConfigurationFileName)
{
// Use IniParser to load our voicemail.config file
// NOTE: the config is MOSTLY like a 1995 era windows.ini file but not exactly
// regular options in a section will parse just fine, but lines such as the mailbox
// definition line WILl STILL parse, but always begin with ">"
// EG:
// [general]
// sendvoicemail=yes
// ----- Will give ["general"]["sendvoicemail"] with a value "yes"
//
// [default]
// 100 => 1234,vm box,foo@bar
// ----- Will give ["default"]["100"] with a value "> 1234,vm box,foo@bar"
//
// So for lines such as VM specs and dialplan extensions, the file will still parse correctly
// but the value will need to be tidied up and/or transformed
//
var parser = new FileIniDataParser();
IniData data = parser.ReadFile(voicemailConfigurationFileName);
// Initialise our VM config and load in the options
Options = new Dictionary<string, string>();
Mailboxes = new Dictionary<string, Dictionary<string, MailboxConfig?>>();
foreach (KeyData key in data["general"])
{
Options.Add(key.KeyName, key.Value);
}
// Now build a list of mailbox numbers associated with each context
// and fill in the mail box details in our VM config
var contextNames = data
.Sections.Select(s => s.SectionName)
.Where(s => s != "general" && s != "zonemessages")
.ToList();
foreach (var contextName in contextNames)
{
if (!Mailboxes.ContainsKey(contextName))
{
Mailboxes.Add(contextName, new Dictionary<string, MailboxConfig?>());
}
foreach (var key in data[contextName])
{
var rawVmConfig = key.Value;
rawVmConfig = rawVmConfig.Trim('>', ' ');
var rawVmConfigParts = rawVmConfig.Split(',');
var newConfig = new MailboxConfig();
newConfig.MailboxNumber = key.KeyName.Trim();
switch (rawVmConfigParts.Length)
{
case 2:
// we have secret & name
newConfig.MailboxSecret = rawVmConfigParts[0].Trim();
newConfig.MailboxName = rawVmConfigParts[1].Trim();
break;
case 3:
// we have secret, name & email
newConfig.MailboxSecret = rawVmConfigParts[0].Trim();
newConfig.MailboxName = rawVmConfigParts[1].Trim();
newConfig.MailboxEmail = rawVmConfigParts[2].Trim();
break;
case 4:
// we have secret, name, email & pager
newConfig.MailboxSecret = rawVmConfigParts[0].Trim();
newConfig.MailboxName = rawVmConfigParts[1].Trim();
newConfig.MailboxEmail = rawVmConfigParts[2].Trim();
newConfig.MailboxPager = rawVmConfigParts[3].Trim();
break;
case 5:
// we have secret, name, email, pager and options
newConfig.MailboxSecret = rawVmConfigParts[0].Trim();
newConfig.MailboxName = rawVmConfigParts[1].Trim();
newConfig.MailboxEmail = rawVmConfigParts[2].Trim();
newConfig.MailboxPager = rawVmConfigParts[3].Trim();
newConfig.MailboxOptions = rawVmConfigParts[4].Trim();
break;
default:
// we have too few or too many VM config options
// TODO: maybe a custom exception should be thrown here
break;
}
Mailboxes[contextName].Add(key.KeyName.Trim(), newConfig);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment