I have been building a Window Form desktop application using C# that interfaces with Asterisk using Asterisk.NET.
My first problem is catch a Incoming call and transfer it to specific exten.
The first my idea is using OriginateAction, when a call come, I use Dial event and catch it and use OriginateAction to call to a specific exten.
RedirectAction originateAction = new RedirectAction();
originateAction.Channel = e.Channel;
originateAction.Context = "default";
originateAction.Exten = "203";
originateAction.Priority = 1;
ManagerResponse originateResponse = manager.SendAction(originateAction);
Console.WriteLine(originateResponse);
But it not work like my wish.
The second my idea is using RedirectAction:
RedirectAction originateAction = new RedirectAction();
originateAction.Channel = e.Channel;
originateAction.Context = "default";
originateAction.Exten = "203";
originateAction.Priority = 1;
ManagerResponse originateResponse = manager.SendAction(originateAction);
Console.WriteLine(originateResponse);
And it not work.
I have find on many websites but the documents is very little.
How can I solve this issue?
Thanks!
I would suggest using some kind of dynamic dialplan instead of "catching" calls reactively. Why not use an AGI script?
Essentially, your application tells a database or other central system what to do when calls matching certain criteria come in. Then Asterisk runs the script you setup when calls reach a certain context (such as all incoming calls), and then the script routes the call dynamically based on the inputs given by your application.
Since you seem to like .NET, here's a .NET AGI project to help you get started: AsterNET. It looks like the library you mentioned, Asterisk.NET, is also capable of Fast CGI (what AGI uses), but the last release was in 2009, whereas AsterNet is active as recently as 3 months ago.
I personally use phpAGI to do all kinds of neat ACD and call routing stuff in our call center.
For more info on AGI, see the official docs.
Edit:
I should probably also explain some basic call flow terminology (from the docs):
Originate: Generates an outgoing call to a Extension/Context/Priority or Application/Data. Example: User clicks a button, Originate a call to their desk phone, when they answer that call, it executes dialplan, or a dialplan application.
Redirect: Redirect (transfer) a call. Example: Agent and Customer are talking, but Manager wants to take over the call. Use Redirect to "take" the call from Agent and ring the Manager.
Dial: (in dialplan only, not AMI) Dial the technology/channel specified. Note that you can only Originate from your .NET application, not Dial.
Can you show your event handler code? It looks like that library would say something like manager.NewChannel += new ManagerEventHandler(new_channel);
Related
I am trying to create something of an application bot. I need the bot to be triggered in a generic channel and then continue the application process in a private DM channel with the applicant.
My issue is this : The bot can have only one on_message function defined. I find it extremely complicated (and inefficient) to check everytime if the on_message was triggered by a message from a DM channel vs the generic channel. Also, makes it difficult to keep track of an applicants answers. I want to check if the following is possible : Have the bot respond to messages from the generic channel as usual. If it receives an application prompt, start a new subprocess (or bot?) that handles the DMs with the applicant separately.
Is the above possible? if not, is there an alternative to handling this in a better way ?
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.channel.type==discord.ChannelType.private:
await dm_channel.send("Whats your age?") ## Question 2
elif message.channel.type == discord.ChannelType.text:
if message.content.startswith('$h'):
member = message.author
if "apply" in message.content:
await startApply(member)
else:
await message.channel.send('Hello!')
# await message.reply('Hello!', mention_author=True)
async def startApply(member):
dm_channel = await member.create_dm()
await dm_channel.send("Whats your name?") ## Question 1
I have the above code as of now. I want the startApply function to trigger a new bot/subprocess to handle the DMs with an applicant.
Option 1
Comparatively speaking, a single if check like that is not too much overhead, but there are a few different solutions. First, you could try your hand at slash commands. This is library built as an extension for the discord.py library for slash commands. You could make one that only works in DM's, and then have it run from there with continuous slash commands.
Option 2
Use a webhook to start up a new bot. This is most likely more complicated, as youll have to get a domain or find some sort of free service to catch webhooks. You could use a webhook like this though to 'wake up' a bot and have it chat with the user in dm's.
Option 3 (Recommended)
Create functions that handle the text depending on the channel, and keep that if - elif in there. As i said, one if isn't that bad. If you had functions that are called in your code that handled everything, it actually should be fairly easy to deal with:
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.channel.type==discord.ChannelType.private:
respondToPrivate(message)
elif message.channel.type == discord.ChannelType.text:
repondToText(message)
In terms of keeping track of the data, if this is a smaller personal project, MySQL is great and easy to learn. You can have each function store whatever data needed to the database so that you can have it stored to be looked at / safe in case of bot crash & then it will also be out of memory.
We have a notification which will post data to an application using the application end point.
notification ABC{
post = savedetailsurl
body = {{.|json}}
useBody = true
}
So the end point will save all the details in mysql DB.
Now in our template we call another end point to get the details which we saved using the webhook in notification.
template ABC {
use the " getDetailsUrl" and use the details in forming the email
}
Now the problem is race condition. Sometimes the details are not saved yet in the backend (mysql), and getDetailsUrl is called. So we get the empty result.
Is there are way to solve the race condition.
Bosun's notification system is designed to be very basic. If you want something more advanced you will need to use a separate system to generate the notification details and/or handle the alert workflow. Some people have used pagerduty or other monitoring systems like Shinken to do more advanced notifications or alert management.
Your best bet is to skip the built in notifications and do everything in a external system. You can still use the http://bosun.org/api to integrate with the various alert states (crit/warn/ack/close/etc) or you can change your alerts to use log = true to bypass all the built in states and create your own workflow.
I use twain 2.3 (TWAINDSM.DLL) in my application with HP Scanjet 200 TWAIN Protocol 1.9.
My TWAIIN calls are:
OpenDSM: DG_CONTROL, DAT_PARENT, MSG_OPENDSM
OpenDS: DG_CONTROL, DAT_IDENTITY, MSG_OPENDS
EnableDS: DG_CONTROL, DAT_USERINTERFACE, MSG_ENABLEDS
ProcessDeviceEvent: DG_CONTROL, DAT_EVENT, MSG_PROCESSEVENT
and as a result of the last call I allways get TWRC_NOTDSEVENT instead of TWRC_DSEVENT.
Could please someone help with this?
Once you use DG_CONTROL / DAT_EVENT / MSG_PROCESSEVENT, all messages from the applications message loop must be sent to the data source for processing. Receiving TWRC_NOTDSEVENT means the forwarded message isn't for the source so the application should process it as normal.
Keep forwarding all messages to the source until you receive MSG_XFERREADY which means there is data to transfer. Once the transfer is finished and you have sent MSG_DISABLEDS that's when you can stop forwarding messages to the source.
Twain is a standard, and when many company implement that standard, not all of them do the same way. Along the way to support Twain, we will learn and adjust the code to support all the different implementations.
I experienced this situation before, and this is my workaround:
Instead of placing (rc == TWRC_DSEVENT) at the beginning of code (will skip the following MSG_XFERREADY processing afterward) you can move the comparison to the end after MSG_XFERREADY processing, so that MSG_XFERREADY is always checked and processed.
(rc == TWRC_DSEVENT) is only to determine if we should forward the window message or not.
I don't know your specific situation. I ran into a similar issue because I called OpenDSM with a HWND/wId which is from another process. You should call OpenDSM with the HWND of
the active window/dialog which is owned by current process.
Well i have an adobe air , downloaded from below link.. it is wonderful app..
http://www.adobe.com/devnet/air/flex/articles/air_screenrecording.html
and this works fine. It captures my screen , record audio but it just does not stop or quit as vlc-player.exe continues to run in the task manager.
i tried lots of vlc- commands but it just does not stop once it starts capturing screen video.
I need help on it..
I know this is a old thread, but just in case someone wants to know...
You can't use rc-fake-tty because Windows doesn't support terminal. For Windows, tell VLC to run with only one instance, then send it the quit command as a separate NativeProcess call.
So, in the linked article, change the stopRecording() method to this:
public function stopRecording():void{
var startupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
startupInfo.executable = vlcFile;
var processArgs:Vector.<String> = new Vector.<String>();
processArgs.push("-I");
processArgs.push("rc"); //Remote control
processArgs.push("--one-instance");
processArgs.push("vlc://quit");
startupInfo.arguments = processArgs;
var killSwitch:NativeProcess = new NativeProcess();
killSwitch.start(startupInfo);
}
And make sure to add this:
processArgs.push("--one-instance");
To your initial screen record startupInfo in startRecording() method.
I quit using vlc for the same reason and started to write my recording application using .Net 4, but i am having less performance using c# now.
Edit:
VLC for windows does not support fake rc control so setting rc-fake-tty is useless. As the very last try, i wanna control is via socket. If you got it working this way, please make me informed.
Environment : ASP.NET, C#
I am writing a web program that will export 12 tables to another database. When the user click the "Export" button, the export process will get started. The thing is, I like to show some messages to client such as "preparing..., deleting old records..., exporting..., export completed."
But now, It is showing all status once 12 table are completed.
Please guide me how to do this.
Doing long processes like this is on a web page is probably not a good idea, you will need change the timeout settings on pages etc
Rather build a windows service that does all the work. You can then use the Page to initialte the process. The service could update some status that is read by the page. This way the page does very little work, ie initiate the process and poll for status updates. This can be done via simple jquery/ajax calls.
try this
put this on c#
and call ajavascript function per process
Page.RegisterClientScriptBlock("1","alert('add to table now')");
Use a javascript timer to periodically load content from a status page or service.
The timer is fairly simple:
setTimeout('checkProcessStatus()', waitTime);
The update itself depends on your choice of tech - for instance if using MVC and jQuery:
function checkProcessStatus() {
//dynamically add the html from the status page to <div id="taskStatusPanel"
$('#taskStatusPanel').load('export/status/' + taskId);
//set timer to call this again
setTimeout('checkProcessStatus()', waitTime);
}
Then the ExportController.Status action would return a simple view that displayed the HTML for the current status.