mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-17 16:42:48 +01:00
Working on bots
This commit is contained in:
parent
845e25df2d
commit
7f3bd44d9a
@ -23,7 +23,6 @@ class Kernel extends ConsoleKernel
|
|||||||
'App\Console\Commands\SendReminders',
|
'App\Console\Commands\SendReminders',
|
||||||
'App\Console\Commands\GenerateResources',
|
'App\Console\Commands\GenerateResources',
|
||||||
'App\Console\Commands\TestOFX',
|
'App\Console\Commands\TestOFX',
|
||||||
'App\Console\Commands\TestBot',
|
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
89
app/Http/Controllers/BotController.php
Normal file
89
app/Http/Controllers/BotController.php
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Ninja\Repositories\InvoiceRepository;
|
||||||
|
use App\Ninja\Intents\BaseIntent;
|
||||||
|
|
||||||
|
class BotController extends Controller
|
||||||
|
{
|
||||||
|
protected $invoiceRepo;
|
||||||
|
|
||||||
|
public function __construct(InvoiceRepository $invoiceRepo)
|
||||||
|
{
|
||||||
|
//parent::__construct();
|
||||||
|
|
||||||
|
$this->invoiceRepo = $invoiceRepo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleMessage($platform)
|
||||||
|
{
|
||||||
|
//$message = 'Here\'s your <a href=\'http://ninja.dev/invoices/1/edit\'>invoice</a>';
|
||||||
|
$message = 'create an invoice for test client';
|
||||||
|
$to = '29:1C-OsU7OWBEDOYJhQUsDkYHmycOwOq9QOg5FVTwRX9ts';
|
||||||
|
|
||||||
|
$appId = env('MSBOT_LUIS_APP_ID');
|
||||||
|
$subKey = env('MSBOT_LUIS_SUBSCRIPTION_KEY');
|
||||||
|
$message = rawurlencode($message);
|
||||||
|
|
||||||
|
$url = sprintf('%s?id=%s&subscription-key=%s&q=%s', MSBOT_LUIS_URL, $appId, $subKey, $message);
|
||||||
|
$data = file_get_contents($url);
|
||||||
|
$data = json_decode($data);
|
||||||
|
|
||||||
|
if ( ! count($data->intents)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$intent = $data->intents[0];
|
||||||
|
$intentType = $intent->intent;
|
||||||
|
|
||||||
|
$intent = BaseIntent::createIntent($intentType, $data->entities);
|
||||||
|
$message = $intent->process();
|
||||||
|
|
||||||
|
$this->sendResponse($to, $message);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function sendResponse($to, $message)
|
||||||
|
{
|
||||||
|
$clientId = env('MSBOT_CLIENT_ID');
|
||||||
|
$clientSecret = env('MSBOT_CLIENT_SECRET');
|
||||||
|
$scope = 'https://graph.microsoft.com/.default';
|
||||||
|
|
||||||
|
$data = sprintf('grant_type=client_credentials&client_id=%s&client_secret=%s&scope=%s', $clientId, $clientSecret, $scope);
|
||||||
|
$curl = curl_init();
|
||||||
|
|
||||||
|
$opts = [
|
||||||
|
CURLOPT_URL => MSBOT_LOGIN_URL,
|
||||||
|
CURLOPT_RETURNTRANSFER => true,
|
||||||
|
CURLOPT_POST => 'POST',
|
||||||
|
CURLOPT_POSTFIELDS => $data,
|
||||||
|
];
|
||||||
|
|
||||||
|
curl_setopt_array($curl, $opts);
|
||||||
|
curl_exec($curl);
|
||||||
|
|
||||||
|
|
||||||
|
$response = json_decode(curl_exec($curl));
|
||||||
|
$token = $response->access_token;
|
||||||
|
print_r($token);
|
||||||
|
|
||||||
|
$url = sprintf('%s/conversations/%s/activities/', SKYPE_API_URL, $to);
|
||||||
|
|
||||||
|
$opts = [
|
||||||
|
CURLOPT_URL => $url,
|
||||||
|
CURLOPT_RETURNTRANSFER => true,
|
||||||
|
CURLOPT_POST => 'POST',
|
||||||
|
CURLOPT_POSTFIELDS => $message,
|
||||||
|
CURLOPT_HTTPHEADER => [
|
||||||
|
'Authorization: Bearer ' . $token,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
curl_setopt_array($curl, $opts);
|
||||||
|
$response = curl_exec($curl);
|
||||||
|
curl_close($curl);
|
||||||
|
|
||||||
|
var_dump($response);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -85,6 +85,7 @@ Route::match(['GET', 'POST'], '/buy_now/{gateway_type?}', 'OnlinePaymentControll
|
|||||||
|
|
||||||
Route::post('/hook/email_bounced', 'AppController@emailBounced');
|
Route::post('/hook/email_bounced', 'AppController@emailBounced');
|
||||||
Route::post('/hook/email_opened', 'AppController@emailOpened');
|
Route::post('/hook/email_opened', 'AppController@emailOpened');
|
||||||
|
Route::any('/hook/bot/{platform?}', 'BotController@handleMessage');
|
||||||
Route::post('/payment_hook/{accountKey}/{gatewayId}', 'OnlinePaymentController@handlePaymentWebhook');
|
Route::post('/payment_hook/{accountKey}/{gatewayId}', 'OnlinePaymentController@handlePaymentWebhook');
|
||||||
|
|
||||||
// Laravel auth routes
|
// Laravel auth routes
|
||||||
@ -609,7 +610,7 @@ if (!defined('CONTACT_EMAIL')) {
|
|||||||
define('NINJA_WEB_URL', env('NINJA_WEB_URL', 'https://www.invoiceninja.com'));
|
define('NINJA_WEB_URL', env('NINJA_WEB_URL', 'https://www.invoiceninja.com'));
|
||||||
define('NINJA_APP_URL', env('NINJA_APP_URL', 'https://app.invoiceninja.com'));
|
define('NINJA_APP_URL', env('NINJA_APP_URL', 'https://app.invoiceninja.com'));
|
||||||
define('NINJA_DATE', '2000-01-01');
|
define('NINJA_DATE', '2000-01-01');
|
||||||
define('NINJA_VERSION', '2.6.7' . env('NINJA_VERSION_SUFFIX'));
|
define('NINJA_VERSION', '2.6.8' . env('NINJA_VERSION_SUFFIX'));
|
||||||
|
|
||||||
define('SOCIAL_LINK_FACEBOOK', env('SOCIAL_LINK_FACEBOOK', 'https://www.facebook.com/invoiceninja'));
|
define('SOCIAL_LINK_FACEBOOK', env('SOCIAL_LINK_FACEBOOK', 'https://www.facebook.com/invoiceninja'));
|
||||||
define('SOCIAL_LINK_TWITTER', env('SOCIAL_LINK_TWITTER', 'https://twitter.com/invoiceninja'));
|
define('SOCIAL_LINK_TWITTER', env('SOCIAL_LINK_TWITTER', 'https://twitter.com/invoiceninja'));
|
||||||
@ -627,6 +628,8 @@ if (!defined('CONTACT_EMAIL')) {
|
|||||||
define('OFX_HOME_URL', env('OFX_HOME_URL', 'http://www.ofxhome.com/index.php/home/directory/all'));
|
define('OFX_HOME_URL', env('OFX_HOME_URL', 'http://www.ofxhome.com/index.php/home/directory/all'));
|
||||||
define('GOOGLE_ANALYITCS_URL', env('GOOGLE_ANALYITCS_URL', 'https://www.google-analytics.com/collect'));
|
define('GOOGLE_ANALYITCS_URL', env('GOOGLE_ANALYITCS_URL', 'https://www.google-analytics.com/collect'));
|
||||||
define('MSBOT_LOGIN_URL', 'https://login.microsoftonline.com/common/oauth2/v2.0/token');
|
define('MSBOT_LOGIN_URL', 'https://login.microsoftonline.com/common/oauth2/v2.0/token');
|
||||||
|
define('MSBOT_LUIS_URL', 'https://api.projectoxford.ai/luis/v1/application');
|
||||||
|
define('SKYPE_API_URL', 'https://apis.skype.com/v3');
|
||||||
|
|
||||||
define('BLANK_IMAGE', 'data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=');
|
define('BLANK_IMAGE', 'data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=');
|
||||||
|
|
||||||
|
24
app/Ninja/Intents/BaseIntent.php
Normal file
24
app/Ninja/Intents/BaseIntent.php
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php namespace App\Ninja\Intents;
|
||||||
|
|
||||||
|
|
||||||
|
class BaseIntent
|
||||||
|
{
|
||||||
|
protected $parameters;
|
||||||
|
|
||||||
|
public function __construct($parameters)
|
||||||
|
{
|
||||||
|
$this->parameters = $parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function createIntent($intentType, $parameters)
|
||||||
|
{
|
||||||
|
$className = "App\\Ninja\\Intents\\{$intentType}Intent";
|
||||||
|
return new $className($parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function process()
|
||||||
|
{
|
||||||
|
// do nothing by default
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
43
app/Ninja/Intents/CreateInvoiceIntent.php
Normal file
43
app/Ninja/Intents/CreateInvoiceIntent.php
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?php namespace App\Ninja\Intents;
|
||||||
|
|
||||||
|
class CreateInvoiceIntent extends BaseIntent
|
||||||
|
{
|
||||||
|
public function process()
|
||||||
|
{
|
||||||
|
$clientRepo = app('App\Ninja\Repositories\ClientRepository');
|
||||||
|
$invoiceRepo = app('App\Ninja\Repositories\InvoiceRepository');
|
||||||
|
$client = false;
|
||||||
|
|
||||||
|
foreach ($this->parameters as $param) {
|
||||||
|
if ($param->type == 'client') {
|
||||||
|
$client = $clientRepo->findPhonetically($param->entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($client) {
|
||||||
|
$data = [
|
||||||
|
'client_id' => $client->id,
|
||||||
|
'invoice_items' => [],
|
||||||
|
];
|
||||||
|
|
||||||
|
$invoice = $invoiceRepo->save($data);
|
||||||
|
|
||||||
|
return view('bots.skype.invoice', [
|
||||||
|
'invoice' => $invoice
|
||||||
|
])->render();
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
if ($invoice->amount > 0) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return view('bots.skype.card', [
|
||||||
|
'title' => 'Testing',
|
||||||
|
'subtitle' => $invoice->invoice_number,
|
||||||
|
])->render();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -14,6 +14,14 @@ class InvoicePresenter extends EntityPresenter {
|
|||||||
return $this->entity->user->getDisplayName();
|
return $this->entity->user->getDisplayName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function amount()
|
||||||
|
{
|
||||||
|
$invoice = $this->entity;
|
||||||
|
$account = $invoice->account;
|
||||||
|
|
||||||
|
return $account->formatMoney($invoice->amount, $invoice->client);
|
||||||
|
}
|
||||||
|
|
||||||
public function balanceDueLabel()
|
public function balanceDueLabel()
|
||||||
{
|
{
|
||||||
if ($this->entity->partial > 0) {
|
if ($this->entity->partial > 0) {
|
||||||
|
@ -132,4 +132,47 @@ class ClientRepository extends BaseRepository
|
|||||||
|
|
||||||
return $client;
|
return $client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function findPhonetically($clientName)
|
||||||
|
{
|
||||||
|
$clientNameMeta = metaphone($clientName);
|
||||||
|
|
||||||
|
$map = [];
|
||||||
|
$max = 0;
|
||||||
|
$clientId = 0;
|
||||||
|
|
||||||
|
$clients = Client::scope()->get(['id', 'name']);
|
||||||
|
|
||||||
|
foreach ($clients as $client) {
|
||||||
|
if ( ! $client->name) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$map[$client->id] = $client;
|
||||||
|
$similar = similar_text($clientNameMeta, metaphone($client->name), $percent);
|
||||||
|
|
||||||
|
if ($percent > $max) {
|
||||||
|
$clientId = $client->id;
|
||||||
|
$max = $percent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$contacts = Contact::scope()->get(['client_id', 'first_name', 'last_name']);
|
||||||
|
|
||||||
|
foreach ($contacts as $contact) {
|
||||||
|
if ( ! $contact->getFullName()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$similar = similar_text($clientNameMeta, metaphone($contact->getFullName()), $percent);
|
||||||
|
|
||||||
|
if ($percent > $max) {
|
||||||
|
$clientId = $contact->client_id;
|
||||||
|
$max = $percent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return isset($map[$clientId]) ? $map[$clientId] : null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2051,6 +2051,7 @@ $LANG = array(
|
|||||||
|
|
||||||
'gateway_config_error' => 'It may help to set new passwords or generate new API keys.',
|
'gateway_config_error' => 'It may help to set new passwords or generate new API keys.',
|
||||||
'payment_type_on_file' => ':type on file',
|
'payment_type_on_file' => ':type on file',
|
||||||
|
'invoice_for_client' => 'Invoice :invoice for :client',
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
43
resources/views/bots/skype/card.blade.php
Normal file
43
resources/views/bots/skype/card.blade.php
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
"type":"message/card.carousel",
|
||||||
|
"attachments":[
|
||||||
|
{
|
||||||
|
"contentType":"application/vnd.microsoft.card.hero",
|
||||||
|
"content":{
|
||||||
|
"title":"{!! $title !!}"
|
||||||
|
@if ( ! empty($subtitle))
|
||||||
|
, "subtitle":"{!! $subtitle !!}"
|
||||||
|
@endif
|
||||||
|
@if ( ! empty($text))
|
||||||
|
, "text":"{!! $text !!}"
|
||||||
|
@endif
|
||||||
|
@if ( ! empty($images))
|
||||||
|
, "images":[
|
||||||
|
@foreach($images as $image)
|
||||||
|
@if ($images[0] != $image)
|
||||||
|
,
|
||||||
|
@endif
|
||||||
|
{
|
||||||
|
"image":"{{ $image }}"
|
||||||
|
}
|
||||||
|
@endforeach
|
||||||
|
]
|
||||||
|
@endif
|
||||||
|
@if ( ! empty($buttons))
|
||||||
|
, "buttons":[
|
||||||
|
@foreach($buttons as $button)
|
||||||
|
@if ($buttons[0] != $button)
|
||||||
|
,
|
||||||
|
@endif
|
||||||
|
{
|
||||||
|
"type":"{{ $button['type'] }}",
|
||||||
|
"title":"{!! $button['title'] !!}",
|
||||||
|
"value":"{!! $button['value'] !!}"
|
||||||
|
}
|
||||||
|
@endforeach
|
||||||
|
]
|
||||||
|
@endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
43
resources/views/bots/skype/invoice.blade.php
Normal file
43
resources/views/bots/skype/invoice.blade.php
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
"type":"message/card.receipt",
|
||||||
|
"attachments":[
|
||||||
|
{
|
||||||
|
"contentType":"application/vnd.microsoft.card.receipt",
|
||||||
|
"content":{
|
||||||
|
"title" : '{!! trans('texts.invoice_for_client', [
|
||||||
|
'invoice' => link_to($invoice->getRoute(), $invoice->invoice_number),
|
||||||
|
'client' => link_to($invoice->client->getRoute(), $invoice->client->getDisplayName())
|
||||||
|
]) !!}',
|
||||||
|
"items":[
|
||||||
|
@foreach ($invoice->invoice_items as $item)
|
||||||
|
@if ($invoice->invoice_items[0] != $item)
|
||||||
|
,
|
||||||
|
@endif
|
||||||
|
{
|
||||||
|
"title":"{{ $item->product_key }}",
|
||||||
|
"subtitle":"{{ $item->notes }}",
|
||||||
|
"price":"{{ $item->cost }}",
|
||||||
|
"quantity":"{{ $item->qty }}"
|
||||||
|
}
|
||||||
|
@endforeach
|
||||||
|
],
|
||||||
|
@if (false)
|
||||||
|
"tax":"0.00",
|
||||||
|
@endif
|
||||||
|
"total":"{{ $invoice->present()->amount }}",
|
||||||
|
"buttons":[
|
||||||
|
{
|
||||||
|
"type":"imBack",
|
||||||
|
"title":"{{ trans('texts.send_email') }}",
|
||||||
|
"value":"send_email"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type":"imBack",
|
||||||
|
"title":"{{ trans('texts.download_pdf') }}",
|
||||||
|
"value":"download_pdf"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user