title: Asterisk ARI conference call app: authorize / ask for pin number
body: <p>I'm using a C#/.NET <a href="https://github.com/skrusty/AsterNET.ARI/tree/master/Samples/SimpleConfExample" rel="noreferrer">library </a> to implement the <a href="https://wiki.asterisk.org/wiki/pages/viewpage.action?pageId=29395573" rel="noreferrer">Asterisk RESTful Interface (ARI)</a> to create conference call app.</p>
  
  <p>So far the app works like this:</p>
  
  <ol>
  <li>User calls the number</li>
  <li>App answers</li>
  <li>App starts voice detection</li>
  <li>App asks for name and records the audio</li>
  <li>App adds the user to the conference</li>
  </ol>
  
  <p><strong>Requirement:</strong></p>
  
  <p>I need to add in the above process some kind of authorization, before the user is added into the conference. I need to implement the <strong>ask for a PIN number</strong> functionality, create a PIN number construct and if the caller enters the correct PIN add the caller to the correct conference call.</p>
  
  <p><strong>The Code:</strong></p>
  
  <p><strong>Conference:</strong></p>
  
  <pre><code>    public Conference( AriClient c, Guid id, string name)
      {
          _client = c;
          Id = id;
          ConferenceName = name;
          State = ConferenceState.Destroyed;
  
          c.OnChannelDtmfReceivedEvent += c_OnChannelDtmfReceivedEvent; // ??
          c.OnBridgeCreatedEvent += c_OnBridgeCreatedEvent;
          c.OnChannelEnteredBridgeEvent += c_OnChannelEnteredBridgeEvent;
          c.OnBridgeDestroyedEvent += c_OnBridgeDestroyedEvent;
          c.OnChannelLeftBridgeEvent += c_OnChannelLeftBridgeEvent;
          c.OnRecordingFinishedEvent += c_OnRecordingFinishedEvent;
  
          // Added support for talk detection
          c.OnChannelTalkingStartedEvent += c_OnChannelTalkingStartedEvent;
          c.OnChannelTalkingFinishedEvent += c_OnChannelTalkingFinishedEvent;
  
          Debug.Print("Added Conference {0}", ConferenceName);
      }
  </code></pre>
  
  <p><strong>OnChannelEnteredBridgeEvent:</strong></p>
  
  <pre><code>private void c_OnChannelEnteredBridgeEvent(object sender, ChannelEnteredBridgeEvent e)
  {
      ConferenceUser confUser = ConferenceUsers.SingleOrDefault(x =&gt; x.Channel.Id == e.Channel.Id);
      if (confUser == null) return;
  
      confUser.State = ConferenceUserState.InConf;
  
      if (ConferenceUsers.Count(x =&gt; x.State == ConferenceUserState.InConf) &gt; 1) // are we the only ones here
      {
          // stop moh
          _client.Bridges.StopMoh(Confbridge.Id);
  
          // change state
          State = ConferenceState.Ready;
  
          // announce new user
          _client.Bridges.Play(Confbridge.Id, "recording:" + confUser.CurrentRecodingId, "en", 0, 0, Guid.NewGuid().ToString());
          _client.Bridges.Play(Confbridge.Id, "sound:conf-hasjoin", "en", 0, 0, Guid.NewGuid().ToString());
      }
      else
      {          
          // only caller in conf
          _client.Channels.Play(e.Channel.Id, "sound:conf-onlyperson", "en", 0, 0, Guid.NewGuid().ToString());
      }
  }
  </code></pre>
  
  <p><strong>StartConference:</strong></p>
  
  <pre><code>    public bool StartConference()
      {
  
          // Create the conference bridge
          Debug.Print("Requesting new bridge {0} for {1}", Id, ConferenceName);
          Bridge bridge = _client.Bridges.Create("mixing", Id.ToString(), ConferenceName);
  
          if (bridge == null)
          {
              return false;
          }
  
          Debug.Print("Subscribing to events on bridge {0} for {1}", Id, ConferenceName);
          _client.Applications.Subscribe(AppConfig.AppName, "bridge:" + bridge.Id);
  
          // Start MOH on conf bridge
          _client.Bridges.StartMoh(bridge.Id, "default");
  
          // Default state is ReadyWaiting until MOH is turned off
          State = ConferenceState.ReadyWaiting;
          Confbridge = bridge;
  
          // Conference ready to accept calls
          State = ConferenceState.Ready;
  
          return true;
      }
  </code></pre>
  
  <p><strong>AddUser:</strong></p>
  
  <pre><code>    public bool AddUser(Channel c) //here check for pin and caller id
      {
          if (State == ConferenceState.Destroying)
              return false;
          if (State == ConferenceState.Destroyed)
          {
              // We should initiate a new conference bridge
              if (!StartConference())
                  return false;
          }
          if (State &lt; ConferenceState.Ready) return false;
  
          // Answer channel
          _client.Channels.Answer(c.Id);
  
          // Turn on talk detection on this channel
          _client.Channels.SetChannelVar(c.Id, "TALK_DETECT(set)", "");
  
          // Add conference user to collection
          ConferenceUsers.Add(new ConferenceUser(this, c, _client, ConferenceUserType.Normal));
  
          return true;
      }
  </code></pre>
  
  <p><strong>Question:</strong></p>
  
  <p>How can I raise/invoke the "ask for pin number" event/channel within the app and grab the input DTMF digits into a variable? </p>
  
  <p>Can this be done solely in my C# ARI application, or do I need to fiddle with the .conf files on the Asterisk server?</p>
  
  <p>My preferred way of doing is is by implementing it in my C# ARI app, as this would give me more control over conferences.</p>