GetAccessToken for Twilio

This commit is contained in:
Haiping Chen 2023-12-06 16:55:55 -06:00
parent 52b8c501b4
commit 8e940e991d
10 changed files with 335 additions and 72 deletions

BIN
arts/BotSharp.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 58 KiB

View file

@ -0,0 +1,196 @@
<mxfile host="Electron" modified="2023-12-03T23:30:26.063Z" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/21.6.8 Chrome/114.0.5735.289 Electron/25.5.0 Safari/537.36" etag="IvHaZH6SDwmnJ8tZsnsQ" version="21.6.8" type="device">
<diagram name="Page-1" id="OM8AWSVk84VDS_qQZt_8">
<mxGraphModel dx="1434" dy="836" grid="0" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="DSK56pGmYBBsuVGbvvgk-1" value="" style="shape=mxgraph.mockup.containers.marginRect;rectMarginTop=10;strokeWidth=1;dashed=0;rounded=1;arcSize=5;recursiveResize=0;html=1;whiteSpace=wrap;fillColor=#f5f5f5;fontColor=#333333;strokeColor=#666666;sketch=1;curveFitting=1;jiggle=2;" parent="1" vertex="1">
<mxGeometry x="303" y="851" width="244" height="124" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-2" value="&lt;b&gt;Agent&lt;/b&gt;" style="shape=rect;strokeColor=none;fillColor=#008cff;strokeWidth=1;dashed=0;rounded=1;arcSize=20;fontColor=#ffffff;fontSize=17;spacing=2;spacingTop=-2;align=left;autosize=1;spacingLeft=4;resizeWidth=0;resizeHeight=0;perimeter=none;html=1;whiteSpace=wrap;" parent="DSK56pGmYBBsuVGbvvgk-1" vertex="1">
<mxGeometry x="5" width="70" height="30" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-13" value="Profile" style="html=1;shadow=0;dashed=0;shape=mxgraph.bootstrap.rrect;rSize=5;strokeColor=none;strokeWidth=1;fillColor=#33A64C;fontColor=#FFFFFF;whiteSpace=wrap;align=center;verticalAlign=middle;spacingLeft=0;fontStyle=1;fontSize=14;spacing=5;" parent="DSK56pGmYBBsuVGbvvgk-1" vertex="1">
<mxGeometry x="143" y="30" width="75" height="20" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-14" value="Template" style="html=1;shadow=0;dashed=0;shape=mxgraph.bootstrap.rrect;rSize=5;strokeColor=none;strokeWidth=1;fillColor=#33A64C;fontColor=#FFFFFF;whiteSpace=wrap;align=center;verticalAlign=middle;spacingLeft=0;fontStyle=1;fontSize=14;spacing=5;" parent="DSK56pGmYBBsuVGbvvgk-1" vertex="1">
<mxGeometry x="143" y="60" width="75" height="20" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-38" value="" style="image;aspect=fixed;html=1;points=[];align=center;fontSize=12;image=img/lib/azure2/management_governance/My_Customers.svg;" parent="DSK56pGmYBBsuVGbvvgk-1" vertex="1">
<mxGeometry x="47.94" y="41" width="48.06" height="39" as="geometry" />
</mxCell>
<mxCell id="ZzXoi5AJEcWWfDo458m0-20" value="Role" style="html=1;shadow=0;dashed=0;shape=mxgraph.bootstrap.rrect;rSize=5;strokeColor=none;strokeWidth=1;fillColor=#33A64C;fontColor=#FFFFFF;whiteSpace=wrap;align=center;verticalAlign=middle;spacingLeft=0;fontStyle=1;fontSize=14;spacing=5;" parent="DSK56pGmYBBsuVGbvvgk-1" vertex="1">
<mxGeometry x="23" y="90" width="47" height="20" as="geometry" />
</mxCell>
<mxCell id="ZzXoi5AJEcWWfDo458m0-21" value="Instruction" style="html=1;shadow=0;dashed=0;shape=mxgraph.bootstrap.rrect;rSize=5;strokeColor=none;strokeWidth=1;fillColor=#33A64C;fontColor=#FFFFFF;whiteSpace=wrap;align=center;verticalAlign=middle;spacingLeft=0;fontStyle=1;fontSize=14;spacing=5;" parent="DSK56pGmYBBsuVGbvvgk-1" vertex="1">
<mxGeometry x="96" y="90" width="122" height="20" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-3" value="" style="shape=mxgraph.mockup.containers.marginRect;rectMarginTop=10;strokeColor=#82b366;strokeWidth=1;dashed=0;rounded=1;arcSize=5;recursiveResize=0;html=1;whiteSpace=wrap;fillColor=#d5e8d4;sketch=1;curveFitting=1;jiggle=2;" parent="1" vertex="1">
<mxGeometry x="342" y="578" width="147.5" height="200" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-4" value="&lt;b&gt;Routing&lt;/b&gt;" style="shape=rect;strokeColor=none;fillColor=#008cff;strokeWidth=1;dashed=0;rounded=1;arcSize=20;fontColor=#ffffff;fontSize=17;spacing=2;spacingTop=-2;align=center;autosize=1;spacingLeft=4;resizeWidth=0;resizeHeight=0;perimeter=none;html=1;whiteSpace=wrap;" parent="DSK56pGmYBBsuVGbvvgk-3" vertex="1">
<mxGeometry x="5" width="90" height="30" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-21" value="Planning" style="html=1;shadow=0;dashed=0;shape=mxgraph.bootstrap.rrect;rSize=5;strokeColor=none;strokeWidth=1;fillColor=#33A64C;fontColor=#FFFFFF;whiteSpace=wrap;align=center;verticalAlign=middle;spacingLeft=0;fontStyle=1;fontSize=14;spacing=5;" parent="DSK56pGmYBBsuVGbvvgk-3" vertex="1">
<mxGeometry x="33.75" y="85" width="80" height="20" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-23" value="Validation" style="html=1;shadow=0;dashed=0;shape=mxgraph.bootstrap.rrect;rSize=5;strokeColor=none;strokeWidth=1;fillColor=#33A64C;fontColor=#FFFFFF;whiteSpace=wrap;align=center;verticalAlign=middle;spacingLeft=0;fontStyle=1;fontSize=14;spacing=5;" parent="DSK56pGmYBBsuVGbvvgk-3" vertex="1">
<mxGeometry x="33.75" y="112" width="80" height="20" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-40" value="" style="image;aspect=fixed;html=1;points=[];align=center;fontSize=12;image=img/lib/azure2/other/API_Proxy.svg;" parent="DSK56pGmYBBsuVGbvvgk-3" vertex="1">
<mxGeometry x="48.69" y="38" width="57.27" height="32" as="geometry" />
</mxCell>
<mxCell id="ZzXoi5AJEcWWfDo458m0-8" value="Redirect" style="html=1;shadow=0;dashed=0;shape=mxgraph.bootstrap.rrect;rSize=5;strokeColor=none;strokeWidth=1;fillColor=#33A64C;fontColor=#FFFFFF;whiteSpace=wrap;align=center;verticalAlign=middle;spacingLeft=0;fontStyle=1;fontSize=14;spacing=5;" parent="DSK56pGmYBBsuVGbvvgk-3" vertex="1">
<mxGeometry x="33.75" y="142" width="81.25" height="20" as="geometry" />
</mxCell>
<mxCell id="ZzXoi5AJEcWWfDo458m0-23" value="Reasoning" style="html=1;shadow=0;dashed=0;shape=mxgraph.bootstrap.rrect;rSize=5;strokeColor=none;strokeWidth=1;fillColor=#33A64C;fontColor=#FFFFFF;whiteSpace=wrap;align=center;verticalAlign=middle;spacingLeft=0;fontStyle=1;fontSize=14;spacing=5;" parent="DSK56pGmYBBsuVGbvvgk-3" vertex="1">
<mxGeometry x="33.75" y="170" width="81.25" height="20" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-5" value="" style="shape=mxgraph.mockup.containers.marginRect;rectMarginTop=10;strokeColor=#666666;strokeWidth=1;dashed=0;rounded=1;arcSize=5;recursiveResize=0;html=1;whiteSpace=wrap;fillColor=#f5f5f5;fontColor=#333333;sketch=1;curveFitting=1;jiggle=2;" parent="1" vertex="1">
<mxGeometry x="605" y="583" width="148" height="200" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-6" value="&lt;b&gt;Action&lt;/b&gt;" style="shape=rect;strokeColor=none;fillColor=#008cff;strokeWidth=1;dashed=0;rounded=1;arcSize=20;fontColor=#ffffff;fontSize=17;spacing=2;spacingTop=-2;align=center;autosize=1;spacingLeft=4;resizeWidth=0;resizeHeight=0;perimeter=none;html=1;whiteSpace=wrap;" parent="DSK56pGmYBBsuVGbvvgk-5" vertex="1">
<mxGeometry x="5" width="80" height="30" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-24" value="Function" style="html=1;shadow=0;dashed=0;shape=mxgraph.bootstrap.rrect;rSize=5;strokeColor=none;strokeWidth=1;fillColor=#33A64C;fontColor=#FFFFFF;whiteSpace=wrap;align=center;verticalAlign=middle;spacingLeft=0;fontStyle=1;fontSize=14;spacing=5;" parent="DSK56pGmYBBsuVGbvvgk-5" vertex="1">
<mxGeometry x="39" y="81" width="72" height="20" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-37" value="" style="image;aspect=fixed;html=1;points=[];align=center;fontSize=12;image=img/lib/azure2/compute/Function_Apps.svg;" parent="DSK56pGmYBBsuVGbvvgk-5" vertex="1">
<mxGeometry x="58" y="37" width="37.4" height="33" as="geometry" />
</mxCell>
<mxCell id="ZzXoi5AJEcWWfDo458m0-7" value="Code Interpreter" style="html=1;shadow=0;dashed=0;shape=mxgraph.bootstrap.rrect;rSize=5;strokeColor=none;strokeWidth=1;fillColor=#33A64C;fontColor=#FFFFFF;whiteSpace=wrap;align=center;verticalAlign=middle;spacingLeft=0;fontStyle=1;fontSize=14;spacing=5;" parent="DSK56pGmYBBsuVGbvvgk-5" vertex="1">
<mxGeometry x="15.5" y="164" width="123" height="20" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-25" value="API Call" style="html=1;shadow=0;dashed=0;shape=mxgraph.bootstrap.rrect;rSize=5;strokeColor=none;strokeWidth=1;fillColor=#33A64C;fontColor=#FFFFFF;whiteSpace=wrap;align=center;verticalAlign=middle;spacingLeft=0;fontStyle=1;fontSize=14;spacing=5;" parent="DSK56pGmYBBsuVGbvvgk-5" vertex="1">
<mxGeometry x="41" y="109" width="72" height="20" as="geometry" />
</mxCell>
<mxCell id="Z7J5NKiKl3a2jxz9pDvI-2" value="Web Driver" style="html=1;shadow=0;dashed=0;shape=mxgraph.bootstrap.rrect;rSize=5;strokeColor=none;strokeWidth=1;fillColor=#33A64C;fontColor=#FFFFFF;whiteSpace=wrap;align=center;verticalAlign=middle;spacingLeft=0;fontStyle=1;fontSize=14;spacing=5;" vertex="1" parent="DSK56pGmYBBsuVGbvvgk-5">
<mxGeometry x="16" y="137" width="121" height="20" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-7" value="" style="shape=mxgraph.mockup.containers.marginRect;rectMarginTop=10;strokeColor=#666666;strokeWidth=1;dashed=0;rounded=1;arcSize=5;recursiveResize=0;html=1;whiteSpace=wrap;fillColor=#f5f5f5;fontColor=#333333;sketch=1;curveFitting=1;jiggle=2;" parent="1" vertex="1">
<mxGeometry x="533" y="298.5" width="220" height="153" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-8" value="&lt;b&gt;Evaluation&lt;/b&gt;" style="shape=rect;strokeColor=none;fillColor=#008cff;strokeWidth=1;dashed=0;rounded=1;arcSize=20;fontColor=#ffffff;fontSize=17;spacing=2;spacingTop=-2;align=center;autosize=1;spacingLeft=4;resizeWidth=0;resizeHeight=0;perimeter=none;html=1;whiteSpace=wrap;" parent="DSK56pGmYBBsuVGbvvgk-7" vertex="1">
<mxGeometry x="5" width="110" height="30" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-10" value="Tester" style="html=1;shadow=0;dashed=0;shape=mxgraph.bootstrap.rrect;rSize=5;strokeColor=none;strokeWidth=1;fillColor=#33A64C;fontColor=#FFFFFF;whiteSpace=wrap;align=center;verticalAlign=middle;spacingLeft=0;fontStyle=1;fontSize=14;spacing=5;" parent="DSK56pGmYBBsuVGbvvgk-7" vertex="1">
<mxGeometry x="20" y="50" width="80" height="20" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-11" value="Evaluator" style="html=1;shadow=0;dashed=0;shape=mxgraph.bootstrap.rrect;rSize=5;strokeColor=none;strokeWidth=1;fillColor=#33A64C;fontColor=#FFFFFF;whiteSpace=wrap;align=center;verticalAlign=middle;spacingLeft=0;fontStyle=1;fontSize=14;spacing=5;" parent="DSK56pGmYBBsuVGbvvgk-7" vertex="1">
<mxGeometry x="20" y="110" width="80" height="20" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-12" value="Reviewer" style="html=1;shadow=0;dashed=0;shape=mxgraph.bootstrap.rrect;rSize=5;strokeColor=none;strokeWidth=1;fillColor=#33A64C;fontColor=#FFFFFF;whiteSpace=wrap;align=center;verticalAlign=middle;spacingLeft=0;fontStyle=1;fontSize=14;spacing=5;" parent="DSK56pGmYBBsuVGbvvgk-7" vertex="1">
<mxGeometry x="125" y="110" width="80" height="20" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-44" value="" style="sketch=0;outlineConnect=0;fontColor=#232F3E;gradientColor=none;fillColor=#067F68;strokeColor=none;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.application_discovery_service_migration_evaluator_collector;" parent="DSK56pGmYBBsuVGbvvgk-7" vertex="1">
<mxGeometry x="139" y="45.5" width="48" height="48" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-49" value="Metrics" style="html=1;shadow=0;dashed=0;shape=mxgraph.bootstrap.rrect;rSize=5;strokeColor=none;strokeWidth=1;fillColor=#33A64C;fontColor=#FFFFFF;whiteSpace=wrap;align=center;verticalAlign=middle;spacingLeft=0;fontStyle=1;fontSize=14;spacing=5;" parent="DSK56pGmYBBsuVGbvvgk-7" vertex="1">
<mxGeometry x="20" y="80" width="80" height="20" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-16" value="" style="shape=mxgraph.mockup.containers.marginRect;rectMarginTop=10;strokeColor=#666666;strokeWidth=1;dashed=0;rounded=1;arcSize=5;recursiveResize=0;html=1;whiteSpace=wrap;fillColor=#f5f5f5;fontColor=#333333;sketch=1;curveFitting=1;jiggle=2;" parent="1" vertex="1">
<mxGeometry x="85" y="578" width="150" height="200" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-17" value="&lt;b&gt;Channel&lt;/b&gt;" style="shape=rect;strokeColor=none;fillColor=#008cff;strokeWidth=1;dashed=0;rounded=1;arcSize=20;fontColor=#ffffff;fontSize=17;spacing=2;spacingTop=-2;align=center;autosize=1;spacingLeft=4;resizeWidth=0;resizeHeight=0;perimeter=none;html=1;whiteSpace=wrap;" parent="DSK56pGmYBBsuVGbvvgk-16" vertex="1">
<mxGeometry x="5" width="90" height="30" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-18" value="Chat" style="html=1;shadow=0;dashed=0;shape=mxgraph.bootstrap.rrect;rSize=5;strokeColor=none;strokeWidth=1;fillColor=#33A64C;fontColor=#FFFFFF;whiteSpace=wrap;align=center;verticalAlign=middle;spacingLeft=0;fontStyle=1;fontSize=14;spacing=5;" parent="DSK56pGmYBBsuVGbvvgk-16" vertex="1">
<mxGeometry x="32.56" y="85" width="65" height="20" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-19" value="SMS" style="html=1;shadow=0;dashed=0;shape=mxgraph.bootstrap.rrect;rSize=5;strokeColor=none;strokeWidth=1;fillColor=#33A64C;fontColor=#FFFFFF;whiteSpace=wrap;align=center;verticalAlign=middle;spacingLeft=0;fontStyle=1;fontSize=14;spacing=5;" parent="DSK56pGmYBBsuVGbvvgk-16" vertex="1">
<mxGeometry x="32.559999999999995" y="141" width="65" height="20" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-20" value="Phone" style="html=1;shadow=0;dashed=0;shape=mxgraph.bootstrap.rrect;rSize=5;strokeColor=none;strokeWidth=1;fillColor=#33A64C;fontColor=#FFFFFF;whiteSpace=wrap;align=center;verticalAlign=middle;spacingLeft=0;fontStyle=1;fontSize=14;spacing=5;" parent="DSK56pGmYBBsuVGbvvgk-16" vertex="1">
<mxGeometry x="32.56" y="113" width="65" height="20" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-39" value="" style="dashed=0;outlineConnect=0;html=1;align=center;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;shape=mxgraph.weblogos.whatsapp;fillColor=#00E676;strokeColor=#dddddd" parent="DSK56pGmYBBsuVGbvvgk-16" vertex="1">
<mxGeometry x="50.14" y="36" width="33.82" height="34" as="geometry" />
</mxCell>
<mxCell id="Z7J5NKiKl3a2jxz9pDvI-1" value="Email" style="html=1;shadow=0;dashed=0;shape=mxgraph.bootstrap.rrect;rSize=5;strokeColor=none;strokeWidth=1;fillColor=#33A64C;fontColor=#FFFFFF;whiteSpace=wrap;align=center;verticalAlign=middle;spacingLeft=0;fontStyle=1;fontSize=14;spacing=5;" vertex="1" parent="DSK56pGmYBBsuVGbvvgk-16">
<mxGeometry x="32.55999999999999" y="169" width="65" height="20" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-29" value="" style="shape=mxgraph.mockup.containers.marginRect;rectMarginTop=10;strokeColor=#666666;strokeWidth=1;dashed=0;rounded=1;arcSize=5;recursiveResize=0;html=1;whiteSpace=wrap;fillColor=#f5f5f5;fontColor=#333333;sketch=1;curveFitting=1;jiggle=2;" parent="1" vertex="1">
<mxGeometry x="85" y="275" width="250" height="200" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-30" value="&lt;b&gt;Conversation&lt;/b&gt;" style="shape=rect;strokeColor=none;fillColor=#008cff;strokeWidth=1;dashed=0;rounded=1;arcSize=20;fontColor=#ffffff;fontSize=17;spacing=2;spacingTop=-2;align=center;autosize=1;spacingLeft=4;resizeWidth=0;resizeHeight=0;perimeter=none;html=1;whiteSpace=wrap;" parent="DSK56pGmYBBsuVGbvvgk-29" vertex="1">
<mxGeometry x="5" width="130" height="30" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-31" value="State" style="html=1;shadow=0;dashed=0;shape=mxgraph.bootstrap.rrect;rSize=5;strokeColor=none;strokeWidth=1;fillColor=#33A64C;fontColor=#FFFFFF;whiteSpace=wrap;align=center;verticalAlign=middle;spacingLeft=0;fontStyle=1;fontSize=14;spacing=5;" parent="DSK56pGmYBBsuVGbvvgk-29" vertex="1">
<mxGeometry x="35" y="90" width="80" height="20" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-32" value="Logging" style="html=1;shadow=0;dashed=0;shape=mxgraph.bootstrap.rrect;rSize=5;strokeColor=none;strokeWidth=1;fillColor=#33A64C;fontColor=#FFFFFF;whiteSpace=wrap;align=center;verticalAlign=middle;spacingLeft=0;fontStyle=1;fontSize=14;spacing=5;" parent="DSK56pGmYBBsuVGbvvgk-29" vertex="1">
<mxGeometry x="35" y="120" width="80" height="20" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-33" value="Statistics" style="html=1;shadow=0;dashed=0;shape=mxgraph.bootstrap.rrect;rSize=5;strokeColor=none;strokeWidth=1;fillColor=#33A64C;fontColor=#FFFFFF;whiteSpace=wrap;align=center;verticalAlign=middle;spacingLeft=0;fontStyle=1;fontSize=14;spacing=5;" parent="DSK56pGmYBBsuVGbvvgk-29" vertex="1">
<mxGeometry x="35" y="150" width="80" height="20" as="geometry" />
</mxCell>
<mxCell id="ZzXoi5AJEcWWfDo458m0-26" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;sketch=1;curveFitting=1;jiggle=2;" parent="DSK56pGmYBBsuVGbvvgk-29" source="DSK56pGmYBBsuVGbvvgk-42" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="337" y="242" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="ZzXoi5AJEcWWfDo458m0-29" value="&lt;h4&gt;&lt;font style=&quot;&quot;&gt;&lt;b style=&quot;&quot;&gt;&lt;font style=&quot;font-size: 12px;&quot;&gt;Conversation Management&lt;/font&gt;&lt;/b&gt;&lt;/font&gt;&lt;/h4&gt;&lt;font style=&quot;&quot;&gt;&lt;div style=&quot;font-size: 11px; text-align: left;&quot;&gt;&lt;span style=&quot;font-size: 11px;&quot;&gt;&lt;font style=&quot;font-size: 11px;&quot;&gt;- State tracking&lt;/font&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-size: 11px; text-align: left;&quot;&gt;&lt;span style=&quot;font-size: 11px;&quot;&gt;&lt;font style=&quot;font-size: 11px;&quot;&gt;- LLM Provider&lt;/font&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-size: 11px; text-align: left;&quot;&gt;&lt;span style=&quot;font-size: 11px;&quot;&gt;&lt;font style=&quot;font-size: 11px;&quot;&gt;- Dialogs history&lt;br&gt;- Execution log&lt;/font&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-size: 11px; text-align: left;&quot;&gt;&lt;span style=&quot;font-size: 11px;&quot;&gt;&lt;font style=&quot;font-size: 11px;&quot;&gt;- Response template&lt;/font&gt;&lt;/span&gt;&lt;/div&gt;&lt;/font&gt;" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="ZzXoi5AJEcWWfDo458m0-26" vertex="1" connectable="0">
<mxGeometry x="0.5293" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-42" value="" style="html=1;verticalLabelPosition=bottom;align=center;labelBackgroundColor=#ffffff;verticalAlign=top;strokeWidth=2;strokeColor=#0080F0;shadow=0;dashed=0;shape=mxgraph.ios7.icons.chat;" parent="DSK56pGmYBBsuVGbvvgk-29" vertex="1">
<mxGeometry x="102" y="44" width="53.33" height="32" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-46" value="LLM Provider" style="html=1;shadow=0;dashed=0;shape=mxgraph.bootstrap.rrect;rSize=5;strokeColor=none;strokeWidth=1;fillColor=#33A64C;fontColor=#FFFFFF;whiteSpace=wrap;align=center;verticalAlign=middle;spacingLeft=0;fontStyle=1;fontSize=14;spacing=5;" parent="DSK56pGmYBBsuVGbvvgk-29" vertex="1">
<mxGeometry x="125" y="90" width="105" height="20" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-48" value="Hook" style="html=1;shadow=0;dashed=0;shape=mxgraph.bootstrap.rrect;rSize=5;strokeColor=none;strokeWidth=1;fillColor=#33A64C;fontColor=#FFFFFF;whiteSpace=wrap;align=center;verticalAlign=middle;spacingLeft=0;fontStyle=1;fontSize=14;spacing=5;" parent="DSK56pGmYBBsuVGbvvgk-29" vertex="1">
<mxGeometry x="125" y="120" width="80" height="20" as="geometry" />
</mxCell>
<mxCell id="DSK56pGmYBBsuVGbvvgk-45" value="" style="verticalLabelPosition=bottom;shadow=0;dashed=0;align=center;html=1;verticalAlign=top;strokeWidth=1;shape=mxgraph.mockup.markup.curlyBrace;whiteSpace=wrap;strokeColor=#999999;fillStyle=auto;sketch=1;curveFitting=1;jiggle=2;" parent="1" vertex="1">
<mxGeometry x="141" y="520" width="561" height="20" as="geometry" />
</mxCell>
<mxCell id="ZzXoi5AJEcWWfDo458m0-14" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;sketch=1;curveFitting=1;jiggle=2;" parent="1" source="DSK56pGmYBBsuVGbvvgk-40" target="DSK56pGmYBBsuVGbvvgk-5" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ZzXoi5AJEcWWfDo458m0-16" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.778;entryY=0.033;entryDx=0;entryDy=0;entryPerimeter=0;sketch=1;curveFitting=1;jiggle=2;" parent="1" source="DSK56pGmYBBsuVGbvvgk-37" target="DSK56pGmYBBsuVGbvvgk-4" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ZzXoi5AJEcWWfDo458m0-18" style="rounded=1;orthogonalLoop=1;jettySize=auto;html=1;edgeStyle=orthogonalEdgeStyle;sketch=1;curveFitting=1;jiggle=2;" parent="1" source="DSK56pGmYBBsuVGbvvgk-39" target="DSK56pGmYBBsuVGbvvgk-3" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ZzXoi5AJEcWWfDo458m0-19" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.822;entryY=0.033;entryDx=0;entryDy=0;entryPerimeter=0;sketch=1;curveFitting=1;jiggle=2;" parent="1" source="DSK56pGmYBBsuVGbvvgk-40" target="DSK56pGmYBBsuVGbvvgk-17" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ZzXoi5AJEcWWfDo458m0-22" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.729;entryY=0.1;entryDx=0;entryDy=0;entryPerimeter=0;sketch=1;curveFitting=1;jiggle=2;" parent="1" source="DSK56pGmYBBsuVGbvvgk-40" target="DSK56pGmYBBsuVGbvvgk-2" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ZzXoi5AJEcWWfDo458m0-30" value="- Load agent profile&lt;br&gt;&lt;div style=&quot;&quot;&gt;- Render the template&lt;/div&gt;" style="edgeLabel;html=1;align=left;verticalAlign=middle;resizable=0;points=[];" parent="ZzXoi5AJEcWWfDo458m0-22" vertex="1" connectable="0">
<mxGeometry x="0.6359" relative="1" as="geometry">
<mxPoint x="-51" y="9" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="ZzXoi5AJEcWWfDo458m0-25" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.738;entryY=-0.033;entryDx=0;entryDy=0;entryPerimeter=0;sketch=1;curveFitting=1;jiggle=2;" parent="1" source="DSK56pGmYBBsuVGbvvgk-44" target="DSK56pGmYBBsuVGbvvgk-30" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="688" y="255" />
<mxPoint x="186" y="255" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="ZzXoi5AJEcWWfDo458m0-27" value="&lt;h4 style=&quot;text-align: left;&quot;&gt;&lt;b&gt;&lt;font style=&quot;font-size: 12px;&quot;&gt;Evaluate the conversation&lt;/font&gt;&lt;/b&gt;&lt;/h4&gt;&lt;div style=&quot;text-align: left;&quot;&gt;- Generate the metrics report&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;- Audit the conversation quality&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;- Make sure the result is as expected&lt;/div&gt;" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="ZzXoi5AJEcWWfDo458m0-25" vertex="1" connectable="0">
<mxGeometry x="0.1386" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="Z7J5NKiKl3a2jxz9pDvI-3" value="" style="image;aspect=fixed;html=1;points=[];align=center;fontSize=12;image=img/lib/azure2/storage/Azure_HCP_Cache.svg;" vertex="1" parent="1">
<mxGeometry x="109" y="884" width="68" height="63" as="geometry" />
</mxCell>
<mxCell id="Z7J5NKiKl3a2jxz9pDvI-4" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.985;entryY=0.429;entryDx=0;entryDy=0;entryPerimeter=0;sketch=1;curveFitting=1;jiggle=2;" edge="1" parent="1" source="DSK56pGmYBBsuVGbvvgk-38" target="Z7J5NKiKl3a2jxz9pDvI-3">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Z7J5NKiKl3a2jxz9pDvI-5" value="File&lt;br&gt;Storage" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="Z7J5NKiKl3a2jxz9pDvI-4">
<mxGeometry x="0.2021" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

View file

@ -1,5 +1,3 @@
using System.Text.Json.Serialization;
namespace BotSharp.Abstraction.Users.Models;
public class Token

View file

@ -1,21 +1,7 @@
using BotSharp.Abstraction.Conversations;
using BotSharp.Plugin.Twilio.Settings;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System;
using Twilio.AspNet.Common;
using Twilio.AspNet.Core;
using Twilio.TwiML;
using Twilio.TwiML.Voice;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using BotSharp.Abstraction.Routing.Settings;
using Twilio.Http;
using Twilio.TwiML.Messaging;
using BotSharp.Abstraction.Agents.Enums;
using BotSharp.Abstraction.Conversations.Models;
using BotSharp.Abstraction.Conversations.Enums;
using System.IdentityModel.Tokens.Jwt;
using BotSharp.Plugin.Twilio.Services;
namespace BotSharp.Plugin.Twilio.Controllers;
@ -30,12 +16,29 @@ public class TwilioVoiceController : TwilioController
_settings = settings;
_services = services;
}
[Authorize]
[HttpGet("/twilio/token")]
public Token GetAccessToken()
{
var twilio = _services.GetRequiredService<TwilioService>();
var accessToken = twilio.GetAccessToken();
var jwt = new JwtSecurityTokenHandler().ReadJwtToken(accessToken);
return new Token
{
AccessToken = accessToken,
ExpireTime = jwt.Payload.Exp.Value,
TokenType = "Bearer",
Scope = "api"
};
}
[HttpPost("/twilio/voice/welcome")]
public async Task<TwiMLResult> StartConversation(VoiceRequest request)
{
string sessionId = $"TwilioVoice_{request.CallSid}";
var response = ReturnInstructions("Hello, how may I help you?");
var twilio = _services.GetRequiredService<TwilioService>();
var response = twilio.ReturnInstructions("Hello, how may I help you?");
return TwiML(response);
}
@ -51,13 +54,18 @@ public class TwilioVoiceController : TwilioController
$"calling_phone={input.DialCallSid}"
});
var twilio = _services.GetRequiredService<TwilioService>();
VoiceResponse response = default;
var result = await conv.SendMessage(agentId,
new RoleDialogModel(AgentRole.User, input.SpeechResult),
async msg =>
{
response = HangUp(msg.Content);
response = twilio.ReturnInstructions(msg.Content);
if (msg.FunctionName == "conversation_end")
{
response = twilio.HangUp(msg.Content);
}
}, async functionExecuting =>
{
}, async functionExecuted =>
@ -66,53 +74,4 @@ public class TwilioVoiceController : TwilioController
return TwiML(response);
}
private VoiceResponse ReturnInstructions(string message)
{
var routingSetting = _services.GetRequiredService<RoutingSettings>();
var response = new VoiceResponse();
var gather = new Gather()
{
Input = new List<Gather.InputEnum>()
{
Gather.InputEnum.Speech
},
Action = new Uri($"{_settings.CallbackHost}/twilio/voice/{routingSetting.RouterId}")
};
gather.Say(message);
response.Append(gather);
return response;
}
private VoiceResponse HangUp(string message)
{
var response = new VoiceResponse();
if (!string.IsNullOrEmpty(message))
{
response.Say(message);
}
response.Hangup();
return response;
}
private VoiceResponse HoldOn(int interval, string message = null)
{
var routingSetting = _services.GetRequiredService<RoutingSettings>();
var response = new VoiceResponse();
var gather = new Gather()
{
Input = new List<Gather.InputEnum>() { Gather.InputEnum.Speech },
Action = new Uri($"{_settings.CallbackHost}/twilio/voice/{routingSetting.RouterId}"),
ActionOnEmptyResult = true
};
if (!string.IsNullOrEmpty(message))
{
gather.Say(message);
}
gather.Pause(interval);
response.Append(gather);
return response;
}
}

View file

@ -0,0 +1,96 @@
using Twilio.Jwt.AccessToken;
using Token = Twilio.Jwt.AccessToken.Token;
namespace BotSharp.Plugin.Twilio.Services;
/// <summary>
/// https://github.com/TwilioDevEd/voice-javascript-sdk-quickstart-csharp
/// </summary>
public class TwilioService
{
private readonly TwilioSetting _settings;
private readonly IServiceProvider _services;
public TwilioService(TwilioSetting settings, IServiceProvider services)
{
_settings = settings;
_services = services;
}
public string GetAccessToken()
{
// These are specific to Voice
var user = _services.GetRequiredService<IUserIdentity>();
// Create a Voice grant for this token
var grant = new VoiceGrant();
grant.OutgoingApplicationSid = _settings.AppSID;
// Optional: add to allow incoming calls
grant.IncomingAllow = true;
var grants = new HashSet<IGrant>
{
{ grant }
};
// Create an Access Token generator
var token = new Token(
_settings.AccountSID,
_settings.ApiKeySID,
_settings.ApiSecret,
user.Id,
grants: grants);
return token.ToJwt();
}
public VoiceResponse ReturnInstructions(string message)
{
var routingSetting = _services.GetRequiredService<RoutingSettings>();
var response = new VoiceResponse();
var gather = new Gather()
{
Input = new List<Gather.InputEnum>()
{
Gather.InputEnum.Speech
},
Action = new Uri($"{_settings.CallbackHost}/twilio/voice/{routingSetting.RouterId}")
};
gather.Say(message);
response.Append(gather);
return response;
}
public VoiceResponse HangUp(string message)
{
var response = new VoiceResponse();
if (!string.IsNullOrEmpty(message))
{
response.Say(message);
}
response.Hangup();
return response;
}
public VoiceResponse HoldOn(int interval, string message = null)
{
var routingSetting = _services.GetRequiredService<RoutingSettings>();
var response = new VoiceResponse();
var gather = new Gather()
{
Input = new List<Gather.InputEnum>() { Gather.InputEnum.Speech },
Action = new Uri($"{_settings.CallbackHost}/twilio/voice/{routingSetting.RouterId}"),
ActionOnEmptyResult = true
};
if (!string.IsNullOrEmpty(message))
{
gather.Say(message);
}
gather.Pause(interval);
response.Append(gather);
return response;
}
}

View file

@ -5,5 +5,8 @@ public class TwilioSetting
public string PhoneNumber { get; set; }
public string AccountSID { get; set; }
public string AuthToken { get; set; }
public string AppSID { get; set; }
public string ApiKeySID { get; set; }
public string ApiSecret { get; set; }
public string CallbackHost { get; set; }
}

View file

@ -1,4 +1,4 @@
using BotSharp.Plugin.Twilio.Settings;
using BotSharp.Plugin.Twilio.Services;
namespace BotSharp.Plugin.Twilio;
@ -12,5 +12,7 @@ public class TwilioPlugin : IBotSharpPlugin
var setting = new TwilioSetting();
config.Bind("Twilio", setting);
services.AddSingleton(setting);
services.AddScoped<TwilioService>();
}
}

View file

@ -14,4 +14,13 @@ global using BotSharp.Abstraction.Models;
global using BotSharp.Abstraction.Agents;
global using BotSharp.Abstraction.Conversations;
global using BotSharp.Abstraction.Plugins;
global using BotSharp.Abstraction.Conversations.Models;
global using BotSharp.Abstraction.Conversations.Models;
global using BotSharp.Abstraction.Routing.Settings;
global using BotSharp.Abstraction.Conversations.Enums;
global using BotSharp.Abstraction.Users.Models;
global using BotSharp.Abstraction.Users;
global using Twilio.AspNet.Common;
global using Twilio.AspNet.Core;
global using Twilio.TwiML;
global using Twilio.TwiML.Voice;
global using BotSharp.Plugin.Twilio.Settings;