Discussions

Ask a Question
ANSWERED

Feedback Request with Direction Based on Client Response "Google Review"

Ideal World My tradesman finishes job and whilst talking to the client, ask's them to leave us feedback. He sends a text message from within servicem8 and the client gets a text similar to the existing feedback request, minus the comment box. The client enters a Star Rating 4 or 5 Star's left, Directs client to Google Listing or Facebook Listing, or a page with both options that they can click whichever they would prefer. 1, 2 or 3 Star's selected, Takes the client to a form that say's "Sorry we didnt meet your expectations, please let us know what we could have done better". Client fills in form which is emailed to manager. What can happen with this?
ANSWERED

Add a form to a Customized Invoice

Hi, am new to servicem8 and have recently started making my own invoices, I want to include a form I created , in a invoice but the images doesn't render. Is there anyway to include a form in my invoice? Secondly, is there anyway to export/ attach a form to my ,for example, invoice in order to send it to my clients? Or just simple export my form? Thank you.

Job Materials API - Distinguish between *actual* materials, and just labour or invoice items

I've been querying the Job Materials API endpoint, and it's returning a lot more than just Job Materials. I'm getting records back that include things like: - Callout charge - $50 - Labour to fix the heater - $150 - Etc. I'm hoping to be able to filter out those above kind of items, and instead only focus on *actual* materials used in the job. E.g. 1m of 50mm pipe, Kitchen sink, door latch, etc. Is there any programmatic way of distinguishing between physical materials, and the above items which appear to just be anything you'd add to an invoice? I did notice that on the Materials API endpoint, there's an attribute called "item_is_inventoried" which can be "0" or "1". Although I'm not sure if that would work for my purpose. Thanks in advance!
ANSWERED

API Error

Hello I am getting the response bellow when I use “event.auth.accessToken” a bearer token { "errorCode": 403, "message": "insufficient_scope", "additionalDetails": "\"read_job_materials\" scope required to complete this request" } This is a sample of the get request: var strJobUUID = event.eventArgs.entry[0].uuid; request.get( { url: 'https://api.servicem8.com/api_1.0/jobmaterial.json?%24filter=job_uuid%20eq%20'+strJobUUID, headers: { accept: 'application/json', authorization : 'Bearer '+event.auth.accessToken } }, Thank you, Mario

Date field on newly created jobs

We have found that when creating new jobs, the serviceM8 API ignores the 'date' field that we have set. Despite this being set in the initial request JSON object, when we query back the API we receive '0000-00-00 00:00:00' as the date. Posting the exact same JSON object back to the API (but to the UUID of the newly created job, to update the job) sees the date update correctly. Apart from posting to the API twice in order to correct the date, is there a means for the API to use the date as supplied in the initial creation request? (This request was also sent to developers@servicem8.com without response - full JSON request/response objects were provided to this email address)

Add on simple function error - 'Error Packaging Function. Please try again or contact support for assistance.'

I am receiving the error 'Error Packaging Function. Please try again or contact support for assistance.' when I try to save a simple function within a custom add on. This problem has only recently occurred as I have been able to save functions in the past. I have tried to save previously working add ons. I have also tried to save functions found in the example add ons (https://github.com/servicem8/addon-sdk-samples). I have also tried clearing my browser cache, cookies, files/images as well as using an incognito window. With the error showing for each.

Issues with posting via API - visible in mobile client but NOT in web client

See JSON below - it works, but ONLY shows on mobile, not on web browser (Chrome) Same issue with JobContacts as well. What are we missing below - again, shows on mobile client. { "active" : 1, "allocated_by_staff_uuid" : "5cb84cbf-b2b4-4902-b435-3598c3e6840b", "allocated_timestamp" : "2018-03-27 22:41:59", "allocation_date" : "2018-03-27 22:41:59", "allocation_window_uuid" : "f73aac98-13c5-43e8-b3ab-8eb09ef1651b", "edit_date" : "2018-03-27 22:41:59", "estimated_duration" : "15", "job_uuid" : "f6697c79-efda-4efe-bcaa-168d2efdb20b", "staff_uuid" : "7f9a23ce-95b7-4b7d-8efc-48eeb89fe2fb" }

"Retrieve a Client" causes add-on to timeout

I'm attempting to create something very similar to the Tasks tab on the Dispatch Board. The code below works but timesout if I replace ``` customer_name = get_job_customer(job_uuid, auth) ``` with ``` customer_name = get_customer_name(get_job_customer(job_uuid, auth), auth) ``` All the code in index.py: ``` import urllib3 import json from urllib.parse import quote def get_job_customer(uuid, auth): http = urllib3.PoolManager() url = "https://api.servicem8.com/api_1.0/job/" + uuid + ".json" response = http.request("GET", url, headers={'Authorization': 'Bearer ' + auth}) job = json.loads(response.data) return job["company_uuid"] def get_customer_name(uuid, auth): http = urllib3.PoolManager() url = "https://api.servicem8.com/api_1.0/company/" + uuid + ".json" response = http.request("GET", url, headers={'Authorization': 'Bearer ' + auth}) customer = json.loads(response.data) return customer["name"] def get_job_number(uuid, auth): http = urllib3.PoolManager() url = "https://api.servicem8.com/api_1.0/job/" + uuid + ".json" response = http.request("GET", url, headers={'Authorization': 'Bearer ' + auth}) job = json.loads(response.data) return job["generated_job_id"] def get_staff_fullname(uuid, auth): http = urllib3.PoolManager() url = "https://api.servicem8.com/api_1.0/staff/" + uuid + ".json" response = http.request("GET", url, headers={'Authorization': 'Bearer ' + auth}) staff = json.loads(response.data) return staff["first"] + " " + staff["last"] def lambda_handler(event, context): try: job_uuid = event['eventArgs']['jobUUID'] auth = event['auth']['accessToken'] http = urllib3.PoolManager() url = 'https://api.servicem8.com/api_1.0/task.json?' + quote('$filter') + '=' + quote("related_object_uuid eq ") +"'" + job_uuid + "'" response = http.request("GET", url, headers={'Authorization': 'Bearer ' + auth}) tasks = json.loads(response.data) for task in tasks: name = task["name"] customer_name = get_job_customer(job_uuid, auth) # ********************************************** Timesout if line above is replaced by line below ************************** #customer_name = get_customer_name(get_job_customer(job_uuid, auth), auth) job_number = get_job_number(job_uuid, auth) assigned = get_staff_fullname(task["assigned_to_staff_uuid"], auth) due_date = task["due_date"] if task["task_complete"] == "0": task_complete = "Not Yet Done" else: task_complete = "Done" response_html = ''' <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" class="gr__ap-southeast-2_go_servicem8_com ext-strict x-viewport"> <head> <link rel="stylesheet" type="text/css" href="//static-ap-southeast-2.servicem8.com/37039/css/css_style_rendered_beta.css"> <link rel="stylesheet" type="text/css" href="//static-ap-southeast-2.servicem8.com/37039/jscripts/extjs/resources/css/ext-compile-2017.css"> <link rel="stylesheet" type="text/css" href="//static-ap-southeast-2.servicem8.com/37039/css/themes/2017/main.css"> <script src="https://platform.servicem8.com/sdk/1.0/sdk.js"></script> <script> var client = SMClient.init(); client.resizeWindow(1150, 400); </script> </head> <body> <div class="x-grid3" hidefocus="true" id="ext-gen138" style="width: 1119px; height: 100px;"> <div class="x-grid3-viewport" id="ext-gen139"> <div class="x-grid3-header" id="ext-gen140"> <div class="x-grid3-header-inner" id="ext-gen142" style="width: 1119px;"> <div class="x-grid3-header-offset" style="width: 1119px;"> <table border="0" cellspacing="0" cellpadding="0" style="width: 1100px;"> <thead> <tr class="x-grid3-hd-row"> <td class="x-grid3-hd x-grid3-cell x-grid3-td-task-title x-grid3-cell-first sort-asc" style="width: 558px;"><div class="x-grid3-hd-inner x-grid3-hd-task-title" unselectable="on" style=""><a class="x-grid3-hd-btn" href="#" id="ext-gen480" style="height: 30px;"></a>Task<img alt="" class="x-grid3-sort-icon" src="data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="></div></td> <td class="x-grid3-hd x-grid3-cell x-grid3-td-1" style="width: 170px;"><div class="x-grid3-hd-inner x-grid3-hd-1" unselectable="on" style=""><a class="x-grid3-hd-btn" href="#" id="ext-gen494" style="height: 30px;"></a>Customer<img alt="" class="x-grid3-sort-icon" src="data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="></div></td> <td class="x-grid3-hd x-grid3-cell x-grid3-td-2" style="width: 60px;"><div class="x-grid3-hd-inner x-grid3-hd-2" unselectable="on" style=""><a class="x-grid3-hd-btn" href="#" id="ext-gen497" style="height: 30px;"></a>Job #<img alt="" class="x-grid3-sort-icon" src="data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="></div></td> <td class="x-grid3-hd x-grid3-cell x-grid3-td-3" style="width: 100px;"><div class="x-grid3-hd-inner x-grid3-hd-3" unselectable="on" style=""><a class="x-grid3-hd-btn" href="#" id="ext-gen496" style="height: 30px;"></a>Assigned Staff<img alt="" class="x-grid3-sort-icon" src="data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="></div></td> <td class="x-grid3-hd x-grid3-cell x-grid3-td-4" style="width: 100px;"><div class="x-grid3-hd-inner x-grid3-hd-4" unselectable="on" style=""><a class="x-grid3-hd-btn" href="#" id="ext-gen501" style="height: 30px;"></a>Due Date<img alt="" class="x-grid3-sort-icon" src="data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="></div></td> <td class="x-grid3-hd x-grid3-cell x-grid3-td-5 x-grid3-cell-last" style="width: 100px;"><div class="x-grid3-hd-inner x-grid3-hd-5" unselectable="on" style=""><a class="x-grid3-hd-btn" href="#"></a>Task Status<img alt="" class="x-grid3-sort-icon" src="data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="></div></td> </tr> </thead> </table> </div> </div> <div class="x-clear"></div> </div> <div class="x-grid3-scroller" id="ext-gen141" style="width: 1119px; height: 100px;"> <div class="x-grid3-body" style="width: 1100px;" id="ext-gen143"> <div class="x-grid3-row x-grid3-row-first" style="width: 1100px;"> <table class="x-grid3-row-table" border="0" cellspacing="0" cellpadding="0" style="width: 1100px;"> <tbody> <tr> <td class="x-grid3-col x-grid3-cell x-grid3-td-task-title x-grid3-cell-first " style="width: 558px;" tabindex="0"><div class="x-grid3-cell-inner x-grid3-col-task-title" unselectable="on">{name}</div></td> <td class="x-grid3-col x-grid3-cell x-grid3-td-1 " style="width: 170px;" tabindex="0"><div class="x-grid3-cell-inner x-grid3-col-1" unselectable="on">{customer_name}</div></td> <td class="x-grid3-col x-grid3-cell x-grid3-td-2 " style="width: 60px;" tabindex="0"><div class="x-grid3-cell-inner x-grid3-col-2" unselectable="on">{job_number}</div></td> <td class="x-grid3-col x-grid3-cell x-grid3-td-3 " style="width: 100px;" tabindex="0"><div class="x-grid3-cell-inner x-grid3-col-3" unselectable="on">{assigned}</div></td> <td class="x-grid3-col x-grid3-cell x-grid3-td-4 " style="width: 100px;" tabindex="0"><div class="x-grid3-cell-inner x-grid3-col-4" unselectable="on">{due_date}</div></td> <td class="x-grid3-col x-grid3-cell x-grid3-td-5 x-grid3-cell-last " style="width: 100px;" tabindex="0"><div class="x-grid3-cell-inner x-grid3-col-5" unselectable="on">{task_complete}</div></td> </tr> </tbody> </table> </div> </div> </div> </div> </div> </body> </html>'''.format(name=name, customer_name=customer_name, job_number=job_number, assigned=assigned, due_date=due_date, task_complete=task_complete) return {'eventResponse': response_html} except: print('Function failed') raise ```

Service pricing questions conditional logic

Would it be possible to add the same conditional logic block used in form questions to the questions in service pricing? If this is possible then the services addon can be used as a quote engine,

Unable to Process Attachment

Hi there, I'm receiving this error from my Attachment Download add-on: ```('Received response with content-encoding: gzip, but failed to decode it.', error('Error -3 while decompressing data: incorrect data check',))``` When I process the URL in Postman or Curl, it's returning an empty list. Here's an example URL: https://api.servicem8.com/api_1.0/attachment.json?%24filter=related_object_uuid%20eq%20'4cb144d4-ba56-408f-915a-7328131fdf9b' Any ideas? Clients are anxiously awaiting my response. Thank you.