interface_95_modZapier_ZapierTriggers.class.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569
  1. <?php
  2. /* Copyright (C) 2017-2020 Frédéric France <frederic.france@netlogic.fr>
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  16. */
  17. /**
  18. * \file core/triggers/interface_99_modZapier_ZapierTriggers.class.php
  19. * \ingroup zapier
  20. * \brief File for Zappier Triggers.
  21. */
  22. require_once DOL_DOCUMENT_ROOT.'/core/triggers/dolibarrtriggers.class.php';
  23. /**
  24. * Class of triggers for Zapier module
  25. */
  26. class InterfaceZapierTriggers extends DolibarrTriggers
  27. {
  28. /**
  29. * Constructor
  30. *
  31. * @param DoliDB $db Database handler
  32. */
  33. public function __construct($db)
  34. {
  35. $this->db = $db;
  36. $this->name = preg_replace('/^Interface/i', '', get_class($this));
  37. $this->family = "technic";
  38. $this->description = "Zapier triggers.";
  39. // 'development', 'experimental', 'dolibarr' or version
  40. $this->version = self::VERSION_DEVELOPMENT;
  41. $this->picto = 'zapier';
  42. }
  43. /**
  44. * Function called when a Dolibarrr business event is done.
  45. * All functions "runTrigger" are triggered if file
  46. * is inside directory core/triggers
  47. *
  48. * @param string $action Event action code
  49. * @param CommonObject $object Object
  50. * @param User $user Object user
  51. * @param Translate $langs Object langs
  52. * @param Conf $conf Object conf
  53. * @return int <0 if KO, 0 if no triggered ran, >0 if OK
  54. */
  55. public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf)
  56. {
  57. if (empty($conf->zapier) || empty($conf->zapier->enabled)) {
  58. // Module not active, we do nothing
  59. return 0;
  60. }
  61. $logtriggeraction = false;
  62. $sql = '';
  63. if ($action != '') {
  64. $actions = explode('_', $action);
  65. $sql = 'SELECT rowid, url FROM '.MAIN_DB_PREFIX.'zapier_hook';
  66. $sql .= ' WHERE module="'.$this->db->escape(strtolower($actions[0])).'" AND action="'.$this->db->escape(strtolower($actions[1])).'"';
  67. //setEventMessages($sql, null);
  68. }
  69. switch ($action) {
  70. // Users
  71. case 'USER_CREATE':
  72. $resql = $this->db->query($sql);
  73. // TODO voir comment regrouper les webhooks en un post
  74. while ($resql && $obj = $this->db->fetch_array($resql)) {
  75. $cleaned = cleanObjectDatas(dol_clone($object));
  76. $json = json_encode($cleaned);
  77. // call the zapierPostWebhook() function
  78. zapierPostWebhook($obj['url'], $json);
  79. }
  80. $logtriggeraction = true;
  81. break;
  82. case 'USER_MODIFY':
  83. $resql = $this->db->query($sql);
  84. // TODO voir comment regrouper les webhooks en un post
  85. while ($resql && $obj = $this->db->fetch_array($resql)) {
  86. $cleaned = cleanObjectDatas(dol_clone($object));
  87. $json = json_encode($cleaned);
  88. // call the zapierPostWebhook() function
  89. zapierPostWebhook($obj['url'], $json);
  90. }
  91. $logtriggeraction = true;
  92. break;
  93. //case 'USER_NEW_PASSWORD':
  94. //case 'USER_ENABLEDISABLE':
  95. //case 'USER_DELETE':
  96. //case 'USER_LOGIN':
  97. //case 'USER_LOGIN_FAILED':
  98. //case 'USER_LOGOUT':
  99. // Actions
  100. case 'ACTION_MODIFY':
  101. //$logtriggeraction = true;
  102. break;
  103. case 'ACTION_CREATE':
  104. $resql = $this->db->query($sql);
  105. // TODO voir comment regrouper les webhooks en un post
  106. while ($resql && $obj = $this->db->fetch_array($resql)) {
  107. $cleaned = cleanObjectDatas(dol_clone($object));
  108. $cleaned = cleanAgendaEventsDatas($cleaned);
  109. $json = json_encode($cleaned);
  110. // call the zapierPostWebhook() function
  111. zapierPostWebhook($obj['url'], $json);
  112. //setEventMessages($obj['url'], null);
  113. }
  114. $logtriggeraction = true;
  115. break;
  116. case 'ACTION_DELETE':
  117. //$logtriggeraction = true;
  118. break;
  119. // Groups
  120. //case 'USERGROUP_CREATE':
  121. //case 'USERGROUP_MODIFY':
  122. //case 'USERGROUP_DELETE':
  123. // Categories
  124. // case 'CATEGORY_CREATE':
  125. // case 'CATEGORY_MODIFY':
  126. // case 'CATEGORY_DELETE':
  127. // case 'CATEGORY_SET_MULTILANGS':
  128. // Companies
  129. case 'COMPANY_CREATE':
  130. $resql = $this->db->query($sql);
  131. while ($resql && $obj = $this->db->fetch_array($resql)) {
  132. $cleaned = cleanObjectDatas(dol_clone($object));
  133. $json = json_encode($cleaned);
  134. // call the zapierPostWebhook() function
  135. zapierPostWebhook($obj['url'], $json);
  136. }
  137. $logtriggeraction = true;
  138. break;
  139. case 'COMPANY_MODIFY':
  140. $resql = $this->db->query($sql);
  141. while ($resql && $obj = $this->db->fetch_array($resql)) {
  142. $cleaned = cleanObjectDatas(dol_clone($object));
  143. $json = json_encode($cleaned);
  144. // call the zapierPostWebhook() function
  145. zapierPostWebhook($obj['url'], $json);
  146. }
  147. $logtriggeraction = true;
  148. break;
  149. case 'COMPANY_DELETE':
  150. //$logtriggeraction = true;
  151. break;
  152. // Contacts
  153. case 'CONTACT_CREATE':
  154. $resql = $this->db->query($sql);
  155. while ($resql && $obj = $this->db->fetch_array($resql)) {
  156. $cleaned = cleanObjectDatas(dol_clone($object));
  157. $json = json_encode($cleaned);
  158. // call the zapierPostWebhook() function
  159. zapierPostWebhook($obj['url'], $json);
  160. }
  161. $logtriggeraction = true;
  162. break;
  163. case 'CONTACT_MODIFY':
  164. $resql = $this->db->query($sql);
  165. while ($resql && $obj = $this->db->fetch_array($resql)) {
  166. $cleaned = cleanObjectDatas(dol_clone($object));
  167. $json = json_encode($cleaned);
  168. // call the zapierPostWebhook() function
  169. zapierPostWebhook($obj['url'], $json);
  170. }
  171. $logtriggeraction = true;
  172. break;
  173. case 'CONTACT_DELETE':
  174. break;
  175. case 'CONTACT_ENABLEDISABLE':
  176. break;
  177. // Products
  178. // case 'PRODUCT_CREATE':
  179. // case 'PRODUCT_MODIFY':
  180. // case 'PRODUCT_DELETE':
  181. // case 'PRODUCT_PRICE_MODIFY':
  182. // case 'PRODUCT_SET_MULTILANGS':
  183. // case 'PRODUCT_DEL_MULTILANGS':
  184. //Stock mouvement
  185. // case 'STOCK_MOVEMENT':
  186. //MYECMDIR
  187. // case 'MYECMDIR_DELETE':
  188. // case 'MYECMDIR_CREATE':
  189. // case 'MYECMDIR_MODIFY':
  190. // Sales orders
  191. case 'ORDER_CREATE':
  192. $resql = $this->db->query($sql);
  193. while ($resql && $obj = $this->db->fetch_array($resql)) {
  194. $cleaned = cleanObjectDatas(dol_clone($object));
  195. $json = json_encode($cleaned);
  196. // call the zapierPostWebhook() function
  197. zapierPostWebhook($obj['url'], $json);
  198. }
  199. $logtriggeraction = true;
  200. break;
  201. case 'ORDER_CLONE':
  202. break;
  203. case 'ORDER_VALIDATE':
  204. break;
  205. case 'ORDER_DELETE':
  206. case 'ORDER_CANCEL':
  207. case 'ORDER_SENTBYMAIL':
  208. case 'ORDER_CLASSIFY_BILLED':
  209. case 'ORDER_SETDRAFT':
  210. case 'LINEORDER_INSERT':
  211. case 'LINEORDER_UPDATE':
  212. case 'LINEORDER_DELETE':
  213. break;
  214. // Supplier orders
  215. // case 'ORDER_SUPPLIER_CREATE':
  216. // case 'ORDER_SUPPLIER_CLONE':
  217. // case 'ORDER_SUPPLIER_VALIDATE':
  218. // case 'ORDER_SUPPLIER_DELETE':
  219. // case 'ORDER_SUPPLIER_APPROVE':
  220. // case 'ORDER_SUPPLIER_REFUSE':
  221. // case 'ORDER_SUPPLIER_CANCEL':
  222. // case 'ORDER_SUPPLIER_SENTBYMAIL':
  223. // case 'ORDER_SUPPLIER_RECEIVE':
  224. // case 'LINEORDER_SUPPLIER_DISPATCH':
  225. // case 'LINEORDER_SUPPLIER_CREATE':
  226. // case 'LINEORDER_SUPPLIER_UPDATE':
  227. // Proposals
  228. // case 'PROPAL_CREATE':
  229. // case 'PROPAL_CLONE':
  230. // case 'PROPAL_MODIFY':
  231. // case 'PROPAL_VALIDATE':
  232. // case 'PROPAL_SENTBYMAIL':
  233. // case 'PROPAL_CLOSE_SIGNED':
  234. // case 'PROPAL_CLOSE_REFUSED':
  235. // case 'PROPAL_DELETE':
  236. // case 'LINEPROPAL_INSERT':
  237. // case 'LINEPROPAL_UPDATE':
  238. // case 'LINEPROPAL_DELETE':
  239. // SupplierProposal
  240. // case 'SUPPLIER_PROPOSAL_CREATE':
  241. // case 'SUPPLIER_PROPOSAL_CLONE':
  242. // case 'SUPPLIER_PROPOSAL_MODIFY':
  243. // case 'SUPPLIER_PROPOSAL_VALIDATE':
  244. // case 'SUPPLIER_PROPOSAL_SENTBYMAIL':
  245. // case 'SUPPLIER_PROPOSAL_CLOSE_SIGNED':
  246. // case 'SUPPLIER_PROPOSAL_CLOSE_REFUSED':
  247. // case 'SUPPLIER_PROPOSAL_DELETE':
  248. // case 'LINESUPPLIER_PROPOSAL_INSERT':
  249. // case 'LINESUPPLIER_PROPOSAL_UPDATE':
  250. // case 'LINESUPPLIER_PROPOSAL_DELETE':
  251. // Contracts
  252. // case 'CONTRACT_CREATE':
  253. // case 'CONTRACT_ACTIVATE':
  254. // case 'CONTRACT_CANCEL':
  255. // case 'CONTRACT_CLOSE':
  256. // case 'CONTRACT_DELETE':
  257. // case 'LINECONTRACT_INSERT':
  258. // case 'LINECONTRACT_UPDATE':
  259. // case 'LINECONTRACT_DELETE':
  260. // Bills
  261. // case 'BILL_CREATE':
  262. // case 'BILL_CLONE':
  263. // case 'BILL_MODIFY':
  264. // case 'BILL_VALIDATE':
  265. // case 'BILL_UNVALIDATE':
  266. // case 'BILL_SENTBYMAIL':
  267. // case 'BILL_CANCEL':
  268. // case 'BILL_DELETE':
  269. // case 'BILL_PAYED':
  270. // case 'LINEBILL_INSERT':
  271. // case 'LINEBILL_UPDATE':
  272. // case 'LINEBILL_DELETE':
  273. //Supplier Bill
  274. // case 'BILL_SUPPLIER_CREATE':
  275. // case 'BILL_SUPPLIER_UPDATE':
  276. // case 'BILL_SUPPLIER_DELETE':
  277. // case 'BILL_SUPPLIER_PAYED':
  278. // case 'BILL_SUPPLIER_UNPAYED':
  279. // case 'BILL_SUPPLIER_VALIDATE':
  280. // case 'BILL_SUPPLIER_UNVALIDATE':
  281. // case 'LINEBILL_SUPPLIER_CREATE':
  282. // case 'LINEBILL_SUPPLIER_UPDATE':
  283. // case 'LINEBILL_SUPPLIER_DELETE':
  284. // Payments
  285. // case 'PAYMENT_CUSTOMER_CREATE':
  286. // case 'PAYMENT_SUPPLIER_CREATE':
  287. // case 'PAYMENT_ADD_TO_BANK':
  288. // case 'PAYMENT_DELETE':
  289. // Online
  290. // case 'PAYMENT_PAYBOX_OK':
  291. // case 'PAYMENT_PAYPAL_OK':
  292. // case 'PAYMENT_STRIPE_OK':
  293. // Donation
  294. // case 'DON_CREATE':
  295. // case 'DON_UPDATE':
  296. // case 'DON_DELETE':
  297. // Interventions
  298. // case 'FICHINTER_CREATE':
  299. // case 'FICHINTER_MODIFY':
  300. // case 'FICHINTER_VALIDATE':
  301. // case 'FICHINTER_DELETE':
  302. // case 'LINEFICHINTER_CREATE':
  303. // case 'LINEFICHINTER_UPDATE':
  304. // case 'LINEFICHINTER_DELETE':
  305. // Members
  306. case 'MEMBER_CREATE':
  307. $resql = $this->db->query($sql);
  308. while ($resql && $obj = $this->db->fetch_array($resql)) {
  309. $cleaned = cleanObjectDatas(dol_clone($object));
  310. $json = json_encode($cleaned);
  311. // call the zapierPostWebhook() function
  312. zapierPostWebhook($obj['url'], $json);
  313. }
  314. $logtriggeraction = true;
  315. break;
  316. case 'MEMBER_MODIFY':
  317. $resql = $this->db->query($sql);
  318. while ($resql && $obj = $this->db->fetch_array($resql)) {
  319. $cleaned = cleanObjectDatas(dol_clone($object));
  320. $json = json_encode($cleaned);
  321. // call the zapierPostWebhook() function
  322. zapierPostWebhook($obj['url'], $json);
  323. }
  324. $logtriggeraction = true;
  325. break;
  326. // case 'MEMBER_VALIDATE':
  327. // case 'MEMBER_SUBSCRIPTION':
  328. // case 'MEMBER_NEW_PASSWORD':
  329. // case 'MEMBER_RESILIATE':
  330. // case 'MEMBER_DELETE':
  331. // Projects
  332. // case 'PROJECT_CREATE':
  333. // case 'PROJECT_MODIFY':
  334. // case 'PROJECT_DELETE':
  335. // Project tasks
  336. // case 'TASK_CREATE':
  337. // case 'TASK_MODIFY':
  338. // case 'TASK_DELETE':
  339. // Task time spent
  340. // case 'TASK_TIMESPENT_CREATE':
  341. // case 'TASK_TIMESPENT_MODIFY':
  342. // case 'TASK_TIMESPENT_DELETE':
  343. case 'TICKET_CREATE':
  344. $resql = $this->db->query($sql);
  345. // TODO voir comment regrouper les webhooks en un post
  346. while ($resql && $obj = $this->db->fetch_array($resql)) {
  347. $cleaned = cleanObjectDatas(dol_clone($object));
  348. $json = json_encode($cleaned);
  349. // call the zapierPostWebhook() function
  350. zapierPostWebhook($obj['url'], $json);
  351. }
  352. $logtriggeraction = true;
  353. break;
  354. // case 'TICKET_MODIFY':
  355. // break;
  356. // case 'TICKET_DELETE':
  357. // break;
  358. // Shipping
  359. // case 'SHIPPING_CREATE':
  360. // case 'SHIPPING_MODIFY':
  361. // case 'SHIPPING_VALIDATE':
  362. // case 'SHIPPING_SENTBYMAIL':
  363. // case 'SHIPPING_BILLED':
  364. // case 'SHIPPING_CLOSED':
  365. // case 'SHIPPING_REOPEN':
  366. // case 'SHIPPING_DELETE':
  367. }
  368. if ($logtriggeraction) {
  369. dol_syslog("Trigger '".$this->name."' for action '".$action."' launched by ".__FILE__." id=".$object->id);
  370. }
  371. return 0;
  372. }
  373. }
  374. /**
  375. * Post webhook in zapier with object data
  376. *
  377. * @param string $url Url provided by zapier
  378. * @param string $json Data to send
  379. * @return void
  380. */
  381. function zapierPostWebhook($url, $json)
  382. {
  383. $headers = array('Accept: application/json', 'Content-Type: application/json');
  384. // TODO disable wekhook if error ?
  385. dol_syslog("Send message to Zapier with json size=".dol_strlen($json), LOG_DEBUG);
  386. getURLContent($url, 'POSTALREADYFORMATED', $json, 1, $headers, array('http', 'https'), 0);
  387. /*
  388. $ch = curl_init();
  389. curl_setopt($ch, CURLOPT_URL, $url);
  390. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  391. curl_setopt($ch, CURLOPT_TIMEOUT, 10);
  392. curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
  393. curl_setopt($ch, CURLOPT_POST, 1);
  394. curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
  395. curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  396. $output = curl_exec($ch);
  397. curl_close($ch);
  398. */
  399. }
  400. /**
  401. * Clean sensible object datas
  402. *
  403. * @param Object $toclean Object to clean
  404. * @return Object Object with cleaned properties
  405. */
  406. function cleanObjectDatas($toclean)
  407. {
  408. // Remove $db object property for object
  409. unset($toclean->db);
  410. // Remove linkedObjects. We should already have linkedObjectsIds that avoid huge responses
  411. unset($toclean->linkedObjects);
  412. unset($toclean->lines); // should be ->lines
  413. unset($toclean->fields);
  414. unset($toclean->oldline);
  415. unset($toclean->error);
  416. unset($toclean->errors);
  417. unset($toclean->ref_previous);
  418. unset($toclean->ref_next);
  419. unset($toclean->projet); // Should be fk_project
  420. unset($toclean->project); // Should be fk_project
  421. unset($toclean->author); // Should be fk_user_author
  422. unset($toclean->timespent_old_duration);
  423. unset($toclean->timespent_id);
  424. unset($toclean->timespent_duration);
  425. unset($toclean->timespent_date);
  426. unset($toclean->timespent_datehour);
  427. unset($toclean->timespent_withhour);
  428. unset($toclean->timespent_fk_user);
  429. unset($toclean->timespent_note);
  430. unset($toclean->statuts);
  431. unset($toclean->statuts_short);
  432. unset($toclean->statuts_logo);
  433. unset($toclean->statuts_long);
  434. unset($toclean->element);
  435. unset($toclean->fk_element);
  436. unset($toclean->table_element);
  437. unset($toclean->table_element_line);
  438. unset($toclean->picto);
  439. unset($toclean->skip_update_total);
  440. unset($toclean->context);
  441. // Remove the $oldcopy property because it is not supported by the JSON
  442. // encoder. The following error is generated when trying to serialize
  443. // it: "Error encoding/decoding JSON: Type is not supported"
  444. // Note: Event if this property was correctly handled by the JSON
  445. // encoder, it should be ignored because keeping it would let the API
  446. // have a very strange behavior: calling PUT and then GET on the same
  447. // resource would give different results:
  448. // PUT /objects/{id} -> returns object with oldcopy = previous version of the object
  449. // GET /objects/{id} -> returns object with oldcopy empty
  450. unset($toclean->oldcopy);
  451. // If object has lines, remove $db property
  452. if (isset($toclean->lines) && count($toclean->lines) > 0) {
  453. $nboflines = count($toclean->lines);
  454. for ($i = 0; $i < $nboflines; $i++) {
  455. cleanObjectDatas($toclean->lines[$i]);
  456. }
  457. }
  458. // If object has linked objects, remove $db property
  459. /*
  460. if(isset($toclean->linkedObjects) && count($toclean->linkedObjects) > 0) {
  461. foreach($toclean->linkedObjects as $type_object => $linked_object) {
  462. foreach($linked_object as $toclean2clean) {
  463. $this->cleanObjectDatas($toclean2clean);
  464. }
  465. }
  466. }*/
  467. return $toclean;
  468. }
  469. /**
  470. * Clean sensible object datas
  471. *
  472. * @param Object $toclean Object to clean
  473. * @return Object Object with cleaned properties
  474. */
  475. function cleanAgendaEventsDatas($toclean)
  476. {
  477. unset($toclean->usermod);
  478. unset($toclean->libelle);
  479. //unset($toclean->array_options);
  480. unset($toclean->context);
  481. unset($toclean->canvas);
  482. unset($toclean->contact);
  483. unset($toclean->contact_id);
  484. unset($toclean->thirdparty);
  485. unset($toclean->user);
  486. unset($toclean->origin);
  487. unset($toclean->origin_id);
  488. unset($toclean->ref_ext);
  489. unset($toclean->statut);
  490. unset($toclean->country);
  491. unset($toclean->country_id);
  492. unset($toclean->country_code);
  493. unset($toclean->barcode_type);
  494. unset($toclean->barcode_type_code);
  495. unset($toclean->barcode_type_label);
  496. unset($toclean->barcode_type_coder);
  497. unset($toclean->mode_reglement_id);
  498. unset($toclean->cond_reglement_id);
  499. unset($toclean->cond_reglement);
  500. unset($toclean->fk_delivery_address);
  501. unset($toclean->shipping_method_id);
  502. unset($toclean->fk_account);
  503. unset($toclean->total_ht);
  504. unset($toclean->total_tva);
  505. unset($toclean->total_localtax1);
  506. unset($toclean->total_localtax2);
  507. unset($toclean->total_ttc);
  508. unset($toclean->fk_incoterms);
  509. unset($toclean->libelle_incoterms);
  510. unset($toclean->location_incoterms);
  511. unset($toclean->name);
  512. unset($toclean->lastname);
  513. unset($toclean->firstname);
  514. unset($toclean->civility_id);
  515. unset($toclean->contact);
  516. unset($toclean->societe);
  517. return $toclean;
  518. }